Improve loading of chat events

This commit is contained in:
LittleSheep 2024-09-15 10:55:27 +08:00
parent 00449f3f83
commit 2183a2ca55
5 changed files with 29 additions and 49 deletions

View File

@ -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"

View File

@ -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);
}

View File

@ -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);

View File

@ -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),

View File

@ -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!,
);
},
);
}),
],