mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
This commit is contained in:
parent
e0e2d26b4b
commit
39fcd3b9c9
@ -374,6 +374,7 @@
|
|||||||
C4F69156C31A447FEFF2A47C /* DTHTMLElement+AttributedStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E508AB0EDEE017FF4F6F8D1 /* DTHTMLElement+AttributedStringBuilder.swift */; };
|
C4F69156C31A447FEFF2A47C /* DTHTMLElement+AttributedStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E508AB0EDEE017FF4F6F8D1 /* DTHTMLElement+AttributedStringBuilder.swift */; };
|
||||||
C4F784AABFF44E4716E7A8BC /* RoomDetailsViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87B3A76EA6AB67910C11330F /* RoomDetailsViewModelProtocol.swift */; };
|
C4F784AABFF44E4716E7A8BC /* RoomDetailsViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87B3A76EA6AB67910C11330F /* RoomDetailsViewModelProtocol.swift */; };
|
||||||
C55A44C99F64A479ABA85B46 /* RoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */; };
|
C55A44C99F64A479ABA85B46 /* RoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */; };
|
||||||
|
C6136E848E55D2C86BF760F5 /* NetworkMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C789E7BFC066CF39B8AE0974 /* NetworkMonitor.swift */; };
|
||||||
C74EE50257ED925C2B8EFCE6 /* MockSoftLogoutScreenState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B869438A1B52836F912A702 /* MockSoftLogoutScreenState.swift */; };
|
C74EE50257ED925C2B8EFCE6 /* MockSoftLogoutScreenState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B869438A1B52836F912A702 /* MockSoftLogoutScreenState.swift */; };
|
||||||
C76892321558E75101E68ED6 /* ReadableFrameModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */; };
|
C76892321558E75101E68ED6 /* ReadableFrameModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */; };
|
||||||
C7B251DC896C0867C51B616D /* AnalyticsPrompt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 541542F5AC323709D8563458 /* AnalyticsPrompt.swift */; };
|
C7B251DC896C0867C51B616D /* AnalyticsPrompt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 541542F5AC323709D8563458 /* AnalyticsPrompt.swift */; };
|
||||||
@ -915,6 +916,7 @@
|
|||||||
C687844F60BFF532D49A994C /* AnalyticsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsTests.swift; sourceTree = "<group>"; };
|
C687844F60BFF532D49A994C /* AnalyticsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsTests.swift; sourceTree = "<group>"; };
|
||||||
C6FEA87EA3752203065ECE27 /* BugReportUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportUITests.swift; sourceTree = "<group>"; };
|
C6FEA87EA3752203065ECE27 /* BugReportUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportUITests.swift; sourceTree = "<group>"; };
|
||||||
C75EF87651B00A176AB08E97 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
C75EF87651B00A176AB08E97 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
C789E7BFC066CF39B8AE0974 /* NetworkMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkMonitor.swift; sourceTree = "<group>"; };
|
||||||
C830A64609CBD152F06E0457 /* NotificationConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationConstants.swift; sourceTree = "<group>"; };
|
C830A64609CBD152F06E0457 /* NotificationConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationConstants.swift; sourceTree = "<group>"; };
|
||||||
C88508B6F7974CFABEC4B261 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = "<group>"; };
|
C88508B6F7974CFABEC4B261 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
C888BCD78E2A55DCE364F160 /* MediaProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProviderProtocol.swift; sourceTree = "<group>"; };
|
C888BCD78E2A55DCE364F160 /* MediaProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProviderProtocol.swift; sourceTree = "<group>"; };
|
||||||
@ -2142,6 +2144,7 @@
|
|||||||
12A626D74BBE9F4A60763B45 /* ImageAnonymizer.swift */,
|
12A626D74BBE9F4A60763B45 /* ImageAnonymizer.swift */,
|
||||||
6A580295A56B55A856CC4084 /* InfoPlistReader.swift */,
|
6A580295A56B55A856CC4084 /* InfoPlistReader.swift */,
|
||||||
6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */,
|
6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */,
|
||||||
|
C789E7BFC066CF39B8AE0974 /* NetworkMonitor.swift */,
|
||||||
F754E66A8970963B15B2A41E /* PermalinkBuilder.swift */,
|
F754E66A8970963B15B2A41E /* PermalinkBuilder.swift */,
|
||||||
53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */,
|
53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */,
|
||||||
BB3073CCD77D906B330BC1D6 /* Tests.swift */,
|
BB3073CCD77D906B330BC1D6 /* Tests.swift */,
|
||||||
@ -3008,6 +3011,7 @@
|
|||||||
FA2BBAE9FC5E2E9F960C0980 /* NavigationCoordinators.swift in Sources */,
|
FA2BBAE9FC5E2E9F960C0980 /* NavigationCoordinators.swift in Sources */,
|
||||||
71C1347F23868324A4F43940 /* NavigationModule.swift in Sources */,
|
71C1347F23868324A4F43940 /* NavigationModule.swift in Sources */,
|
||||||
B5E455C9689EA600EDB3E9E0 /* NavigationRootCoordinator.swift in Sources */,
|
B5E455C9689EA600EDB3E9E0 /* NavigationRootCoordinator.swift in Sources */,
|
||||||
|
C6136E848E55D2C86BF760F5 /* NetworkMonitor.swift in Sources */,
|
||||||
8BBD3AA589DEE02A1B0923B2 /* NoticeRoomTimelineItem.swift in Sources */,
|
8BBD3AA589DEE02A1B0923B2 /* NoticeRoomTimelineItem.swift in Sources */,
|
||||||
368C8758FCD079E6AAA18C2C /* NoticeRoomTimelineView.swift in Sources */,
|
368C8758FCD079E6AAA18C2C /* NoticeRoomTimelineView.swift in Sources */,
|
||||||
3F70E237CE4C3FAB02FC227F /* NotificationConstants.swift in Sources */,
|
3F70E237CE4C3FAB02FC227F /* NotificationConstants.swift in Sources */,
|
||||||
|
@ -47,6 +47,7 @@ class AppCoordinator: AppCoordinatorProtocol {
|
|||||||
private let bugReportService: BugReportServiceProtocol
|
private let bugReportService: BugReportServiceProtocol
|
||||||
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
||||||
|
|
||||||
|
private var userSessionCancellables = Set<AnyCancellable>()
|
||||||
private var cancellables = Set<AnyCancellable>()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
private(set) var notificationManager: NotificationManagerProtocol?
|
private(set) var notificationManager: NotificationManagerProtocol?
|
||||||
|
|
||||||
@ -79,9 +80,8 @@ class AppCoordinator: AppCoordinatorProtocol {
|
|||||||
|
|
||||||
Bundle.elementFallbackLanguage = "en"
|
Bundle.elementFallbackLanguage = "en"
|
||||||
|
|
||||||
startObservingApplicationState()
|
observeApplicationState()
|
||||||
|
observeNetworkState()
|
||||||
// Benchmark.trackingEnabled = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
@ -101,6 +101,7 @@ class AppCoordinator: AppCoordinatorProtocol {
|
|||||||
private static func setupServiceLocator(navigationRootCoordinator: NavigationRootCoordinator) {
|
private static func setupServiceLocator(navigationRootCoordinator: NavigationRootCoordinator) {
|
||||||
ServiceLocator.shared.register(userNotificationController: UserNotificationController(rootCoordinator: navigationRootCoordinator))
|
ServiceLocator.shared.register(userNotificationController: UserNotificationController(rootCoordinator: navigationRootCoordinator))
|
||||||
ServiceLocator.shared.register(appSettings: AppSettings())
|
ServiceLocator.shared.register(appSettings: AppSettings())
|
||||||
|
ServiceLocator.shared.register(networkMonitor: NetworkMonitor())
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func setupLogging() {
|
private static func setupLogging() {
|
||||||
@ -329,12 +330,11 @@ class AppCoordinator: AppCoordinatorProtocol {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &userSessionCancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func deobserveUserSessionChanges() {
|
private func deobserveUserSessionChanges() {
|
||||||
cancellables.forEach { $0.cancel() }
|
userSessionCancellables.removeAll()
|
||||||
cancellables.removeAll()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Toasts and loading indicators
|
// MARK: Toasts and loading indicators
|
||||||
@ -366,7 +366,7 @@ class AppCoordinator: AppCoordinatorProtocol {
|
|||||||
userSession?.clientProxy.startSync()
|
userSession?.clientProxy.startSync()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func startObservingApplicationState() {
|
private func observeApplicationState() {
|
||||||
NotificationCenter.default.addObserver(self,
|
NotificationCenter.default.addObserver(self,
|
||||||
selector: #selector(applicationWillResignActive),
|
selector: #selector(applicationWillResignActive),
|
||||||
name: UIApplication.willResignActiveNotification,
|
name: UIApplication.willResignActiveNotification,
|
||||||
@ -401,6 +401,19 @@ class AppCoordinator: AppCoordinatorProtocol {
|
|||||||
resume()
|
resume()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func observeNetworkState() {
|
||||||
|
let reachabilityNotificationIdentifier = "io.element.elementx.reachability.notification"
|
||||||
|
ServiceLocator.shared.networkMonitor.reachabilityPublisher.sink { reachable in
|
||||||
|
if reachable {
|
||||||
|
ServiceLocator.shared.userNotificationController.retractNotificationWithId(reachabilityNotificationIdentifier)
|
||||||
|
} else {
|
||||||
|
ServiceLocator.shared.userNotificationController.submitNotification(.init(id: reachabilityNotificationIdentifier,
|
||||||
|
title: ElementL10n.a11yPresenceOffline,
|
||||||
|
persistent: true))
|
||||||
|
}
|
||||||
|
}.store(in: &cancellables)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - AuthenticationCoordinatorDelegate
|
// MARK: - AuthenticationCoordinatorDelegate
|
||||||
|
@ -32,4 +32,10 @@ class ServiceLocator {
|
|||||||
func register(appSettings: AppSettings) {
|
func register(appSettings: AppSettings) {
|
||||||
settings = appSettings
|
settings = appSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private(set) var networkMonitor: NetworkMonitor!
|
||||||
|
|
||||||
|
func register(networkMonitor: NetworkMonitor) {
|
||||||
|
self.networkMonitor = networkMonitor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
50
ElementX/Sources/Other/NetworkMonitor.swift
Normal file
50
ElementX/Sources/Other/NetworkMonitor.swift
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2022 New Vector Ltd
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
import Network
|
||||||
|
|
||||||
|
class NetworkMonitor {
|
||||||
|
private let pathMonitor: NWPathMonitor
|
||||||
|
private let queue: DispatchQueue
|
||||||
|
let reachabilityPublisher: CurrentValueSubject<Bool, Never>
|
||||||
|
|
||||||
|
var isCurrentConnectionExpensive: Bool {
|
||||||
|
pathMonitor.currentPath.isExpensive
|
||||||
|
}
|
||||||
|
|
||||||
|
var isCurrentConnectionConstrained: Bool {
|
||||||
|
pathMonitor.currentPath.isConstrained
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
queue = DispatchQueue(label: "io.element.elementx.networkmonitor")
|
||||||
|
pathMonitor = NWPathMonitor()
|
||||||
|
reachabilityPublisher = CurrentValueSubject<Bool, Never>(pathMonitor.currentPath.status == .satisfied)
|
||||||
|
|
||||||
|
pathMonitor.pathUpdateHandler = { [weak self] path in
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
if path.status == .satisfied {
|
||||||
|
self?.reachabilityPublisher.send(true)
|
||||||
|
} else {
|
||||||
|
self?.reachabilityPublisher.send(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pathMonitor.start(queue: queue)
|
||||||
|
}
|
||||||
|
}
|
@ -120,7 +120,6 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
func stop() {
|
func stop() {
|
||||||
cancellables.forEach { $0.cancel() }
|
|
||||||
cancellables.removeAll()
|
cancellables.removeAll()
|
||||||
state.contextMenuBuilder = nil
|
state.contextMenuBuilder = nil
|
||||||
}
|
}
|
||||||
|
1
changelog.d/258.feature
Normal file
1
changelog.d/258.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
Display an indicator if the network is currently unreachable
|
Loading…
x
Reference in New Issue
Block a user