⚡ Improve loading of chat events
This commit is contained in:
		| @@ -51,6 +51,14 @@ | ||||
|                  to determine the Window background behind the Flutter UI. --> | ||||
|             <meta-data android:name="flutter_deeplinking_enabled" android:value="true" /> | ||||
|  | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.VIEW" /> | ||||
|  | ||||
|                 <category android:name="android.intent.category.DEFAULT" /> | ||||
|                 <category android:name="android.intent.category.BROWSABLE" /> | ||||
|                 <data android:scheme="solink" /> | ||||
|             </intent-filter> | ||||
|  | ||||
|             <intent-filter android:autoVerify="true"> | ||||
|                 <action android:name="android.intent.action.VIEW" /> | ||||
|                 <category android:name="android.intent.category.DEFAULT" /> | ||||
| @@ -61,14 +69,6 @@ | ||||
|                 <data android:scheme="https" /> | ||||
|             </intent-filter> | ||||
|  | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.VIEW" /> | ||||
|  | ||||
|                 <category android:name="android.intent.category.DEFAULT" /> | ||||
|                 <category android:name="android.intent.category.BROWSABLE" /> | ||||
|                 <data android:scheme="solink" /> | ||||
|             </intent-filter> | ||||
|  | ||||
|             <meta-data | ||||
|                 android:name="io.flutter.embedding.android.NormalTheme" | ||||
|                 android:resource="@style/NormalTheme" | ||||
|   | ||||
| @@ -12,7 +12,7 @@ class ChatEventController { | ||||
|       RxList.empty(growable: true); | ||||
|   final RxInt totalEvents = 0.obs; | ||||
|  | ||||
|   final RxBool isLoading = false.obs; | ||||
|   final RxBool isLoading = true.obs; | ||||
|  | ||||
|   Channel? channel; | ||||
|   String? scope; | ||||
| @@ -27,7 +27,7 @@ class ChatEventController { | ||||
|     return await src.getEvent(id, channel!, scope: scope!); | ||||
|   } | ||||
|  | ||||
|   Future<void> getEvents(Channel channel, String scope) async { | ||||
|   Future<void> getInitialEvents(Channel channel, String scope) async { | ||||
|     this.channel = channel; | ||||
|     this.scope = scope; | ||||
|  | ||||
| @@ -38,7 +38,7 @@ class ChatEventController { | ||||
|       final result = await src.fetchRemoteEvents( | ||||
|         channel, | ||||
|         scope, | ||||
|         remainDepth: 3, | ||||
|         depth: 1, | ||||
|         offset: 0, | ||||
|       ); | ||||
|       totalEvents.value = result?.$2 ?? 0; | ||||
| @@ -58,6 +58,7 @@ class ChatEventController { | ||||
|       final result = await src.pullRemoteEvents( | ||||
|         channel, | ||||
|         scope: scope, | ||||
|         depth: 1, | ||||
|       ); | ||||
|       totalEvents.value = result?.$2 ?? 0; | ||||
|       await syncLocal(channel); | ||||
| @@ -71,7 +72,7 @@ class ChatEventController { | ||||
|       final result = await src.fetchRemoteEvents( | ||||
|         channel, | ||||
|         scope, | ||||
|         remainDepth: 3, | ||||
|         depth: 3, | ||||
|         offset: currentEvents.length, | ||||
|       ); | ||||
|       if (result != null) { | ||||
| @@ -123,6 +124,7 @@ class ChatEventController { | ||||
|       entry = await src.receiveEvent(remote); | ||||
|     } | ||||
|  | ||||
|     totalEvents.value++; | ||||
|     insertEvent(entry); | ||||
|     applyEvent(entry); | ||||
|   } | ||||
|   | ||||
| @@ -51,12 +51,12 @@ class MessagesFetchingProvider extends GetxController { | ||||
|   Future<(List<Event>, int)?> fetchRemoteEvents( | ||||
|     Channel channel, | ||||
|     String scope, { | ||||
|     required int remainDepth, | ||||
|     required int depth, | ||||
|     bool Function(List<Event> items)? onBrake, | ||||
|     take = 10, | ||||
|     offset = 0, | ||||
|   }) async { | ||||
|     if (remainDepth <= 0) { | ||||
|     if (depth <= 0) { | ||||
|       return null; | ||||
|     } | ||||
|  | ||||
| @@ -84,7 +84,7 @@ class MessagesFetchingProvider extends GetxController { | ||||
|     final expandResult = (await fetchRemoteEvents( | ||||
|           channel, | ||||
|           scope, | ||||
|           remainDepth: remainDepth - 1, | ||||
|           depth: depth - 1, | ||||
|           take: take, | ||||
|           offset: offset + result.length, | ||||
|         )) | ||||
| @@ -162,7 +162,7 @@ class MessagesFetchingProvider extends GetxController { | ||||
|     final data = await fetchRemoteEvents( | ||||
|       channel, | ||||
|       scope, | ||||
|       remainDepth: depth, | ||||
|       depth: depth, | ||||
|       offset: offset, | ||||
|       onBrake: (items) { | ||||
|         return items.any((x) => x.id == lastOne?.id); | ||||
|   | ||||
| @@ -2,7 +2,6 @@ import 'dart:async'; | ||||
| import 'dart:ui'; | ||||
|  | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter_animate/flutter_animate.dart'; | ||||
| import 'package:get/get.dart'; | ||||
| import 'package:solian/controllers/chat_events_controller.dart'; | ||||
| import 'package:solian/exts.dart'; | ||||
| @@ -156,7 +155,7 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> | ||||
|  | ||||
|   void _keepUpdateWithServer() { | ||||
|     _getOngoingCall(); | ||||
|     _chatController.getEvents(_channel!, widget.realm); | ||||
|     _chatController.getInitialEvents(_channel!, widget.realm); | ||||
|     setState(() => _isOutOfSyncSince = null); | ||||
|   } | ||||
|  | ||||
| @@ -193,7 +192,7 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> | ||||
|  | ||||
|     _getOngoingCall(); | ||||
|     _getChannel().then((_) { | ||||
|       _chatController.getEvents(_channel!, widget.realm); | ||||
|       _chatController.getInitialEvents(_channel!, widget.realm); | ||||
|       _listenMessages(); | ||||
|     }); | ||||
|   } | ||||
| @@ -295,13 +294,6 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> | ||||
|                       }, | ||||
|                     ), | ||||
|                   ), | ||||
|                   Obx(() { | ||||
|                     if (_chatController.isLoading.isTrue) { | ||||
|                       return const LinearProgressIndicator().animate().slideY(); | ||||
|                     } else { | ||||
|                       return const SizedBox.shrink(); | ||||
|                     } | ||||
|                   }), | ||||
|                   ClipRect( | ||||
|                     child: BackdropFilter( | ||||
|                       filter: ImageFilter.blur(sigmaX: 50, sigmaY: 50), | ||||
|   | ||||
| @@ -6,6 +6,7 @@ import 'package:solian/models/event.dart'; | ||||
| import 'package:solian/providers/last_read.dart'; | ||||
| import 'package:solian/widgets/chat/chat_event.dart'; | ||||
| import 'package:solian/widgets/chat/chat_event_action.dart'; | ||||
| import 'package:very_good_infinite_list/very_good_infinite_list.dart'; | ||||
|  | ||||
| class ChatEventList extends StatelessWidget { | ||||
|   final String scope; | ||||
| @@ -36,8 +37,9 @@ class ChatEventList extends StatelessWidget { | ||||
|       reverse: true, | ||||
|       slivers: [ | ||||
|         Obx(() { | ||||
|           return SliverList.builder( | ||||
|           return SliverInfiniteList( | ||||
|             key: Key('chat-history#${channel.id}'), | ||||
|             isLoading: chatController.isLoading.value, | ||||
|             itemCount: chatController.currentEvents.length, | ||||
|             itemBuilder: (context, index) { | ||||
|               Get.find<LastReadProvider>().messagesLastReadAt = | ||||
| @@ -89,28 +91,12 @@ class ChatEventList extends StatelessWidget { | ||||
|                 }, | ||||
|               ); | ||||
|             }, | ||||
|           ); | ||||
|         }), | ||||
|         Obx(() { | ||||
|           final amount = | ||||
|               chatController.totalEvents - chatController.currentEvents.length; | ||||
|  | ||||
|           if (amount.value <= 0 || chatController.isLoading.isTrue) { | ||||
|             return const SliverToBoxAdapter(child: SizedBox.shrink()); | ||||
|           } | ||||
|  | ||||
|           return SliverToBoxAdapter( | ||||
|             child: ListTile( | ||||
|               tileColor: Theme.of(context).colorScheme.surfaceContainerLow, | ||||
|               leading: const Icon(Icons.sync_disabled), | ||||
|               title: Text('messageUnSync'.tr), | ||||
|               subtitle: Text('messageUnSyncCaption'.trParams({ | ||||
|                 'count': amount.string, | ||||
|               })), | ||||
|               onTap: () { | ||||
|                 chatController.loadEvents(channel, scope); | ||||
|               }, | ||||
|             ), | ||||
|             onFetchData: () { | ||||
|               chatController.loadEvents( | ||||
|                 chatController.channel!, | ||||
|                 chatController.scope!, | ||||
|               ); | ||||
|             }, | ||||
|           ); | ||||
|         }), | ||||
|       ], | ||||
|   | ||||
		Reference in New Issue
	
	Block a user