Janky waypoint edit

This commit is contained in:
Garth Vander Houwen 2023-01-16 17:40:28 -08:00
parent ac6cca636f
commit b00f8c2daa
8 changed files with 95 additions and 35 deletions

View file

@ -70,6 +70,7 @@
DD964FBF296E76EF007C176F /* WaypointFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FBE296E76EF007C176F /* WaypointFormView.swift */; };
DD964FC2297272AE007C176F /* WaypointEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FC1297272AE007C176F /* WaypointEntityExtension.swift */; };
DD964FC42974767D007C176F /* MapViewFitExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FC32974767D007C176F /* MapViewFitExtension.swift */; };
DD964FC62975DBFD007C176F /* QueryCoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FC52975DBFD007C176F /* QueryCoreData.swift */; };
DD97E96628EFD9820056DDA4 /* MeshtasticLogo.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD97E96528EFD9820056DDA4 /* MeshtasticLogo.swift */; };
DD97E96828EFE9A00056DDA4 /* About.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD97E96728EFE9A00056DDA4 /* About.swift */; };
DD994B69295F88B60013760A /* IntervalEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD994B68295F88B60013760A /* IntervalEnums.swift */; };
@ -197,6 +198,7 @@
DD964FC029724F6D007C176F /* MeshtasticDataModelV6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV6.xcdatamodel; sourceTree = "<group>"; };
DD964FC1297272AE007C176F /* WaypointEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaypointEntityExtension.swift; sourceTree = "<group>"; };
DD964FC32974767D007C176F /* MapViewFitExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewFitExtension.swift; sourceTree = "<group>"; };
DD964FC52975DBFD007C176F /* QueryCoreData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryCoreData.swift; sourceTree = "<group>"; };
DD97E96528EFD9820056DDA4 /* MeshtasticLogo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticLogo.swift; sourceTree = "<group>"; };
DD97E96728EFE9A00056DDA4 /* About.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = About.swift; sourceTree = "<group>"; };
DD994B68295F88B60013760A /* IntervalEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntervalEnums.swift; sourceTree = "<group>"; };
@ -570,6 +572,7 @@
DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */,
DDD9E4E3284B208E003777C5 /* UserEntityExtension.swift */,
DD58C5F12919AD3C00D5BEFB /* ChannelEntityExtension.swift */,
DD964FC52975DBFD007C176F /* QueryCoreData.swift */,
DD3CC6C128EB9D4900FA9159 /* UpdateCoreData.swift */,
DD964FC1297272AE007C176F /* WaypointEntityExtension.swift */,
);
@ -804,6 +807,7 @@
DDA1C48E28DB49D3009933EC /* ChannelRoles.swift in Sources */,
DD8ED9C8289CE4B900B3B0AB /* RoutingError.swift in Sources */,
DDAF8C5826ED07FD0058C060 /* mesh.pb.swift in Sources */,
DD964FC62975DBFD007C176F /* QueryCoreData.swift in Sources */,
DD8169FB271F1F3A00F4AB02 /* MeshLog.swift in Sources */,
DD8ED9C52898D51F00B3B0AB /* NetworkConfig.swift in Sources */,
DDC3B274283F411B00AC321C /* LastHeardText.swift in Sources */,

View file

@ -732,7 +732,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
var success = false
let fromNodeNum = UInt32(connectedPeripheral.num)
var waypointPacket = waypoint
waypointPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
var meshPacket = MeshPacket()
meshPacket.to = emptyNodeNum
meshPacket.from = fromNodeNum
@ -752,13 +751,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
success = true
let wayPointEntity = WaypointEntity(context: context!)
wayPointEntity.id = Int64(waypointPacket.id)
wayPointEntity.name = waypointPacket.name.count >= 1 ? waypointPacket.name : "Dropped Pin"
wayPointEntity.longDescription = waypointPacket.description_p
wayPointEntity.icon = Int64(waypointPacket.icon)
wayPointEntity.latitudeI = waypointPacket.latitudeI
wayPointEntity.longitudeI = waypointPacket.longitudeI
let wayPointEntity = getWaypoint(id: Int64(waypoint.id), context: context!)
wayPointEntity.name = waypoint.name.count >= 1 ? waypointPacket.name : "Dropped Pin"
wayPointEntity.longDescription = waypoint.description_p
wayPointEntity.icon = Int64(waypoint.icon)
wayPointEntity.latitudeI = waypoint.latitudeI
wayPointEntity.longitudeI = waypoint.longitudeI
do {
try context!.save()
print("💾 Updated Waypoint from Waypoint App Packet From: \(fromNodeNum)")

View file

@ -0,0 +1,24 @@
//
// QueryCoreData.swift
// Meshtastic
//
// Created(c) Garth Vander Houwen 1/16/23.
//
import CoreData
public func getWaypoint(id: Int64, context: NSManagedObjectContext) -> WaypointEntity {
let fetchWaypointRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "WaypointEntity")
fetchWaypointRequest.predicate = NSPredicate(format: "id == %lld", Int64(id))
do {
let fetchedWaypoint = try context.fetch(fetchWaypointRequest) as! [WaypointEntity]
if fetchedWaypoint.count == 1 {
return fetchedWaypoint[0]
}
} catch {
return WaypointEntity()
}
return WaypointEntity()
}

View file

@ -3,14 +3,13 @@
// Meshtastic
//
// Copyright(c) Josh Pirihi & Garth Vander Houwen 1/16/22.
//
import SwiftUI
import MapKit
struct MapViewSwiftUI: UIViewRepresentable {
var onMarkerTap: (_ waypointCoordinate: CLLocationCoordinate2D? ) -> Void
var onMarkerTap: (_ waypointCoordinate: CLLocationCoordinate2D?, _ tag: Int? ) -> Void
let mapView = MKMapView()
let positions: [PositionEntity]
let waypoints: [WaypointEntity]
@ -111,9 +110,11 @@ struct MapViewSwiftUI: UIViewRepresentable {
case _ as MKClusterAnnotation:
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "nodeGroup") as? MKMarkerAnnotationView ?? MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "nodeGroup")
annotationView.markerTintColor = .brown//.systemRed
annotationView.tag = -1
return annotationView
case _ as PositionEntity:
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "node") as? MKMarkerAnnotationView ?? MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "Node")
annotationView.tag = -1
annotationView.canShowCallout = true
annotationView.glyphText = "📟"
annotationView.clusteringIdentifier = "nodeGroup"
@ -122,6 +123,7 @@ struct MapViewSwiftUI: UIViewRepresentable {
return annotationView
case let waypointAnnotation as WaypointEntity:
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "waypoint") as? MKMarkerAnnotationView ?? MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "Waypoint")
annotationView.tag = Int(waypointAnnotation.id)
annotationView.canShowCallout = true
if waypointAnnotation.icon == 0 {
annotationView.glyphText = "📍"
@ -136,12 +138,24 @@ struct MapViewSwiftUI: UIViewRepresentable {
}
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView)
{
// Only Allow Edit for annotations with a tag
if view.tag > 0 {
// 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)
parent.onMarkerTap(coordinate, view.tag)
}
}
@objc func longPressHandler(_ gesture: UILongPressGestureRecognizer) {
// 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)
parent.onMarkerTap(coordinate)
parent.onMarkerTap(coordinate, 0)
// Add annotation:
let annotation = MKPointAnnotation()
annotation.title = "Dropped Pin"
@ -291,7 +305,6 @@ struct MapViewSwiftUI: UIViewRepresentable {
let urlstring = self.mapName+"\(path.z)/\(path.x)/\(path.y).png"
return URL(string: urlstring)!
}
}
}

View file

@ -13,9 +13,10 @@ struct WaypointFormView: View {
@EnvironmentObject var bleManager: BLEManager
@Environment(\.dismiss) private var dismiss
@State var coordinate: CLLocationCoordinate2D
@State var id: Int = 0
@FocusState private var iconIsFocused: Bool
@State private var id: Int32?
@State private var name: String = ""
@State private var description: String = ""
@State private var icon: String = "📍"
@ -26,7 +27,7 @@ struct WaypointFormView: View {
var body: some View {
Form {
let distance = CLLocation(latitude: LocationHelper.currentLocation.latitude, longitude: LocationHelper.currentLocation.longitude).distance(from: CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude))
Section(header: Text("Waypoint")) {
Section(header: Text((id > 0) ? "Editing Waypoint" : "Create Waypoint")) {
HStack {
Text("Location: \(String(format: "%.5f", coordinate.latitude ) + "," + String(format: "%.5f", coordinate.longitude ))")
.textSelection(.enabled)
@ -121,7 +122,14 @@ struct WaypointFormView: View {
}
HStack {
Button {
var newWaypoint = Waypoint()
if id == 0 {
newWaypoint.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
} else {
newWaypoint.id = UInt32(id)
}
newWaypoint.name = name.count < 1 ? "Dropped Pin" : name
newWaypoint.description_p = description
newWaypoint.latitudeI = Int32(coordinate.latitude * 1e7)
@ -161,5 +169,20 @@ struct WaypointFormView: View {
.controlSize(.large)
.padding()
}
.onAppear {
if id > 0 {
let waypoint = getWaypoint(id: Int64(id), context: bleManager.context!)
id = Int(waypoint.id)
name = waypoint.name ?? "Dropped Pin"
description = waypoint.longDescription ?? ""
icon = String(UnicodeScalar(Int(waypoint.icon)) ?? "📍")
if waypoint.expire != nil {
expires = true
expire = waypoint.expire ?? Date()
} else {
expires = false
}
}
}
}
}

View file

@ -14,6 +14,7 @@ struct NodeDetail: View {
@State var satsInView = 0
@State private var mapType: MKMapType = .standard
@State var waypointCoordinate: CLLocationCoordinate2D?
@State var editingWaypoint: Int = 0
@State private var showingDetailsPopover = false
@State private var showingShutdownConfirm: Bool = false
@State private var showingRebootConfirm: Bool = false
@ -47,11 +48,10 @@ struct NodeDetail: View {
ZStack {
let annotations = node.positions?.array as! [PositionEntity]
ZStack {
MapViewSwiftUI(onMarkerTap: { coord in
MapViewSwiftUI(onMarkerTap: { coord, id in
waypointCoordinate = coord
if waypointCoordinate == nil {
presentingWaypointForm = false
} else {
editingWaypoint = id ?? 0
if waypointCoordinate != nil {
presentingWaypointForm = true
}
}, positions: annotations, waypoints: Array(waypoints), mapViewType: mapType,
@ -66,12 +66,9 @@ struct NodeDetail: View {
.font(.caption)
.offset(y: 20)
Picker("Map Type", selection: $mapType) {
Text("Standard").tag(MKMapType.standard)
Text("Muted").tag(MKMapType.mutedStandard)
Text("Hybrid").tag(MKMapType.hybrid)
Text("Hybrid Flyover").tag(MKMapType.hybridFlyover)
Text("Satellite").tag(MKMapType.satellite)
Text("Sat Flyover").tag(MKMapType.satelliteFlyover)
ForEach(MeshMapType.allCases) { map in
Text(map.description).tag(map.MKMapTypeValue())
}
}
.pickerStyle(.menu)
}
@ -388,11 +385,9 @@ struct NodeDetail: View {
}
.edgesIgnoringSafeArea([.leading, .trailing])
.sheet(isPresented: $presentingWaypointForm ) {//, onDismiss: didDismissSheet) {
if waypointCoordinate != nil {
WaypointFormView(coordinate: waypointCoordinate!)
WaypointFormView(coordinate: waypointCoordinate ?? LocationHelper.DefaultLocation, id: editingWaypoint)
.presentationDetents([.medium, .large])
.presentationDragIndicator(.automatic)
}
}
.navigationBarTitle(String(node.user?.longName ?? NSLocalizedString("unknown", comment: "")), displayMode: .inline)
.navigationBarItems(trailing:

View file

@ -41,6 +41,7 @@ struct NodeMap: View {
@State private var mapType: MKMapType = .standard
@State var waypointCoordinate: CLLocationCoordinate2D?
@State var editingWaypoint: Int = 0
@State private var presentingWaypointForm = false
@State private var customMapOverlay: MapViewSwiftUI.CustomMapOverlay? = MapViewSwiftUI.CustomMapOverlay(
mapName: "offlinemap",
@ -54,7 +55,8 @@ struct NodeMap: View {
NavigationStack {
ZStack {
MapViewSwiftUI(onMarkerTap: { coord in
MapViewSwiftUI(onMarkerTap: { coord, id in
editingWaypoint = id ?? 0
waypointCoordinate = coord
if waypointCoordinate == nil {
presentingWaypointForm = false
@ -69,12 +71,9 @@ struct NodeMap: View {
VStack {
Spacer()
Picker("Map Type", selection: $mapType) {
Text("Standard").tag(MKMapType.standard)
Text("Standard Muted").tag(MKMapType.mutedStandard)
Text("Hybrid").tag(MKMapType.hybrid)
Text("Hybrid Flyover").tag(MKMapType.hybridFlyover)
Text("Satellite").tag(MKMapType.satellite)
Text("Satellite Flyover").tag(MKMapType.satelliteFlyover)
ForEach(MeshMapType.allCases) { map in
Text(map.description).tag(map.MKMapTypeValue())
}
}
.pickerStyle(.menu)
}
@ -83,7 +82,7 @@ struct NodeMap: View {
.frame(maxHeight: .infinity)
.sheet(isPresented: $presentingWaypointForm ) {//, onDismiss: didDismissSheet) {
if waypointCoordinate != nil {
WaypointFormView(coordinate: waypointCoordinate!)
WaypointFormView(coordinate: waypointCoordinate!, id: editingWaypoint)
.presentationDetents([.medium, .large])
.presentationDragIndicator(.automatic)
}

View file

@ -102,6 +102,9 @@ struct AppSettings: View {
.onAppear {
self.bleManager.context = context
}
.onChange(of: userSettings.provideLocation) { newProvideLocation in
self.bleManager.sendWantConfig()
}
}
}