🐛 Fix messages loading
This commit is contained in:
parent
e11bf204af
commit
5941cb9fd5
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:solian/models/channel.dart';
|
import 'package:solian/models/channel.dart';
|
||||||
import 'package:solian/models/event.dart';
|
import 'package:solian/models/event.dart';
|
||||||
@ -30,14 +32,31 @@ class ChatEventController {
|
|||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
|
|
||||||
isLoading.value = true;
|
const firstTake = 20;
|
||||||
await syncLocal(channel, take: 10);
|
const furtherTake = 100;
|
||||||
|
|
||||||
src.pullRemoteEvents(channel, scope: scope, take: 10).then((result) {
|
isLoading.value = true;
|
||||||
totalEvents.value = result?.$2 ?? 0;
|
await syncLocal(channel, take: firstTake);
|
||||||
syncLocal(channel, take: 10);
|
|
||||||
});
|
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
|
|
||||||
|
// Take a small range of messages to check is local database up to date
|
||||||
|
var isUpToDate = true;
|
||||||
|
final result =
|
||||||
|
await src.pullRemoteEvents(channel, scope: scope, take: firstTake);
|
||||||
|
totalEvents.value = result?.$2 ?? 0;
|
||||||
|
if ((result?.$1.length ?? 0) > 0) {
|
||||||
|
final minId = result!.$1.map((x) => x.id).reduce(math.min);
|
||||||
|
isUpToDate = await src.getEventFromLocal(minId) != null;
|
||||||
|
}
|
||||||
|
syncLocal(channel, take: firstTake);
|
||||||
|
|
||||||
|
if (!isUpToDate) {
|
||||||
|
// Loading more content due to isn't up to date
|
||||||
|
final result =
|
||||||
|
await src.pullRemoteEvents(channel, scope: scope, take: furtherTake);
|
||||||
|
totalEvents.value = result?.$2 ?? 0;
|
||||||
|
syncLocal(channel, take: furtherTake);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> loadEvents(Channel channel, String scope) async {
|
Future<void> loadEvents(Channel channel, String scope) async {
|
||||||
@ -46,7 +65,9 @@ class ChatEventController {
|
|||||||
|
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
await syncLocal(channel, take: take, offset: offset);
|
await syncLocal(channel, take: take, offset: offset);
|
||||||
src.pullRemoteEvents(channel, scope: scope, offset: offset).then((result) {
|
src
|
||||||
|
.pullRemoteEvents(channel, scope: scope, take: take, offset: offset)
|
||||||
|
.then((result) {
|
||||||
totalEvents.value = result?.$2 ?? 0;
|
totalEvents.value = result?.$2 ?? 0;
|
||||||
syncLocal(channel, take: take, offset: offset);
|
syncLocal(channel, take: take, offset: offset);
|
||||||
});
|
});
|
||||||
@ -56,7 +77,11 @@ class ChatEventController {
|
|||||||
Future<bool> syncLocal(Channel channel,
|
Future<bool> syncLocal(Channel channel,
|
||||||
{required int take, int offset = 0}) async {
|
{required int take, int offset = 0}) async {
|
||||||
final data = await src.listEvents(channel, take: take, offset: offset);
|
final data = await src.listEvents(channel, take: take, offset: offset);
|
||||||
currentEvents.replaceRange(0, currentEvents.length, data);
|
if (currentEvents.length >= offset + take) {
|
||||||
|
currentEvents.replaceRange(offset, offset + take, data);
|
||||||
|
} else {
|
||||||
|
currentEvents.insertAll(currentEvents.length, data);
|
||||||
|
}
|
||||||
for (final x in data.reversed) {
|
for (final x in data.reversed) {
|
||||||
applyEvent(x);
|
applyEvent(x);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ part 'packet.g.dart';
|
|||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class NetworkPackage {
|
class NetworkPackage {
|
||||||
@JsonKey(name: 'w')
|
@JsonKey(name: 'w', defaultValue: 'unknown')
|
||||||
String method;
|
String method;
|
||||||
@JsonKey(name: 'e')
|
@JsonKey(name: 'e')
|
||||||
String? endpoint;
|
String? endpoint;
|
||||||
|
@ -8,7 +8,7 @@ part of 'packet.dart';
|
|||||||
|
|
||||||
NetworkPackage _$NetworkPackageFromJson(Map<String, dynamic> json) =>
|
NetworkPackage _$NetworkPackageFromJson(Map<String, dynamic> json) =>
|
||||||
NetworkPackage(
|
NetworkPackage(
|
||||||
method: json['w'] as String,
|
method: json['w'] as String? ?? 'unknown',
|
||||||
endpoint: json['e'] as String?,
|
endpoint: json['e'] as String?,
|
||||||
message: json['m'] as String?,
|
message: json['m'] as String?,
|
||||||
payload: json['p'] as Map<String, dynamic>?,
|
payload: json['p'] as Map<String, dynamic>?,
|
||||||
|
@ -129,6 +129,14 @@ class MessagesFetchingProvider extends GetxController {
|
|||||||
return await receiveEvent(remoteRecord);
|
return await receiveEvent(remoteRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<LocalMessageEventTableData?> getEventFromLocal(int id) async {
|
||||||
|
final database = Get.find<DatabaseProvider>().database;
|
||||||
|
final localRecord = await (database.select(database.localMessageEventTable)
|
||||||
|
..where((x) => x.id.equals(id)))
|
||||||
|
.getSingleOrNull();
|
||||||
|
return localRecord;
|
||||||
|
}
|
||||||
|
|
||||||
/// Pull the remote events to local database
|
/// Pull the remote events to local database
|
||||||
Future<(List<Event>, int)?> pullRemoteEvents(Channel channel,
|
Future<(List<Event>, int)?> pullRemoteEvents(Channel channel,
|
||||||
{String scope = 'global', take = 10, offset = 0}) async {
|
{String scope = 'global', take = 10, offset = 0}) async {
|
||||||
|
@ -92,10 +92,13 @@ class ChatEventList extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
onFetchData: () {
|
onFetchData: () {
|
||||||
|
if (chatController.currentEvents.length <
|
||||||
|
chatController.totalEvents.value) {
|
||||||
chatController.loadEvents(
|
chatController.loadEvents(
|
||||||
chatController.channel!,
|
chatController.channel!,
|
||||||
chatController.scope!,
|
chatController.scope!,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
Loading…
Reference in New Issue
Block a user