diff --git a/lib/config/setting_keys.dart b/lib/config/setting_keys.dart index c8713a8a..dc54252f 100644 --- a/lib/config/setting_keys.dart +++ b/lib/config/setting_keys.dart @@ -17,7 +17,6 @@ abstract class SettingKeys { static const String unifiedPushRegistered = 'chat.fluffy.unifiedpush.registered'; static const String unifiedPushEndpoint = 'chat.fluffy.unifiedpush.endpoint'; - static const String notificationCurrentIds = 'chat.fluffy.notification_ids'; static const String ownStatusMessage = 'chat.fluffy.status_msg'; static const String dontAskForBootstrapKey = 'chat.fluffychat.dont_ask_bootstrap'; diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 53475f75..ac998c78 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -13,13 +13,13 @@ import 'package:emoji_picker_flutter/emoji_picker_flutter.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; -import 'package:universal_html/html.dart' as html; import 'package:go_router/go_router.dart'; import 'package:image_picker/image_picker.dart'; import 'package:matrix/matrix.dart'; import 'package:record/record.dart'; import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:universal_html/html.dart' as html; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; diff --git a/lib/utils/background_push.dart b/lib/utils/background_push.dart index dfdb171b..039dde89 100644 --- a/lib/utils/background_push.dart +++ b/lib/utils/background_push.dart @@ -70,9 +70,6 @@ class BackgroundPush { bool upAction = false; BackgroundPush._(this.client) { - onRoomSync ??= client.onSync.stream - .where((s) => s.hasRoomUpdate) - .listen((s) => _onClearingPush(getFromServer: false)); firebase?.setListeners( onMessage: (message) => pushHelper( PushNotification.fromJson( @@ -128,8 +125,6 @@ class BackgroundPush { } } - StreamSubscription? onRoomSync; - Future setupPusher({ String? gatewayUrl, String? token, @@ -405,95 +400,4 @@ class BackgroundPush { activeRoomId: matrix?.activeRoomId, ); } - - /// Workaround for the problem that local notification IDs must be int but we - /// sort by [roomId] which is a String. To make sure that we don't have duplicated - /// IDs we map the [roomId] to a number and matrix?.store this number. - late Map idMap; - Future _loadIdMap() async { - idMap = Map.from( - json.decode( - (matrix?.store.getString(SettingKeys.notificationCurrentIds)) ?? '{}', - ), - ); - } - - bool _clearingPushLock = false; - Future _onClearingPush({bool getFromServer = true}) async { - if (_clearingPushLock) { - return; - } - try { - _clearingPushLock = true; - late Iterable emptyRooms; - if (getFromServer) { - Logs().v('[Push] Got new clearing push'); - var syncErrored = false; - if (client.syncPending) { - Logs().v('[Push] waiting for existing sync'); - // we need to catchError here as the Future might be in a different execution zone - await client.oneShotSync().catchError((e) { - syncErrored = true; - Logs().v('[Push] Error one-shot syncing', e); - }); - } - if (!syncErrored) { - Logs().v('[Push] single oneShotSync'); - // we need to catchError here as the Future might be in a different execution zone - await client.oneShotSync().catchError((e) { - syncErrored = true; - Logs().v('[Push] Error one-shot syncing', e); - }); - if (!syncErrored) { - emptyRooms = client.rooms - .where((r) => r.notificationCount == 0) - .map((r) => r.id); - } - } - if (syncErrored) { - try { - Logs().v( - '[Push] failed to sync for fallback push, fetching notifications endpoint...', - ); - final notifications = await client.getNotifications(limit: 20); - final notificationRooms = - notifications.notifications.map((n) => n.roomId).toSet(); - emptyRooms = client.rooms - .where((r) => !notificationRooms.contains(r.id)) - .map((r) => r.id); - } catch (e) { - Logs().v( - '[Push] failed to fetch pending notifications for clearing push, falling back...', - e, - ); - emptyRooms = client.rooms - .where((r) => r.notificationCount == 0) - .map((r) => r.id); - } - } - } else { - emptyRooms = client.rooms - .where((r) => r.notificationCount == 0) - .map((r) => r.id); - } - await _loadIdMap(); - var changed = false; - for (final roomId in emptyRooms) { - final id = idMap[roomId]; - if (id != null) { - idMap.remove(roomId); - changed = true; - await _flutterLocalNotificationsPlugin.cancel(id); - } - } - if (changed) { - await matrix?.store.setString( - SettingKeys.notificationCurrentIds, - json.encode(idMap), - ); - } - } finally { - _clearingPushLock = false; - } - } } diff --git a/lib/utils/push_helper.dart b/lib/utils/push_helper.dart index 381162e7..e8097c0c 100644 --- a/lib/utils/push_helper.dart +++ b/lib/utils/push_helper.dart @@ -1,10 +1,10 @@ -import 'dart:convert'; import 'dart:io'; import 'dart:ui'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:collection/collection.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; @@ -13,7 +13,6 @@ import 'package:matrix/matrix.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:fluffychat/config/app_config.dart'; -import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/utils/client_manager.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -113,14 +112,20 @@ Future _tryPushHelper( if (event == null) { Logs().v('Notification is a clearing indicator.'); - if (notification.counts?.unread == 0) { - if (notification.counts == null || notification.counts?.unread == 0) { - await flutterLocalNotificationsPlugin.cancelAll(); - final store = await SharedPreferences.getInstance(); - await store.setString( - SettingKeys.notificationCurrentIds, - json.encode({}), + if (notification.counts?.unread == null || + notification.counts?.unread == 0) { + await flutterLocalNotificationsPlugin.cancelAll(); + } else { + await client.roomsLoading; + final activeNotifications = + await flutterLocalNotificationsPlugin.getActiveNotifications(); + for (final activeNotification in activeNotifications) { + final room = client.rooms.singleWhereOrNull( + (room) => room.id.hashCode == activeNotification.id, ); + if (room == null || !room.isUnreadOrInvited) { + flutterLocalNotificationsPlugin.cancel(activeNotification.id!); + } } } return; diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart index 152d42ee..c57ee96d 100644 --- a/lib/widgets/matrix.dart +++ b/lib/widgets/matrix.dart @@ -466,7 +466,6 @@ class MatrixState extends State with WidgetsBindingObserver { client.httpClient.close(); onFocusSub?.cancel(); onBlurSub?.cancel(); - backgroundPush?.onRoomSync?.cancel(); linuxNotifications?.close();