forked from Nexus/nexus
refactor and improve notification handling
This commit is contained in:
parent
9cf16db669
commit
765e96cce4
2 changed files with 91 additions and 63 deletions
|
|
@ -10,8 +10,16 @@ import "package:nexus/main.dart";
|
|||
import "package:flutter_local_notifications/flutter_local_notifications.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:nexus/controllers/notification_request.dart";
|
||||
import "package:nexus/models/push_notification.dart";
|
||||
import "package:xdg_desktop_portal/xdg_desktop_portal.dart";
|
||||
|
||||
typedef NotificationMessage = ({
|
||||
NotificationUser sender,
|
||||
NotificationUser self,
|
||||
File? senderAvatar,
|
||||
bool isDm,
|
||||
});
|
||||
|
||||
class NotificationController
|
||||
extends AsyncNotifier<FlutterLocalNotificationsPlugin> {
|
||||
@override
|
||||
|
|
@ -140,24 +148,24 @@ class NotificationController
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Passing [message] shows it as a chat message in the conversation for
|
||||
/// [threadId], naming the sender in group chats.
|
||||
Future<void> send({
|
||||
required int id,
|
||||
required String title,
|
||||
String? body,
|
||||
File? icon,
|
||||
required String body,
|
||||
String? payload,
|
||||
String? senderName,
|
||||
File? senderAvatar,
|
||||
String? selfName,
|
||||
bool isGroup = false,
|
||||
bool sound = true,
|
||||
DateTime? timestamp,
|
||||
String? threadId,
|
||||
DateTime? timestamp,
|
||||
File? icon,
|
||||
bool sound = true,
|
||||
NotificationMessage? message,
|
||||
}) async {
|
||||
debugPrint("Sending notification for $id");
|
||||
|
||||
// In DMs the title is already the sender, so only prefix in groups
|
||||
final prefix = isGroup ? senderName : null;
|
||||
// In DMs the title is already the sender
|
||||
final sender = message == null || message.isDm ? null : message.sender;
|
||||
final prefixedBody = sender == null ? body : "${sender.name}: $body";
|
||||
|
||||
if (Platform.isLinux) {
|
||||
final portal = await ref.read(PortalController.provider.future);
|
||||
|
|
@ -166,14 +174,14 @@ class NotificationController
|
|||
await portal.notification.addNotification(
|
||||
id.toString(),
|
||||
title: title,
|
||||
body: prefix == null || body == null ? body : "$prefix: $body",
|
||||
markupBody: prefix == null || body == null
|
||||
body: prefixedBody,
|
||||
markupBody: sender == null
|
||||
? null
|
||||
: "<b>${escape.convert(prefix)}</b>: ${escape.convert(body)}",
|
||||
: "<b>${escape.convert(sender.name)}</b>: ${escape.convert(body)}",
|
||||
defaultAction: "app.event",
|
||||
defaultActionTarget: payload,
|
||||
sound: sound ? null : const XdgNotificationSoundSilent(),
|
||||
category: XdgNotificationCategory.imReceived,
|
||||
category: message == null ? null : XdgNotificationCategory.imReceived,
|
||||
priority: .normal,
|
||||
buttons: [
|
||||
// TODO: Impl when notif daemons actualy support imReplyWithText
|
||||
|
|
@ -184,11 +192,13 @@ class NotificationController
|
|||
// ),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
final controller = await future;
|
||||
|
||||
// Append to the conversation already shown under this id, if any
|
||||
final existingStyle = Platform.isAndroid
|
||||
final existingStyle = Platform.isAndroid && message != null
|
||||
? await controller
|
||||
.resolvePlatformSpecificImplementation<
|
||||
AndroidFlutterLocalNotificationsPlugin
|
||||
|
|
@ -201,28 +211,50 @@ class NotificationController
|
|||
presentSound: sound,
|
||||
threadIdentifier: threadId,
|
||||
);
|
||||
final notificationDetails = NotificationDetails(
|
||||
android: .new(
|
||||
|
||||
await controller.show(
|
||||
id: id,
|
||||
title: title,
|
||||
body: prefixedBody,
|
||||
payload: payload,
|
||||
notificationDetails: .new(
|
||||
android: message == null
|
||||
? .new(
|
||||
"general",
|
||||
"General",
|
||||
silent: !sound,
|
||||
when: timestamp?.millisecondsSinceEpoch,
|
||||
largeIcon: icon == null
|
||||
? null
|
||||
: FilePathAndroidBitmap(icon.path),
|
||||
styleInformation: BigTextStyleInformation(body),
|
||||
)
|
||||
: .new(
|
||||
"messages",
|
||||
"Messages",
|
||||
silent: !sound,
|
||||
largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path),
|
||||
styleInformation: senderName == null || body == null
|
||||
when: timestamp?.millisecondsSinceEpoch,
|
||||
category: .message,
|
||||
largeIcon: icon == null
|
||||
? null
|
||||
: MessagingStyleInformation(
|
||||
.new(name: selfName ?? "You"),
|
||||
conversationTitle: isGroup ? title : null,
|
||||
groupConversation: isGroup,
|
||||
: FilePathAndroidBitmap(icon.path),
|
||||
styleInformation: MessagingStyleInformation(
|
||||
.new(key: message.self.id, name: message.self.name),
|
||||
conversationTitle: message.isDm ? null : title,
|
||||
groupConversation: !message.isDm,
|
||||
messages: [
|
||||
...?existingStyle?.messages,
|
||||
.new(
|
||||
body,
|
||||
timestamp ?? .now(),
|
||||
.new(
|
||||
name: senderName,
|
||||
icon: senderAvatar == null
|
||||
key: message.sender.id,
|
||||
name: message.sender.name,
|
||||
icon: message.senderAvatar == null
|
||||
? null
|
||||
: BitmapFilePathAndroidIcon(senderAvatar.path),
|
||||
: BitmapFilePathAndroidIcon(
|
||||
message.senderAvatar!.path,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -237,16 +269,8 @@ class NotificationController
|
|||
? null
|
||||
: .new(id: threadId, title: title, arguments: payload ?? ""),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await controller.show(
|
||||
id: id,
|
||||
title: title,
|
||||
body: prefix == null || body == null ? body : "$prefix: $body",
|
||||
notificationDetails: notificationDetails,
|
||||
payload: payload,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static final provider =
|
||||
|
|
|
|||
|
|
@ -122,17 +122,21 @@ class UnifiedPushController extends AsyncNotifier<String?> {
|
|||
: notification.eventId)
|
||||
.hashCode &
|
||||
0x7fffffff,
|
||||
title: notification.roomName,
|
||||
icon: icon,
|
||||
payload: notification.eventRowId.toString(),
|
||||
body: notification.text,
|
||||
senderName: pmp?.name ?? notification.sender.name,
|
||||
senderAvatar: senderAvatar,
|
||||
selfName: notification.self.name,
|
||||
isGroup: !notification.isDm,
|
||||
sound: notification.sound,
|
||||
timestamp: notification.timestamp,
|
||||
threadId: notification.roomId,
|
||||
title: notification.roomName,
|
||||
body: notification.text,
|
||||
payload: notification.eventRowId.toString(),
|
||||
timestamp: notification.timestamp,
|
||||
icon: icon,
|
||||
sound: notification.sound,
|
||||
message: (
|
||||
sender: pmp == null
|
||||
? notification.sender
|
||||
: pmp.copyWith(id: "${notification.sender.id}/${pmp.id}"),
|
||||
self: notification.self,
|
||||
senderAvatar: senderAvatar,
|
||||
isDm: notification.isDm,
|
||||
),
|
||||
);
|
||||
|
||||
if (isInBackground) exit(0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue