♻️ 使用 SQLITE 来存储本地消息记录 #1
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
|
||||||
|
if (amount.value <= 0 ||
|
||||||
|
_chatController.isLoading.isTrue) {
|
||||||
|
return const SliverToBoxAdapter(child: SizedBox());
|
||||||
|
}
|
||||||
|
|
||||||
return SliverToBoxAdapter(
|
return SliverToBoxAdapter(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
tileColor: Theme.of(context)
|
tileColor:
|
||||||
.colorScheme
|
Theme.of(context).colorScheme.surfaceContainerLow,
|
||||||
.surfaceContainerLow,
|
|
||||||
leading: const Icon(Icons.sync_disabled),
|
leading: const Icon(Icons.sync_disabled),
|
||||||
title: Text('messageUnsync'.tr),
|
title: Text('messageUnsync'.tr),
|
||||||
subtitle: Text('messageUnsyncCaption'.trParams({
|
subtitle: Text('messageUnsyncCaption'.trParams({
|
||||||
'count': amount.string,
|
'count': amount.string,
|
||||||
})),
|
})),
|
||||||
onTap: () {},
|
onTap: () {
|
||||||
|
_chatController.getMoreMessages(
|
||||||
|
_channel!,
|
||||||
|
widget.realm,
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
}),
|
||||||
|
Obx(() {
|
||||||
|
if (_chatController.isLoading.isFalse) {
|
||||||
return const SliverToBoxAdapter(child: SizedBox());
|
return const SliverToBoxAdapter(child: SizedBox());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return SliverToBoxAdapter(
|
||||||
|
child: const LinearProgressIndicator()
|
||||||
|
.animate()
|
||||||
|
.slideY()
|
||||||
|
.paddingOnly(bottom: 4),
|
||||||
|
);
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Loading…
Reference in New Issue
Block a user