aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2022-02-07 01:43:27 -0600
committerIván Ávalos <avalos@disroot.org>2022-02-07 01:43:27 -0600
commit4f0129a70bafeca1d9e565ba2076213eb183c779 (patch)
tree08f9acf0c7c4233c260feeffb0b0d454d3ab0e9b
parent8d040f0f02b9462d82fd03041529fdea423f02d3 (diff)
downloadetbsa-trackermap-mobile-4f0129a70bafeca1d9e565ba2076213eb183c779.tar.gz
etbsa-trackermap-mobile-4f0129a70bafeca1d9e565ba2076213eb183c779.tar.bz2
etbsa-trackermap-mobile-4f0129a70bafeca1d9e565ba2076213eb183c779.zip
Finished details view and implemented commands view
-rw-r--r--iosApp/iosApp.xcodeproj/project.pbxproj4
-rw-r--r--iosApp/iosApp/Details/Commands/UnitCommandsView.swift25
-rw-r--r--iosApp/iosApp/Details/Commands/UnitCommandsViewModel.swift46
-rw-r--r--iosApp/iosApp/Details/Information/UnitInformationView.swift146
-rw-r--r--iosApp/iosApp/Localizable.strings4
-rw-r--r--iosApp/iosApp/Shared/Utils.swift7
-rw-r--r--iosApp/iosApp/iOSApp.swift6
7 files changed, 171 insertions, 67 deletions
diff --git a/iosApp/iosApp.xcodeproj/project.pbxproj b/iosApp/iosApp.xcodeproj/project.pbxproj
index 7faf845..7dea34f 100644
--- a/iosApp/iosApp.xcodeproj/project.pbxproj
+++ b/iosApp/iosApp.xcodeproj/project.pbxproj
@@ -11,6 +11,7 @@
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 */; };
+ E3385A4F27B0D8A10025311C /* UnitCommandsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3385A4E27B0D8A10025311C /* UnitCommandsViewModel.swift */; };
E33A236027A4FD2C00DD647F /* UnitMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33A235F27A4FD2C00DD647F /* UnitMapView.swift */; };
E33A236527A530F300DD647F /* SmallLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33A236427A530F300DD647F /* SmallLabelStyle.swift */; };
E33A236727A64E4500DD647F /* MarkerTransformations.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33A236627A64E4500DD647F /* MarkerTransformations.swift */; };
@@ -60,6 +61,7 @@
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>"; };
+ E3385A4E27B0D8A10025311C /* UnitCommandsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitCommandsViewModel.swift; sourceTree = "<group>"; };
E33A235F27A4FD2C00DD647F /* UnitMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitMapView.swift; sourceTree = "<group>"; };
E33A236427A530F300DD647F /* SmallLabelStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmallLabelStyle.swift; sourceTree = "<group>"; };
E33A236627A64E4500DD647F /* MarkerTransformations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkerTransformations.swift; sourceTree = "<group>"; };
@@ -177,6 +179,7 @@
isa = PBXGroup;
children = (
E396282727AFBD72005D070E /* UnitCommandsView.swift */,
+ E3385A4E27B0D8A10025311C /* UnitCommandsViewModel.swift */,
);
path = Commands;
sourceTree = "<group>";
@@ -353,6 +356,7 @@
E396282227AF66A3005D070E /* DetailsViewModel.swift in Sources */,
E396282827AFBD72005D070E /* UnitCommandsView.swift in Sources */,
E38F241C27A26DD70069FC45 /* RootViewModel.swift in Sources */,
+ E3385A4F27B0D8A10025311C /* UnitCommandsViewModel.swift in Sources */,
E36DF77B27AB740C003C561C /* MapViewController.swift in Sources */,
E33A237327A7581A00DD647F /* Utils.swift in Sources */,
E3E77EE6279E6CE400150070 /* FlowCollector.swift in Sources */,
diff --git a/iosApp/iosApp/Details/Commands/UnitCommandsView.swift b/iosApp/iosApp/Details/Commands/UnitCommandsView.swift
index fade29b..9e4b280 100644
--- a/iosApp/iosApp/Details/Commands/UnitCommandsView.swift
+++ b/iosApp/iosApp/Details/Commands/UnitCommandsView.swift
@@ -19,10 +19,31 @@ import SwiftUI
import shared
struct UnitCommandsView: View {
+ @ObservedObject var unitCommandsViewModel = UnitCommandsViewModel()
+
var unit: UnitInformation
+ init(unit: UnitInformation) {
+ self.unit = unit
+ unitCommandsViewModel.fetchCommands(id: unit.device.id)
+ }
+
var body: some View {
-
- Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
+ VStack {
+ List {
+ Picker("commands", selection: $unitCommandsViewModel.selectedId) {
+ ForEach(unitCommandsViewModel.commands, id: \.id) { command in
+ Text(command.description_ ?? "\(command.id!)")
+ .tag(Int(truncating: command.id!))
+ }
+ }.pickerStyle(InlinePickerStyle())
+
+ Button {
+ unitCommandsViewModel.sendCommand()
+ } label: {
+ Label("send-command", systemImage: "paperplane")
+ }
+ }
+ }
}
}
diff --git a/iosApp/iosApp/Details/Commands/UnitCommandsViewModel.swift b/iosApp/iosApp/Details/Commands/UnitCommandsViewModel.swift
new file mode 100644
index 0000000..aac82c9
--- /dev/null
+++ b/iosApp/iosApp/Details/Commands/UnitCommandsViewModel.swift
@@ -0,0 +1,46 @@
+/**
+ * TrackerMap
+ * Copyright (C) 2021-2022 Iván Ávalos <avalos@disroot.org>, Henoch Ojeda <imhenoch@protonmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+import Foundation
+import shared
+
+class UnitCommandsViewModel: ObservableObject {
+ @Inject var commandsController: CommandsController
+
+ @Published var commands = [Command]()
+ @Published var selected: Command?
+ @Published var selectedId: Int = 0 {
+ didSet {
+ selected = commands.first(where: {
+ Int(truncating: $0.id!) == selectedId
+ })
+ }
+ }
+
+ func fetchCommands(id: Int32) {
+ commandsController.fetchCommands(deviceId: id) { commands, error in
+ print("We've got the commands! \(commands ?? [])")
+ self.commands = commands ?? []
+ }
+ }
+
+ func sendCommand() {
+ if let command = selected {
+ commandsController.sendCommand(command: command) { _, error in }
+ }
+ }
+}
diff --git a/iosApp/iosApp/Details/Information/UnitInformationView.swift b/iosApp/iosApp/Details/Information/UnitInformationView.swift
index 3a52b84..f713ab4 100644
--- a/iosApp/iosApp/Details/Information/UnitInformationView.swift
+++ b/iosApp/iosApp/Details/Information/UnitInformationView.swift
@@ -23,80 +23,96 @@ struct UnitInformationView: View {
var body: some View {
List {
- // MARK: - Contact
- if let contact = unit.device.contact {
- HStack {
- Text("contact")
- Spacer()
- Text(contact).foregroundColor(.secondaryLabel)
+ Section {
+ // MARK: - Contact
+ if let contact = unit.device.contact {
+ HStack {
+ Text("contact")
+ Spacer()
+ Text(contact).foregroundColor(.secondaryLabel)
+ }
}
- }
- // MARK: - Unique ID
- if let uniqueId = unit.device.uniqueId {
- HStack {
- Text("unique-id")
- Spacer()
- Text(uniqueId).foregroundColor(.secondaryLabel)
+ // MARK: - Unique ID
+ if let uniqueId = unit.device.uniqueId {
+ HStack {
+ Text("unique-id")
+ Spacer()
+ Text(uniqueId).foregroundColor(.secondaryLabel)
+ }
}
- }
- // MARK: - Date time
- if let datetime = unit.position?.fixTime {
- HStack {
- Text("datetime")
- Spacer()
- Text(Formatter.companion.formatDate(str: datetime))
- .foregroundColor(.secondaryLabel)
+ // MARK: - Date time
+ if let datetime = unit.position?.fixTime {
+ HStack {
+ Text("datetime")
+ Spacer()
+ Text(Formatter.companion.formatDate(str: datetime))
+ .foregroundColor(.secondaryLabel)
+ }
}
- }
- // MARK: - Latitude
- if let latitude = unit.position?.latitude {
- HStack {
- Text("latitude")
- Spacer()
- Text("\(latitude)").foregroundColor(.secondaryLabel)
+ // MARK: - Latitude
+ if let latitude = unit.position?.latitude {
+ HStack {
+ Text("latitude")
+ Spacer()
+ Text("\(latitude)").foregroundColor(.secondaryLabel)
+ }
}
- }
- // MARK: - Longitude
- if let longitude = unit.position?.longitude {
- HStack {
- Text("longitude")
- Spacer()
- Text("\(longitude)").foregroundColor(.secondaryLabel)
+ // MARK: - Longitude
+ if let longitude = unit.position?.longitude {
+ HStack {
+ Text("longitude")
+ Spacer()
+ Text("\(longitude)").foregroundColor(.secondaryLabel)
+ }
}
- }
- // MARK: - Speed
- if let speed = unit.position?.speed {
- HStack {
- Text("speed")
- Spacer()
- Text(Formatter.companion.formatSpeed(
- speed: Double(truncating: speed), unit: .kmh))
- .foregroundColor(.secondaryLabel)
+ // MARK: - Speed
+ if let speed = unit.position?.speed {
+ HStack {
+ Text("speed")
+ Spacer()
+ Text(Formatter.companion.formatSpeed(
+ speed: Double(truncating: speed), unit: .kmh))
+ .foregroundColor(.secondaryLabel)
+ }
}
- }
- // MARK: - Address
- if let address = unit.position?.address {
- HStack {
- Text("address")
- Spacer()
- Text(address).foregroundColor(.secondaryLabel)
+ // MARK: - Address
+ if let address = unit.position?.address {
+ HStack {
+ Text("address")
+ Spacer()
+ Text(address).foregroundColor(.secondaryLabel)
+ }
}
- }
- // MARK: - Hours
- if let hours = unit.getHourmeter() {
- HStack {
- Text("hourmeter")
- Spacer()
- Text(Formatter.companion.formatHours(millis: Int64(truncating: hours)))
- .foregroundColor(.secondaryLabel)
+ // MARK: - Hours
+ if let hours = unit.getHourmeter() {
+ HStack {
+ Text("hourmeter")
+ Spacer()
+ Text(Formatter.companion.formatHours(millis: Int64(truncating: hours)))
+ .foregroundColor(.secondaryLabel)
+ }
+ }
+ // MARK: - Protocol
+ if let protocol_ = unit.position?.protocol {
+ HStack {
+ Text("protocol")
+ Spacer()
+ Text(protocol_).foregroundColor(.secondaryLabel)
+ }
}
}
- // MARK: - Protocol
- if let protocol_ = unit.position?.protocol {
- HStack {
- Text("protocol")
- Spacer()
- Text(protocol_).foregroundColor(.secondaryLabel)
+ Section {
+ Button {
+ if let longitude = unit.position?.longitude,
+ let latitude = unit.position?.latitude,
+ let url = Utils.getMapsURL(longitude: Float(truncating: longitude),
+ latitude: Float(truncating: latitude)) {
+ if UIApplication.shared.canOpenURL(url) {
+ UIApplication.shared.open(url, options: [:])
+ }
+ }
+ } label: {
+ Label("open-location-browser", systemImage: "globe")
}
}
}
diff --git a/iosApp/iosApp/Localizable.strings b/iosApp/iosApp/Localizable.strings
index 9013574..4d1e1f2 100644
--- a/iosApp/iosApp/Localizable.strings
+++ b/iosApp/iosApp/Localizable.strings
@@ -48,3 +48,7 @@
"address" = "Address";
"hourmeter" = "Hourmeter";
"protocol" = "Protocol";
+"open-location-browser" = "Open location in browser";
+"maps-url-template" = "https://www.google.com/maps/place/{y},{x}?z=19";
+
+"send-command" = "Send command";
diff --git a/iosApp/iosApp/Shared/Utils.swift b/iosApp/iosApp/Shared/Utils.swift
index 9b473a5..61a8f90 100644
--- a/iosApp/iosApp/Shared/Utils.swift
+++ b/iosApp/iosApp/Shared/Utils.swift
@@ -38,4 +38,11 @@ class Utils {
tileInfo.cacheDir = thisCacheDir
return tileInfo
}
+
+ static func getMapsURL(longitude: Float, latitude: Float) -> URL? {
+ let template = NSLocalizedString("maps-url-template", comment: "")
+ return URL(string: template
+ .replacingOccurrences(of: "{x}", with: "\(latitude)")
+ .replacingOccurrences(of: "{y}", with: "\(longitude)"))
+ }
}
diff --git a/iosApp/iosApp/iOSApp.swift b/iosApp/iosApp/iOSApp.swift
index 6bf6710..338c06b 100644
--- a/iosApp/iosApp/iOSApp.swift
+++ b/iosApp/iosApp/iOSApp.swift
@@ -49,6 +49,9 @@ struct iOSApp: App {
Resolver.shared.add(GeofencesApi.self) { resolver in
return GeofencesApi(sessionManager: resolver.resolve())
}
+ Resolver.shared.add(CommandsApi.self) { resolver in
+ return CommandsApi(sessionManager: resolver.resolve())
+ }
Resolver.shared.add(SessionController.self) { resolver in
return SessionController(sessionApi: resolver.resolve(), usersApi: resolver.resolve())
}
@@ -61,6 +64,9 @@ struct iOSApp: App {
Resolver.shared.add(ReportController.self) { resolver in
return ReportController(reportsApi: resolver.resolve(), geofencesApi: resolver.resolve())
}
+ Resolver.shared.add(CommandsController.self) { resolver in
+ return CommandsController(commandsApi: resolver.resolve())
+ }
}
var body: some Scene {