attempt to remember position when loading history

This commit is contained in:
Henry Hiles 2026-06-02 20:42:04 -04:00
commit 1215be0b21
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
2 changed files with 30 additions and 6 deletions

View file

@ -39,7 +39,9 @@ class RoomChatController extends AsyncNotifier<IList<Event>> {
}
return room.timeline
.toValueIList(sort: true, compare: (a, b) => (a ?? 0).compareTo(b ?? 0))
.toEntryIList(compare: (a, b) => (a?.key ?? 0).compareTo(b?.key ?? 0))
.map((element) => element.value)
.toIList()
.addAll(room.sticky)
.map((entry) {
final foundEvent = entry == null ? null : room.events[entry];

View file

@ -79,6 +79,13 @@ class RoomChat extends HookConsumerWidget {
final scrollController = useScrollController();
final controllerData = ref.watch(controllerProvider);
final heightBeforeLoad = useState<double?>(null);
Future<void> loadOlder() async {
heightBeforeLoad.value = scrollController.position.maxScrollExtent;
await notifier.loadOlder();
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (scrollController.hasClients) {
@ -90,8 +97,19 @@ class RoomChat extends HookConsumerWidget {
}, [scrollController.hasClients]);
useEffect(() {
if (scrollController.hasClients &&
scrollController.position.atEdge &&
if (!scrollController.hasClients || controllerData is! AsyncData) return;
if (heightBeforeLoad.value != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (scrollController.hasClients) {
scrollController.jumpTo(
scrollController.position.maxScrollExtent -
heightBeforeLoad.value!,
);
}
heightBeforeLoad.value = null;
});
} else if (scrollController.position.atEdge &&
scrollController.position.pixels != 0) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (scrollController.hasClients) {
@ -104,7 +122,9 @@ class RoomChat extends HookConsumerWidget {
useEffect(() {
Future<void> listener() async {
if (!scrollController.position.atEdge) return;
if (!scrollController.hasClients || !scrollController.position.atEdge) {
return;
}
final room = ref.watch(
RoomsController.provider.select((value) => value[roomId]),
@ -112,7 +132,9 @@ class RoomChat extends HookConsumerWidget {
if (room == null) return;
if (scrollController.position.pixels == 0) {
if (room.hasMore) await notifier.loadOlder();
if (room.hasMore) {
await loadOlder();
}
} else {
await client.markRead(room);
}
@ -369,7 +391,7 @@ class RoomChat extends HookConsumerWidget {
child: Center(
child: ElevatedButton(
onPressed: controllerData is AsyncData
? notifier.loadOlder
? loadOlder
: null,
child: Text("Load More"),
),