Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
edc8b5d34d |
5 changed files with 67 additions and 94 deletions
|
|
@ -49,7 +49,7 @@ nexus = {
|
||||||
This tracks the latest commit on `main`. To stay on a release instead, pin the input to its tag:
|
This tracks the latest commit on `main`. To stay on a release instead, pin the input to its tag:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
url = "git+https://git.federated.nexus/Nexus/nexus?ref=refs/tags/v1.0.0-alpha4";
|
url = "git+https://git.federated.nexus/Nexus/nexus?ref=refs/tags/v1.0.0-alpha5";
|
||||||
```
|
```
|
||||||
|
|
||||||
Then import the module and enable it in your NixOS configuration:
|
Then import the module and enable it in your NixOS configuration:
|
||||||
|
|
|
||||||
|
|
@ -10,16 +10,8 @@ import "package:nexus/main.dart";
|
||||||
import "package:flutter_local_notifications/flutter_local_notifications.dart";
|
import "package:flutter_local_notifications/flutter_local_notifications.dart";
|
||||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||||
import "package:nexus/controllers/notification_request.dart";
|
import "package:nexus/controllers/notification_request.dart";
|
||||||
import "package:nexus/models/push_notification.dart";
|
|
||||||
import "package:xdg_desktop_portal/xdg_desktop_portal.dart";
|
import "package:xdg_desktop_portal/xdg_desktop_portal.dart";
|
||||||
|
|
||||||
typedef NotificationMessage = ({
|
|
||||||
NotificationUser sender,
|
|
||||||
NotificationUser self,
|
|
||||||
File? senderAvatar,
|
|
||||||
bool isDm,
|
|
||||||
});
|
|
||||||
|
|
||||||
class NotificationController
|
class NotificationController
|
||||||
extends AsyncNotifier<FlutterLocalNotificationsPlugin> {
|
extends AsyncNotifier<FlutterLocalNotificationsPlugin> {
|
||||||
@override
|
@override
|
||||||
|
|
@ -148,24 +140,24 @@ class NotificationController
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Passing [message] shows it as a chat message in the conversation for
|
|
||||||
/// [threadId], naming the sender in group chats.
|
|
||||||
Future<void> send({
|
Future<void> send({
|
||||||
required int id,
|
required int id,
|
||||||
required String title,
|
required String title,
|
||||||
required String body,
|
String? body,
|
||||||
String? payload,
|
|
||||||
String? threadId,
|
|
||||||
DateTime? timestamp,
|
|
||||||
File? icon,
|
File? icon,
|
||||||
|
String? payload,
|
||||||
|
String? senderName,
|
||||||
|
File? senderAvatar,
|
||||||
|
String? selfName,
|
||||||
|
bool isGroup = false,
|
||||||
bool sound = true,
|
bool sound = true,
|
||||||
NotificationMessage? message,
|
DateTime? timestamp,
|
||||||
|
String? threadId,
|
||||||
}) async {
|
}) async {
|
||||||
debugPrint("Sending notification for $id");
|
debugPrint("Sending notification for $id");
|
||||||
|
|
||||||
// In DMs the title is already the sender
|
// In DMs the title is already the sender, so only prefix in groups
|
||||||
final sender = message == null || message.isDm ? null : message.sender;
|
final prefix = isGroup ? senderName : null;
|
||||||
final prefixedBody = sender == null ? body : "${sender.name}: $body";
|
|
||||||
|
|
||||||
if (Platform.isLinux) {
|
if (Platform.isLinux) {
|
||||||
final portal = await ref.read(PortalController.provider.future);
|
final portal = await ref.read(PortalController.provider.future);
|
||||||
|
|
@ -174,14 +166,14 @@ class NotificationController
|
||||||
await portal.notification.addNotification(
|
await portal.notification.addNotification(
|
||||||
id.toString(),
|
id.toString(),
|
||||||
title: title,
|
title: title,
|
||||||
body: prefixedBody,
|
body: prefix == null || body == null ? body : "$prefix: $body",
|
||||||
markupBody: sender == null
|
markupBody: prefix == null || body == null
|
||||||
? null
|
? null
|
||||||
: "<b>${escape.convert(sender.name)}</b>: ${escape.convert(body)}",
|
: "<b>${escape.convert(prefix)}</b>: ${escape.convert(body)}",
|
||||||
defaultAction: "app.event",
|
defaultAction: "app.event",
|
||||||
defaultActionTarget: payload,
|
defaultActionTarget: payload,
|
||||||
sound: sound ? null : const XdgNotificationSoundSilent(),
|
sound: sound ? null : const XdgNotificationSoundSilent(),
|
||||||
category: message == null ? null : XdgNotificationCategory.imReceived,
|
category: XdgNotificationCategory.imReceived,
|
||||||
priority: .normal,
|
priority: .normal,
|
||||||
buttons: [
|
buttons: [
|
||||||
// TODO: Impl when notif daemons actualy support imReplyWithText
|
// TODO: Impl when notif daemons actualy support imReplyWithText
|
||||||
|
|
@ -192,74 +184,50 @@ class NotificationController
|
||||||
// ),
|
// ),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
return;
|
} else {
|
||||||
}
|
final controller = await future;
|
||||||
|
|
||||||
final controller = await future;
|
// Append to the conversation already shown under this id, if any
|
||||||
|
final existingStyle = Platform.isAndroid
|
||||||
|
? await controller
|
||||||
|
.resolvePlatformSpecificImplementation<
|
||||||
|
AndroidFlutterLocalNotificationsPlugin
|
||||||
|
>()
|
||||||
|
?.getActiveNotificationMessagingStyle(id: id)
|
||||||
|
.onError((_, _) => null)
|
||||||
|
: null;
|
||||||
|
|
||||||
// Append to the conversation already shown under this id, if any
|
final darwin = DarwinNotificationDetails(
|
||||||
final existingStyle = Platform.isAndroid && message != null
|
presentSound: sound,
|
||||||
? await controller
|
threadIdentifier: threadId,
|
||||||
.resolvePlatformSpecificImplementation<
|
);
|
||||||
AndroidFlutterLocalNotificationsPlugin
|
final notificationDetails = NotificationDetails(
|
||||||
>()
|
android: .new(
|
||||||
?.getActiveNotificationMessagingStyle(id: id)
|
"messages",
|
||||||
.onError((_, _) => null)
|
"Messages",
|
||||||
: null;
|
silent: !sound,
|
||||||
|
largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path),
|
||||||
final darwin = DarwinNotificationDetails(
|
styleInformation: senderName == null || body == null
|
||||||
presentSound: sound,
|
? null
|
||||||
threadIdentifier: threadId,
|
: MessagingStyleInformation(
|
||||||
);
|
.new(name: selfName ?? "You"),
|
||||||
|
conversationTitle: isGroup ? title : null,
|
||||||
await controller.show(
|
groupConversation: isGroup,
|
||||||
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,
|
|
||||||
when: timestamp?.millisecondsSinceEpoch,
|
|
||||||
category: .message,
|
|
||||||
largeIcon: icon == null
|
|
||||||
? null
|
|
||||||
: FilePathAndroidBitmap(icon.path),
|
|
||||||
styleInformation: MessagingStyleInformation(
|
|
||||||
.new(key: message.self.id, name: message.self.name),
|
|
||||||
conversationTitle: message.isDm ? null : title,
|
|
||||||
groupConversation: !message.isDm,
|
|
||||||
messages: [
|
messages: [
|
||||||
...?existingStyle?.messages,
|
...?existingStyle?.messages,
|
||||||
.new(
|
.new(
|
||||||
body,
|
body,
|
||||||
timestamp ?? .now(),
|
timestamp ?? .now(),
|
||||||
.new(
|
.new(
|
||||||
key: message.sender.id,
|
name: senderName,
|
||||||
name: message.sender.name,
|
icon: senderAvatar == null
|
||||||
icon: message.senderAvatar == null
|
|
||||||
? null
|
? null
|
||||||
: BitmapFilePathAndroidIcon(
|
: BitmapFilePathAndroidIcon(senderAvatar.path),
|
||||||
message.senderAvatar!.path,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
iOS: darwin,
|
iOS: darwin,
|
||||||
macOS: darwin,
|
macOS: darwin,
|
||||||
windows: .new(
|
windows: .new(
|
||||||
|
|
@ -269,8 +237,16 @@ class NotificationController
|
||||||
? null
|
? null
|
||||||
: .new(id: threadId, title: title, arguments: payload ?? ""),
|
: .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 =
|
static final provider =
|
||||||
|
|
|
||||||
|
|
@ -122,21 +122,17 @@ class UnifiedPushController extends AsyncNotifier<String?> {
|
||||||
: notification.eventId)
|
: notification.eventId)
|
||||||
.hashCode &
|
.hashCode &
|
||||||
0x7fffffff,
|
0x7fffffff,
|
||||||
threadId: notification.roomId,
|
|
||||||
title: notification.roomName,
|
title: notification.roomName,
|
||||||
body: notification.text,
|
|
||||||
payload: notification.eventRowId.toString(),
|
|
||||||
timestamp: notification.timestamp,
|
|
||||||
icon: icon,
|
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,
|
sound: notification.sound,
|
||||||
message: (
|
timestamp: notification.timestamp,
|
||||||
sender: pmp == null
|
threadId: notification.roomId,
|
||||||
? notification.sender
|
|
||||||
: pmp.copyWith(id: "${notification.sender.id}/${pmp.id}"),
|
|
||||||
self: notification.self,
|
|
||||||
senderAvatar: senderAvatar,
|
|
||||||
isDm: notification.isDm,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isInBackground) exit(0);
|
if (isInBackground) exit(0);
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
flutter.buildFlutterApplication {
|
flutter.buildFlutterApplication {
|
||||||
pname = "nexus";
|
pname = "nexus";
|
||||||
version = "1.0.0-alpha4";
|
version = "1.0.0-alpha5";
|
||||||
inherit src;
|
inherit src;
|
||||||
|
|
||||||
preBuild = ''
|
preBuild = ''
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
name: nexus
|
name: nexus
|
||||||
description: "A simple and user-friendly Matrix client"
|
description: "A simple and user-friendly Matrix client"
|
||||||
version: 1.0.0-alpha4
|
version: 1.0.0-alpha5
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
fonts:
|
fonts:
|
||||||
|
- family: bundled-emoji
|
||||||
- family: bundled-sans
|
- family: bundled-sans
|
||||||
fonts:
|
fonts:
|
||||||
- asset: assets/fonts/Inter.ttf
|
- asset: assets/fonts/Inter.ttf
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue