aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2022-02-16 00:22:05 -0600
committerIván Ávalos <avalos@disroot.org>2022-02-16 00:22:05 -0600
commitde9eb9dc2b932066e8ef1668d71170230edd1d38 (patch)
tree050066a09cd85d598655309ea6b2d61059c26da8
parentfe30451d02b541a51f35e8ea68100c9b04f046ba (diff)
downloadetbsa-trackermap-mobile-de9eb9dc2b932066e8ef1668d71170230edd1d38.tar.gz
etbsa-trackermap-mobile-de9eb9dc2b932066e8ef1668d71170230edd1d38.tar.bz2
etbsa-trackermap-mobile-de9eb9dc2b932066e8ef1668d71170230edd1d38.zip
- Localized strings.
- Implemented account details, about and sign out. - Map shows first on startup now. - Save server URL on preferences. - More improvements and fixes!
-rw-r--r--iosApp/iosApp.xcodeproj/project.pbxproj37
-rw-r--r--iosApp/iosApp/Details/DetailsView.swift2
-rw-r--r--iosApp/iosApp/Devices/DeviceRow.swift11
-rw-r--r--iosApp/iosApp/Map/MapView.swift5
-rw-r--r--iosApp/iosApp/Map/MapViewController.swift4
-rw-r--r--iosApp/iosApp/Map/MapViewController.xib10
-rw-r--r--iosApp/iosApp/Session/AboutView.swift34
-rw-r--r--iosApp/iosApp/Session/AccountView.swift73
-rw-r--r--iosApp/iosApp/Session/AccountViewModel.swift29
-rw-r--r--iosApp/iosApp/Session/RootView.swift48
-rw-r--r--iosApp/iosApp/Session/RootViewModel.swift23
-rw-r--r--iosApp/iosApp/Session/UserInformationView.swift50
-rw-r--r--iosApp/iosApp/Units/UnitsView.swift10
-rw-r--r--iosApp/iosApp/Units/UnitsViewModel.swift13
-rw-r--r--iosApp/iosApp/en.lproj/Localizable.strings (renamed from iosApp/iosApp/Localizable.strings)15
-rw-r--r--iosApp/iosApp/es-419.lproj/Localizable.strings68
16 files changed, 389 insertions, 43 deletions
diff --git a/iosApp/iosApp.xcodeproj/project.pbxproj b/iosApp/iosApp.xcodeproj/project.pbxproj
index b3e7b29..9bd7b9a 100644
--- a/iosApp/iosApp.xcodeproj/project.pbxproj
+++ b/iosApp/iosApp.xcodeproj/project.pbxproj
@@ -20,7 +20,11 @@
E33A237127A7553500DD647F /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33A237027A7553500DD647F /* MapView.swift */; };
E33A237327A7581A00DD647F /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33A237227A7581A00DD647F /* Utils.swift */; };
E34A2F4827A7878200AD8AEB /* HyperlinkText.swift in Sources */ = {isa = PBXBuildFile; fileRef = E34A2F4727A7878200AD8AEB /* HyperlinkText.swift */; };
- E34A2F4D27A7DB2200AD8AEB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E34A2F4C27A7DB2200AD8AEB /* Localizable.strings */; };
+ E360251527BCA3AD00958B21 /* UserInformationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E360251427BCA3AD00958B21 /* UserInformationView.swift */; };
+ E360251727BCA83300958B21 /* AccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E360251627BCA83300958B21 /* AccountView.swift */; };
+ E360251927BCA84000958B21 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E360251827BCA84000958B21 /* AboutView.swift */; };
+ E360251B27BCA8A600958B21 /* AccountViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E360251A27BCA8A600958B21 /* AccountViewModel.swift */; };
+ E360251C27BCC97000958B21 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E360251E27BCC97000958B21 /* Localizable.strings */; };
E36A5A8627B4BFC40070DED5 /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = E36A5A8527B4BFC40070DED5 /* FirebaseMessaging */; };
E36DF77B27AB740C003C561C /* MapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E36DF77927AB740C003C561C /* MapViewController.swift */; };
E36DF77C27AB740C003C561C /* MapViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E36DF77A27AB740C003C561C /* MapViewController.xib */; };
@@ -72,7 +76,12 @@
E33A237027A7553500DD647F /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = "<group>"; };
E33A237227A7581A00DD647F /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; };
E34A2F4727A7878200AD8AEB /* HyperlinkText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HyperlinkText.swift; sourceTree = "<group>"; };
- E34A2F4C27A7DB2200AD8AEB /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = "<group>"; };
+ E360251427BCA3AD00958B21 /* UserInformationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInformationView.swift; sourceTree = "<group>"; };
+ E360251627BCA83300958B21 /* AccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountView.swift; sourceTree = "<group>"; };
+ E360251827BCA84000958B21 /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; };
+ E360251A27BCA8A600958B21 /* AccountViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountViewModel.swift; sourceTree = "<group>"; };
+ E360251D27BCC97000958B21 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
+ E360251F27BCC97300958B21 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/Localizable.strings"; sourceTree = "<group>"; };
E36A5A8927B4C8BB0070DED5 /* iosApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = iosApp.entitlements; sourceTree = "<group>"; };
E36DF77927AB740C003C561C /* MapViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewController.swift; sourceTree = "<group>"; };
E36DF77A27AB740C003C561C /* MapViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MapViewController.xib; sourceTree = "<group>"; };
@@ -138,7 +147,7 @@
children = (
E392BE1827B791F0002698F3 /* GoogleService-Info.plist */,
E36A5A8927B4C8BB0070DED5 /* iosApp.entitlements */,
- E34A2F4C27A7DB2200AD8AEB /* Localizable.strings */,
+ E360251E27BCC97000958B21 /* Localizable.strings */,
E33A235E27A4FD1C00DD647F /* Map */,
E35A078427AB615F00F24D71 /* Details */,
E39ABC4427A4EBB000965D05 /* Devices */,
@@ -233,6 +242,10 @@
children = (
7555FF82242A565900829871 /* RootView.swift */,
E38F241B27A26DD70069FC45 /* RootViewModel.swift */,
+ E360251427BCA3AD00958B21 /* UserInformationView.swift */,
+ E360251627BCA83300958B21 /* AccountView.swift */,
+ E360251827BCA84000958B21 /* AboutView.swift */,
+ E360251A27BCA8A600958B21 /* AccountViewModel.swift */,
);
path = Session;
sourceTree = "<group>";
@@ -323,7 +336,7 @@
buildActionMask = 2147483647;
files = (
058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */,
- E34A2F4D27A7DB2200AD8AEB /* Localizable.strings in Resources */,
+ E360251C27BCC97000958B21 /* Localizable.strings in Resources */,
E392BE1927B791F0002698F3 /* GoogleService-Info.plist in Resources */,
058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */,
E36DF77C27AB740C003C561C /* MapViewController.xib in Resources */,
@@ -363,6 +376,9 @@
E38F241727A242C70069FC45 /* Resolver.swift in Sources */,
E33A236027A4FD2C00DD647F /* UnitMapView.swift in Sources */,
E396282427AFBD3D005D070E /* UnitInformationView.swift in Sources */,
+ E360251727BCA83300958B21 /* AccountView.swift in Sources */,
+ E360251527BCA3AD00958B21 /* UserInformationView.swift in Sources */,
+ E360251927BCA84000958B21 /* AboutView.swift in Sources */,
E312E74F27B366060018C5DE /* DevicesViewModel.swift in Sources */,
E33A236727A64E4500DD647F /* MarkerTransformations.swift in Sources */,
E38F241527A242870069FC45 /* Inject.swift in Sources */,
@@ -376,6 +392,7 @@
E3E77EE6279E6CE400150070 /* FlowCollector.swift in Sources */,
E33A236527A530F300DD647F /* SmallLabelStyle.swift in Sources */,
E39ABC4327A4E88C00965D05 /* UnitsViewModel.swift in Sources */,
+ E360251B27BCA8A600958B21 /* AccountViewModel.swift in Sources */,
E34A2F4827A7878200AD8AEB /* HyperlinkText.swift in Sources */,
2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */,
E39ABC4627A4EBD500965D05 /* DevicesView.swift in Sources */,
@@ -387,6 +404,18 @@
};
/* End PBXSourcesBuildPhase section */
+/* Begin PBXVariantGroup section */
+ E360251E27BCC97000958B21 /* Localizable.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ E360251D27BCC97000958B21 /* en */,
+ E360251F27BCC97300958B21 /* es-419 */,
+ );
+ name = Localizable.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
/* Begin XCBuildConfiguration section */
7555FFA3242A565B00829871 /* Debug */ = {
isa = XCBuildConfiguration;
diff --git a/iosApp/iosApp/Details/DetailsView.swift b/iosApp/iosApp/Details/DetailsView.swift
index abbed0a..1b86d2b 100644
--- a/iosApp/iosApp/Details/DetailsView.swift
+++ b/iosApp/iosApp/Details/DetailsView.swift
@@ -40,6 +40,8 @@ struct DetailsView: View {
UnitReportsView(unit: unit)
case .commands:
UnitCommandsView(unit: unit)
+ default:
+ EmptyView()
}
} else {
LoadingView()
diff --git a/iosApp/iosApp/Devices/DeviceRow.swift b/iosApp/iosApp/Devices/DeviceRow.swift
index 2c2cf3b..42ef0dc 100644
--- a/iosApp/iosApp/Devices/DeviceRow.swift
+++ b/iosApp/iosApp/Devices/DeviceRow.swift
@@ -25,6 +25,7 @@ struct DeviceRow: View {
case details
case reports
case commands
+ case close
}
var callback: (Action) -> ()
var isCell: Bool = true
@@ -98,6 +99,16 @@ struct DeviceRow: View {
/* MARK: - Device name */
Text(unit.device.name)
Spacer()
+
+ /* MARK: - Close button */
+ if !isCell {
+ Button {
+ callback(.close)
+ } label: {
+ Image(systemName: "xmark")
+ .foregroundColor(.secondary)
+ }
+ }
}
.padding(.bottom, 5.0)
diff --git a/iosApp/iosApp/Map/MapView.swift b/iosApp/iosApp/Map/MapView.swift
index f9757f4..e52c034 100644
--- a/iosApp/iosApp/Map/MapView.swift
+++ b/iosApp/iosApp/Map/MapView.swift
@@ -28,8 +28,6 @@ struct MapView: UIViewControllerRepresentable {
@Binding var selected: Marker?
var markerCallback: MarkerCallback?
- var shouldCenter = true
-
class Coordinator {
var shouldCenter: Bool = true
var oldMarkers: [Marker] = []
@@ -52,11 +50,12 @@ struct MapView: UIViewControllerRepresentable {
// MARK: - Set markers
if context.coordinator.oldMarkers != markers {
+ print("center = \(context.coordinator.shouldCenter)")
uiViewController.display(markers: markers,
isReport: false,
center: context.coordinator.shouldCenter)
+ context.coordinator.shouldCenter = false
}
- context.coordinator.shouldCenter = false
context.coordinator.oldMarkers = markers
// MARK: - Center selected marker
diff --git a/iosApp/iosApp/Map/MapViewController.swift b/iosApp/iosApp/Map/MapViewController.swift
index bc793e2..131a511 100644
--- a/iosApp/iosApp/Map/MapViewController.swift
+++ b/iosApp/iosApp/Map/MapViewController.swift
@@ -77,7 +77,7 @@ class MapViewController: UIViewController {
func display(markers: [Marker],
isReport: Bool,
center: Bool = false) {
- DispatchQueue.main.async {
+ mapView.runOnInit {
self.mapView.display(markers: markers,
isReport: isReport,
center: center)
@@ -85,7 +85,7 @@ class MapViewController: UIViewController {
}
func focusOn(marker: Marker) {
- DispatchQueue.main.async {
+ mapView.runOnInit {
self.mapView.focusOn(marker: marker)
}
}
diff --git a/iosApp/iosApp/Map/MapViewController.xib b/iosApp/iosApp/Map/MapViewController.xib
index 9d1694f..305a15b 100644
--- a/iosApp/iosApp/Map/MapViewController.xib
+++ b/iosApp/iosApp/Map/MapViewController.xib
@@ -35,6 +35,11 @@
<imageReference key="image" image="plus" catalog="system" symbolScale="large"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration"/>
</state>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
+ <integer key="value" value="10"/>
+ </userDefinedRuntimeAttribute>
+ </userDefinedRuntimeAttributes>
<connections>
<action selector="onZoomInPressed:" destination="-1" eventType="touchUpInside" id="x4P-sk-jdi"/>
</connections>
@@ -54,6 +59,11 @@
<imageReference key="image" image="minus" catalog="system" symbolScale="large"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration"/>
</state>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
+ <integer key="value" value="10"/>
+ </userDefinedRuntimeAttribute>
+ </userDefinedRuntimeAttributes>
<connections>
<action selector="onZoomOutPressed:" destination="-1" eventType="touchUpInside" id="rt2-fy-VCy"/>
</connections>
diff --git a/iosApp/iosApp/Session/AboutView.swift b/iosApp/iosApp/Session/AboutView.swift
new file mode 100644
index 0000000..c0f9099
--- /dev/null
+++ b/iosApp/iosApp/Session/AboutView.swift
@@ -0,0 +1,34 @@
+//
+// AboutView.swift
+// iosApp
+//
+// Created by Iván on 15/02/22.
+// Copyright © 2022 orgName. All rights reserved.
+//
+
+import SwiftUI
+
+struct AboutView: View {
+ var body: some View {
+ List {
+ Text("about-text").padding()
+ HStack {
+ Text("version")
+ Spacer()
+ Text("1.0").foregroundColor(.secondary)
+ }
+
+ Button {
+ // TODO
+ } label: {
+ Label("source-code", systemImage: "chevron.left.forwardslash.chevron.right")
+ }
+
+ Button {
+ // TODO
+ } label: {
+ Label("website", systemImage: "globe")
+ }
+ }
+ }
+}
diff --git a/iosApp/iosApp/Session/AccountView.swift b/iosApp/iosApp/Session/AccountView.swift
new file mode 100644
index 0000000..4ca453a
--- /dev/null
+++ b/iosApp/iosApp/Session/AccountView.swift
@@ -0,0 +1,73 @@
+//
+// AccountView.swift
+// iosApp
+//
+// Created by Iván on 15/02/22.
+// Copyright © 2022 orgName. All rights reserved.
+//
+
+import SwiftUI
+
+struct AccountView: View {
+ @StateObject var accountViewModel = AccountViewModel()
+ @EnvironmentObject var rootViewModel: RootViewModel
+
+ var body: some View {
+ List {
+ Section {
+ // MARK: - Name
+ if let name = accountViewModel.user?.name {
+ HStack {
+ Text("username")
+ Spacer()
+ Text(name).foregroundColor(.secondaryLabel)
+ }
+ }
+ // MARK: - E-mail
+ if let email = accountViewModel.user?.email {
+ HStack {
+ Text("email")
+ Spacer()
+ Text(email).foregroundColor(.secondaryLabel)
+ }
+ }
+ // MARK: - Unique ID
+ if let uid = accountViewModel.user?.id {
+ HStack {
+ Text("unique-id")
+ Spacer()
+ Text("\(uid)").foregroundColor(.secondaryLabel)
+ }
+ }
+ // MARK: - Administrator
+ if let admin = accountViewModel.user?.administrator {
+ HStack {
+ Text("admin")
+ Spacer()
+ Text("\(admin)").foregroundColor(.secondaryLabel)
+ }
+ }
+ // MARK: - Server URL
+ if let server = UserDefaults.standard.string(forKey: "server-url") {
+ HStack {
+ Text("server-url")
+ Spacer()
+ Text(server).foregroundColor(.secondaryLabel)
+ }
+ }
+ }
+
+ Section {
+ // MARK: - Sign out
+ Button {
+ rootViewModel.signOut()
+ } label: {
+ Label("signout", systemImage: "rectangle.portrait.and.arrow.right")
+ .foregroundColor(.systemRed)
+ }
+ }
+ }.onAppear {
+ accountViewModel.fetchUserInfo()
+ }
+ }
+}
diff --git a/iosApp/iosApp/Session/AccountViewModel.swift b/iosApp/iosApp/Session/AccountViewModel.swift
new file mode 100644
index 0000000..7953265
--- /dev/null
+++ b/iosApp/iosApp/Session/AccountViewModel.swift
@@ -0,0 +1,29 @@
+//
+// AccountViewModel.swift
+// iosApp
+//
+// Created by Iván on 15/02/22.
+// Copyright © 2022 orgName. All rights reserved.
+//
+
+import Foundation
+import shared
+
+class AccountViewModel: ObservableObject {
+ @Inject var sessionController: SessionController
+
+ @Published var user: User? = nil
+
+ init() {
+ let userCollector = Collector<User?>(callback: setUser)
+ sessionController.userFlow.collect(collector: userCollector) {_, _ in }
+ }
+
+ func setUser(user: User?) {
+ self.user = user
+ }
+
+ func fetchUserInfo() {
+ self.sessionController.getSession()
+ }
+}
diff --git a/iosApp/iosApp/Session/RootView.swift b/iosApp/iosApp/Session/RootView.swift
index bc8a7d1..297a2aa 100644
--- a/iosApp/iosApp/Session/RootView.swift
+++ b/iosApp/iosApp/Session/RootView.swift
@@ -18,24 +18,35 @@
import SwiftUI
import shared
+class SessionState: ObservableObject {
+ @Published var loggedIn = false
+}
+
struct RootView: View {
@StateObject private var rootViewModel = RootViewModel()
@State private var username = ""
@State private var password = ""
- @State private var server = ""
+ @State private var server: String
+
+ init() {
+ server = UserDefaults.standard.string(forKey: "server-url")
+ ?? NSLocalizedString("app-server-url", comment: "")
+ }
var body: some View {
- switch rootViewModel.loginState {
- case is SessionController.LoginStateLoading:
- LoadingView()
- case is SessionController.LoginStateSuccess:
- UnitsView()
- default:
- LoginContentView(username: $username,
- password: $password,
- server: $server,
- onLogin: rootViewModel.login)
- }
+ 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)
+ }
+ }.environmentObject(rootViewModel)
}
}
@@ -44,13 +55,7 @@ struct LoginContentView: View {
@Binding var password: String
@Binding var server: String
- let onLogin: (SessionBody) -> Void
-
- func getFcmToken() -> String? {
- let token = UserDefaults.standard.string(forKey: "fcmtoken")
- print("FCM token is \(String(describing: token))")
- return token
- }
+ let onLogin: (String, String, String) -> Void
var body: some View {
VStack {
@@ -63,10 +68,7 @@ struct LoginContentView: View {
server: $server)
Button(action: {
- self.onLogin(SessionBody(url: server,
- email: username,
- password: password,
- fcmToken: getFcmToken()))
+ self.onLogin(username, password, server)
}) {
Text("login")
.font(.system(size: 18))
diff --git a/iosApp/iosApp/Session/RootViewModel.swift b/iosApp/iosApp/Session/RootViewModel.swift
index d065777..682deee 100644
--- a/iosApp/iosApp/Session/RootViewModel.swift
+++ b/iosApp/iosApp/Session/RootViewModel.swift
@@ -38,10 +38,23 @@ class RootViewModel: ObservableObject {
sessionController.restoreSession()
}
- func login(session: SessionBody) {
- print("Username: \(session.email)")
- print("Password: \(session.password)")
- print("Server URL: \(session.url)")
- sessionController.login(body: session)
+ private func getFcmToken() -> String? {
+ let token = UserDefaults.standard.string(forKey: "fcmtoken")
+ print("FCM token is \(String(describing: token))")
+ return token
+ }
+
+ func login(username: String, password: String, url: String) {
+ print("Username: \(username)")
+ print("Password: \(password)")
+ print("Server URL: \(url)")
+ sessionController.login(body: SessionBody(url: url,
+ email: username,
+ password: password,
+ fcmToken: getFcmToken()))
+ }
+
+ func signOut() {
+ sessionController.logout(token: getFcmToken())
}
}
diff --git a/iosApp/iosApp/Session/UserInformationView.swift b/iosApp/iosApp/Session/UserInformationView.swift
new file mode 100644
index 0000000..98d4bfd
--- /dev/null
+++ b/iosApp/iosApp/Session/UserInformationView.swift
@@ -0,0 +1,50 @@
+//
+// UserInformationView.swift
+// iosApp
+//
+// Created by Iván on 15/02/22.
+// Copyright © 2022 orgName. All rights reserved.
+//
+
+import SwiftUI
+
+struct UserInformationView: View {
+ @Environment(\.presentationMode) var presentationMode
+ @State var action = Action.account
+
+ enum Action {
+ case account
+ case about
+ }
+
+ var body: some View {
+ NavigationView {
+ VStack {
+ switch action {
+ case .account:
+ AccountView()
+ case .about:
+ AboutView()
+ }
+ }
+ .navigationBarTitleView(
+ Picker(selection: $action) {
+ Text("account").tag(Action.account)
+ Text("about").tag(Action.about)
+ } label: {
+ EmptyView()
+ }.pickerStyle(SegmentedPickerStyle())
+ )
+ .navigationBarTitleDisplayMode(.inline)
+ .toolbar {
+ ToolbarItem(placement: .navigationBarTrailing) {
+ Button {
+ presentationMode.wrappedValue.dismiss()
+ } label: {
+ Text("done").bold()
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/iosApp/iosApp/Units/UnitsView.swift b/iosApp/iosApp/Units/UnitsView.swift
index d813c6d..a91511e 100644
--- a/iosApp/iosApp/Units/UnitsView.swift
+++ b/iosApp/iosApp/Units/UnitsView.swift
@@ -67,7 +67,9 @@ struct UnitsView: View {
.visible(unitsViewModel.unitsDisplayMode == .map)
}
ToolbarItem(placement: .navigationBarTrailing) {
- Button(action: {}) {
+ Button {
+ unitsViewModel.showUserInfo = true
+ } label: {
Image(systemName: "person")
}
}
@@ -81,6 +83,12 @@ struct UnitsView: View {
action: unitsViewModel.detailsAction,
for: unitsViewModel.detailsUnit)
}
+ .sheet(isPresented: $unitsViewModel.showUserInfo) {
+ print("Dismissed")
+ } content: {
+ UserInformationView()
+ }
+
}
private func getNavigationTitle(_ unitDisplayMode: UnitsViewModel.UnitsDisplayMode) -> LocalizedStringKey {
diff --git a/iosApp/iosApp/Units/UnitsViewModel.swift b/iosApp/iosApp/Units/UnitsViewModel.swift
index 7ffcfd1..af6fe32 100644
--- a/iosApp/iosApp/Units/UnitsViewModel.swift
+++ b/iosApp/iosApp/Units/UnitsViewModel.swift
@@ -52,7 +52,8 @@ class UnitsViewModel: ObservableObject {
}
@Published var isEditing = false
@Published var showDetails = false
- @Published var unitsDisplayMode: UnitsDisplayMode = .list
+ @Published var showUserInfo = false
+ @Published var unitsDisplayMode: UnitsDisplayMode = .map
@Published var units: [UnitInformation] = [] {
didSet {
markers = units.compactMap(Marker.companion.fromUnit)
@@ -127,8 +128,12 @@ class UnitsViewModel: ObservableObject {
}
func show(action: DeviceRow.Action, for unit: UnitInformation) {
- detailsAction = action
- detailsUnit = unit
- showDetails = true
+ if action != .close {
+ detailsAction = action
+ detailsUnit = unit
+ showDetails = true
+ } else {
+ selectedUnit = nil
+ }
}
}
diff --git a/iosApp/iosApp/Localizable.strings b/iosApp/iosApp/en.lproj/Localizable.strings
index 76e7bd4..392bc1c 100644
--- a/iosApp/iosApp/Localizable.strings
+++ b/iosApp/iosApp/en.lproj/Localizable.strings
@@ -16,7 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
"app-name" = "TrackerMap";
-"app-server-url" = "https://etbsa.net/api";
+"app-server-url" = "https://gps.trackermap.mx/api";
+"app-website" = "https://trackermap.mx";
+"app-source-code" = "https://git.sr.ht/~avalos/trackermap-mobile";
"loading" = "Loading";
"done" = "Done";
@@ -53,3 +55,14 @@
"send-command" = "Send command";
"send-command-confirm" = "Are you sure you want to send the command?";
+
+"account" = "Account";
+"about" = "About";
+"email" = "E-mail";
+"admin" = "Administrator";
+"signout" = "Sign out";
+
+"about-text" = "TrackerMap is a free (as in freedom) software app for tracking and managing GPS devices in Traccar servers.\n\nTrackerMap source code is licensed under the GNU General Public License Version 3.";
+"version" = "Version";
+"website" = "Website";
+"source-code" = "Source code";
diff --git a/iosApp/iosApp/es-419.lproj/Localizable.strings b/iosApp/iosApp/es-419.lproj/Localizable.strings
new file mode 100644
index 0000000..401582e
--- /dev/null
+++ b/iosApp/iosApp/es-419.lproj/Localizable.strings
@@ -0,0 +1,68 @@
+/**
+ * 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/>.
+ */
+"app-name" = "TrackerMap";
+"app-server-url" = "https://gps.trackermap.mx/api";
+"app-website" = "https://trackermap.mx";
+"app-source-code" = "https://git.sr.ht/~avalos/trackermap-mobile";
+
+"loading" = "Cargando";
+"done" = "Hecho";
+
+"username" = "Usuario";
+"password" = "Contraseña";
+"server-url" = "URL del servidor";
+"login" = "Iniciar sesión";
+
+"devices" = "Dispositivos";
+"map" = "Mapa";
+"search" = "Buscar";
+
+"details" = "Detalles";
+"reports" = "Reportes";
+"commands" = "Comandos";
+"select-action" = "Seleccionar una acción";
+
+"map-layer" = "Capa del mapa";
+"openstreetmap" = "OpenStreetMap";
+"satellite" = "Satélite";
+
+"contact" = "Contacto";
+"unique-id" = "ID único";
+"datetime" = "Fecha y hora";
+"latitude" = "Latitud";
+"longitude" = "Longitud";
+"speed" = "Velocidad";
+"address" = "Dirección";
+"hourmeter" = "Horómetro";
+"protocol" = "Protocolo";
+"open-location-browser" = "Abrir ubicación en navegador";
+"maps-url-template" = "https://www.google.com/maps/place/{y},{x}?z=19";
+
+"send-command" = "Enviar comando";
+"send-command-confirm" = "¿Está seguro que desea enviar el comando?";
+
+"account" = "Cuenta";
+"about" = "Acerca de";
+"email" = "Correo electrónico";
+"admin" = "Administrador";
+"signout" = "Cerrar sesión";
+
+"about-text" = "TrackerMap es una aplicación de software libre para rastrear y gestionar dispositivos GPS en servidores de Traccar.\n\nEl código fuente de TrackerMap está disponible bajo la licencia GNU General Public License versión 3.";
+"version" = "Versión";
+"website" = "Sitio web";
+"source-code" = "Código fuente";