From 2d339037ae0334a1bb567173da6d8c5dc744e4e3 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 9 Sep 2023 11:29:08 -0700 Subject: [PATCH] Fully update position log in 3 column mode --- Meshtastic.xcodeproj/project.pbxproj | 4 ++ .../Views/Nodes/Helpers/NodeDetailItem.swift | 34 +++----------- .../Views/Nodes/Helpers/NodeInfoItem.swift | 46 ++++++++----------- .../Views/Nodes/Helpers/NodeListItem.swift | 2 +- .../Views/Nodes/Helpers/NodeMapControl.swift | 8 ++++ Meshtastic/Views/Nodes/NodeList.swift | 7 ++- Meshtastic/Views/Nodes/NodeListSplit.swift | 24 ++++++++-- Meshtastic/Views/Nodes/PositionLog.swift | 20 ++++++-- 8 files changed, 77 insertions(+), 68 deletions(-) create mode 100644 Meshtastic/Views/Nodes/Helpers/NodeMapControl.swift diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 208e0b8d..3f6c4300 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -138,6 +138,7 @@ DDDB26422AABF655003AFCB7 /* NodeListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB26412AABF655003AFCB7 /* NodeListItem.swift */; }; DDDB26442AAC0206003AFCB7 /* NodeDetailItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB26432AAC0206003AFCB7 /* NodeDetailItem.swift */; }; DDDB26462AACC0B7003AFCB7 /* NodeInfoItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB26452AACC0B7003AFCB7 /* NodeInfoItem.swift */; }; + DDDB26482AACD6D1003AFCB7 /* NodeMapControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB26472AACD6D1003AFCB7 /* NodeMapControl.swift */; }; DDDB443629F6287000EE2349 /* MapButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB443529F6287000EE2349 /* MapButtons.swift */; }; DDDB443D29F6592F00EE2349 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB443C29F6592F00EE2349 /* NetworkManager.swift */; }; DDDB444029F79AB000EE2349 /* UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB443F29F79AB000EE2349 /* UserDefaults.swift */; }; @@ -357,6 +358,7 @@ DDDB26412AABF655003AFCB7 /* NodeListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeListItem.swift; sourceTree = ""; }; DDDB26432AAC0206003AFCB7 /* NodeDetailItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeDetailItem.swift; sourceTree = ""; }; DDDB26452AACC0B7003AFCB7 /* NodeInfoItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeInfoItem.swift; sourceTree = ""; }; + DDDB26472AACD6D1003AFCB7 /* NodeMapControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeMapControl.swift; sourceTree = ""; }; DDDB443529F6287000EE2349 /* MapButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapButtons.swift; sourceTree = ""; }; DDDB443C29F6592F00EE2349 /* NetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkManager.swift; sourceTree = ""; }; DDDB443F29F79AB000EE2349 /* UserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaults.swift; sourceTree = ""; }; @@ -811,6 +813,7 @@ DDDB26432AAC0206003AFCB7 /* NodeDetailItem.swift */, DDDB26452AACC0B7003AFCB7 /* NodeInfoItem.swift */, DDDB26412AABF655003AFCB7 /* NodeListItem.swift */, + DDDB26472AACD6D1003AFCB7 /* NodeMapControl.swift */, ); path = Helpers; sourceTree = ""; @@ -1101,6 +1104,7 @@ DDDB263F2AABEE20003AFCB7 /* NodeListSplit.swift in Sources */, DDA0B6B2294CDC55001356EC /* Channels.swift in Sources */, DDB8F4102A9EE5B400230ECE /* Messages.swift in Sources */, + DDDB26482AACD6D1003AFCB7 /* NodeMapControl.swift in Sources */, DD4A911E2708C65400501B7E /* AppSettings.swift in Sources */, DD5E5209298EE33B00D21B61 /* module_config.pb.swift in Sources */, DD2160AF28C5552500C17253 /* MQTTConfig.swift in Sources */, diff --git a/Meshtastic/Views/Nodes/Helpers/NodeDetailItem.swift b/Meshtastic/Views/Nodes/Helpers/NodeDetailItem.swift index 84b0a3b6..e1f553b8 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeDetailItem.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeDetailItem.swift @@ -13,14 +13,6 @@ struct NodeDetailItem: View { @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager @Environment(\.colorScheme) var colorScheme: ColorScheme - @AppStorage("meshMapType") private var meshMapType = 0 - @AppStorage("meshMapShowNodeHistory") private var meshMapShowNodeHistory = false - @AppStorage("meshMapShowRouteLines") private var meshMapShowRouteLines = false - @State private var selectedMapLayer: MapLayer = .standard - @State var waypointCoordinate: WaypointCoordinate? - @State var editingWaypoint: Int = 0 - @State private var loadedWeather: Bool = false - @State private var showingDetailsPopover = false @State private var showingForecast = false @State private var showingShutdownConfirm: Bool = false @State private var showingRebootConfirm: Bool = false @@ -29,21 +21,7 @@ struct NodeDetailItem: View { tileType: "png", canReplaceMapContent: true ) - @ObservedObject var node: NodeInfoEntity - @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "name", ascending: false)], - predicate: NSPredicate( - format: "expire == nil || expire >= %@", Date() as NSDate - ), animation: .none) - private var waypoints: FetchedResults - - /// The current weather condition for the city. - @State private var condition: WeatherCondition? - @State private var temperature: Measurement? - @State private var humidity: Int? - @State private var symbolName: String = "cloud.fill" - - @State private var attributionLink: URL? - @State private var attributionLogo: URL? + var node: NodeInfoEntity var body: some View { @@ -102,12 +80,12 @@ struct NodeDetailItem: View { } } } + .onAppear { + if self.bleManager.context == nil { + self.bleManager.context = context + } + } .edgesIgnoringSafeArea([.leading, .trailing]) - .sheet(item: $waypointCoordinate, content: { wpc in - WaypointFormView(coordinate: wpc) - .presentationDetents([.medium, .large]) - .presentationDragIndicator(.automatic) - }) .navigationBarTitle(String(node.user?.longName ?? "unknown".localized), displayMode: .inline) .navigationBarItems(trailing: ZStack { diff --git a/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift b/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift index 26c3c2fc..3d36bcb0 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift @@ -12,14 +12,6 @@ import MapKit struct NodeInfoItem: View { var node: NodeInfoEntity - - enum SelectedDetail { - case positionLog - case nodeMap - case deviceMetricsLog - case environmentMetricsLog - case detectionSensorLog - } var body: some View { @@ -105,26 +97,7 @@ struct NodeInfoItem: View { VStack { // List { - if node.hasPositions { - - NavigationLink { - PositionLog(node: node) - .onAppear { - } - } label: { - - Image(systemName: "building.columns") - .symbolRenderingMode(.hierarchical) - .font(.title) - - Text("Position Log") - .font(.title3) - } - .fixedSize(horizontal: false, vertical: true) - Divider() - } - if node.hasDeviceMetrics { NavigationLink { @@ -154,6 +127,25 @@ struct NodeInfoItem: View { } Divider() } + if node.hasPositions { + + NavigationLink { + PositionLog(node: node) + .onAppear { + + } + } label: { + + Image(systemName: "building.columns") + .symbolRenderingMode(.hierarchical) + .font(.title) + + Text("Position Log") + .font(.title3) + } + .fixedSize(horizontal: false, vertical: true) + Divider() + } NavigationLink { DetectionSensorLog(node: node) } label: { diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift b/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift index d619c379..432901d6 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift @@ -10,7 +10,7 @@ import CoreLocation struct NodeListItem: View { - public var node: NodeInfoEntity + @ObservedObject var node: NodeInfoEntity var connected: Bool var connectedNode: Int64 var modemPreset: Int diff --git a/Meshtastic/Views/Nodes/Helpers/NodeMapControl.swift b/Meshtastic/Views/Nodes/Helpers/NodeMapControl.swift new file mode 100644 index 00000000..78a4d5c7 --- /dev/null +++ b/Meshtastic/Views/Nodes/Helpers/NodeMapControl.swift @@ -0,0 +1,8 @@ +// +// NodeMapControl.swift +// Meshtastic +// +// Created by Garth Vander Houwen on 9/9/23. +// + +import Foundation diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index e949b7a2..3ab4a478 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -13,9 +13,6 @@ import CoreLocation struct NodeList: View { - init () { - //self.bleManager.context = context - } @State private var searchText = "" var nodesQuery: Binding { Binding { @@ -123,7 +120,9 @@ struct NodeList: View { MeshtasticLogo() ) .onAppear { - // self.bleManager.context = context + if self.bleManager.context == nil { + self.bleManager.context = context + } } } detail: { if let node = selection { diff --git a/Meshtastic/Views/Nodes/NodeListSplit.swift b/Meshtastic/Views/Nodes/NodeListSplit.swift index a83667d1..6ac85836 100644 --- a/Meshtastic/Views/Nodes/NodeListSplit.swift +++ b/Meshtastic/Views/Nodes/NodeListSplit.swift @@ -7,9 +7,22 @@ import SwiftUI import CoreLocation +enum SelectedDetail { + case positionLog + case nodeMap + case deviceMetricsLog + case environmentMetricsLog + case detectionSensorLog +} + struct NodeListSplit: View { + // Layout variables @State private var columnVisibility = NavigationSplitViewVisibility.all + @State private var selectedNode: NodeInfoEntity? + @State private var selectedDetail: SelectedDetail? + + @SceneStorage("selectedDetailView") var selectedDetailView: String? @State private var searchText = "" var nodesQuery: Binding { @@ -30,14 +43,14 @@ struct NodeListSplit: View { private var nodes: FetchedResults - @State private var selection: NodeInfoEntity? // Nothing selected by default. + var body: some View { NavigationSplitView(columnVisibility: $columnVisibility) { let connectedNodeNum = Int(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral?.num ?? 0 : 0) let connectedNode = nodes.first(where: { $0.num == connectedNodeNum }) - List(nodes, id: \.self, selection: $selection) { node in + List(nodes, id: \.self, selection: $selectedNode) { node in NodeListItem(node: node, connected: bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral?.num ?? -1 == node.num, connectedNode: (bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral?.num ?? -1 : -1), modemPreset: Int(connectedNode?.loRaConfig?.modemPreset ?? 0)) } @@ -50,7 +63,7 @@ struct NodeListSplit: View { ) } content: { - if let node = selection { + if let node = selectedNode { NodeDetailItem(node: node) } else { @@ -61,6 +74,11 @@ struct NodeListSplit: View { Text("Content") } .navigationSplitViewStyle(.balanced) + .onAppear { + if self.bleManager.context == nil { + self.bleManager.context = context + } + } // } detail: { // VStack { diff --git a/Meshtastic/Views/Nodes/PositionLog.swift b/Meshtastic/Views/Nodes/PositionLog.swift index 2322a8d2..2100f955 100644 --- a/Meshtastic/Views/Nodes/PositionLog.swift +++ b/Meshtastic/Views/Nodes/PositionLog.swift @@ -17,12 +17,19 @@ struct PositionLog: View { } @State var isExporting = false @State var exportString = "" - var node: NodeInfoEntity + @ObservedObject var node: NodeInfoEntity @State private var isPresentingClearLogConfirm = false @State private var sortOrder = [KeyPathComparator(\PositionEntity.time)] var body: some View { NavigationStack { + + + if node.hasPositions { + + } else { + Text("Node has no positions.") + } let localeDateFormat = DateFormatter.dateFormat(fromTemplate: "yyMMddjmma", options: 0, locale: Locale.current) let dateFormatString = (localeDateFormat ?? "MM/dd/YY j:mma").replacingOccurrences(of: ",", with: "") if UIDevice.current.userInterfaceIdiom == .pad && !useGrid || UIDevice.current.userInterfaceIdiom == .mac { @@ -159,12 +166,15 @@ struct PositionLog: View { ) } .navigationTitle("Position Log \(node.positions?.count ?? 0) Points") - .navigationBarItems(trailing: - ZStack { - ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?") + .navigationBarItems( + trailing: + ZStack { + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?") }) .onAppear { - self.bleManager.context = context + if self.bleManager.context == nil { + self.bleManager.context = context + } } } }