diff --git a/lib/controllers/room_chat.dart b/lib/controllers/room_chat.dart index 53d7f7f..b1b0f6a 100644 --- a/lib/controllers/room_chat.dart +++ b/lib/controllers/room_chat.dart @@ -66,7 +66,9 @@ class RoomChatController(final String roomId) ), ); - Future loadOlder() async { + Future loadOlder() async { + if (state.isLoading) return; + state = .loading(); final timelineKeys = ref .read(RoomsController.provider.select((value) => value[roomId])) @@ -85,30 +87,28 @@ class RoomChatController(final String roomId) if (response.events.isEmpty) { state = .data(state.value); - } else { - ref - .read(RoomsController.provider.notifier) - .update( - IMap({ - roomId: Room( - 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, - ), - ), - }), - .new(), - ); } - return response.hasMore; + ref + .read(RoomsController.provider.notifier) + .update( + IMap({ + roomId: Room( + 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, + ), + ), + }), + .new(), + ); } Future send( @@ -123,7 +123,7 @@ class RoomChatController(final String roomId) baseContent = relation?.content; } else { final provider = AttachmentController.provider(roomId); - baseContent = ref.watch(provider)?.$2; + baseContent = ref.read(provider)?.$2; ref.invalidate(provider); } @@ -139,7 +139,7 @@ class RoomChatController(final String roomId) ); } - final client = ref.watch(ClientController.provider.notifier); + final client = ref.read(ClientController.provider.notifier); final event = await client.sendMessage( SendMessageRequest( roomId: roomId, @@ -161,7 +161,7 @@ class RoomChatController(final String roomId) ); ref - .watch(RoomsController.provider.notifier) + .read(RoomsController.provider.notifier) .update( .new({ roomId: .new( diff --git a/lib/helpers/hooks/chat_scroll.dart b/lib/helpers/hooks/chat_scroll.dart index 15a5add..54dd967 100644 --- a/lib/helpers/hooks/chat_scroll.dart +++ b/lib/helpers/hooks/chat_scroll.dart @@ -16,7 +16,7 @@ final class ChatScroll({ static ChatScroll use({ required AsyncValue?> controllerData, required String Function(T item) id, - required Future Function() loadOlder, + required Future Function() loadOlder, required Future Function() onReachedBottom, }) { final historyListController = useRef(ListController()); @@ -59,35 +59,25 @@ final class ChatScroll({ ); }, [controllerData, anchorIdValue]); - Future loadOlderItems() async { - if (controllerData.isLoading) return; - - await loadOlder(); - } - useEffect(() { - const loadThreshold = 500.0; + const topThreshold = 500.0; const bottomThreshold = 50.0; - void checkPosition() { + Future checkPosition() async { if (!scrollController.hasClients) return; final position = scrollController.position; - if (position.extentAfter <= loadThreshold) { - loadOlderItems(); - } - - if (position.extentBefore <= bottomThreshold) { + if (position.extentAfter <= topThreshold) { + await loadOlder(); + } else if (position.extentBefore <= bottomThreshold) { onReachedBottom(); } } scrollController.addListener(checkPosition); - WidgetsBinding.instance.addPostFrameCallback((_) { - checkPosition(); - }); + WidgetsBinding.instance.addPostFrameCallback((_) => checkPosition()); return () { scrollController.removeListener(checkPosition);