forked from Nexus/nexus
use xdg_desktop_portal over flutter_local_notifications on linux
This commit is contained in:
parent
deaf564c36
commit
fea39e4191
6 changed files with 132 additions and 76 deletions
|
|
@ -1,10 +1,13 @@
|
|||
import "dart:io";
|
||||
|
||||
import "package:flutter/foundation.dart";
|
||||
import "package:material_ui/material_ui.dart";
|
||||
import "package:nexus/controllers/portal.dart";
|
||||
import "package:nexus/main.dart";
|
||||
import "package:flutter_local_notifications/flutter_local_notifications.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:nexus/pages/notifications.dart";
|
||||
import "package:xdg_desktop_portal/xdg_desktop_portal.dart";
|
||||
|
||||
class NotificationController
|
||||
extends AsyncNotifier<FlutterLocalNotificationsPlugin> {
|
||||
|
|
@ -12,40 +15,77 @@ class NotificationController
|
|||
Future<FlutterLocalNotificationsPlugin> build() async {
|
||||
final notifications = FlutterLocalNotificationsPlugin();
|
||||
|
||||
final darwin = DarwinInitializationSettings();
|
||||
if (!Platform.isLinux) {
|
||||
final darwin = DarwinInitializationSettings();
|
||||
|
||||
await notifications.initialize(
|
||||
settings: .new(
|
||||
windows: .new(
|
||||
appName: "Nexus",
|
||||
appUserModelId: "nexus.federated.nexus",
|
||||
guid: "dde78daf-130f-4e46-a80a-e31deeab45d7",
|
||||
await notifications.initialize(
|
||||
settings: .new(
|
||||
windows: .new(
|
||||
appName: "Nexus",
|
||||
appUserModelId: "nexus.federated.nexus",
|
||||
guid: "dde78daf-130f-4e46-a80a-e31deeab45d7",
|
||||
),
|
||||
android: .new("ic_launcher_foreground"),
|
||||
iOS: darwin,
|
||||
macOS: darwin,
|
||||
),
|
||||
android: .new("ic_launcher_foreground"),
|
||||
iOS: darwin,
|
||||
macOS: darwin,
|
||||
linux: .new(defaultActionName: "Open"),
|
||||
),
|
||||
onDidReceiveNotificationResponse: (details) {
|
||||
if (details.payload case final eventId?) {
|
||||
if (navigatorKey.currentContext case final context?) {
|
||||
onDidReceiveNotificationResponse: (details) {
|
||||
if (details.payload case final eventId?) {
|
||||
if (navigatorKey.currentContext case final context?) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => NotificationsPage(
|
||||
highlightedEventId: eventId,
|
||||
defaultToAllNotifications: true,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (Platform.isLinux) {
|
||||
final portal = await ref.watch(PortalController.provider.future);
|
||||
|
||||
portal.notification.actionInvoked.listen((event) {
|
||||
if (event.action != "app.event") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (navigatorKey.currentContext case final context?) {
|
||||
if (context.mounted) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => NotificationsPage(
|
||||
highlightedEventId: eventId,
|
||||
highlightedEventId: event.id,
|
||||
defaultToAllNotifications: true,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
ref.onDispose(() {
|
||||
// The portal client owns its D-Bus connection.
|
||||
if (Platform.isLinux) {
|
||||
ref.read(PortalController.provider.future).then((portal) {
|
||||
portal.close();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return notifications;
|
||||
}
|
||||
|
||||
Future<bool> requestPermissions() async {
|
||||
if (Platform.isLinux) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final controller = await future;
|
||||
|
||||
if (Platform.isIOS) {
|
||||
|
|
@ -82,31 +122,41 @@ class NotificationController
|
|||
String? payload,
|
||||
}) async {
|
||||
debugPrint("Sending notification for $id");
|
||||
final notificationDetails = NotificationDetails(
|
||||
android: .new(
|
||||
"messages",
|
||||
"Messages",
|
||||
largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path),
|
||||
),
|
||||
linux: .new(
|
||||
category: LinuxNotificationCategory.imReceived,
|
||||
defaultActionName: "app.event",
|
||||
icon: icon == null ? null : FilePathLinuxIcon(icon.path),
|
||||
),
|
||||
// TODO: See if icons can be added to iOS, macOS, and Windows notifications (#68)
|
||||
iOS: .new(),
|
||||
macOS: .new(),
|
||||
windows: .new(),
|
||||
);
|
||||
|
||||
final controller = await future;
|
||||
await controller.show(
|
||||
id: id,
|
||||
title: title,
|
||||
body: body,
|
||||
notificationDetails: notificationDetails,
|
||||
payload: payload,
|
||||
);
|
||||
if (Platform.isLinux) {
|
||||
final portal = await ref.read(PortalController.provider.future);
|
||||
|
||||
await portal.notification.addNotification(
|
||||
id.toString(),
|
||||
title: title,
|
||||
body: body,
|
||||
icon: icon == null ? null : XdgNotificationIconFile(icon.path),
|
||||
defaultAction: "app.event",
|
||||
);
|
||||
} else {
|
||||
final notificationDetails = NotificationDetails(
|
||||
android: .new(
|
||||
"messages",
|
||||
"Messages",
|
||||
largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path),
|
||||
),
|
||||
// TODO: See if icons can be added to iOS, macOS, and Windows
|
||||
// notifications (#68)
|
||||
iOS: .new(),
|
||||
macOS: .new(),
|
||||
windows: .new(),
|
||||
);
|
||||
|
||||
final controller = await future;
|
||||
|
||||
await controller.show(
|
||||
id: id,
|
||||
title: title,
|
||||
body: body,
|
||||
notificationDetails: notificationDetails,
|
||||
payload: payload,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static final provider =
|
||||
|
|
|
|||
17
lib/controllers/portal.dart
Normal file
17
lib/controllers/portal.dart
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:xdg_desktop_portal/xdg_desktop_portal.dart";
|
||||
|
||||
class PortalController extends AsyncNotifier<XdgDesktopPortalClient> {
|
||||
@override
|
||||
Future<XdgDesktopPortalClient> build() async {
|
||||
final portal = XdgDesktopPortalClient();
|
||||
await portal.registerApplication("nexus.federated.nexus");
|
||||
|
||||
return portal;
|
||||
}
|
||||
|
||||
static final provider =
|
||||
AsyncNotifierProvider<PortalController, XdgDesktopPortalClient>(
|
||||
PortalController.new,
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue