diff --git a/lib/controllers/chat_history_controller.dart b/lib/controllers/chat_history_controller.dart index b7f69c8..2a97bd6 100644 --- a/lib/controllers/chat_history_controller.dart +++ b/lib/controllers/chat_history_controller.dart @@ -10,16 +10,31 @@ class ChatHistoryController { final RxList currentHistory = RxList.empty(growable: true); final RxInt totalHistoryCount = 0.obs; + final RxBool isLoading = false.obs; + initialize() async { database = await createHistoryDb(); currentHistory.clear(); } Future getMessages(Channel channel, String scope) async { - totalHistoryCount.value = await database.syncMessages(channel, scope: scope); + totalHistoryCount.value = + await database.syncMessages(channel, scope: scope); await syncHistory(channel); } + Future getMoreMessages(Channel channel, String scope) async { + isLoading.value = true; + totalHistoryCount.value = await database.syncMessages( + channel, + breath: 3, + scope: scope, + offset: currentHistory.length, + ); + await syncHistory(channel); + isLoading.value = false; + } + Future syncHistory(Channel channel) async { currentHistory.replaceRange(0, currentHistory.length, await database.localMessages.findAllByChannel(channel.id)); @@ -27,7 +42,6 @@ class ChatHistoryController { receiveMessage(Message remote) async { final entry = await database.receiveMessage(remote); - totalHistoryCount.value++; currentHistory.add(entry); } @@ -42,7 +56,6 @@ class ChatHistoryController { void burnMessage(int id) async { await database.burnMessage(id); - totalHistoryCount.value--; currentHistory.removeWhere((x) => x.id == id); } } diff --git a/lib/providers/message/helper.dart b/lib/providers/message/helper.dart index f397e13..4404f79 100644 --- a/lib/providers/message/helper.dart +++ b/lib/providers/message/helper.dart @@ -36,13 +36,13 @@ extension MessageHistoryHelper on MessageHistoryDb { await localMessages.delete(id); } - syncMessages(Channel channel, {String scope = 'global', offset = 0}) async { + syncMessages(Channel channel, {String scope = 'global', breath = 10, offset = 0}) async { final lastOne = await localMessages.findLastByChannel(channel.id); final data = await _getRemoteMessages( channel, scope, - remainBreath: 10, + remainBreath: breath, offset: offset, onBrake: (items) { return items.any((x) => x.id == lastOne?.id); diff --git a/lib/screens/channel/channel_chat.dart b/lib/screens/channel/channel_chat.dart index 840e0af..8ad1d4c 100644 --- a/lib/screens/channel/channel_chat.dart +++ b/lib/screens/channel/channel_chat.dart @@ -2,6 +2,7 @@ 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_history_controller.dart'; import 'package:solian/exts.dart'; @@ -330,23 +331,41 @@ class _ChannelChatScreenState extends State { Obx(() { final amount = _chatController.totalHistoryCount - _chatController.currentHistory.length; - if (amount > 0) { - 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: () {}, - ), - ); - } else { + + if (amount.value <= 0 || + _chatController.isLoading.isTrue) { return const SliverToBoxAdapter(child: SizedBox()); } + + 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.getMoreMessages( + _channel!, + widget.realm, + ); + }, + ), + ); + }), + Obx(() { + if (_chatController.isLoading.isFalse) { + return const SliverToBoxAdapter(child: SizedBox()); + } + + return SliverToBoxAdapter( + child: const LinearProgressIndicator() + .animate() + .slideY() + .paddingOnly(bottom: 4), + ); }), ], ),