diff --git a/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift index 5e9ad6e6b..a513f49e6 100644 --- a/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift @@ -285,7 +285,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol { .store(in: &cancellables) let reachabilityNotificationID = "io.element.elementx.reachability.notification" - userSession.clientProxy.homeserverReachabilityPublisher.removeDuplicates() + userSession.clientProxy.homeserverConnectivityPublisher.removeDuplicates() .combineLatest(flowParameters.appMediator.networkMonitor.reachabilityPublisher.removeDuplicates()) .receive(on: DispatchQueue.main) .sink { [weak self] homeserverReachability, networkReachability in diff --git a/ElementX/Sources/Mocks/ClientProxyMock.swift b/ElementX/Sources/Mocks/ClientProxyMock.swift index a34a79401..4866f7ebb 100644 --- a/ElementX/Sources/Mocks/ClientProxyMock.swift +++ b/ElementX/Sources/Mocks/ClientProxyMock.swift @@ -63,6 +63,7 @@ extension ClientProxyMock { loadingStatePublisher = .init(.notLoading) verificationStatePublisher = .init(.unknown) homeserverReachabilityPublisher = .init(.reachable) + homeserverConnectivityPublisher = .init(.reachable) userAvatarURLPublisher = .init(nil) userDisplayNamePublisher = .init("User display name") diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index fd33492da..ce32a3806 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -2232,6 +2232,11 @@ nonisolated class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable { set(value) { underlyingHomeserverReachabilityPublisher = value } } nonisolated(unsafe) var underlyingHomeserverReachabilityPublisher: CurrentValuePublisher! + var homeserverConnectivityPublisher: CurrentValuePublisher { + get { return underlyingHomeserverConnectivityPublisher } + set(value) { underlyingHomeserverConnectivityPublisher = value } + } + nonisolated(unsafe) var underlyingHomeserverConnectivityPublisher: CurrentValuePublisher! var userID: String { get { return underlyingUserID } set(value) { underlyingUserID = value } diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 877a7459b..ef7b21fa8 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -180,11 +180,21 @@ class ClientProxy: ClientProxyProtocol { verificationStateSubject.asCurrentValuePublisher() } + /// Reports unreachable while suspended (the store is closed) as well as when offline. Use this to gate + /// work that needs an open store, such as media loading. private let homeserverReachabilitySubject = CurrentValueSubject(.reachable) var homeserverReachabilityPublisher: CurrentValuePublisher { homeserverReachabilitySubject.asCurrentValuePublisher() } + /// The homeserver's reachability derived from the sync service alone, i.e. it stays reachable while the + /// client is suspended. Use this for user-facing messaging so we don't claim the server is unreachable + /// when we've simply paused syncing. + private let homeserverConnectivitySubject = CurrentValueSubject(.reachable) + var homeserverConnectivityPublisher: CurrentValuePublisher { + homeserverConnectivitySubject.asCurrentValuePublisher() + } + private let timelineMediaVisibilitySubject = CurrentValueSubject(.always) var timelineMediaVisibilityPublisher: CurrentValuePublisher { timelineMediaVisibilitySubject.asCurrentValuePublisher() @@ -1200,6 +1210,8 @@ class ClientProxy: ClientProxyProtocol { } private func updateHomeserverReachability() { + homeserverConnectivitySubject.send(syncServiceState == .offline ? .unreachable : .reachable) + let reachability: NetworkMonitorReachability = if desiredServiceState == .running, syncServiceState != .offline { .reachable } else { diff --git a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift index 6746b1609..08e8a1af5 100644 --- a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift +++ b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift @@ -110,6 +110,8 @@ protocol ClientProxyProtocol: AnyObject { var homeserverReachabilityPublisher: CurrentValuePublisher { get } + var homeserverConnectivityPublisher: CurrentValuePublisher { get } + var userID: String { get } var deviceID: String? { get }