From e28a9709452585dc793787898f019053254e1e2f Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 9 Apr 2023 11:04:08 -0700 Subject: [PATCH] Waypoint bug fixes --- Meshtastic/Helpers/LocationHelper.swift | 5 +- .../Views/Map/Custom/MapViewSwiftUI.swift | 131 ++++++++---------- Meshtastic/Views/Map/WaypointFormView.swift | 54 ++++---- Meshtastic/Views/Nodes/NodeDetail.swift | 24 ++-- Meshtastic/Views/Nodes/NodeMap.swift | 37 +++-- Meshtastic/Views/Settings/AppSettings.swift | 38 +++-- Meshtastic/Views/Settings/Settings.swift | 6 +- 7 files changed, 130 insertions(+), 165 deletions(-) diff --git a/Meshtastic/Helpers/LocationHelper.swift b/Meshtastic/Helpers/LocationHelper.swift index bb4c168a..98bd233d 100644 --- a/Meshtastic/Helpers/LocationHelper.swift +++ b/Meshtastic/Helpers/LocationHelper.swift @@ -21,9 +21,6 @@ class LocationHelper: NSObject, ObservableObject, CLLocationManagerDelegate { // Apple Park static let DefaultLocation = CLLocation(latitude: 37.3346, longitude: -122.0090) - //static let DefaultAltitude = CLLocationDistance(integerLiteral: 0) - //static let DefaultSpeed = CLLocationSpeed(integerLiteral: 0) - //static let DefaultHeading = CLLocationDirection(integerLiteral: 0) static var currentLocation: CLLocation { @@ -72,12 +69,12 @@ class LocationHelper: NSObject, ObservableObject, CLLocationManagerDelegate { } // Extra Smart positioning logic throwing out bad readings from the phone GPS let age = -mostRecentLocation.timestamp.timeIntervalSinceNow - print("Location: HA-\(mostRecentLocation.horizontalAccuracy) VA-\(mostRecentLocation.verticalAccuracy) AGE-\(age)") manager.stopUpdatingLocation() if age > 10 || mostRecentLocation.horizontalAccuracy < 0 || mostRecentLocation.horizontalAccuracy > 100 { print("Bad Location: HA-\(mostRecentLocation.horizontalAccuracy) VA-\(mostRecentLocation.verticalAccuracy) AGE-\(age)") manager.startUpdatingLocation() } else { + print("Good Location: HA-\(mostRecentLocation.horizontalAccuracy) VA-\(mostRecentLocation.verticalAccuracy) AGE-\(age)") lastLocation = mostRecentLocation } } diff --git a/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift b/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift index ed361a48..34950ae0 100644 --- a/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift +++ b/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift @@ -13,17 +13,18 @@ func degreesToRadians(_ number: Double) -> Double { struct MapViewSwiftUI: UIViewRepresentable { - var onLongPress: (_ waypointCoordinate: CLLocationCoordinate2D) -> Void - var onWaypointEdit: (_ waypointId: Int ) -> Void + var onLongPress: ((CLLocationCoordinate2D) -> Void) + var onWaypointEdit: ((Int) -> Void) let mapView = MKMapView() // Parameters let positions: [PositionEntity] let waypoints: [WaypointEntity] let mapViewType: MKMapType let userTrackingMode: MKUserTrackingMode - let showNodeHistory: Bool - let showRouteLines: Bool + // User Defaults Values @AppStorage("meshMapRecentering") private var recenter: Bool = false + @AppStorage("meshMapShowNodeHistory") private var showNodeHistory = false + @AppStorage("meshMapShowRouteLines") private var showRouteLines = false // Offline Map Tiles @AppStorage("lastUpdatedLocalMapFile") private var lastUpdatedLocalMapFile = 0 @State private var loadedLastUpdatedLocalMapFile = 0 @@ -116,56 +117,50 @@ struct MapViewSwiftUI: UIViewRepresentable { } } - DispatchQueue.main.async { - let latest = positions - .filter { $0.latest == true } - .sorted { $0.nodePosition?.num ?? 0 > $1.nodePosition?.num ?? -1 } - let annotationCount = waypoints.count + (showNodeHistory ? positions.count : latest.count) - - - if annotationCount != mapView.annotations.count { - print("Annotation Count: \(annotationCount) Map Annotations: \(mapView.annotations.count)") - mapView.removeAnnotations(mapView.annotations) - mapView.addAnnotations(waypoints) - if showRouteLines { - // Remove all existing PolyLine Overlays - for overlay in mapView.overlays { - if overlay is MKPolyline { - mapView.removeOverlay(overlay) - } - } - var lineIndex = 0 - for position in latest { - - let nodePositions = positions.filter { $0.nodePosition?.num ?? 0 == position.nodePosition?.num ?? -1 } - let lineCoords = nodePositions.map ({ - (position) -> CLLocationCoordinate2D in - return position.nodeCoordinate! - }) - let polyline = MKPolyline(coordinates: lineCoords, count: nodePositions.count) - polyline.title = "\(String(position.nodePosition?.num ?? 0))" - mapView.addOverlay(polyline) - lineIndex += 1 - // There are 18 colors for lines, start over if we are at index 17 - if lineIndex > 17 { - lineIndex = 0 - } - } - } - if userTrackingMode == MKUserTrackingMode.none { - mapView.showsUserLocation = false - mapView.addAnnotations(showNodeHistory ? positions : latest) - if recenter { - mapView.fit(annotations:showNodeHistory || showRouteLines ? positions : latest, andShow: false) - } - } else { - // Centering Done by tracking mode - mapView.addAnnotations(showNodeHistory ? positions : latest) - mapView.showsUserLocation = true - } - mapView.setUserTrackingMode(userTrackingMode, animated: true) + let latest = positions + .filter { $0.latest == true } + .sorted { $0.nodePosition?.num ?? 0 > $1.nodePosition?.num ?? -1 } + let annotationCount = waypoints.count + (showNodeHistory ? positions.count : latest.count) + print("Annotation Count: \(annotationCount) Map Annotations: \(mapView.annotations.count)") + mapView.removeAnnotations(mapView.annotations) + mapView.addAnnotations(waypoints) + mapView.addAnnotations(showNodeHistory ? positions : latest) + // Remove all existing PolyLine Overlays + for overlay in mapView.overlays { + if overlay is MKPolyline { + mapView.removeOverlay(overlay) } } + if showRouteLines { + + var lineIndex = 0 + for position in latest { + + let nodePositions = positions.filter { $0.nodePosition?.num ?? 0 == position.nodePosition?.num ?? -1 } + let lineCoords = nodePositions.map ({ + (position) -> CLLocationCoordinate2D in + return position.nodeCoordinate! + }) + let polyline = MKPolyline(coordinates: lineCoords, count: nodePositions.count) + polyline.title = "\(String(position.nodePosition?.num ?? 0))" + mapView.addOverlay(polyline) + lineIndex += 1 + // There are 18 colors for lines, start over if we are at index 17 + if lineIndex > 17 { + lineIndex = 0 + } + } + } + if userTrackingMode == MKUserTrackingMode.none { + mapView.showsUserLocation = false + if recenter { + mapView.fit(annotations:showNodeHistory || showRouteLines ? positions : latest, andShow: false) + } + } else { + // Centering Done by tracking mode + mapView.showsUserLocation = true + } + mapView.setUserTrackingMode(userTrackingMode, animated: true) } func makeCoordinator() -> MapCoordinator { @@ -181,9 +176,6 @@ struct MapViewSwiftUI: UIViewRepresentable { self.parent = parent super.init() self.longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressHandler)) - self.longPressRecognizer.minimumPressDuration = 0.5 - self.longPressRecognizer.cancelsTouchesInView = true - self.longPressRecognizer.delegate = self self.parent.mapView.addGestureRecognizer(longPressRecognizer) } @@ -326,23 +318,20 @@ struct MapViewSwiftUI: UIViewRepresentable { } } - @objc func longPressHandler(_ gesture: UILongPressGestureRecognizer) { + @objc func longPressHandler(_ sender: UILongPressGestureRecognizer) { - if gesture.state != UIGestureRecognizer.State.ended { - return - } else if gesture.state != UIGestureRecognizer.State.began { - - // Screen Position - CGPoint - let location = longPressRecognizer.location(in: self.parent.mapView) - - // Map Coordinate - CLLocationCoordinate2D - let coordinate = self.parent.mapView.convert(location, toCoordinateFrom: self.parent.mapView) - let annotation = MKPointAnnotation() - annotation.title = "Dropped Pin" - annotation.coordinate = coordinate - parent.mapView.addAnnotation(annotation) - UINotificationFeedbackGenerator().notificationOccurred(.success) - parent.onLongPress(coordinate) + if sender.state == .began { + let point = sender.location(in: sender.view) + if let mapView = sender.view as? MKMapView { + let coordinate = mapView.convert(point, toCoordinateFrom: mapView) + let annotation = MKPointAnnotation() + print("Handler Coord - \(coordinate)") + annotation.title = "Dropped Pin" + annotation.coordinate = coordinate + parent.mapView.addAnnotation(annotation) + UINotificationFeedbackGenerator().notificationOccurred(.success) + parent.onLongPress(coordinate) + } } } diff --git a/Meshtastic/Views/Map/WaypointFormView.swift b/Meshtastic/Views/Map/WaypointFormView.swift index 548363dc..43dd23cf 100644 --- a/Meshtastic/Views/Map/WaypointFormView.swift +++ b/Meshtastic/Views/Map/WaypointFormView.swift @@ -12,8 +12,7 @@ struct WaypointFormView: View { @EnvironmentObject var bleManager: BLEManager @Environment(\.dismiss) private var dismiss - @State var coordinate: CLLocationCoordinate2D - @State var waypointId: Int = 0 + @State var coordinate: WaypointCoordinate @FocusState private var iconIsFocused: Bool @@ -23,21 +22,21 @@ struct WaypointFormView: View { @State private var latitude: Double = 0 @State private var longitude: Double = 0 @State private var expires: Bool = false - @State private var expire: Date = Date() // = Date.now.addingTimeInterval(60 * 120) // 1 minute * 120 = 2 Hours + @State private var expire: Date = Date.now.addingTimeInterval(60 * 480) // 1 minute * 480 = 8 Hours @State private var locked: Bool = false @State private var lockedTo: Int64 = 0 var body: some View { Form { - let distance = CLLocation(latitude: LocationHelper.currentLocation.coordinate.latitude, longitude: LocationHelper.currentLocation.coordinate.longitude).distance(from: CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)) - Section(header: Text((waypointId > 0) ? "Editing Waypoint" : "Create Waypoint")) { + let distance = CLLocation(latitude: LocationHelper.currentLocation.coordinate.latitude, longitude: LocationHelper.currentLocation.coordinate.longitude).distance(from: CLLocation(latitude: coordinate.coordinate?.latitude ?? 0, longitude: coordinate.coordinate?.longitude ?? 0)) + Section(header: Text((coordinate.waypointId > 0) ? "Editing Waypoint" : "Create Waypoint")) { HStack { Text("Location: \(String(format: "%.5f", latitude) + "," + String(format: "%.5f", longitude))") .textSelection(.enabled) .foregroundColor(Color.gray) .font(.caption2) - if coordinate.latitude != LocationHelper.DefaultLocation.coordinate.latitude && coordinate.longitude != LocationHelper.DefaultLocation.coordinate.longitude { + if coordinate.coordinate?.latitude ?? -1 != LocationHelper.DefaultLocation.coordinate.latitude && coordinate.coordinate?.longitude ?? 0 != LocationHelper.DefaultLocation.coordinate.longitude { DistanceText(meters: distance) .foregroundColor(Color.gray) .font(.caption2) @@ -128,16 +127,20 @@ struct WaypointFormView: View { Button { var newWaypoint = Waypoint() - - if waypointId > 0 { - newWaypoint.id = UInt32(waypointId) + + if coordinate.waypointId > 0 { + newWaypoint.id = UInt32(coordinate.waypointId) + let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context!) + newWaypoint.latitudeI = waypoint.latitudeI + newWaypoint.longitudeI = waypoint.longitudeI } else { newWaypoint.id = UInt32.random(in: UInt32(UInt8.max).. 0 ? name : "Dropped Pin" newWaypoint.description_p = description - newWaypoint.latitudeI = Int32(coordinate.latitude * 1e7) - newWaypoint.longitudeI = Int32(coordinate.longitude * 1e7) + // Unicode scalar value for the icon emoji string let unicodeScalers = icon.unicodeScalars // First element as an UInt32 @@ -157,10 +160,8 @@ struct WaypointFormView: View { newWaypoint.expire = 0 } if bleManager.sendWaypoint(waypoint: newWaypoint) { - waypointId = 0 dismiss() } else { - waypointId = 0 dismiss() print("Send waypoint failed") } @@ -183,11 +184,11 @@ struct WaypointFormView: View { .controlSize(.large) .padding(.bottom) - if waypointId > 0 { + if coordinate.waypointId > 0 { Menu { Button("For me", action: { - let waypoint = getWaypoint(id: Int64(waypointId), context: bleManager.context!) + let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context!) bleManager.context!.delete(waypoint) do { try bleManager.context!.save() @@ -198,13 +199,13 @@ struct WaypointFormView: View { Button("For everyone", action: { var newWaypoint = Waypoint() - if waypointId > 0 { - newWaypoint.id = UInt32(waypointId) + if coordinate.waypointId > 0 { + newWaypoint.id = UInt32(coordinate.waypointId) } newWaypoint.name = name.count > 0 ? name : "Dropped Pin" newWaypoint.description_p = description - newWaypoint.latitudeI = Int32(coordinate.latitude * 1e7) - newWaypoint.longitudeI = Int32(coordinate.longitude * 1e7) + newWaypoint.latitudeI = Int32(coordinate.coordinate?.latitude ?? 0 * 1e7) + newWaypoint.longitudeI = Int32(coordinate.coordinate?.longitude ?? 0 * 1e7) // Unicode scalar value for the icon emoji string let unicodeScalers = icon.unicodeScalars // First element as an UInt32 @@ -220,10 +221,8 @@ struct WaypointFormView: View { } newWaypoint.expire = 1 if bleManager.sendWaypoint(waypoint: newWaypoint) { - waypointId = 0 dismiss() } else { - waypointId = 0 dismiss() print("Send waypoint failed") } @@ -239,14 +238,9 @@ struct WaypointFormView: View { .padding(.bottom) } } - .onChange(of: waypointId) { newId in - print(newId) - - } .onAppear { - if waypointId > 0 { - let waypoint = getWaypoint(id: Int64(waypointId), context: bleManager.context!) - waypointId = Int(waypoint.id) + if coordinate.waypointId > 0 { + let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context!) name = waypoint.name ?? "Dropped Pin" description = waypoint.longDescription ?? "" icon = String(UnicodeScalar(Int(waypoint.icon)) ?? "📍") @@ -269,8 +263,8 @@ struct WaypointFormView: View { expires = false expire = Date.now.addingTimeInterval(60 * 120) icon = "📍" - latitude = coordinate.latitude - longitude = coordinate.longitude + latitude = coordinate.coordinate?.latitude ?? 0 + longitude = coordinate.coordinate?.longitude ?? 0 } } } diff --git a/Meshtastic/Views/Nodes/NodeDetail.swift b/Meshtastic/Views/Nodes/NodeDetail.swift index c43b42d4..976db5fe 100644 --- a/Meshtastic/Views/Nodes/NodeDetail.swift +++ b/Meshtastic/Views/Nodes/NodeDetail.swift @@ -14,11 +14,8 @@ struct NodeDetail: View { @EnvironmentObject var bleManager: BLEManager @Environment(\.colorScheme) var colorScheme: ColorScheme @AppStorage("meshMapType") private var meshMapType = "standard" - @AppStorage("meshMapShowNodeHistory") private var meshMapShowNodeHistory = false - @AppStorage("meshMapShowRouteLines") private var meshMapShowRouteLines = false @State private var mapType: MKMapType = .standard - @State var waypointCoordinate: CLLocationCoordinate2D? - @State var editingWaypoint: Int = 0 + @State var waypointCoordinate: WaypointCoordinate? @State private var loadedWeather: Bool = false @State private var showingDetailsPopover = false @State private var showingForecast = false @@ -64,19 +61,14 @@ struct NodeDetail: View { // let todaysPositions = positionArray.filter { $0.time! >= Calendar.current.startOfDay(for: Date()) } ZStack { MapViewSwiftUI(onLongPress: { coord in - waypointCoordinate = coord - editingWaypoint = 0 - presentingWaypointForm = true + waypointCoordinate = WaypointCoordinate(id: .init(), coordinate: coord, waypointId: 0) }, onWaypointEdit: { wpId in if wpId > 0 { - editingWaypoint = wpId - presentingWaypointForm = true + waypointCoordinate = WaypointCoordinate(id: .init(), coordinate: nil, waypointId: Int64(wpId)) } }, positions: lastTenThousand, waypoints: Array(waypoints), mapViewType: mapType, userTrackingMode: MKUserTrackingMode.none, - showNodeHistory: meshMapShowNodeHistory, - showRouteLines: meshMapShowRouteLines, customMapOverlay: self.customMapOverlay ) VStack(alignment: .leading) { @@ -210,11 +202,11 @@ struct NodeDetail: View { } } .edgesIgnoringSafeArea([.leading, .trailing]) - .sheet(isPresented: $presentingWaypointForm ) {// , onDismiss: didDismissSheet) { - WaypointFormView(coordinate: waypointCoordinate ?? LocationHelper.DefaultLocation.coordinate, waypointId: editingWaypoint) - .presentationDetents([.medium, .large]) - .presentationDragIndicator(.automatic) - } + .sheet(item: $waypointCoordinate, content: { wpc in + WaypointFormView(coordinate: wpc) + .presentationDetents([.medium, .large]) + .presentationDragIndicator(.automatic) + }) .navigationBarTitle(String(node.user?.longName ?? NSLocalizedString("unknown", comment: "")), displayMode: .inline) .navigationBarItems(trailing: ZStack { diff --git a/Meshtastic/Views/Nodes/NodeMap.swift b/Meshtastic/Views/Nodes/NodeMap.swift index 9829d09a..2583f940 100644 --- a/Meshtastic/Views/Nodes/NodeMap.swift +++ b/Meshtastic/Views/Nodes/NodeMap.swift @@ -10,6 +10,14 @@ import MapKit import CoreLocation import CoreData +// A simple struct with waypoint data +struct WaypointCoordinate: Identifiable { + + let id: UUID + let coordinate: CLLocationCoordinate2D? + let waypointId: Int64 +} + struct NodeMap: View { @Environment(\.managedObjectContext) var context @@ -31,8 +39,6 @@ struct NodeMap: View { } @AppStorage("meshMapType") private var meshMapType = "hybridFlyover" @AppStorage("meshMapUserTrackingMode") private var meshMapUserTrackingMode = 0 - @AppStorage("meshMapShowNodeHistory") private var meshMapShowNodeHistory = false - @AppStorage("meshMapShowRouteLines") private var meshMapShowRouteLines = false @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "time", ascending: true)], predicate: NSPredicate(format: "time >= %@ && nodePosition != nil", Calendar.current.startOfDay(for: Date()) as NSDate), animation: .none) @@ -46,9 +52,7 @@ struct NodeMap: View { @State private var mapType: MKMapType = .standard @State private var userTrackingMode: MKUserTrackingMode = .none - @State var waypointCoordinate: CLLocationCoordinate2D = LocationHelper.DefaultLocation.coordinate - @State var editingWaypoint: Int = 0 - @State private var presentingWaypointForm = false + @State var waypointCoordinate: WaypointCoordinate? @State private var customMapOverlay: MapViewSwiftUI.CustomMapOverlay? = MapViewSwiftUI.CustomMapOverlay( mapName: "offlinemap", tileType: "png", @@ -60,25 +64,17 @@ struct NodeMap: View { NavigationStack { ZStack { - MapViewSwiftUI(onLongPress: { coord in - waypointCoordinate = coord - editingWaypoint = 0 - if waypointCoordinate.distance(from: LocationHelper.DefaultLocation.coordinate) == 0.0 { - print("Apple Park") - } else { - presentingWaypointForm = true - } + MapViewSwiftUI( + onLongPress: { coord in + waypointCoordinate = WaypointCoordinate(id: .init(), coordinate: coord, waypointId: 0) }, onWaypointEdit: { wpId in if wpId > 0 { - editingWaypoint = wpId - presentingWaypointForm = true + waypointCoordinate = WaypointCoordinate(id: .init(), coordinate: nil, waypointId: Int64(wpId)) } }, positions: Array(positions), waypoints: Array(waypoints), mapViewType: mapType, userTrackingMode: userTrackingMode, - showNodeHistory: meshMapShowNodeHistory, - showRouteLines: meshMapShowRouteLines, customMapOverlay: self.customMapOverlay ) VStack { @@ -95,12 +91,11 @@ struct NodeMap: View { } .ignoresSafeArea(.all, edges: [.top, .leading, .trailing]) .frame(maxHeight: .infinity) - .sheet(isPresented: $presentingWaypointForm ) {// , onDismiss: didDismissSheet) { - WaypointFormView(coordinate: waypointCoordinate, waypointId: editingWaypoint) + .sheet(item: $waypointCoordinate, content: { wpc in + WaypointFormView(coordinate: wpc) .presentationDetents([.medium, .large]) .presentationDragIndicator(.automatic) - - } + }) } .navigationBarItems(leading: MeshtasticLogo(), trailing: diff --git a/Meshtastic/Views/Settings/AppSettings.swift b/Meshtastic/Views/Settings/AppSettings.swift index 6d190c15..a5a49d67 100644 --- a/Meshtastic/Views/Settings/AppSettings.swift +++ b/Meshtastic/Views/Settings/AppSettings.swift @@ -43,28 +43,26 @@ struct AppSettings: View { let accuracy = Measurement(value: locationHelper.lastLocation?.horizontalAccuracy ?? 300, unit: UnitLength.meters) let altitiude = Measurement(value: locationHelper.lastLocation?.altitude ?? 0, unit: UnitLength.meters) let speed = Measurement(value: locationHelper.lastLocation?.speed ?? 0, unit: UnitSpeed.kilometersPerHour) - Label("Coordinates \(String(format: "%.5f", locationHelper.lastLocation?.coordinate.latitude ?? 0)), \(String(format: "%.5f", locationHelper.lastLocation?.coordinate.longitude ?? 0))", systemImage: "mappin") - .textSelection(.enabled) HStack { - Label("GPS Accuracy \(accuracy.formatted())", systemImage: "scope") - .font(.caption) - - if LocationHelper.currentLocation.verticalAccuracy > 0 { - Label("Altitude \(altitiude.formatted())", systemImage: "mountain.2") - .font(.caption) - } + Label("Accuracy \(accuracy.formatted())", systemImage: "scope") + .font(.callout) + Label("Sats \(LocationHelper.satsInView)", systemImage: "sparkles") + .font(.callout) } - if locationHelper.lastLocation?.courseAccuracy ?? 0 > 0 || locationHelper.lastLocation?.speedAccuracy ?? 0 > 0 { - HStack { - if locationHelper.lastLocation?.courseAccuracy ?? 0 > 0 { - Label("Heading \(String(format: "%.2f", locationHelper.lastLocation?.course ?? 0))°", systemImage: "location.circle") - .font(.caption) - } - if locationHelper.lastLocation?.speedAccuracy ?? 0 > 0 { - Label("Speed \(speed.formatted())", systemImage: "speedometer") - .font(.caption) - } - } + Label("Coordinates \(String(format: "%.5f", locationHelper.lastLocation?.coordinate.latitude ?? 0)), \(String(format: "%.5f", locationHelper.lastLocation?.coordinate.longitude ?? 0))", systemImage: "mappin") + .font(.callout) + .textSelection(.enabled) + if LocationHelper.currentLocation.verticalAccuracy > 0 { + Label("Altitude \(altitiude.formatted())", systemImage: "mountain.2") + .font(.callout) + } + if locationHelper.lastLocation?.courseAccuracy ?? 0 > 0 { + Label("Heading \(String(format: "%.2f", locationHelper.lastLocation?.course ?? 0))°", systemImage: "location.circle") + .font(.callout) + } + if locationHelper.lastLocation?.speedAccuracy ?? 0 > 0 { + Label("Speed \(speed.formatted())", systemImage: "speedometer") + .font(.callout) } Toggle(isOn: $userSettings.provideLocation) { diff --git a/Meshtastic/Views/Settings/Settings.swift b/Meshtastic/Views/Settings/Settings.swift index b5c8fbd6..cacfdb0b 100644 --- a/Meshtastic/Views/Settings/Settings.swift +++ b/Meshtastic/Views/Settings/Settings.swift @@ -64,7 +64,7 @@ struct Settings: View { } .tag(SettingsSidebar.appSettings) let node = nodes.first(where: { $0.num == connectedNodeNum }) - if node?.myInfo?.adminIndex ?? 0 > 0 { + //if node?.myInfo?.adminIndex ?? 0 > 0 { Section("Configure") { Picker("Configuring Node", selection: $selectedNode) { if selectedNode == 0 { @@ -83,7 +83,7 @@ struct Settings: View { } } } - .pickerStyle(.menu) + .pickerStyle(.automatic) .labelsHidden() .onChange(of: selectedNode) { newValue in if selectedNode > 0 { @@ -101,7 +101,7 @@ struct Settings: View { } } } - } + //} Section("radio.configuration") {