make loadOlder properly guard

This commit is contained in:
Henry Hiles 2026-08-11 10:39:45 -04:00
commit 43d2e94d62
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
2 changed files with 38 additions and 31 deletions

View file

@ -75,12 +75,13 @@ class RoomChatController extends AsyncNotifier<IList<Event>?> {
); );
Future<bool> loadOlder() async { Future<bool> loadOlder() async {
state = AsyncLoading();
final timelineKeys = ref final timelineKeys = ref
.read(RoomsController.provider.select((value) => value[roomId])) .read(RoomsController.provider.select((value) => value[roomId]))
?.timeline ?.timeline
.keys; .keys;
final response = await ref final response = await ref
.watch(ClientController.provider.notifier) .read(ClientController.provider.notifier)
.paginate( .paginate(
.new( .new(
roomId: roomId, roomId: roomId,
@ -90,26 +91,30 @@ class RoomChatController extends AsyncNotifier<IList<Event>?> {
), ),
); );
ref if (response.events.isEmpty) {
.watch(RoomsController.provider.notifier) state = .data(state.value);
.update( } else {
IMap({ ref
roomId: Room( .read(RoomsController.provider.notifier)
events: IMap.fromIterable( .update(
response.events.addAll(response.relatedEvents), IMap({
keyMapper: (event) => event.rowId, roomId: Room(
valueMapper: (event) => event, events: IMap.fromIterable(
response.events.addAll(response.relatedEvents),
keyMapper: (event) => event.rowId,
valueMapper: (event) => event,
),
hasMore: response.hasMore,
timeline: IMap.fromIterable(
response.events,
keyMapper: (event) => event.timelineRowId,
valueMapper: (event) => event.rowId,
),
), ),
hasMore: response.hasMore, }),
timeline: IMap.fromIterable( .new(),
response.events, );
keyMapper: (event) => event.timelineRowId, }
valueMapper: (event) => event.rowId,
),
),
}),
.new(),
);
return response.hasMore; return response.hasMore;
} }

View file

@ -80,6 +80,7 @@ class RoomChat extends HookConsumerWidget {
final controllerData = ref.watch(controllerProvider); final controllerData = ref.watch(controllerProvider);
final topEventBeforeLoad = useState<String?>(null); final topEventBeforeLoad = useState<String?>(null);
final hasMore = useState<bool>(true);
Future<void> jumpToId(String eventId) async { Future<void> jumpToId(String eventId) async {
final index = controllerData.value?.indexWhere( final index = controllerData.value?.indexWhere(
@ -105,7 +106,7 @@ class RoomChat extends HookConsumerWidget {
Future<void> loadOlder() async { Future<void> loadOlder() async {
if (controllerData case AsyncData(:final value?)) { if (controllerData case AsyncData(:final value?)) {
topEventBeforeLoad.value = value.firstOrNull?.eventId; topEventBeforeLoad.value = value.firstOrNull?.eventId;
await notifier.loadOlder(); hasMore.value = await notifier.loadOlder();
} }
} }
@ -470,19 +471,20 @@ class RoomChat extends HookConsumerWidget {
ScrollViewKeyboardDismissBehavior.onDrag, ScrollViewKeyboardDismissBehavior.onDrag,
controller: scrollController, controller: scrollController,
slivers: [ slivers: [
SliverToBoxAdapter( if (hasMore.value)
child: Padding( SliverToBoxAdapter(
padding: .symmetric(vertical: 36), child: Padding(
child: Center( padding: .symmetric(vertical: 36),
child: ElevatedButton( child: Center(
onPressed: controllerData is AsyncData child: ElevatedButton(
? loadOlder onPressed: controllerData is AsyncData
: null, ? loadOlder
child: Text("Load More"), : null,
child: Text("Load More"),
),
), ),
), ),
), ),
),
SuperSliverList.builder( SuperSliverList.builder(
listController: listController.value, listController: listController.value,