smarter notif logic

This commit is contained in:
Henry Hiles 2026-08-26 11:55:20 -04:00
commit 0122feae1d
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
2 changed files with 47 additions and 24 deletions

View file

@ -1,9 +1,11 @@
import "dart:convert";
import "dart:io";
import "package:flutter_local_notifications/flutter_local_notifications.dart";
// ignore: implementation_imports
import "package:flutter_local_notifications_linux/src/model/hint.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/event.dart";
class NotificationsController
extends AsyncNotifier<FlutterLocalNotificationsPlugin> {
@ -26,7 +28,11 @@ class NotificationsController
linux: .new(defaultActionName: "Open"),
),
onDidReceiveNotificationResponse: (details) {
print(details.data);
if (details.payload case final payload?) {
final event = ref.watch(
EventController.provider(.fromJson(json.decode(payload))),
);
}
},
);
@ -75,8 +81,6 @@ class NotificationsController
"Messages",
largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path),
),
iOS: .new(),
macOS: .new(),
linux: .new(
customHints: icon == null
? null
@ -87,6 +91,9 @@ class NotificationsController
),
],
),
// TODO: See if icons can be added to iOS, macOS, and Windows notifications (#68)
iOS: .new(),
macOS: .new(),
windows: .new(),
);

View file

@ -3,15 +3,19 @@ import "dart:io";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:intl/intl.dart";
import "package:nexus/controllers/key.dart";
import "package:nexus/controllers/notifications.dart";
import "package:nexus/controllers/rooms.dart";
import "package:nexus/main.dart";
import "package:nexus/controllers/client.dart";
import "package:nexus/controllers/client_state.dart";
import "package:nexus/models/content/message.dart";
import "package:nexus/models/content/sticker.dart";
import "package:nexus/models/requests/get_event.dart";
import "package:nexus/models/requests/register_pusher.dart";
import "package:unifiedpush/unifiedpush.dart";
import "package:unifiedpush_storage_shared_preferences/storage.dart";
import "package:window_manager/window_manager.dart";
class UnifiedPushController extends AsyncNotifier<bool> {
@override
@ -23,8 +27,7 @@ class UnifiedPushController extends AsyncNotifier<bool> {
storage: UnifiedPushStorageSharedPreferences(),
background: isInBackground,
),
onNewEndpoint: (endpoint, instance) async {
await client.registerPusher(
onNewEndpoint: (endpoint, instance) => client.registerPusher(
.new(
appDisplayName: "Nexus",
appId: "nexus.federated.nexus",
@ -38,17 +41,25 @@ class UnifiedPushController extends AsyncNotifier<bool> {
lang: "en",
pushKey: endpoint.pubKeySet!.pubKey,
),
);
},
),
onMessage: (message, instance) async {
if (message.decrypted == false) {
// TODO: Handle more gracefully, show option to re-register pusher
throw Exception("Failed to decrypt notification");
throw Exception(
"Failed to decrypt notification. Try toggling off and on UnifiedPush in settings.",
);
}
final event = await client.handlePush(
json.decode(String.fromCharCodes(message.content)),
);
if (event.unreadType?.shouldNotify != true ||
(!isInBackground &&
await windowManager.isFocused() &&
ref.watch(KeyController.provider(KeyController.roomKey)) ==
event.roomId)) {
return;
}
final room = ref.read(
RoomsController.provider.select((rooms) => rooms[event.roomId]),
);
@ -64,14 +75,19 @@ class UnifiedPushController extends AsyncNotifier<bool> {
.read(NotificationsController.provider.notifier)
.send(
id: event.eventId.hashCode & 0x7fffffff,
title: room?.metadata?.name ?? "New Message",
title: room?.metadata?.name ?? "New Event",
icon: icon,
payload: json.encode(
GetEventRequest(eventId: event.eventId, roomId: event.roomId),
),
body: switch (event.content) {
MessageContent(:final body) => body,
// TODO: Handle more types
MessageContent(:final body?) ||
StickerContent(:final body) => body,
_ => null,
},
);
if (isInBackground) exit(0);
},
onRegistrationFailed: (error, instance) => throw error,
onUnregistered: (instance) => ref.invalidateSelf(),