aboutsummaryrefslogtreecommitdiff
path: root/iosApp/iosApp
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2023-09-17 21:56:55 -0600
committerIván Ávalos <avalos@disroot.org>2023-09-17 23:51:33 -0600
commitedbd2c7713a0ba4e7e7a3ba6d59d16861ea4eb23 (patch)
tree885ca095c993c7a661303d215d9be0a6271ba3ea /iosApp/iosApp
parent7aec305729b872d668df45eae4821b106c1a20cb (diff)
downloadetbsa-trackermap-mobile-edbd2c7713a0ba4e7e7a3ba6d59d16861ea4eb23.tar.gz
etbsa-trackermap-mobile-edbd2c7713a0ba4e7e7a3ba6d59d16861ea4eb23.tar.bz2
etbsa-trackermap-mobile-edbd2c7713a0ba4e7e7a3ba6d59d16861ea4eb23.zip
- [shared] Implement network state monitoring
- [android] UI reacts to network state - [ios] UI reacts to network state
Diffstat (limited to 'iosApp/iosApp')
-rw-r--r--iosApp/iosApp/Session/RootView.swift32
-rw-r--r--iosApp/iosApp/Session/RootViewModel.swift36
-rw-r--r--iosApp/iosApp/Shared/OfflineBanner.swift27
-rw-r--r--iosApp/iosApp/Units/UnitsViewModel.swift12
-rw-r--r--iosApp/iosApp/en.lproj/Localizable.strings1
-rw-r--r--iosApp/iosApp/es-419.lproj/Localizable.strings1
-rw-r--r--iosApp/iosApp/iOSApp.swift9
7 files changed, 103 insertions, 15 deletions
diff --git a/iosApp/iosApp/Session/RootView.swift b/iosApp/iosApp/Session/RootView.swift
index 297a2aa..d4f28f5 100644
--- a/iosApp/iosApp/Session/RootView.swift
+++ b/iosApp/iosApp/Session/RootView.swift
@@ -35,16 +35,28 @@ struct RootView: View {
var body: some View {
Group {
- switch rootViewModel.loginState {
- case is SessionController.LoginStateLoading:
- LoadingView()
- case is SessionController.LoginStateSuccess:
- UnitsView()
- default:
- LoginContentView(username: $username,
- password: $password,
- server: $server,
- onLogin: rootViewModel.login)
+ VStack {
+ if (rootViewModel.networkAvailable != true) {
+ OfflineBanner()
+ }
+
+ if rootViewModel.showLoadingView {
+ LoadingView()
+ .frame(minHeight: 0, maxHeight: .infinity)
+ } else {
+ switch rootViewModel.loginState {
+ case is SessionController.LoginStateSuccess:
+ UnitsView()
+ case is SessionController.LoginStateLoading:
+ LoadingView()
+ .frame(minHeight: 0, maxHeight: .infinity)
+ default:
+ LoginContentView(username: $username,
+ password: $password,
+ server: $server,
+ onLogin: rootViewModel.login)
+ }
+ }
}
}.environmentObject(rootViewModel)
}
diff --git a/iosApp/iosApp/Session/RootViewModel.swift b/iosApp/iosApp/Session/RootViewModel.swift
index ec103ba..16f21f3 100644
--- a/iosApp/iosApp/Session/RootViewModel.swift
+++ b/iosApp/iosApp/Session/RootViewModel.swift
@@ -20,14 +20,42 @@ import shared
@MainActor
class RootViewModel: ObservableObject {
+ @Inject private var networkController: NetworkController
@Inject private var sessionController: SessionController
+ @Published var networkAvailable: Bool? = nil
@Published var loginState: SessionController.LoginState = SessionController.LoginStateNothing()
+ @Published var showLoadingView: Bool = false
+
+ var hasSession: Bool{
+ get { return sessionController.hasSession }
+ }
init() {
- let collector = Collector<SessionController.LoginState?>(callback: setLoginState)
- sessionController.loginStateFlow.collect(collector: collector) { _ in }
- restoreSession()
+ let networkCollector = Collector<Bool?>(callback: setNetworkState)
+ networkController.networkAvailable.collect(collector: networkCollector) { _ in }
+ let sessionCollector = Collector<SessionController.LoginState?>(callback: setLoginState)
+ sessionController.loginStateFlow.collect(collector: sessionCollector) { _ in }
+ }
+
+ func setNetworkState(state: Bool?) {
+ print("Network state is: \(state?.description ?? "")")
+ Task { @MainActor in
+ self.networkAvailable = state
+
+ // Wait for internet to restore session
+ if (state == true && sessionController.hasSession) {
+ showLoadingView = false
+ restoreSession()
+ return
+ }
+
+ if (state == nil) {
+ showLoadingView = true
+ } else {
+ showLoadingView = hasSession
+ }
+ }
}
func setLoginState(state: SessionController.LoginState?) {
@@ -38,7 +66,7 @@ class RootViewModel: ObservableObject {
}
func restoreSession() {
- sessionController.restoreSession()
+ sessionController.getSession()
}
private func getFcmToken() -> String? {
diff --git a/iosApp/iosApp/Shared/OfflineBanner.swift b/iosApp/iosApp/Shared/OfflineBanner.swift
new file mode 100644
index 0000000..f29ab7d
--- /dev/null
+++ b/iosApp/iosApp/Shared/OfflineBanner.swift
@@ -0,0 +1,27 @@
+//
+// OfflineBanner.swift
+// iosApp
+//
+// Created by Ivan Avalos on 17/09/23.
+// Copyright © 2023 orgName. All rights reserved.
+//
+
+import SwiftUI
+
+struct OfflineBanner: View {
+ var body: some View {
+ Group {
+ Text("offline")
+ .foregroundColor(.white)
+ .padding(5)
+ }
+ .frame(minWidth: 0, maxWidth: .infinity)
+ .background(Color.red)
+ }
+}
+
+struct OfflineBanner_Previews: PreviewProvider {
+ static var previews: some View {
+ OfflineBanner()
+ }
+}
diff --git a/iosApp/iosApp/Units/UnitsViewModel.swift b/iosApp/iosApp/Units/UnitsViewModel.swift
index 7fcc80e..b12291e 100644
--- a/iosApp/iosApp/Units/UnitsViewModel.swift
+++ b/iosApp/iosApp/Units/UnitsViewModel.swift
@@ -21,6 +21,7 @@ import shared
@MainActor
class UnitsViewModel: ObservableObject {
+ @Inject var networkController: NetworkController
@Inject var unitsController: UnitsController
@Inject var geofenceController: GeofencesController
@@ -34,6 +35,7 @@ class UnitsViewModel: ObservableObject {
var detailsUnit: UnitInformation? = nil
var detailsAction = DeviceRow.Action.details
+ @Published var networkAvailable: Bool? = nil
@Published var searchQuery = "" {
didSet {
unitsDisplayMode = .list
@@ -83,6 +85,9 @@ class UnitsViewModel: ObservableObject {
}
private func setupObservers() {
+ let networkCollector = Collector<Bool?>(callback: setNetworkState)
+ networkController.networkAvailable.collect(collector: networkCollector) { _ in }
+
let unitsCollector = Collector<[UnitInformation]>(callback: setUnits)
unitsController.displayedUnitsFlow.collect(collector: unitsCollector) { _ in }
@@ -90,6 +95,13 @@ class UnitsViewModel: ObservableObject {
geofenceController.geofencesFlow.collect(collector: geofencesCollector) { _ in }
}
+ private func setNetworkState(state: Bool?) {
+ print("Network state is: \(state?.description ?? "")")
+ Task { @MainActor in
+ self.networkAvailable = state
+ }
+ }
+
private func setUnits(units: [UnitInformation]) {
print("Positions")
Task { @MainActor in
diff --git a/iosApp/iosApp/en.lproj/Localizable.strings b/iosApp/iosApp/en.lproj/Localizable.strings
index ca1c3b8..0c5ff4a 100644
--- a/iosApp/iosApp/en.lproj/Localizable.strings
+++ b/iosApp/iosApp/en.lproj/Localizable.strings
@@ -22,6 +22,7 @@
"loading" = "Loading";
"done" = "Done";
+"offline" = "No internet access";
"username" = "Username";
"password" = "Password";
diff --git a/iosApp/iosApp/es-419.lproj/Localizable.strings b/iosApp/iosApp/es-419.lproj/Localizable.strings
index 146da98..995473e 100644
--- a/iosApp/iosApp/es-419.lproj/Localizable.strings
+++ b/iosApp/iosApp/es-419.lproj/Localizable.strings
@@ -22,6 +22,7 @@
"loading" = "Cargando";
"done" = "Hecho";
+"offline" = "No hay acceso a internet";
"username" = "Usuario";
"password" = "Contraseña";
diff --git a/iosApp/iosApp/iOSApp.swift b/iosApp/iosApp/iOSApp.swift
index 763e0e2..46848ae 100644
--- a/iosApp/iosApp/iOSApp.swift
+++ b/iosApp/iosApp/iOSApp.swift
@@ -53,8 +53,15 @@ struct iOSApp: App {
Resolver.shared.add(CommandsApi.self) { resolver in
return CommandsApi(sessionManager: resolver.resolve())
}
+ Resolver.shared.add(NetworkController.self) { resolver in
+ return NetworkController()
+ }
Resolver.shared.add(SessionController.self) { resolver in
- return SessionController(sessionApi: resolver.resolve(), usersApi: resolver.resolve())
+ return SessionController(
+ sessionManager: resolver.resolve(),
+ sessionApi: resolver.resolve(),
+ usersApi: resolver.resolve()
+ )
}
Resolver.shared.add(UnitsController.self) { resolver in
return UnitsController(devicesApi: resolver.resolve(), positionsApi: resolver.resolve())