Compare commits

..
Author SHA1 Message Date
edc8b5d34d
release v1.0.0-alpha5 2026-10-19 20:47:28 -04:00
5 changed files with 67 additions and 94 deletions

View file

@ -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:

View file

@ -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,13 +184,11 @@ class NotificationController
// ), // ),
], ],
); );
return; } else {
}
final controller = await future; final controller = await future;
// Append to the conversation already shown under this id, if any // Append to the conversation already shown under this id, if any
final existingStyle = Platform.isAndroid && message != null final existingStyle = Platform.isAndroid
? await controller ? await controller
.resolvePlatformSpecificImplementation< .resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin AndroidFlutterLocalNotificationsPlugin
@ -211,50 +201,28 @@ class NotificationController
presentSound: sound, presentSound: sound,
threadIdentifier: threadId, threadIdentifier: threadId,
); );
final notificationDetails = NotificationDetails(
await controller.show( android: .new(
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",
"Messages", "Messages",
silent: !sound, silent: !sound,
when: timestamp?.millisecondsSinceEpoch, largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path),
category: .message, styleInformation: senderName == null || body == null
largeIcon: icon == null
? null ? null
: FilePathAndroidBitmap(icon.path), : MessagingStyleInformation(
styleInformation: MessagingStyleInformation( .new(name: selfName ?? "You"),
.new(key: message.self.id, name: message.self.name), conversationTitle: isGroup ? title : null,
conversationTitle: message.isDm ? null : title, groupConversation: isGroup,
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,
),
), ),
), ),
], ],
@ -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 =

View file

@ -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,
sound: notification.sound, payload: notification.eventRowId.toString(),
message: ( body: notification.text,
sender: pmp == null senderName: pmp?.name ?? notification.sender.name,
? notification.sender
: pmp.copyWith(id: "${notification.sender.id}/${pmp.id}"),
self: notification.self,
senderAvatar: senderAvatar, senderAvatar: senderAvatar,
isDm: notification.isDm, selfName: notification.self.name,
), isGroup: !notification.isDm,
sound: notification.sound,
timestamp: notification.timestamp,
threadId: notification.roomId,
); );
if (isInBackground) exit(0); if (isInBackground) exit(0);

View file

@ -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 = ''

View file

@ -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