smarter notif logic
This commit is contained in:
parent
74207e405b
commit
0122feae1d
2 changed files with 47 additions and 24 deletions
|
|
@ -1,9 +1,11 @@
|
||||||
|
import "dart:convert";
|
||||||
import "dart:io";
|
import "dart:io";
|
||||||
|
|
||||||
import "package:flutter_local_notifications/flutter_local_notifications.dart";
|
import "package:flutter_local_notifications/flutter_local_notifications.dart";
|
||||||
// ignore: implementation_imports
|
// ignore: implementation_imports
|
||||||
import "package:flutter_local_notifications_linux/src/model/hint.dart";
|
import "package:flutter_local_notifications_linux/src/model/hint.dart";
|
||||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||||
|
import "package:nexus/controllers/event.dart";
|
||||||
|
|
||||||
class NotificationsController
|
class NotificationsController
|
||||||
extends AsyncNotifier<FlutterLocalNotificationsPlugin> {
|
extends AsyncNotifier<FlutterLocalNotificationsPlugin> {
|
||||||
|
|
@ -26,7 +28,11 @@ class NotificationsController
|
||||||
linux: .new(defaultActionName: "Open"),
|
linux: .new(defaultActionName: "Open"),
|
||||||
),
|
),
|
||||||
onDidReceiveNotificationResponse: (details) {
|
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",
|
"Messages",
|
||||||
largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path),
|
largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path),
|
||||||
),
|
),
|
||||||
iOS: .new(),
|
|
||||||
macOS: .new(),
|
|
||||||
linux: .new(
|
linux: .new(
|
||||||
customHints: icon == null
|
customHints: icon == null
|
||||||
? 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(),
|
windows: .new(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,19 @@ import "dart:io";
|
||||||
|
|
||||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||||
import "package:intl/intl.dart";
|
import "package:intl/intl.dart";
|
||||||
|
import "package:nexus/controllers/key.dart";
|
||||||
import "package:nexus/controllers/notifications.dart";
|
import "package:nexus/controllers/notifications.dart";
|
||||||
import "package:nexus/controllers/rooms.dart";
|
import "package:nexus/controllers/rooms.dart";
|
||||||
import "package:nexus/main.dart";
|
import "package:nexus/main.dart";
|
||||||
import "package:nexus/controllers/client.dart";
|
import "package:nexus/controllers/client.dart";
|
||||||
import "package:nexus/controllers/client_state.dart";
|
import "package:nexus/controllers/client_state.dart";
|
||||||
import "package:nexus/models/content/message.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:nexus/models/requests/register_pusher.dart";
|
||||||
import "package:unifiedpush/unifiedpush.dart";
|
import "package:unifiedpush/unifiedpush.dart";
|
||||||
import "package:unifiedpush_storage_shared_preferences/storage.dart";
|
import "package:unifiedpush_storage_shared_preferences/storage.dart";
|
||||||
|
import "package:window_manager/window_manager.dart";
|
||||||
|
|
||||||
class UnifiedPushController extends AsyncNotifier<bool> {
|
class UnifiedPushController extends AsyncNotifier<bool> {
|
||||||
@override
|
@override
|
||||||
|
|
@ -23,32 +27,39 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
||||||
storage: UnifiedPushStorageSharedPreferences(),
|
storage: UnifiedPushStorageSharedPreferences(),
|
||||||
background: isInBackground,
|
background: isInBackground,
|
||||||
),
|
),
|
||||||
onNewEndpoint: (endpoint, instance) async {
|
onNewEndpoint: (endpoint, instance) => client.registerPusher(
|
||||||
await client.registerPusher(
|
.new(
|
||||||
.new(
|
appDisplayName: "Nexus",
|
||||||
appDisplayName: "Nexus",
|
appId: "nexus.federated.nexus",
|
||||||
appId: "nexus.federated.nexus",
|
data: PusherData.webPush(
|
||||||
data: PusherData.webPush(
|
url: Uri.parse(endpoint.url),
|
||||||
url: Uri.parse(endpoint.url),
|
auth: endpoint.pubKeySet!.auth,
|
||||||
auth: endpoint.pubKeySet!.auth,
|
|
||||||
),
|
|
||||||
deviceDisplayName:
|
|
||||||
"Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}",
|
|
||||||
kind: .webPush,
|
|
||||||
lang: "en",
|
|
||||||
pushKey: endpoint.pubKeySet!.pubKey,
|
|
||||||
),
|
),
|
||||||
);
|
deviceDisplayName:
|
||||||
},
|
"Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}",
|
||||||
|
kind: .webPush,
|
||||||
|
lang: "en",
|
||||||
|
pushKey: endpoint.pubKeySet!.pubKey,
|
||||||
|
),
|
||||||
|
),
|
||||||
onMessage: (message, instance) async {
|
onMessage: (message, instance) async {
|
||||||
if (message.decrypted == false) {
|
if (message.decrypted == false) {
|
||||||
// TODO: Handle more gracefully, show option to re-register pusher
|
throw Exception(
|
||||||
throw Exception("Failed to decrypt notification");
|
"Failed to decrypt notification. Try toggling off and on UnifiedPush in settings.",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
final event = await client.handlePush(
|
final event = await client.handlePush(
|
||||||
json.decode(String.fromCharCodes(message.content)),
|
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(
|
final room = ref.read(
|
||||||
RoomsController.provider.select((rooms) => rooms[event.roomId]),
|
RoomsController.provider.select((rooms) => rooms[event.roomId]),
|
||||||
);
|
);
|
||||||
|
|
@ -64,14 +75,19 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
||||||
.read(NotificationsController.provider.notifier)
|
.read(NotificationsController.provider.notifier)
|
||||||
.send(
|
.send(
|
||||||
id: event.eventId.hashCode & 0x7fffffff,
|
id: event.eventId.hashCode & 0x7fffffff,
|
||||||
title: room?.metadata?.name ?? "New Message",
|
title: room?.metadata?.name ?? "New Event",
|
||||||
icon: icon,
|
icon: icon,
|
||||||
|
payload: json.encode(
|
||||||
|
GetEventRequest(eventId: event.eventId, roomId: event.roomId),
|
||||||
|
),
|
||||||
body: switch (event.content) {
|
body: switch (event.content) {
|
||||||
MessageContent(:final body) => body,
|
MessageContent(:final body?) ||
|
||||||
// TODO: Handle more types
|
StickerContent(:final body) => body,
|
||||||
_ => null,
|
_ => null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (isInBackground) exit(0);
|
||||||
},
|
},
|
||||||
onRegistrationFailed: (error, instance) => throw error,
|
onRegistrationFailed: (error, instance) => throw error,
|
||||||
onUnregistered: (instance) => ref.invalidateSelf(),
|
onUnregistered: (instance) => ref.invalidateSelf(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue