fixup notif jumping

This commit is contained in:
Henry Hiles 2026-09-29 20:11:57 -04:00
commit b92aaed610
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
2 changed files with 31 additions and 34 deletions

View file

@ -1,3 +1,4 @@
import "package:collection/collection.dart";
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client.dart";
@ -6,15 +7,33 @@ import "package:nexus/models/event.dart";
typedef NotificationsRequest = (UnreadType? unreadType, String? roomId); typedef NotificationsRequest = (UnreadType? unreadType, String? roomId);
class NotificationsController([final NotificationsRequest? request]) class NotificationsController(final NotificationsRequest request)
extends AsyncNotifier<IList<(int, String)>> { extends AsyncNotifier<IList<(int, String)>> {
static const virtualRoomId = "!notifications"; void storeEvents(Iterable<Event> events) => ref
.read(RoomsController.provider.notifier)
.update(
.new(
events
.groupListsBy((event) => event.roomId)
.map(
(roomId, roomEvents) => .new(
roomId,
.new(
events: IMap.fromIterable(
roomEvents,
keyMapper: (event) => event.rowId,
),
),
),
),
),
);
@override @override
Future<IList<(int, String)>> build() async { Future<IList<(int, String)>> build() async {
final client = ref.read(ClientController.provider.notifier); final client = ref.read(ClientController.provider.notifier);
final (unreadType, roomId) = request ?? (null, null); final (unreadType, roomId) = request;
final mentions = await client.getMentions( final mentions = await client.getMentions(
.new( .new(
@ -24,18 +43,7 @@ class NotificationsController([final NotificationsRequest? request])
), ),
); );
ref storeEvents(mentions);
.watch(RoomsController.provider.notifier)
.update(
.new({
virtualRoomId: .new(
events: IMap.fromIterable(
mentions,
keyMapper: (event) => event.rowId,
),
),
}),
);
return .new(mentions.map((event) => (event.rowId, event.roomId))); return .new(mentions.map((event) => (event.rowId, event.roomId)));
} }
@ -44,20 +52,21 @@ class NotificationsController([final NotificationsRequest? request])
final currentNotifications = await future; final currentNotifications = await future;
state = .loading(); state = .loading();
state = await .guard(() async { state = await .guard(() async {
final lastNotification = currentNotifications.lastOrNull?.$1; final lastNotification = currentNotifications.lastOrNull;
final lastTs = lastNotification == null final lastTs = lastNotification == null
? null ? null
: ref.watch( : ref.watch(
RoomsController.provider.select( RoomsController.provider.select(
(rooms) => (rooms) => rooms[lastNotification.$2]
rooms[virtualRoomId]?.events[lastNotification]?.timestamp, ?.events[lastNotification.$1]
?.timestamp,
), ),
); );
if (lastTs == null) return currentNotifications; if (lastTs == null) return currentNotifications;
final client = ref.read(ClientController.provider.notifier); final client = ref.read(ClientController.provider.notifier);
final (unreadType, roomId) = request ?? (null, null); final (unreadType, roomId) = request;
final newNotifications = await client.getMentions( final newNotifications = await client.getMentions(
.new( .new(
@ -67,18 +76,7 @@ class NotificationsController([final NotificationsRequest? request])
), ),
); );
ref storeEvents(newNotifications);
.watch(RoomsController.provider.notifier)
.update(
.new({
virtualRoomId: .new(
events: IMap.fromIterable(
newNotifications,
keyMapper: (event) => event.rowId,
),
),
}),
);
return currentNotifications.addAll( return currentNotifications.addAll(
newNotifications.map((event) => (event.rowId, event.roomId)), newNotifications.map((event) => (event.rowId, event.roomId)),
@ -90,6 +88,6 @@ class NotificationsController([final NotificationsRequest? request])
.autoDispose< .autoDispose<
NotificationsController, NotificationsController,
IList<(int, String)>, IList<(int, String)>,
NotificationsRequest? NotificationsRequest
>(NotificationsController.new); >(NotificationsController.new);
} }

View file

@ -134,8 +134,7 @@ class const NotificationsPage({
child: IgnorePointer( child: IgnorePointer(
child: EventRenderer( child: EventRenderer(
rowId, rowId,
roomId: NotificationsController roomId: roomId,
.virtualRoomId,
), ),
), ),
), ),