121 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Dart
		
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Dart
		
	
	
	
| import 'dart:io';
 | |
| 
 | |
| import 'package:flutter/foundation.dart';
 | |
| import 'package:flutter/material.dart';
 | |
| 
 | |
| import 'package:desktop_notifications/desktop_notifications.dart';
 | |
| import 'package:extera_next/generated/l10n/l10n.dart';
 | |
| import 'package:go_router/go_router.dart';
 | |
| import 'package:matrix/matrix.dart';
 | |
| import 'package:universal_html/html.dart' as html;
 | |
| 
 | |
| import 'package:extera_next/config/app_config.dart';
 | |
| import 'package:extera_next/utils/client_download_content_extension.dart';
 | |
| import 'package:extera_next/utils/matrix_sdk_extensions/matrix_locals.dart';
 | |
| import 'package:extera_next/utils/platform_infos.dart';
 | |
| import 'package:extera_next/widgets/matrix.dart';
 | |
| 
 | |
| extension LocalNotificationsExtension on MatrixState {
 | |
|   static final html.AudioElement _audioPlayer = html.AudioElement()
 | |
|     ..src = 'assets/assets/sounds/notification.ogg'
 | |
|     ..load();
 | |
| 
 | |
|   void showLocalNotification(Event event) async {
 | |
|     final roomId = event.room.id;
 | |
|     if (activeRoomId == roomId) {
 | |
|       if (kIsWeb && webHasFocus) return;
 | |
|       if (PlatformInfos.isDesktop &&
 | |
|           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 = 64;
 | |
|         const thumbnailMethod = ThumbnailMethod.crop;
 | |
|         // Pre-cache so that we can later just set the thumbnail uri as icon:
 | |
|         await client.downloadMxcCached(
 | |
|           avatarUrl,
 | |
|           width: size,
 | |
|           height: size,
 | |
|           thumbnailMethod: thumbnailMethod,
 | |
|           isThumbnail: true,
 | |
|         );
 | |
| 
 | |
|         thumbnailUri =
 | |
|             await event.senderFromMemoryOrFallback.avatarUrl?.getThumbnailUri(
 | |
|           client,
 | |
|           width: size,
 | |
|           height: size,
 | |
|           method: thumbnailMethod,
 | |
|         );
 | |
|       }
 | |
| 
 | |
|       _audioPlayer.play();
 | |
| 
 | |
|       html.Notification(
 | |
|         title,
 | |
|         body: body,
 | |
|         icon: thumbnailUri?.toString(),
 | |
|         tag: event.room.id,
 | |
|       );
 | |
|     } else if (Platform.isLinux) {
 | |
|       final notification = await linuxNotifications!.notify(
 | |
|         title,
 | |
|         body: body,
 | |
|         replacesId: linuxNotificationIds[roomId] ?? 0,
 | |
|         appName: AppConfig.applicationName,
 | |
|         appIcon: 'fluffychat',
 | |
|         actions: [
 | |
|           NotificationAction(
 | |
|             DesktopNotificationActions.openChat.name,
 | |
|             L10n.of(context).openChat,
 | |
|           ),
 | |
|           NotificationAction(
 | |
|             DesktopNotificationActions.seen.name,
 | |
|             L10n.of(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:
 | |
|             event.room.setReadMarker(
 | |
|               event.eventId,
 | |
|               mRead: event.eventId,
 | |
|               public: AppConfig.sendPublicReadReceipts,
 | |
|             );
 | |
|             break;
 | |
|           case DesktopNotificationActions.openChat:
 | |
|             context.go('/rooms/${event.room.id}');
 | |
|             break;
 | |
|         }
 | |
|       });
 | |
|       linuxNotificationIds[roomId] = notification.id;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| enum DesktopNotificationActions { seen, openChat }
 |