♻️ 使用 SQLITE 来存储本地消息记录 #1

Merged
LittleSheep merged 6 commits from features/local-message-history into master 2024-06-23 11:13:42 +00:00
3 changed files with 52 additions and 20 deletions
Showing only changes of commit d0cd75d653 - Show all commits

View File

@ -10,16 +10,31 @@ class ChatHistoryController {
final RxList<LocalMessage> currentHistory = RxList.empty(growable: true); final RxList<LocalMessage> currentHistory = RxList.empty(growable: true);
final RxInt totalHistoryCount = 0.obs; final RxInt totalHistoryCount = 0.obs;
final RxBool isLoading = false.obs;
initialize() async { initialize() async {
database = await createHistoryDb(); database = await createHistoryDb();
currentHistory.clear(); currentHistory.clear();
} }
Future<void> getMessages(Channel channel, String scope) async { Future<void> 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); await syncHistory(channel);
} }
Future<void> 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<void> syncHistory(Channel channel) async { Future<void> syncHistory(Channel channel) async {
currentHistory.replaceRange(0, currentHistory.length, currentHistory.replaceRange(0, currentHistory.length,
await database.localMessages.findAllByChannel(channel.id)); await database.localMessages.findAllByChannel(channel.id));
@ -27,7 +42,6 @@ class ChatHistoryController {
receiveMessage(Message remote) async { receiveMessage(Message remote) async {
final entry = await database.receiveMessage(remote); final entry = await database.receiveMessage(remote);
totalHistoryCount.value++;
currentHistory.add(entry); currentHistory.add(entry);
} }
@ -42,7 +56,6 @@ class ChatHistoryController {
void burnMessage(int id) async { void burnMessage(int id) async {
await database.burnMessage(id); await database.burnMessage(id);
totalHistoryCount.value--;
currentHistory.removeWhere((x) => x.id == id); currentHistory.removeWhere((x) => x.id == id);
} }
} }

View File

@ -36,13 +36,13 @@ extension MessageHistoryHelper on MessageHistoryDb {
await localMessages.delete(id); 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 lastOne = await localMessages.findLastByChannel(channel.id);
final data = await _getRemoteMessages( final data = await _getRemoteMessages(
channel, channel,
scope, scope,
remainBreath: 10, remainBreath: breath,
offset: offset, offset: offset,
onBrake: (items) { onBrake: (items) {
return items.any((x) => x.id == lastOne?.id); return items.any((x) => x.id == lastOne?.id);

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:solian/controllers/chat_history_controller.dart'; import 'package:solian/controllers/chat_history_controller.dart';
import 'package:solian/exts.dart'; import 'package:solian/exts.dart';
@ -330,23 +331,41 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> {
Obx(() { Obx(() {
final amount = _chatController.totalHistoryCount - final amount = _chatController.totalHistoryCount -
_chatController.currentHistory.length; _chatController.currentHistory.length;
if (amount > 0) {
return SliverToBoxAdapter( if (amount.value <= 0 ||
child: ListTile( _chatController.isLoading.isTrue) {
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 {
return const SliverToBoxAdapter(child: SizedBox()); 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),
);
}), }),
], ],
), ),