mirror of
https://github.com/krille-chan/fluffychat
synced 2024-07-13 18:54:11 +00:00
refactor: Better logic for removing outdated notifications
This commit is contained in:
parent
c0ba68dff5
commit
6d973db6fc
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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<SyncUpdate>? onRoomSync;
|
||||
|
||||
Future<void> 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<String, int> idMap;
|
||||
Future<void> _loadIdMap() async {
|
||||
idMap = Map<String, int>.from(
|
||||
json.decode(
|
||||
(matrix?.store.getString(SettingKeys.notificationCurrentIds)) ?? '{}',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool _clearingPushLock = false;
|
||||
Future<void> _onClearingPush({bool getFromServer = true}) async {
|
||||
if (_clearingPushLock) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
_clearingPushLock = true;
|
||||
late Iterable<String> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<void> _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;
|
||||
|
|
|
@ -466,7 +466,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
|||
client.httpClient.close();
|
||||
onFocusSub?.cancel();
|
||||
onBlurSub?.cancel();
|
||||
backgroundPush?.onRoomSync?.cancel();
|
||||
|
||||
linuxNotifications?.close();
|
||||
|
||||
|
|
Loading…
Reference in a new issue