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.
155 lines
4.8 KiB
Dart
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 }
|