diff --git a/lib/controllers/room_chat.dart b/lib/controllers/room_chat.dart index 3e531bb..98a3fd9 100644 --- a/lib/controllers/room_chat.dart +++ b/lib/controllers/room_chat.dart @@ -17,27 +17,31 @@ import "package:nexus/models/room.dart"; class RoomChatController extends AsyncNotifier?> { final String roomId; + Future? _loadingOlder; RoomChatController(this.roomId); @override Future?> build() async { final client = ref.watch(ClientController.provider.notifier); - final room = ref.watch( + final initialRoom = ref.watch( RoomsController.provider.select((rooms) => rooms[roomId]), ); - if (room == null) return null; + if (initialRoom == null) return null; + Room room = initialRoom; if (!room.hasFetchedState) { final state = await client.getRoomState(.new(roomId: roomId)); 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 // until there's no more or the conditions are met. if (room.hasMore && room.timeline.length < 20) { - loadOlder(); + await loadOlder(); + room = ref.read(RoomsController.provider)[roomId] ?? room; } return room.timeline @@ -74,18 +78,22 @@ class RoomChatController extends AsyncNotifier?> { ), ); - Future loadOlder() async { - final timelineKeys = ref - .read(RoomsController.provider.select((value) => value[roomId])) - ?.timeline - .keys; + Future loadOlder() => _loadingOlder ??= _loadOlder().whenComplete(() { + _loadingOlder = null; + }); + + Future _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 .watch(ClientController.provider.notifier) .paginate( .new( roomId: roomId, - maxTimelineId: timelineKeys?.isNotEmpty == true - ? timelineKeys?.reduce(min) + maxTimelineId: timelineKeys.isNotEmpty + ? timelineKeys.reduce(min) : null, ), );