mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Prevent race conditions when adding timeline listeners between the timeline provider and other screens
This commit is contained in:
committed by
Stefan Ceriu
parent
0082aba9d4
commit
142a8d6275
@@ -186,13 +186,14 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
timelineLimit: UInt32(SlidingSyncConstants.timelinePrecachingTimelineLimit))
|
timelineLimit: UInt32(SlidingSyncConstants.timelinePrecachingTimelineLimit))
|
||||||
roomSubscriptionObservationToken = slidingSyncRoom.subscribeToRoom(settings: settings)
|
roomSubscriptionObservationToken = slidingSyncRoom.subscribeToRoom(settings: settings)
|
||||||
|
|
||||||
let listener = RoomTimelineListener { [weak self] timelineDiff in
|
let timelineListener = RoomTimelineListener { [weak self] timelineDiff in
|
||||||
self?.updatesSubject.send(timelineDiff)
|
self?.updatesSubject.send(timelineDiff)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let result = try? slidingSyncRoom.addTimelineListener(listener: listener) {
|
self.timelineListener = timelineListener
|
||||||
|
|
||||||
|
if let result = try? slidingSyncRoom.addTimelineListener(listener: timelineListener) {
|
||||||
roomTimelineObservationToken = result.taskHandle
|
roomTimelineObservationToken = result.taskHandle
|
||||||
timelineListener = listener
|
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
await fetchMembers()
|
await fetchMembers()
|
||||||
@@ -200,6 +201,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
}
|
}
|
||||||
return .success(result.items)
|
return .success(result.items)
|
||||||
} else {
|
} else {
|
||||||
|
self.timelineListener = nil
|
||||||
return .failure(.failedAddingTimelineListener)
|
return .failure(.failedAddingTimelineListener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,24 +39,22 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol {
|
|||||||
self.roomProxy = roomProxy
|
self.roomProxy = roomProxy
|
||||||
serialDispatchQueue = DispatchQueue(label: "io.element.elementx.roomtimelineprovider", qos: .utility)
|
serialDispatchQueue = DispatchQueue(label: "io.element.elementx.roomtimelineprovider", qos: .utility)
|
||||||
itemProxies = []
|
itemProxies = []
|
||||||
|
|
||||||
Task { @MainActor in
|
roomProxy
|
||||||
roomProxy
|
.updatesPublisher
|
||||||
.updatesPublisher
|
.collect(.byTime(serialDispatchQueue, 0.1))
|
||||||
.collect(.byTime(serialDispatchQueue, 0.1))
|
.sink { [weak self] in self?.updateItemsWithDiffs($0) }
|
||||||
.sink { [weak self] in self?.updateItemsWithDiffs($0) }
|
.store(in: &cancellables)
|
||||||
.store(in: &cancellables)
|
|
||||||
|
switch roomProxy.registerTimelineListenerIfNeeded() {
|
||||||
switch roomProxy.registerTimelineListenerIfNeeded() {
|
case let .success(items):
|
||||||
case let .success(items):
|
itemProxies = items.map(TimelineItemProxy.init)
|
||||||
itemProxies = items.map(TimelineItemProxy.init)
|
MXLog.info("Added timeline listener, current items (\(items.count)) : \(items.map(\.debugIdentifier))")
|
||||||
MXLog.info("Added timeline listener, current items (\(items.count)) : \(items.map(\.debugIdentifier))")
|
case .failure(.roomListenerAlreadyRegistered):
|
||||||
case .failure(.roomListenerAlreadyRegistered):
|
MXLog.info("Listener already registered for the room: \(roomProxy.id)")
|
||||||
MXLog.info("Listener already registered for the room: \(roomProxy.id)")
|
case .failure:
|
||||||
case .failure:
|
let roomID = roomProxy.id
|
||||||
let roomID = roomProxy.id
|
MXLog.error("Failed adding timeline listener on room with identifier: \(roomID)")
|
||||||
MXLog.error("Failed adding timeline listener on room with identifier: \(roomID)")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
import Combine
|
import Combine
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
@MainActor
|
||||||
protocol RoomTimelineProviderProtocol {
|
protocol RoomTimelineProviderProtocol {
|
||||||
var itemsPublisher: CurrentValuePublisher<[TimelineItemProxy], Never> { get }
|
var itemsPublisher: CurrentValuePublisher<[TimelineItemProxy], Never> { get }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ class MockScreen: Identifiable {
|
|||||||
let mockUserSession = MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider())
|
let mockUserSession = MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider())
|
||||||
let createRoomParameters = CreateRoomFlowParameters()
|
let createRoomParameters = CreateRoomFlowParameters()
|
||||||
let selectedUsers: [UserProfile] = [.mockAlice, .mockBob, .mockCharlie]
|
let selectedUsers: [UserProfile] = [.mockAlice, .mockBob, .mockCharlie]
|
||||||
let parameters = CreateRoomCoordinatorParameters(userSession: mockUserSession, userIndicatorController: MockUserIndicatorController(), createRoomParameters: .init(createRoomParameters), selectedUsers: .init(selectedUsers))
|
let parameters = CreateRoomCoordinatorParameters(userSession: mockUserSession, userIndicatorController: nil, createRoomParameters: .init(createRoomParameters), selectedUsers: .init(selectedUsers))
|
||||||
let coordinator = CreateRoomCoordinator(parameters: parameters)
|
let coordinator = CreateRoomCoordinator(parameters: parameters)
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
@@ -500,7 +500,7 @@ class MockScreen: Identifiable {
|
|||||||
let clientProxy = MockClientProxy(userID: "@mock:client.com")
|
let clientProxy = MockClientProxy(userID: "@mock:client.com")
|
||||||
let mockUserSession = MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider())
|
let mockUserSession = MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider())
|
||||||
let createRoomParameters = CreateRoomFlowParameters()
|
let createRoomParameters = CreateRoomFlowParameters()
|
||||||
let parameters = CreateRoomCoordinatorParameters(userSession: mockUserSession, userIndicatorController: MockUserIndicatorController(), createRoomParameters: .init(createRoomParameters), selectedUsers: .init([]))
|
let parameters = CreateRoomCoordinatorParameters(userSession: mockUserSession, userIndicatorController: nil, createRoomParameters: .init(createRoomParameters), selectedUsers: .init([]))
|
||||||
let coordinator = CreateRoomCoordinator(parameters: parameters)
|
let coordinator = CreateRoomCoordinator(parameters: parameters)
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
|
|||||||
Reference in New Issue
Block a user