fluffychat/lib/widgets/local_notifications_extension.dart
Christian Kußowski 58d5de4aba
chore: Remove web notification custom sound
Sound is now played on macOS
and Windows by default.
On some Linux distro it may
differ but there it should be
possible to configure it.
2026-03-05 13:12:53 +01:00

155 lines
4.8 KiB
Dart

import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:desktop_notifications/desktop_notifications.dart';
import 'package:image/image.dart';
import 'package:matrix/matrix.dart';
import 'package:universal_html/html.dart' as html;
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/client_download_content_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/push_helper.dart';
import 'package:fluffychat/widgets/fluffy_chat_app.dart';
import 'package:fluffychat/widgets/matrix.dart';
extension LocalNotificationsExtension on MatrixState {
Future<void> showLocalNotification(Event event) async {
final roomId = event.room.id;
if (activeRoomId == roomId) {
if (WidgetsBinding.instance.lifecycleState == AppLifecycleState.resumed) {
return;
}
}
final title = event.room.getLocalizedDisplayname(
MatrixLocals(L10n.of(context)),
);
final body = await event.calcLocalizedBody(
MatrixLocals(L10n.of(context)),
withSenderNamePrefix:
!event.room.isDirectChat ||
event.room.lastEvent?.senderId == client.userID,
plaintextBody: true,
hideReply: true,
hideEdit: true,
removeMarkdown: true,
);
if (kIsWeb) {
final avatarUrl = event.senderFromMemoryOrFallback.avatarUrl;
Uri? thumbnailUri;
if (avatarUrl != null) {
const size = 128;
const thumbnailMethod = ThumbnailMethod.crop;
// Pre-cache so that we can later just set the thumbnail uri as icon:
try {
await client.downloadMxcCached(
avatarUrl,
width: size,
height: size,
thumbnailMethod: thumbnailMethod,
isThumbnail: true,
rounded: true,
);
} catch (e, s) {
Logs().d('Unable to pre-download avatar for web notification', e, s);
}
thumbnailUri = await event.senderFromMemoryOrFallback.avatarUrl
?.getThumbnailUri(
client,
width: size,
height: size,
method: thumbnailMethod,
);
}
html.Notification(
title,
body: body,
icon: thumbnailUri?.toString(),
tag: event.room.id,
);
} else if (Platform.isLinux) {
final avatarUrl = event.room.avatar;
final hints = [NotificationHint.soundName('message-new-instant')];
if (avatarUrl != null) {
const size = notificationAvatarDimension;
const thumbnailMethod = ThumbnailMethod.crop;
// Pre-cache so that we can later just set the thumbnail uri as icon:
final data = await client.downloadMxcCached(
avatarUrl,
width: size,
height: size,
thumbnailMethod: thumbnailMethod,
isThumbnail: true,
rounded: true,
);
final image = decodeImage(data);
if (image != null) {
final realData = image.getBytes(order: ChannelOrder.rgba);
hints.add(
NotificationHint.imageData(
image.width,
image.height,
realData,
hasAlpha: true,
channels: 4,
),
);
}
}
final notification = await linuxNotifications!.notify(
title,
body: body,
replacesId: linuxNotificationIds[roomId] ?? 0,
appName: AppSettings.applicationName.value,
appIcon: 'fluffychat',
actions: [
NotificationAction(
DesktopNotificationActions.openChat.name,
L10n.of(context).openChat,
),
NotificationAction(
DesktopNotificationActions.seen.name,
L10n.of(context).markAsRead,
),
],
hints: hints,
);
notification.action.then((actionStr) {
var action = DesktopNotificationActions.values.singleWhereOrNull(
(a) => a.name == actionStr,
);
if (action == null && actionStr == 'default') {
action = DesktopNotificationActions.openChat;
}
switch (action!) {
case DesktopNotificationActions.seen:
event.room.setReadMarker(
event.eventId,
mRead: event.eventId,
public: AppSettings.sendPublicReadReceipts.value,
);
break;
case DesktopNotificationActions.openChat:
setActiveClient(event.room.client);
FluffyChatApp.router.go('/rooms/${event.room.id}');
break;
}
});
linuxNotificationIds[roomId] = notification.id;
}
}
}
enum DesktopNotificationActions { seen, openChat }