fix: timeline pagination
This commit is contained in:
parent
724171384c
commit
2f3bd7a8ac
1 changed files with 19 additions and 12 deletions
|
|
@ -17,27 +17,30 @@ import "package:nexus/models/room.dart";
|
||||||
|
|
||||||
class RoomChatController extends AsyncNotifier<IList<Event>?> {
|
class RoomChatController extends AsyncNotifier<IList<Event>?> {
|
||||||
final String roomId;
|
final String roomId;
|
||||||
|
Future<bool>? _loadingOlder;
|
||||||
RoomChatController(this.roomId);
|
RoomChatController(this.roomId);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<IList<Event>?> build() async {
|
Future<IList<Event>?> build() async {
|
||||||
final client = ref.watch(ClientController.provider.notifier);
|
final client = ref.watch(ClientController.provider.notifier);
|
||||||
final room = ref.watch(
|
final initialRoom = ref.watch(
|
||||||
RoomsController.provider.select((rooms) => rooms[roomId]),
|
RoomsController.provider.select((rooms) => rooms[roomId]),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (room == null) return null;
|
if (initialRoom == null) return null;
|
||||||
|
Room room = initialRoom;
|
||||||
|
|
||||||
if (!room.hasFetchedState) {
|
if (!room.hasFetchedState) {
|
||||||
final state = await client.getRoomState(.new(roomId: roomId));
|
final state = await client.getRoomState(.new(roomId: roomId));
|
||||||
|
|
||||||
await ref.read(RoomsController.provider.notifier).addState(roomId, state);
|
await ref.read(RoomsController.provider.notifier).addState(roomId, state);
|
||||||
|
room = ref.read(RoomsController.provider)[roomId] ?? room;
|
||||||
}
|
}
|
||||||
|
|
||||||
// While there are under 20 events, try to load more
|
// Load one more page when the initial timeline is short.
|
||||||
// until there's no more or the conditions are met.
|
|
||||||
if (room.hasMore && room.timeline.length < 20) {
|
if (room.hasMore && room.timeline.length < 20) {
|
||||||
loadOlder();
|
await loadOlder();
|
||||||
|
room = ref.read(RoomsController.provider)[roomId] ?? room;
|
||||||
}
|
}
|
||||||
|
|
||||||
return room.timeline
|
return room.timeline
|
||||||
|
|
@ -74,18 +77,22 @@ class RoomChatController extends AsyncNotifier<IList<Event>?> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<bool> loadOlder() async {
|
Future<bool> loadOlder() => _loadingOlder ??= _loadOlder().whenComplete(() {
|
||||||
final timelineKeys = ref
|
_loadingOlder = null;
|
||||||
.read(RoomsController.provider.select((value) => value[roomId]))
|
});
|
||||||
?.timeline
|
|
||||||
.keys;
|
Future<bool> _loadOlder() async {
|
||||||
|
final room = ref.read(RoomsController.provider)[roomId];
|
||||||
|
if (room == null || !room.hasMore) return false;
|
||||||
|
|
||||||
|
final timelineKeys = room.timeline.keys;
|
||||||
final response = await ref
|
final response = await ref
|
||||||
.watch(ClientController.provider.notifier)
|
.watch(ClientController.provider.notifier)
|
||||||
.paginate(
|
.paginate(
|
||||||
.new(
|
.new(
|
||||||
roomId: roomId,
|
roomId: roomId,
|
||||||
maxTimelineId: timelineKeys?.isNotEmpty == true
|
maxTimelineId: timelineKeys.isNotEmpty
|
||||||
? timelineKeys?.reduce(min)
|
? timelineKeys.reduce(min)
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue