|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|