feat: Display room avatar and actions and play sound for linux desktop notifications

This commit is contained in:
Krille Fear 2022-01-22 11:16:40 +01:00
parent 6257a5dc30
commit 530722f2e6
3 changed files with 97 additions and 46 deletions

View File

@ -2706,5 +2706,7 @@
"storyPrivacyWarning": "Please note that people can see and contact each other in your story. Your stories will be visible for 24 hours but there is no guarantee that they will be deleted from all devices and servers.",
"@storyPrivacyWarning": {},
"iUnderstand": "I understand",
"@iUnderstand": {}
"@iUnderstand": {},
"dismiss": "Dismiss",
"markAsRead": "Mark as read"
}

View File

@ -0,0 +1,91 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:desktop_notifications/desktop_notifications.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import 'package:universal_html/html.dart' as html;
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions.dart/matrix_locals.dart';
import 'package:fluffychat/widgets/matrix.dart';
extension LocalNotificationsExtension on MatrixState {
void showLocalNotification(EventUpdate eventUpdate) async {
final roomId = eventUpdate.roomID;
if (webHasFocus && activeRoomId == roomId) return;
final room = client.getRoomById(roomId);
if (room.notificationCount == 0) return;
final event = Event.fromJson(eventUpdate.content, room);
final title =
room.getLocalizedDisplayname(MatrixLocals(L10n.of(widget.context)));
final body = event.getLocalizedBody(
MatrixLocals(L10n.of(widget.context)),
withSenderNamePrefix:
!room.isDirectChat || room.lastEvent.senderId == client.userID,
plaintextBody: true,
hideReply: true,
hideEdit: true,
);
final icon = event.sender.avatarUrl?.getThumbnail(client,
width: 64, height: 64, method: ThumbnailMethod.crop) ??
room.avatar?.getThumbnail(client,
width: 64, height: 64, method: ThumbnailMethod.crop);
if (kIsWeb) {
html.AudioElement()
..src = 'assets/assets/sounds/notification.wav'
..autoplay = true
..load();
html.Notification(
title,
body: body,
icon: icon.toString(),
);
} else if (Platform.isLinux) {
final appIconUrl = room.avatar
?.getThumbnail(
room.client,
width: 56,
height: 56,
)
.toString();
final appIconFile = await DefaultCacheManager().getSingleFile(appIconUrl);
final notification = await linuxNotifications.notify(
title,
body: body,
replacesId: linuxNotificationIds[roomId] ?? 0,
appName: AppConfig.applicationName,
appIcon: appIconFile.path,
actions: [
NotificationAction(
DesktopNotificationActions.dismiss.name,
L10n.of(widget.context).dismiss,
),
NotificationAction(
DesktopNotificationActions.seen.name,
L10n.of(widget.context).markAsRead,
),
],
hints: [
NotificationHint.soundName('message-new-instant'),
],
);
notification.action.then((actionStr) {
final action = DesktopNotificationActions.values
.singleWhere((a) => a.name == actionStr);
switch (action) {
case DesktopNotificationActions.seen:
room.setReadMarker(event.eventId, mRead: event.eventId);
break;
case DesktopNotificationActions.dismiss:
break;
}
});
linuxNotificationIds[roomId] = notification.id;
}
}
}
enum DesktopNotificationActions { seen, dismiss }

View File

@ -20,7 +20,6 @@ import 'package:vrouter/vrouter.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions.dart/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/sentry_controller.dart';
import 'package:fluffychat/utils/uia_request_manager.dart';
@ -31,6 +30,7 @@ import '../utils/account_bundles.dart';
import '../utils/background_push.dart';
import '../utils/famedlysdk_store.dart';
import '../utils/platform_infos.dart';
import 'local_notifications_extension.dart';
class Matrix extends StatefulWidget {
static const String callNamespace = 'chat.fluffy.jitsi_call';
@ -226,51 +226,9 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
String get activeRoomId =>
VRouter.of(navigatorContext).pathParameters['roomid'];
void _showLocalNotification(EventUpdate eventUpdate) async {
final roomId = eventUpdate.roomID;
if (webHasFocus && activeRoomId == roomId) return;
final room = client.getRoomById(roomId);
if (room.notificationCount == 0) return;
final event = Event.fromJson(eventUpdate.content, room);
final title =
room.getLocalizedDisplayname(MatrixLocals(L10n.of(widget.context)));
final body = event.getLocalizedBody(
MatrixLocals(L10n.of(widget.context)),
withSenderNamePrefix:
!room.isDirectChat || room.lastEvent.senderId == client.userID,
plaintextBody: true,
hideReply: true,
hideEdit: true,
);
final icon = event.sender.avatarUrl?.getThumbnail(client,
width: 64, height: 64, method: ThumbnailMethod.crop) ??
room.avatar?.getThumbnail(client,
width: 64, height: 64, method: ThumbnailMethod.crop);
if (kIsWeb) {
html.AudioElement()
..src = 'assets/assets/sounds/notification.wav'
..autoplay = true
..load();
html.Notification(
title,
body: body,
icon: icon.toString(),
);
} else if (Platform.isLinux) {
final notification = await linuxNotifications.notify(
title,
body: body,
replacesId: _linuxNotificationIds[roomId] ?? 0,
appName: AppConfig.applicationName,
appIcon: "im.fluffychat.Fluffychat",
);
_linuxNotificationIds[roomId] = notification.id;
}
}
final linuxNotifications =
PlatformInfos.isLinux ? NotificationsClient() : null;
final Map<String, int> _linuxNotificationIds = {};
final Map<String, int> linuxNotificationIds = {};
@override
void initState() {
@ -385,7 +343,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
[EventTypes.Message, EventTypes.Sticker, EventTypes.Encrypted]
.contains(e.content['type']) &&
e.content['sender'] != c.userID)
.listen(_showLocalNotification);
.listen(showLocalNotification);
});
}
}