mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Send user to set region on BLE connect if region is unset
This commit is contained in:
parent
8befd33bce
commit
0d1e92189e
7 changed files with 71 additions and 122 deletions
|
|
@ -30,7 +30,6 @@
|
|||
DD3CC6BE28E4CD9800FA9159 /* BatteryGauge.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3CC6BD28E4CD9800FA9159 /* BatteryGauge.swift */; };
|
||||
DD3CC6C028E7A60700FA9159 /* MessagingEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3CC6BF28E7A60700FA9159 /* MessagingEnums.swift */; };
|
||||
DD3CC6C228EB9D4900FA9159 /* UpdateCoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3CC6C128EB9D4900FA9159 /* UpdateCoreData.swift */; };
|
||||
DD4033C228B286B70096A444 /* Onboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4033C128B286B70096A444 /* Onboarding.swift */; };
|
||||
DD41582628582E9B009B0E59 /* DeviceConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD41582528582E9B009B0E59 /* DeviceConfig.swift */; };
|
||||
DD415828285859C4009B0E59 /* TelemetryConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD415827285859C4009B0E59 /* TelemetryConfig.swift */; };
|
||||
DD41582A28585C32009B0E59 /* RangeTestConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD41582928585C32009B0E59 /* RangeTestConfig.swift */; };
|
||||
|
|
@ -144,7 +143,6 @@
|
|||
DD3CC6BD28E4CD9800FA9159 /* BatteryGauge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryGauge.swift; sourceTree = "<group>"; };
|
||||
DD3CC6BF28E7A60700FA9159 /* MessagingEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagingEnums.swift; sourceTree = "<group>"; };
|
||||
DD3CC6C128EB9D4900FA9159 /* UpdateCoreData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateCoreData.swift; sourceTree = "<group>"; };
|
||||
DD4033C128B286B70096A444 /* Onboarding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Onboarding.swift; sourceTree = "<group>"; };
|
||||
DD41582528582E9B009B0E59 /* DeviceConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceConfig.swift; sourceTree = "<group>"; };
|
||||
DD415827285859C4009B0E59 /* TelemetryConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelemetryConfig.swift; sourceTree = "<group>"; };
|
||||
DD41582928585C32009B0E59 /* RangeTestConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RangeTestConfig.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -497,7 +495,6 @@
|
|||
children = (
|
||||
DD882F5C2772E4640005BF05 /* Contacts.swift */,
|
||||
DD1BF2F82776FE2E008C8D2F /* MessageList.swift */,
|
||||
DD4033C128B286B70096A444 /* Onboarding.swift */,
|
||||
);
|
||||
path = Messages;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -768,7 +765,6 @@
|
|||
DDA6B2E928419CF2003E8C16 /* MeshPackets.swift in Sources */,
|
||||
DDCE4E2C2869F92900BE9F8F /* UserConfig.swift in Sources */,
|
||||
DD6193752862F6E600E59241 /* ExternalNotificationConfig.swift in Sources */,
|
||||
DD4033C228B286B70096A444 /* Onboarding.swift in Sources */,
|
||||
DDB6ABE428B13FFF00384BA1 /* DisplayEnums.swift in Sources */,
|
||||
DD86D40A287F04F100BAEB7A /* InvalidVersion.swift in Sources */,
|
||||
DDD94A502845C8F5004A87A0 /* DateTimeText.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
@Published var isScanning: Bool = false
|
||||
@Published var isConnecting: Bool = false
|
||||
@Published var isConnected: Bool = false
|
||||
@Published var isSubscribed: Bool = false
|
||||
|
||||
/// Used to make sure we never get foold by old BLE packets
|
||||
private var configNonce: UInt32 = 1
|
||||
|
|
@ -184,6 +185,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
centralManager?.cancelPeripheralConnection(connectedPeripheral.peripheral)
|
||||
FROMRADIO_characteristic = nil
|
||||
isConnected = false
|
||||
isSubscribed = false
|
||||
invalidVersion = false
|
||||
connectedVersion = "0.0.0"
|
||||
startScanning()
|
||||
|
|
@ -199,7 +201,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
peripheralName = name
|
||||
}
|
||||
|
||||
let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: last4Code, longName: peripheralName, lastFourCode: last4Code, firmwareVersion: "Unknown", rssi: RSSI.intValue, bitrate: nil, channelUtilization: nil, airTime: nil, maxChannels: 0, lastUpdate: Date(), subscribed: false, peripheral: peripheral)
|
||||
let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: last4Code, longName: peripheralName, lastFourCode: last4Code, firmwareVersion: "Unknown", rssi: RSSI.intValue, bitrate: nil, channelUtilization: nil, airTime: nil, lastUpdate: Date(), peripheral: peripheral)
|
||||
let peripheralIndex = peripherals.firstIndex(where: { $0.id == newPeripheral.id })
|
||||
|
||||
if peripheralIndex != nil && newPeripheral.peripheral.state != CBPeripheralState.connected {
|
||||
|
|
@ -270,6 +272,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
self.startScanning()
|
||||
self.connectedPeripheral = nil
|
||||
self.isConnecting = false
|
||||
self.isSubscribed = false
|
||||
if let e = error {
|
||||
// https://developer.apple.com/documentation/corebluetooth/cberror/code
|
||||
let errorCode = (e as NSError).code
|
||||
|
|
@ -521,8 +524,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
self.connectedPeripheral.firmwareVersion = myInfo!.firmwareVersion ?? "Unknown"
|
||||
self.connectedPeripheral.name = myInfo!.bleName ?? "Unknown"
|
||||
self.connectedPeripheral.longName = myInfo!.bleName ?? "Unknown"
|
||||
self.connectedPeripheral.maxChannels = myInfo!.maxChannels
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -651,7 +652,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
invalidVersion = false
|
||||
lastConnectionError = ""
|
||||
MeshLogger.log("🤜 BLE Config Complete Packet Id: \(decodedInfo.configCompleteID)")
|
||||
self.connectedPeripheral.subscribed = true
|
||||
self.isSubscribed = true
|
||||
peripherals.removeAll(where: { $0.peripheral.state == CBPeripheralState.disconnected })
|
||||
// Config conplete returns so we don't read the characteristic again
|
||||
return
|
||||
|
|
|
|||
|
|
@ -13,12 +13,10 @@ struct Peripheral: Identifiable {
|
|||
var bitrate: Float?
|
||||
var channelUtilization: Float?
|
||||
var airTime: Float?
|
||||
var maxChannels: Int32
|
||||
var lastUpdate: Date
|
||||
var subscribed: Bool
|
||||
var peripheral: CBPeripheral
|
||||
|
||||
init(id: String, num: Int64, name: String, shortName: String, longName: String, lastFourCode: String, firmwareVersion: String, rssi: Int, bitrate: Float?, channelUtilization: Float?, airTime: Float?, maxChannels: Int32, lastUpdate: Date, subscribed: Bool, peripheral: CBPeripheral) {
|
||||
init(id: String, num: Int64, name: String, shortName: String, longName: String, lastFourCode: String, firmwareVersion: String, rssi: Int, bitrate: Float?, channelUtilization: Float?, airTime: Float?, lastUpdate: Date, peripheral: CBPeripheral) {
|
||||
self.id = id
|
||||
self.num = num
|
||||
self.name = name
|
||||
|
|
@ -30,9 +28,7 @@ struct Peripheral: Identifiable {
|
|||
self.bitrate = bitrate
|
||||
self.channelUtilization = channelUtilization
|
||||
self.airTime = airTime
|
||||
self.maxChannels = maxChannels
|
||||
self.lastUpdate = lastUpdate
|
||||
self.subscribed = subscribed
|
||||
self.peripheral = peripheral
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import SwiftUI
|
||||
import MapKit
|
||||
import CoreData
|
||||
import CoreLocation
|
||||
import CoreBluetooth
|
||||
|
||||
|
|
@ -15,58 +16,47 @@ struct Connect: View {
|
|||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@EnvironmentObject var userSettings: UserSettings
|
||||
@State var node: NodeInfoEntity? = nil
|
||||
|
||||
@State var isPreferredRadio: Bool = false
|
||||
|
||||
@State var isUnsetRegion = false
|
||||
@State var invalidFirmwareVersion = false
|
||||
|
||||
var body: some View {
|
||||
|
||||
NavigationStack {
|
||||
|
||||
VStack {
|
||||
|
||||
List {
|
||||
|
||||
if bleManager.isSwitchedOn {
|
||||
|
||||
Section(header: Text("Connected Radio").font(.title)) {
|
||||
|
||||
if bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.peripheral.state == .connected {
|
||||
|
||||
|
||||
HStack {
|
||||
|
||||
Image(systemName: "antenna.radiowaves.left.and.right")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.imageScale(.large).foregroundColor(.green)
|
||||
.padding(.trailing)
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
|
||||
if bleManager.connectedPeripheral != nil {
|
||||
|
||||
if node != nil {
|
||||
Text(bleManager.connectedPeripheral.longName).font(.title2)
|
||||
|
||||
}
|
||||
Text("BLE Name: ").font(.caption)+Text(bleManager.connectedPeripheral.peripheral.name ?? "Unknown")
|
||||
.font(.caption).foregroundColor(Color.gray)
|
||||
if bleManager.connectedPeripheral != nil {
|
||||
Text("FW Version: ").font(.caption)+Text(bleManager.connectedPeripheral.firmwareVersion)
|
||||
if node != nil {
|
||||
Text("FW Version: ").font(.caption)+Text(node?.myInfo?.firmwareVersion ?? "Unknown")
|
||||
.font(.caption).foregroundColor(Color.gray)
|
||||
}
|
||||
if bleManager.connectedPeripheral.subscribed {
|
||||
if bleManager.isSubscribed {
|
||||
Text("Subscribed to mesh").font(.caption)
|
||||
.foregroundColor(.green)
|
||||
} else {
|
||||
Text("Communicating with device. . . ").font(.caption)
|
||||
.foregroundColor(.orange)
|
||||
|
||||
}
|
||||
}
|
||||
Spacer()
|
||||
|
||||
VStack(alignment: .center) {
|
||||
|
||||
Text("Preferred").font(.caption2)
|
||||
Text("Radio").font(.caption2)
|
||||
Toggle("Preferred Radio", isOn: $bleManager.preferredPeripheral)
|
||||
|
|
@ -74,18 +64,12 @@ struct Connect: View {
|
|||
.labelsHidden()
|
||||
.onChange(of: bleManager.preferredPeripheral) { value in
|
||||
if value {
|
||||
|
||||
if bleManager.connectedPeripheral != nil {
|
||||
|
||||
|
||||
userSettings.preferredPeripheralId = bleManager.connectedPeripheral!.peripheral.identifier.uuidString
|
||||
userSettings.preferredNodeNum = bleManager.connectedPeripheral!.num
|
||||
bleManager.preferredPeripheral = true
|
||||
isPreferredRadio = true
|
||||
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
if bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.peripheral.identifier.uuidString == userSettings.preferredPeripheralId {
|
||||
|
|
@ -98,7 +82,6 @@ struct Connect: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.font(.caption).foregroundColor(Color.gray)
|
||||
.padding([.top, .bottom])
|
||||
|
|
@ -114,18 +97,32 @@ struct Connect: View {
|
|||
}
|
||||
}
|
||||
.contextMenu{
|
||||
|
||||
Text("Num: \(String(bleManager.connectedPeripheral.num))")
|
||||
Text("Short Name: \(bleManager.connectedPeripheral.shortName)")
|
||||
Text("Long Name: \(bleManager.connectedPeripheral.longName)")
|
||||
Text("Unique Code: \(bleManager.connectedPeripheral.lastFourCode)")
|
||||
Text("Max Channels: \(String(bleManager.connectedPeripheral.maxChannels))")
|
||||
Text("Bitrate: \(String(format: "%.2f", bleManager.connectedPeripheral.bitrate ?? 0.00))")
|
||||
Text("Ch. Utilization: \(String(format: "%.2f", bleManager.connectedPeripheral.channelUtilization ?? 0.00))")
|
||||
Text("Air Time: \(String(format: "%.2f", bleManager.connectedPeripheral.airTime ?? 0.00))")
|
||||
Text("BLE RSSI: \(bleManager.connectedPeripheral.rssi)")
|
||||
|
||||
if node != nil {
|
||||
|
||||
Text("Num: \(String(node!.num))")
|
||||
Text("Short Name: \(bleManager.connectedPeripheral.shortName)")
|
||||
Text("Long Name: \(bleManager.connectedPeripheral.longName)")
|
||||
Text("Unique Code: \(bleManager.connectedPeripheral.lastFourCode)")
|
||||
Text("Max Channels: \(String(node!.myInfo!.maxChannels))")
|
||||
Text("Bitrate: \(String(format: "%.2f", bleManager.connectedPeripheral.bitrate ?? 0.00))")
|
||||
Text("Ch. Utilization: \(String(format: "%.2f", bleManager.connectedPeripheral.channelUtilization ?? 0.00))")
|
||||
Text("Air Time: \(String(format: "%.2f", bleManager.connectedPeripheral.airTime ?? 0.00))")
|
||||
Text("BLE RSSI: \(bleManager.connectedPeripheral.rssi)")
|
||||
|
||||
}
|
||||
}
|
||||
if isUnsetRegion {
|
||||
HStack {
|
||||
NavigationLink {
|
||||
LoRaConfig(node: node)
|
||||
} label: {
|
||||
Label("Set LoRa Region", systemImage: "globe.americas.fill")
|
||||
.foregroundColor(.red)
|
||||
.font(.title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if bleManager.isConnecting {
|
||||
|
|
@ -269,14 +266,12 @@ struct Connect: View {
|
|||
.padding(.bottom, 10)
|
||||
}
|
||||
.navigationTitle("Bluetooth")
|
||||
|
||||
.navigationBarItems(leading: MeshtasticLogo(), trailing:
|
||||
ZStack {
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
}
|
||||
.sheet(isPresented: $invalidFirmwareVersion, onDismiss: didDismissSheet) {
|
||||
|
||||
InvalidVersion(minimumVersion: self.bleManager.minimumVersion, version: self.bleManager.connectedVersion)
|
||||
.presentationDetents([.large])
|
||||
.presentationDragIndicator(.automatic)
|
||||
|
|
@ -284,8 +279,31 @@ struct Connect: View {
|
|||
.onChange(of: (self.bleManager.invalidVersion)) { cv in
|
||||
invalidFirmwareVersion = self.bleManager.invalidVersion
|
||||
}
|
||||
.onChange(of: (self.bleManager.isSubscribed)) { sub in
|
||||
|
||||
if userSettings.preferredNodeNum > 0 && sub {
|
||||
|
||||
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
|
||||
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(userSettings.preferredNodeNum))
|
||||
|
||||
do {
|
||||
|
||||
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
|
||||
// Found a node, check it for a region
|
||||
if !fetchedNode.isEmpty {
|
||||
node = fetchedNode[0]
|
||||
if node!.loRaConfig != nil && node!.loRaConfig?.regionCode ?? 0 == RegionCodes.unset.rawValue {
|
||||
isUnsetRegion = true
|
||||
} else {
|
||||
isUnsetRegion = false
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear(perform: {
|
||||
|
||||
self.bleManager.context = context
|
||||
self.bleManager.userSettings = userSettings
|
||||
|
||||
|
|
@ -297,18 +315,8 @@ struct Connect: View {
|
|||
print(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
if self.bleManager.connectedPeripheral != nil {
|
||||
print(self.bleManager.connectedPeripheral.id)
|
||||
print(userSettings.preferredPeripheralId)
|
||||
}
|
||||
if self.bleManager.connectedPeripheral != nil && userSettings.preferredPeripheralId == self.bleManager.connectedPeripheral.id {
|
||||
isPreferredRadio = true
|
||||
if userSettings.preferredNodeNum > 0 {
|
||||
|
||||
print("I wanna set my prefered node")
|
||||
}
|
||||
|
||||
} else {
|
||||
isPreferredRadio = false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ struct Contacts: View {
|
|||
}
|
||||
HStack(alignment: .top) {
|
||||
Text("\(mostRecent != nil ? mostRecent!.messagePayload! : " ")")
|
||||
.frame(height: 60)
|
||||
.frame(height: 50)
|
||||
.truncationMode(.tail)
|
||||
.foregroundColor(Color.gray)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
|
@ -108,7 +108,7 @@ struct Contacts: View {
|
|||
}
|
||||
HStack(alignment: .top) {
|
||||
Text(" ")
|
||||
.frame(height: 60)
|
||||
.frame(height: 50 )
|
||||
.truncationMode(.tail)
|
||||
.foregroundColor(Color.gray)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
//
|
||||
// Onboarding.swift
|
||||
// Meshtastic
|
||||
//
|
||||
// Copyright(c) Garth Vander Houwen 8/21/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct Onboarding: View {
|
||||
|
||||
var body: some View {
|
||||
|
||||
VStack {
|
||||
|
||||
Text("🗺️ Set Your Region to Mesh and Message")
|
||||
.font(.largeTitle)
|
||||
.foregroundColor(.red)
|
||||
|
||||
Text("Your region is currently set to UNSET, please set your device to the appropriate region under Settings > LoRa, after you set your region your Meshtastic device will reboot.")
|
||||
.font(.callout)
|
||||
.padding()
|
||||
|
||||
NavigationLink() {
|
||||
|
||||
LoRaConfig(node: nil)
|
||||
|
||||
} label: {
|
||||
Image(systemName: "dot.radiowaves.left.and.right")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("LoRa")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,6 @@ struct DisplayConfig: View {
|
|||
var node: NodeInfoEntity?
|
||||
|
||||
@State private var isPresentingSaveConfirm: Bool = false
|
||||
@State var initialLoad: Bool = true
|
||||
@State var hasChanges = false
|
||||
|
||||
@State var screenOnSeconds = 0
|
||||
|
|
@ -116,50 +115,34 @@ struct DisplayConfig: View {
|
|||
}
|
||||
.navigationTitle("Display Config")
|
||||
.navigationBarItems(trailing:
|
||||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
if self.initialLoad{
|
||||
|
||||
self.bleManager.context = context
|
||||
|
||||
self.gpsFormat = Int(node?.displayConfig?.gpsFormat ?? 0)
|
||||
self.screenOnSeconds = Int(node?.displayConfig?.screenOnSeconds ?? 0)
|
||||
self.screenCarouselInterval = Int(node?.displayConfig?.screenCarouselInterval ?? 0)
|
||||
self.compassNorthTop = node?.displayConfig?.compassNorthTop ?? false
|
||||
self.hasChanges = false
|
||||
self.initialLoad = false
|
||||
}
|
||||
self.bleManager.context = context
|
||||
self.gpsFormat = Int(node?.displayConfig?.gpsFormat ?? 0)
|
||||
self.screenOnSeconds = Int(node?.displayConfig?.screenOnSeconds ?? 0)
|
||||
self.screenCarouselInterval = Int(node?.displayConfig?.screenCarouselInterval ?? 0)
|
||||
self.compassNorthTop = node?.displayConfig?.compassNorthTop ?? false
|
||||
self.hasChanges = false
|
||||
}
|
||||
.onChange(of: screenOnSeconds) { newScreenSecs in
|
||||
|
||||
if node != nil && node!.displayConfig != nil {
|
||||
|
||||
if newScreenSecs != node!.displayConfig!.screenOnSeconds { hasChanges = true }
|
||||
}
|
||||
}
|
||||
.onChange(of: screenCarouselInterval) { newCarouselSecs in
|
||||
|
||||
if node != nil && node!.displayConfig != nil {
|
||||
|
||||
if newCarouselSecs != node!.displayConfig!.screenCarouselInterval { hasChanges = true }
|
||||
}
|
||||
}
|
||||
.onChange(of: compassNorthTop) { newCompassNorthTop in
|
||||
|
||||
if node != nil && node!.displayConfig != nil {
|
||||
|
||||
if newCompassNorthTop != node!.displayConfig!.compassNorthTop { hasChanges = true }
|
||||
}
|
||||
}
|
||||
.onChange(of: gpsFormat) { newGpsFormat in
|
||||
|
||||
if node != nil && node!.displayConfig != nil {
|
||||
|
||||
if newGpsFormat != node!.displayConfig!.gpsFormat { hasChanges = true }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue