From 6b10e9aabeeb6f15c1b7957075f98fbf4a174393 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 28 Jun 2022 06:56:50 -0700 Subject: [PATCH 1/2] Assorted updates --- Meshtastic.xcodeproj/project.pbxproj | 2 +- Meshtastic/Helpers/BLEManager.swift | 35 ++++++++ Meshtastic/Helpers/MeshPackets.swift | 18 ++--- .../contents | 10 +-- Meshtastic/MeshtasticApp.swift | 7 +- .../Views/Settings/Config/DisplayConfig.swift | 1 - .../Views/Settings/Config/LoRaConfig.swift | 7 +- .../Config/Module/RangeTestConfig.swift | 81 ++++++++++++++++++- .../Settings/Config/PositionConfig.swift | 18 ++--- Meshtastic/Views/Settings/Settings.swift | 36 +++++---- Meshtastic/Views/Settings/UserConfig.swift | 8 +- 11 files changed, 166 insertions(+), 57 deletions(-) diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 3a822d45..47d5cc4f 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -243,8 +243,8 @@ DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */, DD8169FE272476C700F4AB02 /* LogDocument.swift */, DD6B85A728009258000ACD6B /* ShareChannel.swift */, - DD61937A2863876A00E59241 /* Config */, DDCE4E2B2869F92900BE9F8F /* UserConfig.swift */, + DD61937A2863876A00E59241 /* Config */, ); path = Settings; sourceTree = ""; diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index bf283cf8..94841e7a 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -1037,4 +1037,39 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph return false } + + public func saveRangeTestModuleConfig(config: ModuleConfig.RangeTestConfig, destNum: Int64, wantResponse: Bool) -> Bool { + + var adminPacket = AdminMessage() + adminPacket.setModuleConfig.rangeTest = config + + var meshPacket: MeshPacket = MeshPacket() + meshPacket.to = UInt32(connectedPeripheral.num) + meshPacket.from = 0 //UInt32(connectedPeripheral.num) + meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. MyInfoEntity? { let fetchMyInfoRequest: NSFetchRequest = NSFetchRequest.init(entityName: "MyInfoEntity") diff --git a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents index db1356bd..a9000be5 100644 --- a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents +++ b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents @@ -104,7 +104,7 @@ - + @@ -136,16 +136,16 @@ + + + + - - - - \ No newline at end of file diff --git a/Meshtastic/MeshtasticApp.swift b/Meshtastic/MeshtasticApp.swift index 681c36a6..29071654 100644 --- a/Meshtastic/MeshtasticApp.swift +++ b/Meshtastic/MeshtasticApp.swift @@ -19,7 +19,8 @@ struct MeshtasticAppleApp: App { .environment(\.managedObjectContext, persistenceController.container.viewContext) .environmentObject(bleManager) .environmentObject(userSettings) - .onOpenURL(perform: { (url) in + .onOpenURL(perform: { (url) in + //we are expecting a .mbtiles map file that contains raster data //save it to the documents directory, and name it offline_map.mbtiles let fileManager = FileManager.default @@ -43,9 +44,7 @@ struct MeshtasticAppleApp: App { } else { print("💥 Didn't save the map file") } - - } - ) + }) } .onChange(of: scenePhase) { (newScenePhase) in switch newScenePhase { diff --git a/Meshtastic/Views/Settings/Config/DisplayConfig.swift b/Meshtastic/Views/Settings/Config/DisplayConfig.swift index 7192dac0..9cc4e1b6 100644 --- a/Meshtastic/Views/Settings/Config/DisplayConfig.swift +++ b/Meshtastic/Views/Settings/Config/DisplayConfig.swift @@ -153,7 +153,6 @@ struct DisplayConfig: View { Text("How long the screen remains on after the user button is pressed or messages are received.") .font(.caption) - .listRowSeparator(.visible) Picker("Carousel Interval", selection: $screenCarouselInterval ) { ForEach(ScreenCarouselSeconds.allCases) { scs in diff --git a/Meshtastic/Views/Settings/Config/LoRaConfig.swift b/Meshtastic/Views/Settings/Config/LoRaConfig.swift index c1da8dfb..be7d8a59 100644 --- a/Meshtastic/Views/Settings/Config/LoRaConfig.swift +++ b/Meshtastic/Views/Settings/Config/LoRaConfig.swift @@ -297,9 +297,12 @@ struct LoRaConfig: View { } .onChange(of: region) { newRegion in - if newRegion != node.loRaConfig!.regionCode { + if node.loRaConfig != nil { - hasChanges = true + if newRegion != node.loRaConfig!.regionCode { + + hasChanges = true + } } } .onChange(of: modemPreset) { newModemPreset in diff --git a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift index 03851530..7ef25bf5 100644 --- a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift @@ -11,6 +11,12 @@ struct RangeTestConfig: View { @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager + var node: NodeInfoEntity + + @State private var isPresentingSaveConfirm: Bool = false + @State var initialLoad: Bool = true + @State var hasChanges = false + @State var enabled = false @State var sender = false @State var save = false @@ -46,7 +52,46 @@ struct RangeTestConfig: View { Text("Saves a CSV with the range test message details, only available on ESP32 devices with a web server.") .font(.caption) } + } + + Button { + + isPresentingSaveConfirm = true + + } label: { + + Label("Save", systemImage: "square.and.arrow.down") + } + .disabled(bleManager.connectedPeripheral == nil || !hasChanges) + .buttonStyle(.bordered) + .buttonBorderShape(.capsule) + .controlSize(.large) + .padding() + .confirmationDialog( + + "Are you sure?", + isPresented: $isPresentingSaveConfirm + ) { + Button("Save Range Test Module Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") { + + var rtc = ModuleConfig.RangeTestConfig() + rtc.enabled = enabled + rtc.save = save + rtc.sender = sender ? 1 : 0 + + if bleManager.saveRangeTestModuleConfig(config: rtc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) { + + // Should show a saved successfully alert once I know that to be true + // for now just disable the button after a successful save + hasChanges = false + + } else { + + } + } + } + .navigationTitle("Range Test Config") .navigationBarItems(trailing: @@ -56,7 +101,41 @@ struct RangeTestConfig: View { }) .onAppear { - self.bleManager.context = context + if self.initialLoad{ + + self.bleManager.context = context + self.enabled = node.rangeTestConfig?.enabled ?? false + self.save = node.rangeTestConfig?.save ?? false + + if node.rangeTestConfig?.sender != nil { + + self.sender = node.rangeTestConfig!.sender == 1 ? true : false + + } else { + self.sender = false + } + self.sender = node.rangeTestConfig?.sender != nil + self.hasChanges = false + self.initialLoad = false + } + } + .onChange(of: enabled) { newEnabled in + + if newEnabled != node.rangeTestConfig!.enabled { + + hasChanges = true + } + } + .onChange(of: save) { newSave in + + if newSave != node.rangeTestConfig!.save { + + hasChanges = true + } + } + .onChange(of: sender) { newSender in + + hasChanges = true } .navigationViewStyle(StackNavigationViewStyle()) } diff --git a/Meshtastic/Views/Settings/Config/PositionConfig.swift b/Meshtastic/Views/Settings/Config/PositionConfig.swift index 94ee8d03..ae44be5e 100644 --- a/Meshtastic/Views/Settings/Config/PositionConfig.swift +++ b/Meshtastic/Views/Settings/Config/PositionConfig.swift @@ -192,20 +192,16 @@ struct PositionConfig: View { Label("Smart Position Broadcast", systemImage: "location.fill.viewfinder") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) - if !smartPositionEnabled { - Picker("Position Broadcast Interval", selection: $positionBroadcastSeconds) { - ForEach(PositionBroadcastIntervals.allCases) { at in - Text(at.description) - } + Picker("Position Broadcast Interval", selection: $positionBroadcastSeconds) { + ForEach(PositionBroadcastIntervals.allCases) { at in + Text(at.description) } - .pickerStyle(DefaultPickerStyle()) - - Text("We should send our position this often (but only if it has changed significantly)") - .font(.caption) - .listRowSeparator(.visible) - } + .pickerStyle(DefaultPickerStyle()) + + Text("We should send our position this often (but only if it has changed significantly)") + .font(.caption) } Section(header: Text("Position Flags - Non Functional")) { diff --git a/Meshtastic/Views/Settings/Settings.swift b/Meshtastic/Views/Settings/Settings.swift index 17c1d11e..98d6f26d 100644 --- a/Meshtastic/Views/Settings/Settings.swift +++ b/Meshtastic/Views/Settings/Settings.swift @@ -34,6 +34,14 @@ struct Settings: View { .symbolRenderingMode(.hierarchical) Text("App Settings") } + Text("Apple app specific settings and features, app username, share position with mesh options, map and keyboard type, mesh log.") + .font(.caption) + .fixedSize(horizontal: false, vertical: true) + + } + + Section("Radio Configuration") { + NavigationLink { ShareChannel() } label: { @@ -41,13 +49,9 @@ struct Settings: View { .symbolRenderingMode(.hierarchical) Text("Share Channel QR Code") } - } - - Section("Radio Configuration") { Text("Radio config views will be be enabled when there is a connected node. Save buttons will be enabled when there are config changes to save.") .font(.caption) - .listRowSeparator(.visible) .fixedSize(horizontal: false, vertical: true) NavigationLink { @@ -110,15 +114,15 @@ struct Settings: View { } Section("Module Configuration - Non Functional interaction preview.") { -// NavigationLink { -// PositionConfig(node: nodes.first(where: { $0.num == connectedNodeNum }) ?? NodeInfoEntity()) -// } label: { -// -// Image(systemName: "list.bullet.rectangle.fill") -// .symbolRenderingMode(.hierarchical) -// -// Text("Canned Messages") -// } + NavigationLink { + PositionConfig(node: nodes.first(where: { $0.num == connectedNodeNum }) ?? NodeInfoEntity()) + } label: { + + Image(systemName: "list.bullet.rectangle.fill") + .symbolRenderingMode(.hierarchical) + + Text("Canned Messages") + } NavigationLink { ExternalNotificationConfig(node: nodes.first(where: { $0.num == connectedNodeNum }) ?? NodeInfoEntity()) @@ -131,15 +135,15 @@ struct Settings: View { } NavigationLink { - RangeTestConfig() + RangeTestConfig(node: nodes.first(where: { $0.num == connectedNodeNum }) ?? NodeInfoEntity()) } label: { Image(systemName: "point.3.connected.trianglepath.dotted") .symbolRenderingMode(.hierarchical) - Text("Range Test") + Text("Range Test (ESP32 Only)") } - //.disabled(!(nodes.first(where: { $0.num == connectedNodeNum })?.myInfo?.hasWifi ?? true) || bleManager.connectedPeripheral == nil) + .disabled(!(nodes.first(where: { $0.num == connectedNodeNum })?.myInfo?.hasWifi ?? true) || bleManager.connectedPeripheral == nil) NavigationLink { SerialConfig() diff --git a/Meshtastic/Views/Settings/UserConfig.swift b/Meshtastic/Views/Settings/UserConfig.swift index a580da78..1def1199 100644 --- a/Meshtastic/Views/Settings/UserConfig.swift +++ b/Meshtastic/Views/Settings/UserConfig.swift @@ -68,16 +68,18 @@ struct UserConfig: View { } .keyboardType(.default) .disableAutocorrection(true) - .listRowSeparator(.visible) + Text("Long name can me 40 bytes long.") + .font(.caption) HStack { Label("Short Name", systemImage: "circlebadge.fill") TextField("Long Name", text: $shortName) .foregroundColor(.gray) } - .keyboardType(.default) + .keyboardType(.asciiCapable) .disableAutocorrection(true) - .listRowSeparator(.visible) + Text("The short name is used in maps and messaging and will be appended to the last 4 of the device MAC address to set the device's BLE Name. It can be up to 5 bytes long.") + .font(.caption) } From d36c4e94eaae3740a4772a6c01c65afd62f6b340 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 28 Jun 2022 20:20:02 -0700 Subject: [PATCH 2/2] Build for associated domains --- Meshtastic.xcodeproj/project.pbxproj | 8 +++ Meshtastic/Helpers/BLEManager.swift | 70 +++++++++++++++++++ Meshtastic/Meshtastic.entitlements | 2 +- Meshtastic/MeshtasticApp.swift | 14 ++++ .../Config/Module/InputBrokerConfig.swift | 8 +++ .../Config/Module/RangeTestConfig.swift | 30 ++++---- .../Settings/Config/Module/SerialConfig.swift | 48 +++++++++++++ .../Config/Module/StoreForwaredConfig.swift | 8 +++ Meshtastic/Views/Settings/Settings.swift | 19 ++++- 9 files changed, 189 insertions(+), 18 deletions(-) create mode 100644 Meshtastic/Views/Settings/Config/Module/InputBrokerConfig.swift create mode 100644 Meshtastic/Views/Settings/Config/Module/StoreForwaredConfig.swift diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 47d5cc4f..fc609027 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -70,6 +70,8 @@ DDC3B274283F411B00AC321C /* LastHeardText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC3B273283F411B00AC321C /* LastHeardText.swift */; }; DDC4D568275499A500A4208E /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC4D567275499A500A4208E /* Persistence.swift */; }; DDCE4E2C2869F92900BE9F8F /* UserConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCE4E2B2869F92900BE9F8F /* UserConfig.swift */; }; + DDCE4E2E286B7BC400BE9F8F /* StoreForwaredConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCE4E2D286B7BC400BE9F8F /* StoreForwaredConfig.swift */; }; + DDCE4E30286B7BD800BE9F8F /* InputBrokerConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCE4E2F286B7BD800BE9F8F /* InputBrokerConfig.swift */; }; DDCFF601285453A7005FA625 /* localonly.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCFF600285453A7005FA625 /* localonly.pb.swift */; }; DDD94A502845C8F5004A87A0 /* DateTimeText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD94A4F2845C8F5004A87A0 /* DateTimeText.swift */; }; DDD9E4E4284B208E003777C5 /* UserEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD9E4E3284B208E003777C5 /* UserEntityExtension.swift */; }; @@ -165,6 +167,8 @@ DDC3B273283F411B00AC321C /* LastHeardText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastHeardText.swift; sourceTree = ""; }; DDC4D567275499A500A4208E /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; DDCE4E2B2869F92900BE9F8F /* UserConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserConfig.swift; sourceTree = ""; }; + DDCE4E2D286B7BC400BE9F8F /* StoreForwaredConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreForwaredConfig.swift; sourceTree = ""; }; + DDCE4E2F286B7BD800BE9F8F /* InputBrokerConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputBrokerConfig.swift; sourceTree = ""; }; DDCFF600285453A7005FA625 /* localonly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = localonly.pb.swift; sourceTree = ""; }; DDD94A4F2845C8F5004A87A0 /* DateTimeText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTimeText.swift; sourceTree = ""; }; DDD9E4E3284B208E003777C5 /* UserEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserEntityExtension.swift; sourceTree = ""; }; @@ -269,6 +273,8 @@ DD41582928585C32009B0E59 /* RangeTestConfig.swift */, DD6193782863875F00E59241 /* SerialConfig.swift */, DD415827285859C4009B0E59 /* TelemetryConfig.swift */, + DDCE4E2D286B7BC400BE9F8F /* StoreForwaredConfig.swift */, + DDCE4E2F286B7BD800BE9F8F /* InputBrokerConfig.swift */, ); path = Module; sourceTree = ""; @@ -636,6 +642,7 @@ C9A7BC1027759A9600760B50 /* PositionAnnotationView.swift in Sources */, DD882F5D2772E4640005BF05 /* Contacts.swift in Sources */, DD47E3CE26F103C600029299 /* NodeList.swift in Sources */, + DDCE4E30286B7BD800BE9F8F /* InputBrokerConfig.swift in Sources */, DD8EBF43285058FA00426DCA /* DisplayConfig.swift in Sources */, DD47E3D626F17ED900029299 /* CircleText.swift in Sources */, DDC2E18F26CE25FE0042C5E4 /* ContentView.swift in Sources */, @@ -665,6 +672,7 @@ DDAF8C6726ED0C8C0058C060 /* remote_hardware.pb.swift in Sources */, DDAF8C6526ED0A490058C060 /* channel.pb.swift in Sources */, DDC2E15826CE248E0042C5E4 /* MeshtasticApp.swift in Sources */, + DDCE4E2E286B7BC400BE9F8F /* StoreForwaredConfig.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 94841e7a..38615180 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -1038,6 +1038,41 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph return false } + public func getModuleConfig (configType: AdminMessage.ModuleConfigType, destNum: Int64, wantResponse: Bool) -> Bool { + + var adminPacket = AdminMessage() + adminPacket.getModuleConfigRequest = configType + + var meshPacket: MeshPacket = MeshPacket() + meshPacket.to = UInt32(connectedPeripheral.num) + meshPacket.from = 0 //UInt32(connectedPeripheral.num) + meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. Bool { var adminPacket = AdminMessage() @@ -1072,4 +1107,39 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph return false } + + public func saveSerialModuleConfig(config: ModuleConfig.SerialConfig, destNum: Int64, wantResponse: Bool) -> Bool { + + var adminPacket = AdminMessage() + adminPacket.setModuleConfig.serial = config + + var meshPacket: MeshPacket = MeshPacket() + meshPacket.to = UInt32(connectedPeripheral.num) + meshPacket.from = 0 //UInt32(connectedPeripheral.num) + meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. com.apple.developer.associated-domains - applinks:meshtastic.org/e/ + applinks:meshtastic.org/* com.apple.security.app-sandbox diff --git a/Meshtastic/MeshtasticApp.swift b/Meshtastic/MeshtasticApp.swift index 29071654..89be5a4d 100644 --- a/Meshtastic/MeshtasticApp.swift +++ b/Meshtastic/MeshtasticApp.swift @@ -19,8 +19,22 @@ struct MeshtasticAppleApp: App { .environment(\.managedObjectContext, persistenceController.container.viewContext) .environmentObject(bleManager) .environmentObject(userSettings) + .onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in + + print("Continue activity \(userActivity)") + guard let url = userActivity.webpageURL else { + return + } + + print("User wants to open URL: \(url)") + // TODO same handling as done in onOpenURL() + + } .onOpenURL(perform: { (url) in + print("URL OPENED") + print(url) + //we are expecting a .mbtiles map file that contains raster data //save it to the documents directory, and name it offline_map.mbtiles let fileManager = FileManager.default diff --git a/Meshtastic/Views/Settings/Config/Module/InputBrokerConfig.swift b/Meshtastic/Views/Settings/Config/Module/InputBrokerConfig.swift new file mode 100644 index 00000000..c57dc7c9 --- /dev/null +++ b/Meshtastic/Views/Settings/Config/Module/InputBrokerConfig.swift @@ -0,0 +1,8 @@ +// +// InputBrokerConfig.swift +// Meshtastic +// +// Created by Garth Vander Houwen on 6/28/22. +// + +import Foundation diff --git a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift index 7ef25bf5..efbf84cc 100644 --- a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift @@ -104,34 +104,34 @@ struct RangeTestConfig: View { if self.initialLoad{ self.bleManager.context = context - self.enabled = node.rangeTestConfig?.enabled ?? false - self.save = node.rangeTestConfig?.save ?? false - - if node.rangeTestConfig?.sender != nil { - - self.sender = node.rangeTestConfig!.sender == 1 ? true : false - - } else { - self.sender = false - } - self.sender = node.rangeTestConfig?.sender != nil +// self.enabled = node.rangeTestConfig?.enabled ?? false +// self.save = node.rangeTestConfig?.save ?? false +// +// if node.rangeTestConfig?.sender != nil { +// +// self.sender = node.rangeTestConfig!.sender == 1 ? true : false +// +// } else { +// self.sender = false +// } +// self.sender = node.rangeTestConfig?.sender != nil self.hasChanges = false self.initialLoad = false } } .onChange(of: enabled) { newEnabled in - if newEnabled != node.rangeTestConfig!.enabled { + //if newEnabled != node.rangeTestConfig!.enabled { hasChanges = true - } + //} } .onChange(of: save) { newSave in - if newSave != node.rangeTestConfig!.save { + //if newSave != node.rangeTestConfig!.save { hasChanges = true - } + //} } .onChange(of: sender) { newSender in diff --git a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift index ad855f57..fc44b6cd 100644 --- a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift @@ -127,6 +127,10 @@ struct SerialConfig: View { @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager + @State private var isPresentingSaveConfirm: Bool = false + @State var initialLoad: Bool = true + @State var hasChanges = false + @State var enabled = false @State var echo = false @State var rxd = 0 @@ -154,6 +158,8 @@ struct SerialConfig: View { Label("Echo", systemImage: "repeat") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + Text("If set, any packets you send will be echoed back to your device.") + .font(.caption) Picker("Baud Rate", selection: $baudRate ) { ForEach(SerialBaudRates.allCases) { sbr in @@ -168,6 +174,8 @@ struct SerialConfig: View { } } .pickerStyle(DefaultPickerStyle()) + Text("The amount of time to wait before we consider your packet as done.") + .font(.caption) Picker("Mode", selection: $mode ) { ForEach(SerialModeTypes.allCases) { smt in @@ -207,8 +215,48 @@ struct SerialConfig: View { } } .pickerStyle(DefaultPickerStyle()) + Text("Set the GPIO pins for RXD and TXD.") + .font(.caption) } } + + Button { + + isPresentingSaveConfirm = true + + } label: { + + Label("Save", systemImage: "square.and.arrow.down") + } + .disabled(bleManager.connectedPeripheral == nil || !hasChanges) + .buttonStyle(.bordered) + .buttonBorderShape(.capsule) + .controlSize(.large) + .padding() + .confirmationDialog( + + "Are you sure?", + isPresented: $isPresentingSaveConfirm + ) { + Button("Save Range Test Module Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") { + + var sc = ModuleConfig.SerialConfig() + sc.enabled = enabled + //sc.save = save + //sc.sender = sender ? 1 : 0 + + if bleManager.saveSerialModuleConfig(config: sc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) { + + // Should show a saved successfully alert once I know that to be true + // for now just disable the button after a successful save + hasChanges = false + + } else { + + } + } + } + .navigationTitle("Serial Config") .navigationBarItems(trailing: diff --git a/Meshtastic/Views/Settings/Config/Module/StoreForwaredConfig.swift b/Meshtastic/Views/Settings/Config/Module/StoreForwaredConfig.swift new file mode 100644 index 00000000..32f18fd2 --- /dev/null +++ b/Meshtastic/Views/Settings/Config/Module/StoreForwaredConfig.swift @@ -0,0 +1,8 @@ +// +// StoreForwaredConfig.swift +// Meshtastic +// +// Created by Garth Vander Houwen on 6/28/22. +// + +import Foundation diff --git a/Meshtastic/Views/Settings/Settings.swift b/Meshtastic/Views/Settings/Settings.swift index 98d6f26d..8f6947fa 100644 --- a/Meshtastic/Views/Settings/Settings.swift +++ b/Meshtastic/Views/Settings/Settings.swift @@ -17,7 +17,7 @@ struct Settings: View { sortDescriptors: [NSSortDescriptor(key: "lastHeard", ascending: false)], animation: .default) - private var nodes: FetchedResults + private var nodes: FetchedResults var body: some View { NavigationView { @@ -123,6 +123,7 @@ struct Settings: View { Text("Canned Messages") } + .disabled(bleManager.connectedPeripheral == nil) NavigationLink { ExternalNotificationConfig(node: nodes.first(where: { $0.num == connectedNodeNum }) ?? NodeInfoEntity()) @@ -143,7 +144,9 @@ struct Settings: View { Text("Range Test (ESP32 Only)") } - .disabled(!(nodes.first(where: { $0.num == connectedNodeNum })?.myInfo?.hasWifi ?? true) || bleManager.connectedPeripheral == nil) + .disabled(!(bleManager.connectedPeripheral == nil)) + //nodes.first(where: { $0.num == connectedNodeNum })?.myInfo?.hasWifi ?? true) || + // nodes.first(where: { $0.num == connectedNodeNum })!.rangeTestConfig != nil) NavigationLink { SerialConfig() @@ -174,6 +177,18 @@ struct Settings: View { } .listStyle(GroupedListStyle()) .navigationTitle("Settings") + .onAppear { + + // + + // let connectedNode = + +// if nodes.first(where: { $0.num == (bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.num : 0) })!.rangeTestConfig == nil { +// +// // We have no Range Test Config, go get it +// self.bleManager.getModuleConfig(configType: AdminMessage.ModuleConfigType.rangetestConfig, destNum: bleManager.connectedPeripheral.num, wantResponse: tr) +// } + } } } }