make NotificationsController work off of rowIds
This commit is contained in:
parent
281bab0202
commit
ead463262c
12 changed files with 116 additions and 71 deletions
|
|
@ -1,17 +1,16 @@
|
|||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:nexus/models/event.dart";
|
||||
|
||||
class ContextualEventController(String? _) extends Notifier<Event?> {
|
||||
class ContextualEventController(String? _) extends Notifier<int?> {
|
||||
@override
|
||||
Event? build() => null;
|
||||
int? build() => null;
|
||||
|
||||
void set(Event? event) => state = event;
|
||||
void set(int? event) => state = event;
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(_, _) => true;
|
||||
|
||||
static final provider = NotifierProvider.family
|
||||
.autoDispose<ContextualEventController, Event?, String?>(
|
||||
.autoDispose<ContextualEventController, int?, String?>(
|
||||
ContextualEventController.new,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,12 +31,14 @@ class NotificationController
|
|||
macOS: darwin,
|
||||
),
|
||||
onDidReceiveNotificationResponse: (details) {
|
||||
if (details.payload case final eventId?) {
|
||||
if (details.payload == null) return;
|
||||
|
||||
if (int.tryParse(details.payload!) case final rowId?) {
|
||||
if (navigatorKey.currentContext case final context?) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => NotificationsPage(
|
||||
highlightedEventId: eventId,
|
||||
highlightedEvent: rowId,
|
||||
defaultToAllNotifications: true,
|
||||
),
|
||||
),
|
||||
|
|
@ -55,17 +57,17 @@ class NotificationController
|
|||
return;
|
||||
}
|
||||
|
||||
final eventId = call.arguments as String;
|
||||
|
||||
if (navigatorKey.currentContext case final context?) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => NotificationsPage(
|
||||
highlightedEventId: eventId,
|
||||
defaultToAllNotifications: true,
|
||||
if (int.tryParse(call.arguments) case int rowId) {
|
||||
if (navigatorKey.currentContext case final context?) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => NotificationsPage(
|
||||
highlightedEvent: rowId,
|
||||
defaultToAllNotifications: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,33 +1,61 @@
|
|||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:nexus/controllers/client.dart";
|
||||
import "package:nexus/controllers/rooms.dart";
|
||||
import "package:nexus/models/event.dart";
|
||||
|
||||
typedef NotificationsRequest = (UnreadType? unreadType, String? roomId);
|
||||
|
||||
class NotificationsController([final NotificationsRequest? request])
|
||||
extends AsyncNotifier<IList<Event>> {
|
||||
extends AsyncNotifier<IList<(int, String)>> {
|
||||
static const virtualRoomId = "!notifications";
|
||||
|
||||
@override
|
||||
Future<IList<Event>> build() async {
|
||||
Future<IList<(int, String)>> build() async {
|
||||
final client = ref.read(ClientController.provider.notifier);
|
||||
|
||||
final (unreadType, roomId) = request ?? (null, null);
|
||||
|
||||
return await client.getMentions(
|
||||
final mentions = await client.getMentions(
|
||||
.new(
|
||||
maxTimestamp: .now(),
|
||||
unreadType: unreadType ?? .highlight,
|
||||
roomId: roomId,
|
||||
),
|
||||
);
|
||||
|
||||
ref
|
||||
.watch(RoomsController.provider.notifier)
|
||||
.update(
|
||||
.new({
|
||||
virtualRoomId: .new(
|
||||
events: IMap.fromIterable(
|
||||
mentions,
|
||||
keyMapper: (event) => event.rowId,
|
||||
),
|
||||
),
|
||||
}),
|
||||
.new(),
|
||||
);
|
||||
|
||||
return .new(mentions.map((event) => (event.rowId, event.roomId)));
|
||||
}
|
||||
|
||||
Future<void> loadOlder() async {
|
||||
final currentNotifications = await future;
|
||||
state = .loading();
|
||||
state = await .guard(() async {
|
||||
final lastTs = currentNotifications.lastOrNull?.timestamp;
|
||||
if (lastTs == null) return const .empty();
|
||||
final lastNotification = currentNotifications.lastOrNull?.$1;
|
||||
final lastTs = lastNotification == null
|
||||
? null
|
||||
: ref.watch(
|
||||
RoomsController.provider.select(
|
||||
(rooms) =>
|
||||
rooms[virtualRoomId]?.events[lastNotification]?.timestamp,
|
||||
),
|
||||
);
|
||||
|
||||
if (lastTs == null) return currentNotifications;
|
||||
|
||||
final client = ref.read(ClientController.provider.notifier);
|
||||
final (unreadType, roomId) = request ?? (null, null);
|
||||
|
|
@ -40,14 +68,30 @@ class NotificationsController([final NotificationsRequest? request])
|
|||
),
|
||||
);
|
||||
|
||||
return currentNotifications.addAll(newNotifications);
|
||||
ref
|
||||
.watch(RoomsController.provider.notifier)
|
||||
.update(
|
||||
.new({
|
||||
virtualRoomId: .new(
|
||||
events: IMap.fromIterable(
|
||||
newNotifications,
|
||||
keyMapper: (event) => event.rowId,
|
||||
),
|
||||
),
|
||||
}),
|
||||
.new(),
|
||||
);
|
||||
|
||||
return currentNotifications.addAll(
|
||||
newNotifications.map((event) => (event.rowId, event.roomId)),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
static final provider = AsyncNotifierProvider.family
|
||||
.autoDispose<
|
||||
NotificationsController,
|
||||
IList<Event>,
|
||||
IList<(int, String)>,
|
||||
NotificationsRequest?
|
||||
>(NotificationsController.new);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,10 +18,7 @@ import "package:nexus/models/requests/send_message.dart";
|
|||
import "package:nexus/models/room.dart";
|
||||
import "package:nexus/models/room_chat.dart";
|
||||
|
||||
typedef ChatParams = ({
|
||||
String roomId,
|
||||
({int rowId, String eventId})? contextualEvent,
|
||||
});
|
||||
typedef ChatParams = ({String roomId, int? contextualEvent});
|
||||
|
||||
class RoomChatController(final ChatParams info)
|
||||
extends AsyncNotifier<RoomChat?> {
|
||||
|
|
@ -47,7 +44,7 @@ class RoomChatController(final ChatParams info)
|
|||
.nonNulls
|
||||
.toIList();
|
||||
if (info.contextualEvent == null ||
|
||||
timeline.contains(info.contextualEvent!.rowId)) {
|
||||
timeline.contains(info.contextualEvent)) {
|
||||
ref.watch(
|
||||
RoomsController.provider.select(
|
||||
(rooms) =>
|
||||
|
|
@ -62,7 +59,10 @@ class RoomChatController(final ChatParams info)
|
|||
);
|
||||
} else {
|
||||
final context = await client.getEventContext(
|
||||
.new(roomId: info.roomId, eventId: info.contextualEvent!.eventId),
|
||||
.new(
|
||||
roomId: info.roomId,
|
||||
eventId: room.events[info.contextualEvent!]!.eventId,
|
||||
),
|
||||
);
|
||||
|
||||
final events = context.before.add(context.event).addAll(context.after);
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
|||
id: event.eventId.hashCode & 0x7fffffff,
|
||||
title: roomMetadata.name ?? "New Event",
|
||||
icon: icon,
|
||||
payload: event.eventId,
|
||||
payload: event.rowId.toString(),
|
||||
body: switch (event.content) {
|
||||
MessageContent(:final body?) ||
|
||||
StickerContent(:final body) => body,
|
||||
|
|
|
|||
Loading…
Reference in a new issue