import 'package:collection/collection.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:fluffychat/utils/client_manager.dart'; @pragma('vm:entry-point') void notificationTapBackground( NotificationResponse notificationResponse, ) async { Logs().i('Notification tap in background'); final client = (await ClientManager.getClients( initialize: false, store: await SharedPreferences.getInstance(), )) .first; await client.abortSync(); await client.init( waitForFirstSync: false, waitUntilLoadCompletedLoaded: false, ); if (!client.isLogged()) { throw Exception('Notification tab in background but not logged in!'); } notificationTap(notificationResponse, client: client); } void notificationTap( NotificationResponse notificationResponse, { GoRouter? router, required Client client, }) async { Logs().d( 'Notification action handler started', notificationResponse.notificationResponseType.name, ); switch (notificationResponse.notificationResponseType) { case NotificationResponseType.selectedNotification: final roomId = notificationResponse.payload; if (roomId == null) return; if (router == null) { Logs().v('Ignore select notification action in background mode'); return; } Logs().v('Open room from notification tap', roomId); await client.roomsLoading; await client.accountDataLoading; router.go( client.getRoomById(roomId)?.membership == Membership.invite ? '/rooms' : '/rooms/$roomId', ); case NotificationResponseType.selectedNotificationAction: final actionType = FluffyChatNotificationActions.values.singleWhereOrNull( (action) => action.name == notificationResponse.actionId, ); if (actionType == null) { throw Exception('Selected notification with action but no action ID'); } final roomId = notificationResponse.payload; if (roomId == null) { throw Exception('Selected notification with action but no payload'); } final room = client.getRoomById(roomId); if (room == null) { throw Exception( 'Selected notification with action but unknown room $roomId', ); } switch (actionType) { case FluffyChatNotificationActions.markAsRead: await room.setReadMarker(room.lastEvent!.eventId); case FluffyChatNotificationActions.reply: final input = notificationResponse.input; if (input == null || input.isEmpty) { throw Exception( 'Selected notification with reply action but without input', ); } await room.sendTextEvent(input); } } } enum FluffyChatNotificationActions { markAsRead, reply }