mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Avoid race and duplication conditions between local and remote notifications (#848)
* added timestamp control of the local notification * improved the code, and implemented the solution, just needs some testing * sdk bump * UserPreference init with initialValue instead of defaultValue * pr suggestions * changelog * notifications sliding sync view added
This commit is contained in:
@@ -45,7 +45,8 @@ private class WeakClientProxyWrapper: ClientDelegate, NotificationDelegate, Slid
|
||||
// MARK: - NotificationDelegate
|
||||
|
||||
func didReceiveNotification(notification: MatrixRustSDK.NotificationItem) {
|
||||
clientProxy?.didReceiveNotification(notification: NotificationItemProxy(notificationItem: notification))
|
||||
guard let userID = clientProxy?.userID else { return }
|
||||
clientProxy?.didReceiveNotification(notification: NotificationItemProxy(notificationItem: notification, receiverID: userID))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +72,8 @@ class ClientProxy: ClientProxyProtocol {
|
||||
var invitesViewProxy: SlidingSyncViewProxy?
|
||||
var invitesSummaryProvider: RoomSummaryProviderProtocol?
|
||||
|
||||
var notificationsSlidingSyncView: SlidingSyncList?
|
||||
|
||||
private var loadCachedAvatarURLTask: Task<Void, Never>?
|
||||
private let avatarURLSubject = CurrentValueSubject<URL?, Never>(nil)
|
||||
var avatarURLPublisher: AnyPublisher<URL?, Never> {
|
||||
@@ -103,9 +106,9 @@ class ClientProxy: ClientProxyProtocol {
|
||||
let delegate = WeakClientProxyWrapper(clientProxy: self)
|
||||
client.setDelegate(delegate: delegate)
|
||||
// Uncomment to test local notifications
|
||||
// await Task.dispatch(on: clientQueue) {
|
||||
// client.setNotificationDelegate(notificationDelegate: delegate)
|
||||
// }
|
||||
await Task.dispatch(on: clientQueue) {
|
||||
client.setNotificationDelegate(notificationDelegate: delegate)
|
||||
}
|
||||
|
||||
configureSlidingSync()
|
||||
|
||||
@@ -319,6 +322,7 @@ class ClientProxy: ClientProxyProtocol {
|
||||
buildAndConfigureVisibleRoomsSlidingSyncView()
|
||||
buildAndConfigureAllRoomsSlidingSyncView()
|
||||
buildAndConfigureInvitesSlidingSyncView()
|
||||
buildAndConfigureNotificationSyncView()
|
||||
|
||||
guard let visibleRoomsSlidingSyncView else {
|
||||
MXLog.error("Visible rooms sliding sync view unavailable")
|
||||
@@ -438,7 +442,28 @@ class ClientProxy: ClientProxyProtocol {
|
||||
MXLog.error("Failed building the invites sliding sync view with error: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func buildAndConfigureNotificationSyncView() {
|
||||
guard notificationsSlidingSyncView == nil else {
|
||||
fatalError("This shouldn't be called more than once")
|
||||
}
|
||||
|
||||
do {
|
||||
let notificationsSlidingSyncView = try SlidingSyncListBuilder()
|
||||
.noTimelineLimit()
|
||||
.requiredState(requiredState: slidingSyncNotificationsRequiredState)
|
||||
.filters(filters: slidingSyncNotificationsFilters)
|
||||
.name(name: "Notifications")
|
||||
.syncMode(mode: .growing)
|
||||
.batchSize(batchSize: 100)
|
||||
.build()
|
||||
|
||||
self.notificationsSlidingSyncView = notificationsSlidingSyncView
|
||||
} catch {
|
||||
MXLog.error("Failed building the notification sliding sync view with error: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
private func buildRoomSummaryProviders() {
|
||||
guard visibleRoomsSummaryProvider == nil, allRoomsSummaryProvider == nil, invitesSummaryProvider == nil else {
|
||||
fatalError("This shouldn't be called more than once")
|
||||
@@ -459,17 +484,12 @@ class ClientProxy: ClientProxyProtocol {
|
||||
eventStringBuilder: RoomEventStringBuilder(stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID)))
|
||||
}
|
||||
|
||||
private lazy var slidingSyncRequiredState = [
|
||||
RequiredState(key: "m.room.avatar", value: ""),
|
||||
RequiredState(key: "m.room.encryption", value: "")
|
||||
// These are required for notifications
|
||||
// The idea is to create another SS
|
||||
// to listen to them separately
|
||||
// only here for testing purposes when enabling local notifications
|
||||
// RequiredState(key: "m.room.member", value: "$ME"),
|
||||
// RequiredState(key: "m.room.power_levels", value: ""),
|
||||
// RequiredState(key: "m.room.name", value: "")
|
||||
]
|
||||
private lazy var slidingSyncRequiredState = [RequiredState(key: "m.room.avatar", value: ""),
|
||||
RequiredState(key: "m.room.encryption", value: "")]
|
||||
|
||||
private lazy var slidingSyncNotificationsRequiredState = [RequiredState(key: "m.room.member", value: "$ME"),
|
||||
RequiredState(key: "m.room.power_levels", value: ""),
|
||||
RequiredState(key: "m.room.name", value: "")]
|
||||
|
||||
private lazy var slidingSyncInvitesRequiredState = [RequiredState(key: "m.room.avatar", value: ""),
|
||||
RequiredState(key: "m.room.encryption", value: ""),
|
||||
@@ -486,6 +506,17 @@ class ClientProxy: ClientProxyProtocol {
|
||||
roomNameLike: nil,
|
||||
tags: [],
|
||||
notTags: [])
|
||||
|
||||
private lazy var slidingSyncNotificationsFilters = SlidingSyncRequestListFilters(isDm: nil,
|
||||
spaces: [],
|
||||
isEncrypted: nil,
|
||||
isInvite: nil,
|
||||
isTombstoned: false,
|
||||
roomTypes: [],
|
||||
notRoomTypes: ["m.space"],
|
||||
roomNameLike: nil,
|
||||
tags: [],
|
||||
notTags: [])
|
||||
|
||||
private lazy var slidingSyncInviteFilters = SlidingSyncRequestListFilters(isDm: nil,
|
||||
spaces: [],
|
||||
@@ -519,6 +550,13 @@ class ClientProxy: ClientProxyProtocol {
|
||||
} else {
|
||||
MXLog.error("Invites sliding sync view unavailable")
|
||||
}
|
||||
|
||||
if let notificationsSlidingSyncView {
|
||||
MXLog.info("Registering notifications view")
|
||||
_ = slidingSync?.addList(list: notificationsSlidingSyncView)
|
||||
} else {
|
||||
MXLog.error("Notifications sliding sync view unavailable")
|
||||
}
|
||||
|
||||
restartSync()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user