diff options
author | Iván Ávalos <avalos@disroot.org> | 2022-01-29 04:13:25 -0600 |
---|---|---|
committer | Iván Ávalos <avalos@disroot.org> | 2022-01-29 04:13:25 -0600 |
commit | e1d8854d7d5e789ed84e8948f17fb0dac0d44da6 (patch) | |
tree | ab84d7edaead85e03950102e091da51952635159 /iosApp | |
parent | 64c4a58e644229b9d94233b3dd18b7805ffbb8d7 (diff) | |
download | etbsa-trackermap-mobile-e1d8854d7d5e789ed84e8948f17fb0dac0d44da6.tar.gz etbsa-trackermap-mobile-e1d8854d7d5e789ed84e8948f17fb0dac0d44da6.tar.bz2 etbsa-trackermap-mobile-e1d8854d7d5e789ed84e8948f17fb0dac0d44da6.zip |
Initial implementation of device list, and added getStatus() and getEngineStop() methods to UnitInformation
Diffstat (limited to 'iosApp')
-rw-r--r-- | iosApp/Localizable.strings | 4 | ||||
-rw-r--r-- | iosApp/iosApp.xcodeproj/project.pbxproj | 85 | ||||
-rw-r--r-- | iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 8 | ||||
-rw-r--r-- | iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/avalos.xcuserdatad/UserInterfaceState.xcuserstate | bin | 43210 -> 47814 bytes | |||
-rw-r--r-- | iosApp/iosApp/Devices/DeviceRow.swift | 106 | ||||
-rw-r--r-- | iosApp/iosApp/Devices/DevicesView.swift | 32 | ||||
-rw-r--r-- | iosApp/iosApp/Map/MapView.swift | 37 | ||||
-rw-r--r-- | iosApp/iosApp/Shared/SmallLabelStyle.swift | 23 | ||||
-rw-r--r-- | iosApp/iosApp/Units/UnitsView.swift | 30 | ||||
-rw-r--r-- | iosApp/iosApp/Units/UnitsViewModel.swift | 65 |
10 files changed, 365 insertions, 25 deletions
diff --git a/iosApp/Localizable.strings b/iosApp/Localizable.strings index c863844..aee6a31 100644 --- a/iosApp/Localizable.strings +++ b/iosApp/Localizable.strings @@ -12,3 +12,7 @@ "password" = "Password"; "server-url" = "Server URL"; "login" = "Login"; + +"devices" = "Devices"; +"map" = "Map"; +"search" = "Search"; diff --git a/iosApp/iosApp.xcodeproj/project.pbxproj b/iosApp/iosApp.xcodeproj/project.pbxproj index d2f7787..6eeaa69 100644 --- a/iosApp/iosApp.xcodeproj/project.pbxproj +++ b/iosApp/iosApp.xcodeproj/project.pbxproj @@ -11,28 +11,21 @@ 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; }; 7555FF83242A565900829871 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* RootView.swift */; }; + E33A236027A4FD2C00DD647F /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33A235F27A4FD2C00DD647F /* MapView.swift */; }; + E33A236327A5014600DD647F /* SwiftUIX in Frameworks */ = {isa = PBXBuildFile; productRef = E33A236227A5014600DD647F /* SwiftUIX */; }; + E33A236527A530F300DD647F /* SmallLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33A236427A530F300DD647F /* SmallLabelStyle.swift */; }; E38F241527A242870069FC45 /* Inject.swift in Sources */ = {isa = PBXBuildFile; fileRef = E38F241427A242870069FC45 /* Inject.swift */; }; E38F241727A242C70069FC45 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = E38F241627A242C70069FC45 /* Resolver.swift */; }; E38F241C27A26DD70069FC45 /* RootViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E38F241B27A26DD70069FC45 /* RootViewModel.swift */; }; E38F241E27A270D50069FC45 /* UnitsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E38F241D27A270D50069FC45 /* UnitsView.swift */; }; E38F242027A27B550069FC45 /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E38F241F27A27B550069FC45 /* LoadingView.swift */; }; + E39ABC4327A4E88C00965D05 /* UnitsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E39ABC4227A4E88C00965D05 /* UnitsViewModel.swift */; }; + E39ABC4627A4EBD500965D05 /* DevicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E39ABC4527A4EBD500965D05 /* DevicesView.swift */; }; + E39ABC4827A4EDEC00965D05 /* DeviceRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = E39ABC4727A4EDEC00965D05 /* DeviceRow.swift */; }; E3E77EDF279D2B5A00150070 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E3E77EDE279D2B5A00150070 /* Localizable.strings */; }; E3E77EE6279E6CE400150070 /* FlowCollector.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3E77EE5279E6CE400150070 /* FlowCollector.swift */; }; /* End PBXBuildFile section */ -/* Begin PBXCopyFilesBuildPhase section */ - 7555FFB4242A642300829871 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; }; @@ -40,11 +33,17 @@ 7555FF7B242A565900829871 /* iosApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iosApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 7555FF82242A565900829871 /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = "<group>"; }; 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E33A235F27A4FD2C00DD647F /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = "<group>"; }; + E33A236427A530F300DD647F /* SmallLabelStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmallLabelStyle.swift; sourceTree = "<group>"; }; + E37361C827A39A4200306B21 /* WhirlyGlobeMaplyComponent.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WhirlyGlobeMaplyComponent.framework; sourceTree = "<group>"; }; E38F241427A242870069FC45 /* Inject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Inject.swift; sourceTree = "<group>"; }; E38F241627A242C70069FC45 /* Resolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Resolver.swift; sourceTree = "<group>"; }; E38F241B27A26DD70069FC45 /* RootViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootViewModel.swift; sourceTree = "<group>"; }; E38F241D27A270D50069FC45 /* UnitsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitsView.swift; sourceTree = "<group>"; }; E38F241F27A27B550069FC45 /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingView.swift; sourceTree = "<group>"; }; + E39ABC4227A4E88C00965D05 /* UnitsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitsViewModel.swift; sourceTree = "<group>"; }; + E39ABC4527A4EBD500965D05 /* DevicesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DevicesView.swift; sourceTree = "<group>"; }; + E39ABC4727A4EDEC00965D05 /* DeviceRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceRow.swift; sourceTree = "<group>"; }; E3E77EDE279D2B5A00150070 /* Localizable.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = "<group>"; }; E3E77EE5279E6CE400150070 /* FlowCollector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowCollector.swift; sourceTree = "<group>"; }; /* End PBXFileReference section */ @@ -54,6 +53,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + E33A236327A5014600DD647F /* SwiftUIX in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -89,6 +89,8 @@ 7555FF7D242A565900829871 /* iosApp */ = { isa = PBXGroup; children = ( + E33A235E27A4FD1C00DD647F /* Map */, + E39ABC4427A4EBB000965D05 /* Devices */, E38F241A27A2659C0069FC45 /* Units */, E3E77EE1279D43C000150070 /* Shared */, 058557BA273AAA24004C7B11 /* Assets.xcassets */, @@ -103,18 +105,37 @@ 7555FFB0242A642200829871 /* Frameworks */ = { isa = PBXGroup; children = ( + E37361C827A39A4200306B21 /* WhirlyGlobeMaplyComponent.framework */, ); name = Frameworks; sourceTree = "<group>"; }; + E33A235E27A4FD1C00DD647F /* Map */ = { + isa = PBXGroup; + children = ( + E33A235F27A4FD2C00DD647F /* MapView.swift */, + ); + path = Map; + sourceTree = "<group>"; + }; E38F241A27A2659C0069FC45 /* Units */ = { isa = PBXGroup; children = ( E38F241D27A270D50069FC45 /* UnitsView.swift */, + E39ABC4227A4E88C00965D05 /* UnitsViewModel.swift */, ); path = Units; sourceTree = "<group>"; }; + E39ABC4427A4EBB000965D05 /* Devices */ = { + isa = PBXGroup; + children = ( + E39ABC4527A4EBD500965D05 /* DevicesView.swift */, + E39ABC4727A4EDEC00965D05 /* DeviceRow.swift */, + ); + path = Devices; + sourceTree = "<group>"; + }; E3E77EE0279D43B400150070 /* Session */ = { isa = PBXGroup; children = ( @@ -131,6 +152,7 @@ E38F241427A242870069FC45 /* Inject.swift */, E38F241627A242C70069FC45 /* Resolver.swift */, E38F241F27A27B550069FC45 /* LoadingView.swift */, + E33A236427A530F300DD647F /* SmallLabelStyle.swift */, ); path = Shared; sourceTree = "<group>"; @@ -146,13 +168,15 @@ 7555FF77242A565900829871 /* Sources */, 7555FF78242A565900829871 /* Frameworks */, 7555FF79242A565900829871 /* Resources */, - 7555FFB4242A642300829871 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( ); name = iosApp; + packageProductDependencies = ( + E33A236227A5014600DD647F /* SwiftUIX */, + ); productName = iosApp; productReference = 7555FF7B242A565900829871 /* iosApp.app */; productType = "com.apple.product-type.application"; @@ -183,7 +207,7 @@ ); mainGroup = 7555FF72242A565900829871; packageReferences = ( - E3E77EE4279E06C300150070 /* XCRemoteSwiftPackageReference "Swinject" */, + E33A236127A5014600DD647F /* XCRemoteSwiftPackageReference "SwiftUIX" */, ); productRefGroup = 7555FF7C242A565900829871 /* Products */; projectDirPath = ""; @@ -233,10 +257,15 @@ buildActionMask = 2147483647; files = ( E38F241727A242C70069FC45 /* Resolver.swift in Sources */, + E33A236027A4FD2C00DD647F /* MapView.swift in Sources */, E38F241527A242870069FC45 /* Inject.swift in Sources */, + E39ABC4827A4EDEC00965D05 /* DeviceRow.swift in Sources */, E38F241C27A26DD70069FC45 /* RootViewModel.swift in Sources */, E3E77EE6279E6CE400150070 /* FlowCollector.swift in Sources */, + E33A236527A530F300DD647F /* SmallLabelStyle.swift in Sources */, + E39ABC4327A4E88C00965D05 /* UnitsViewModel.swift in Sources */, 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */, + E39ABC4627A4EBD500965D05 /* DevicesView.swift in Sources */, E38F242027A27B550069FC45 /* LoadingView.swift in Sources */, E38F241E27A270D50069FC45 /* UnitsView.swift in Sources */, 7555FF83242A565900829871 /* RootView.swift in Sources */, @@ -370,7 +399,11 @@ DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; DEVELOPMENT_TEAM = 358YRZ9P3L; ENABLE_PREVIEWS = YES; - FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)"; + EXCLUDED_ARCHS = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)", + "$(PROJECT_DIR)", + ); INFOPLIST_FILE = iosApp/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -396,7 +429,11 @@ DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; DEVELOPMENT_TEAM = 358YRZ9P3L; ENABLE_PREVIEWS = YES; - FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)"; + EXCLUDED_ARCHS = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)", + "$(PROJECT_DIR)", + ); INFOPLIST_FILE = iosApp/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -438,15 +475,23 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - E3E77EE4279E06C300150070 /* XCRemoteSwiftPackageReference "Swinject" */ = { + E33A236127A5014600DD647F /* XCRemoteSwiftPackageReference "SwiftUIX" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/Swinject/Swinject.git"; + repositoryURL = "https://github.com/SwiftUIX/SwiftUIX"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 2.0.0; + minimumVersion = 0.1.1; }; }; /* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + E33A236227A5014600DD647F /* SwiftUIX */ = { + isa = XCSwiftPackageProductDependency; + package = E33A236127A5014600DD647F /* XCRemoteSwiftPackageReference "SwiftUIX" */; + productName = SwiftUIX; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 7555FF73242A565900829871 /* Project object */; } diff --git a/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index fc75d3e..c8ce63d 100644 --- a/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -2,12 +2,12 @@ "object": { "pins": [ { - "package": "Swinject", - "repositoryURL": "https://github.com/Swinject/Swinject.git", + "package": "SwiftUIX", + "repositoryURL": "https://github.com/SwiftUIX/SwiftUIX", "state": { "branch": null, - "revision": "f10b6e9ebff440f985c43008f7c2d097639fcb81", - "version": "2.8.1" + "revision": "eb6a23fc4cc79545e40a8cf5c82119684750194f", + "version": "0.1.1" } } ] diff --git a/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/avalos.xcuserdatad/UserInterfaceState.xcuserstate b/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/avalos.xcuserdatad/UserInterfaceState.xcuserstate Binary files differindex 257d7c0..821a1e3 100644 --- a/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/avalos.xcuserdatad/UserInterfaceState.xcuserstate +++ b/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/avalos.xcuserdatad/UserInterfaceState.xcuserstate diff --git a/iosApp/iosApp/Devices/DeviceRow.swift b/iosApp/iosApp/Devices/DeviceRow.swift new file mode 100644 index 0000000..5fc4e11 --- /dev/null +++ b/iosApp/iosApp/Devices/DeviceRow.swift @@ -0,0 +1,106 @@ +// +// DeviceRow.swift +// iosApp +// +// Created by Iván on 28/01/22. +// Copyright © 2022 orgName. All rights reserved. +// + +import SwiftUI +import shared + +struct DeviceRow: View { + var unit: UnitInformation + + var body: some View { + VStack { + HStack { + /* Status icon */ + switch (unit.getStatus()) { + case .online: + Image(systemName: "circle.fill") + .foregroundColor(.systemGreen) + .imageScale(.small) + case .offline: + Image(systemName: "circle.fill") + .foregroundColor(.systemRed) + .imageScale(.small) + default: + EmptyView() + } + + /* Engine stop */ + switch (unit.getEngineStop()) { + case .on: + Image(systemName: "lock.fill") + .foregroundColor(.systemRed) + .imageScale(.small) + case .off: + Image(systemName: "lock.open.fill") + .foregroundColor(.systemGreen) + .imageScale(.small) + default: + EmptyView() + } + + /* Device name */ + Text(unit.device.name) + Spacer() + } + .padding(.bottom, 5.0) + + /* Driver */ + if let contact = unit.device.contact { + HStack { + Label(contact, systemImage: "person") + .labelStyle(SmallLabelStyle()) + Spacer() + } + } + + /* Speed */ + if let speed = unit.position?.speed { + HStack { + Label(Formatter.companion.formatSpeed( + speed: Double(truncating: speed), + unit: .kmh), + systemImage: "speedometer") + .labelStyle(SmallLabelStyle()) + Spacer() + } + } + + /* Address */ + if let address = unit.position?.address { + HStack { + Label(address, systemImage: "mappin.and.ellipse") + .labelStyle(SmallLabelStyle()) + Spacer() + } + } + + /* Hourmeter */ + if let hourmeter = unit.position?.attributes["hours"] { + if let hourmeter = Serialization.companion.longOrNull(json: hourmeter) { + HStack { + Label(Formatter.companion.formatHours( + millis: Int64(truncating: hourmeter)), + systemImage: "timer") + .labelStyle(SmallLabelStyle()) + Spacer() + } + } + } + + /* Date time */ + if let datetime = unit.position?.fixTime { + HStack { + Label(Formatter.companion.formatDate(str: datetime), + systemImage: "calendar") + .labelStyle(SmallLabelStyle()) + Spacer() + } + } + } + } +} diff --git a/iosApp/iosApp/Devices/DevicesView.swift b/iosApp/iosApp/Devices/DevicesView.swift new file mode 100644 index 0000000..7271a70 --- /dev/null +++ b/iosApp/iosApp/Devices/DevicesView.swift @@ -0,0 +1,32 @@ +// +// DevicesView.swift +// iosApp +// +// Created by Iván on 28/01/22. +// Copyright © 2022 orgName. All rights reserved. +// + +import SwiftUI + +struct DevicesView: View { + @StateObject var unitsViewModel: UnitsViewModel + + var body: some View { + List(unitsViewModel.units, id: \.device.id) { unit in + DeviceRow(unit: unit) + } + .navigationTitle("devices") + .toolbar { + ToolbarItem(placement: .navigationBarLeading) { + Button(action: unitsViewModel.toggleDisplayMode) { + Image(systemName: "map") + } + } + ToolbarItem(placement: .navigationBarTrailing) { + Button(action: {}) { + Image(systemName: "person") + } + } + } + } +} diff --git a/iosApp/iosApp/Map/MapView.swift b/iosApp/iosApp/Map/MapView.swift new file mode 100644 index 0000000..3530946 --- /dev/null +++ b/iosApp/iosApp/Map/MapView.swift @@ -0,0 +1,37 @@ +// +// MapView.swift +// iosApp +// +// Created by Iván on 28/01/22. +// Copyright © 2022 orgName. All rights reserved. +// + +import SwiftUI + +struct MapView: View { + @StateObject var unitsViewModel: UnitsViewModel + + var body: some View { + ZStack { + Text("Unimplemented!") + } + .navigationTitle("map") + .toolbar { + ToolbarItem(placement: .navigationBarLeading) { + Button(action: unitsViewModel.toggleDisplayMode) { + Image(systemName: "list.bullet") + } + } + ToolbarItem(placement: .navigationBarTrailing) { + Button(action: {}) { + Image(systemName: "square.stack.3d.up") + } + } + ToolbarItem(placement: .navigationBarTrailing) { + Button(action: {}) { + Image(systemName: "person") + } + } + } + } +} diff --git a/iosApp/iosApp/Shared/SmallLabelStyle.swift b/iosApp/iosApp/Shared/SmallLabelStyle.swift new file mode 100644 index 0000000..27914ff --- /dev/null +++ b/iosApp/iosApp/Shared/SmallLabelStyle.swift @@ -0,0 +1,23 @@ +// +// SmallIconLabelStyle.swift +// iosApp +// +// Created by Iván on 29/01/22. +// Copyright © 2022 orgName. All rights reserved. +// + +import SwiftUI + +struct SmallLabelStyle: LabelStyle { + func makeBody(configuration: Configuration) -> some View { + HStack { + configuration.icon + .foregroundColor(.secondary) + .imageScale(.small) + + configuration.title + .font(.subheadline) + .foregroundColor(.secondary) + } + } +} diff --git a/iosApp/iosApp/Units/UnitsView.swift b/iosApp/iosApp/Units/UnitsView.swift index 1088a5f..fd673a6 100644 --- a/iosApp/iosApp/Units/UnitsView.swift +++ b/iosApp/iosApp/Units/UnitsView.swift @@ -7,9 +7,37 @@ // import SwiftUI +import SwiftUIX +import shared struct UnitsView: View { + @StateObject var unitsViewModel = UnitsViewModel() + var body: some View { - Text("Welcome to UnitsView!") + NavigationView { + ZStack { + switch unitsViewModel.unitsDisplayMode { + case .list: + DevicesView(unitsViewModel: unitsViewModel) + case .map: + MapView(unitsViewModel: unitsViewModel) + } + } + .navigationBarTitleDisplayMode(.inline) + .navigationSearchBar { + searchBar() + } + } + } + + private func searchBar () -> SearchBar { + SearchBar(NSLocalizedString("search", comment: ""), + text: $unitsViewModel.searchQuery, + isEditing: $unitsViewModel.isEditing, + onCommit: {}) + .showsCancelButton(unitsViewModel.isEditing) + .onCancel { + unitsViewModel.searchQuery = "" + } } } diff --git a/iosApp/iosApp/Units/UnitsViewModel.swift b/iosApp/iosApp/Units/UnitsViewModel.swift new file mode 100644 index 0000000..648e429 --- /dev/null +++ b/iosApp/iosApp/Units/UnitsViewModel.swift @@ -0,0 +1,65 @@ +// +// UnitsViewModel.swift +// iosApp +// +// Created by Iván on 28/01/22. +// Copyright © 2022 orgName. All rights reserved. +// + +import Foundation +import shared + +class UnitsViewModel: ObservableObject { + @Inject var unitsController: UnitsController + @Inject var geofenceController: GeofencesController + + enum UnitsDisplayMode { + case map + case list + } + + @Published var searchQuery = "" { + didSet { + unitsDisplayMode = .list + search(query: searchQuery) + } + } + @Published var isEditing = false + @Published var unitsDisplayMode: UnitsDisplayMode = .list + @Published var units: [UnitInformation] = [] + @Published var selectedUnit: UnitInformation? = nil + @Published var geofences: [Int: Geofence] = [:] + + init() { + setupObservers() + } + + private func setupObservers() { + let unitsCollector = Collector<[UnitInformation]>(callback: setUnits) + unitsController.displayedUnitsFlow.collect(collector: unitsCollector) { unit, error in } + + let geofencesCollector = Collector<[Int: Geofence]>(callback: setGeofences) + geofenceController.geofencesFlow.collect(collector: geofencesCollector) { unit, error in } + } + + private func setUnits(units: [UnitInformation]) { + self.units = units + } + + private func setGeofences(geofences: [Int: Geofence]) { + self.geofences = geofences + } + + func toggleDisplayMode() { + switch unitsDisplayMode { + case .map: + unitsDisplayMode = .list + case .list: + unitsDisplayMode = .map + } + } + + func search(query: String) { + unitsController.search(query: query) + } +} |