mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Merge pull request #259 from meshtastic/2.0.7_Working_Changes
2.0.7 Working Changes
This commit is contained in:
commit
7cab56f8da
22 changed files with 150 additions and 102 deletions
|
|
@ -979,7 +979,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.0.6;
|
||||
MARKETING_VERSION = 2.0.7;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
@ -1012,7 +1012,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.0.6;
|
||||
MARKETING_VERSION = 2.0.7;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
|
||||
self.connectedPeripheral = nil
|
||||
self.isConnecting = false
|
||||
self.isConnected = false
|
||||
self.isSubscribed = false
|
||||
if let e = error {
|
||||
// https://developer.apple.com/documentation/corebluetooth/cberror/code
|
||||
|
|
@ -501,11 +502,12 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
MeshLogger.log("ℹ️ MESH PACKET received for Simulator App UNHANDLED \(try! decodedInfo.packet.jsonString())")
|
||||
case .audioApp:
|
||||
MeshLogger.log("ℹ️ MESH PACKET received for Audio App UNHANDLED \(try! decodedInfo.packet.jsonString())")
|
||||
case .tracerouteApp:
|
||||
MeshLogger.log("ℹ️ MESH PACKET received for Trace Route App UNHANDLED \(try! decodedInfo.packet.jsonString())")
|
||||
case .UNRECOGNIZED(_):
|
||||
MeshLogger.log("ℹ️ MESH PACKET received for Other App UNHANDLED \(try! decodedInfo.packet.jsonString())")
|
||||
case .max:
|
||||
print("MAX PORT NUM OF 511")
|
||||
|
||||
}
|
||||
|
||||
// MARK: Check for an All / Broadcast User and delete it as a transition to multi channel
|
||||
|
|
|
|||
|
|
@ -815,6 +815,12 @@ struct Config {
|
|||
/// NUM_CHANNELS (Where num channels depends on the regulatory region).
|
||||
var channelNum: UInt32 = 0
|
||||
|
||||
///
|
||||
/// If true, duty cycle limits will be exceeded and thus you're possibly not following
|
||||
/// the local regulations if you're not a HAM.
|
||||
/// Has no effect if the duty cycle of the used region is 100%.
|
||||
var overrideDutyCycle: Bool = false
|
||||
|
||||
///
|
||||
/// For testing it is useful sometimes to force a node to never listen to
|
||||
/// particular other nodes (simulating radio out of range). All nodenums listed
|
||||
|
|
@ -1830,6 +1836,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
9: .standard(proto: "tx_enabled"),
|
||||
10: .standard(proto: "tx_power"),
|
||||
11: .standard(proto: "channel_num"),
|
||||
12: .standard(proto: "override_duty_cycle"),
|
||||
103: .standard(proto: "ignore_incoming"),
|
||||
]
|
||||
|
||||
|
|
@ -1850,6 +1857,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
case 9: try { try decoder.decodeSingularBoolField(value: &self.txEnabled) }()
|
||||
case 10: try { try decoder.decodeSingularInt32Field(value: &self.txPower) }()
|
||||
case 11: try { try decoder.decodeSingularUInt32Field(value: &self.channelNum) }()
|
||||
case 12: try { try decoder.decodeSingularBoolField(value: &self.overrideDutyCycle) }()
|
||||
case 103: try { try decoder.decodeRepeatedUInt32Field(value: &self.ignoreIncoming) }()
|
||||
default: break
|
||||
}
|
||||
|
|
@ -1890,6 +1898,9 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
if self.channelNum != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.channelNum, fieldNumber: 11)
|
||||
}
|
||||
if self.overrideDutyCycle != false {
|
||||
try visitor.visitSingularBoolField(value: self.overrideDutyCycle, fieldNumber: 12)
|
||||
}
|
||||
if !self.ignoreIncoming.isEmpty {
|
||||
try visitor.visitPackedUInt32Field(value: self.ignoreIncoming, fieldNumber: 103)
|
||||
}
|
||||
|
|
@ -1908,6 +1919,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
if lhs.txEnabled != rhs.txEnabled {return false}
|
||||
if lhs.txPower != rhs.txPower {return false}
|
||||
if lhs.channelNum != rhs.channelNum {return false}
|
||||
if lhs.overrideDutyCycle != rhs.overrideDutyCycle {return false}
|
||||
if lhs.ignoreIncoming != rhs.ignoreIncoming {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -968,6 +968,10 @@ struct Routing {
|
|||
/// (possibly due to bad channel permissions)
|
||||
case noResponse // = 8
|
||||
|
||||
///
|
||||
/// Cannot send currently because duty cycle regulations will be violated.
|
||||
case dutyCycleLimit // = 9
|
||||
|
||||
///
|
||||
/// The application layer service on the remote node received your request, but considered your request somehow invalid
|
||||
case badRequest // = 32
|
||||
|
|
@ -993,6 +997,7 @@ struct Routing {
|
|||
case 6: self = .noChannel
|
||||
case 7: self = .tooLarge
|
||||
case 8: self = .noResponse
|
||||
case 9: self = .dutyCycleLimit
|
||||
case 32: self = .badRequest
|
||||
case 33: self = .notAuthorized
|
||||
default: self = .UNRECOGNIZED(rawValue)
|
||||
|
|
@ -1010,6 +1015,7 @@ struct Routing {
|
|||
case .noChannel: return 6
|
||||
case .tooLarge: return 7
|
||||
case .noResponse: return 8
|
||||
case .dutyCycleLimit: return 9
|
||||
case .badRequest: return 32
|
||||
case .notAuthorized: return 33
|
||||
case .UNRECOGNIZED(let i): return i
|
||||
|
|
@ -1035,6 +1041,7 @@ extension Routing.Error: CaseIterable {
|
|||
.noChannel,
|
||||
.tooLarge,
|
||||
.noResponse,
|
||||
.dutyCycleLimit,
|
||||
.badRequest,
|
||||
.notAuthorized,
|
||||
]
|
||||
|
|
@ -2627,6 +2634,7 @@ extension Routing.Error: SwiftProtobuf._ProtoNameProviding {
|
|||
6: .same(proto: "NO_CHANNEL"),
|
||||
7: .same(proto: "TOO_LARGE"),
|
||||
8: .same(proto: "NO_RESPONSE"),
|
||||
9: .same(proto: "DUTY_CYCLE_LIMIT"),
|
||||
32: .same(proto: "BAD_REQUEST"),
|
||||
33: .same(proto: "NOT_AUTHORIZED"),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -241,14 +241,6 @@ struct ModuleConfig {
|
|||
/// Whether Audio is enabled
|
||||
var codec2Enabled: Bool = false
|
||||
|
||||
///
|
||||
/// ADC where Microphone is connected
|
||||
var micChan: UInt32 = 0
|
||||
|
||||
///
|
||||
/// DAC where Speaker is connected
|
||||
var ampPin: UInt32 = 0
|
||||
|
||||
///
|
||||
/// PTT Pin
|
||||
var pttPin: UInt32 = 0
|
||||
|
|
@ -257,6 +249,22 @@ struct ModuleConfig {
|
|||
/// The audio sample rate to use for codec2
|
||||
var bitrate: ModuleConfig.AudioConfig.Audio_Baud = .codec2Default
|
||||
|
||||
///
|
||||
/// I2S Word Select
|
||||
var i2SWs: UInt32 = 0
|
||||
|
||||
///
|
||||
/// I2S Data IN
|
||||
var i2SSd: UInt32 = 0
|
||||
|
||||
///
|
||||
/// I2S Data OUT
|
||||
var i2SDin: UInt32 = 0
|
||||
|
||||
///
|
||||
/// I2S Clock
|
||||
var i2SSck: UInt32 = 0
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
///
|
||||
|
|
@ -1057,10 +1065,12 @@ extension ModuleConfig.AudioConfig: SwiftProtobuf.Message, SwiftProtobuf._Messag
|
|||
static let protoMessageName: String = ModuleConfig.protoMessageName + ".AudioConfig"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "codec2_enabled"),
|
||||
2: .standard(proto: "mic_chan"),
|
||||
3: .standard(proto: "amp_pin"),
|
||||
4: .standard(proto: "ptt_pin"),
|
||||
5: .same(proto: "bitrate"),
|
||||
2: .standard(proto: "ptt_pin"),
|
||||
3: .same(proto: "bitrate"),
|
||||
4: .standard(proto: "i2s_ws"),
|
||||
5: .standard(proto: "i2s_sd"),
|
||||
6: .standard(proto: "i2s_din"),
|
||||
7: .standard(proto: "i2s_sck"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
|
|
@ -1070,10 +1080,12 @@ extension ModuleConfig.AudioConfig: SwiftProtobuf.Message, SwiftProtobuf._Messag
|
|||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularBoolField(value: &self.codec2Enabled) }()
|
||||
case 2: try { try decoder.decodeSingularUInt32Field(value: &self.micChan) }()
|
||||
case 3: try { try decoder.decodeSingularUInt32Field(value: &self.ampPin) }()
|
||||
case 4: try { try decoder.decodeSingularUInt32Field(value: &self.pttPin) }()
|
||||
case 5: try { try decoder.decodeSingularEnumField(value: &self.bitrate) }()
|
||||
case 2: try { try decoder.decodeSingularUInt32Field(value: &self.pttPin) }()
|
||||
case 3: try { try decoder.decodeSingularEnumField(value: &self.bitrate) }()
|
||||
case 4: try { try decoder.decodeSingularUInt32Field(value: &self.i2SWs) }()
|
||||
case 5: try { try decoder.decodeSingularUInt32Field(value: &self.i2SSd) }()
|
||||
case 6: try { try decoder.decodeSingularUInt32Field(value: &self.i2SDin) }()
|
||||
case 7: try { try decoder.decodeSingularUInt32Field(value: &self.i2SSck) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
|
@ -1083,27 +1095,35 @@ extension ModuleConfig.AudioConfig: SwiftProtobuf.Message, SwiftProtobuf._Messag
|
|||
if self.codec2Enabled != false {
|
||||
try visitor.visitSingularBoolField(value: self.codec2Enabled, fieldNumber: 1)
|
||||
}
|
||||
if self.micChan != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.micChan, fieldNumber: 2)
|
||||
}
|
||||
if self.ampPin != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.ampPin, fieldNumber: 3)
|
||||
}
|
||||
if self.pttPin != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.pttPin, fieldNumber: 4)
|
||||
try visitor.visitSingularUInt32Field(value: self.pttPin, fieldNumber: 2)
|
||||
}
|
||||
if self.bitrate != .codec2Default {
|
||||
try visitor.visitSingularEnumField(value: self.bitrate, fieldNumber: 5)
|
||||
try visitor.visitSingularEnumField(value: self.bitrate, fieldNumber: 3)
|
||||
}
|
||||
if self.i2SWs != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.i2SWs, fieldNumber: 4)
|
||||
}
|
||||
if self.i2SSd != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.i2SSd, fieldNumber: 5)
|
||||
}
|
||||
if self.i2SDin != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.i2SDin, fieldNumber: 6)
|
||||
}
|
||||
if self.i2SSck != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.i2SSck, fieldNumber: 7)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: ModuleConfig.AudioConfig, rhs: ModuleConfig.AudioConfig) -> Bool {
|
||||
if lhs.codec2Enabled != rhs.codec2Enabled {return false}
|
||||
if lhs.micChan != rhs.micChan {return false}
|
||||
if lhs.ampPin != rhs.ampPin {return false}
|
||||
if lhs.pttPin != rhs.pttPin {return false}
|
||||
if lhs.bitrate != rhs.bitrate {return false}
|
||||
if lhs.i2SWs != rhs.i2SWs {return false}
|
||||
if lhs.i2SSd != rhs.i2SSd {return false}
|
||||
if lhs.i2SDin != rhs.i2SDin {return false}
|
||||
if lhs.i2SSck != rhs.i2SSck {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,6 +130,11 @@ enum PortNum: SwiftProtobuf.Enum {
|
|||
/// Project files at https://github.com/GUVWAF/Meshtasticator
|
||||
case simulatorApp // = 69
|
||||
|
||||
///
|
||||
/// Provides a traceroute functionality to show the route a packet towards
|
||||
/// a certain destination would take on the mesh.
|
||||
case tracerouteApp // = 70
|
||||
|
||||
///
|
||||
/// Private applications should use portnums >= 256.
|
||||
/// To simplify initial development and testing you can use "PRIVATE_APP"
|
||||
|
|
@ -169,6 +174,7 @@ enum PortNum: SwiftProtobuf.Enum {
|
|||
case 67: self = .telemetryApp
|
||||
case 68: self = .zpsApp
|
||||
case 69: self = .simulatorApp
|
||||
case 70: self = .tracerouteApp
|
||||
case 256: self = .privateApp
|
||||
case 257: self = .atakForwarder
|
||||
case 511: self = .max
|
||||
|
|
@ -196,6 +202,7 @@ enum PortNum: SwiftProtobuf.Enum {
|
|||
case .telemetryApp: return 67
|
||||
case .zpsApp: return 68
|
||||
case .simulatorApp: return 69
|
||||
case .tracerouteApp: return 70
|
||||
case .privateApp: return 256
|
||||
case .atakForwarder: return 257
|
||||
case .max: return 511
|
||||
|
|
@ -228,6 +235,7 @@ extension PortNum: CaseIterable {
|
|||
.telemetryApp,
|
||||
.zpsApp,
|
||||
.simulatorApp,
|
||||
.tracerouteApp,
|
||||
.privateApp,
|
||||
.atakForwarder,
|
||||
.max,
|
||||
|
|
@ -262,6 +270,7 @@ extension PortNum: SwiftProtobuf._ProtoNameProviding {
|
|||
67: .same(proto: "TELEMETRY_APP"),
|
||||
68: .same(proto: "ZPS_APP"),
|
||||
69: .same(proto: "SIMULATOR_APP"),
|
||||
70: .same(proto: "TRACEROUTE_APP"),
|
||||
256: .same(proto: "PRIVATE_APP"),
|
||||
257: .same(proto: "ATAK_FORWARDER"),
|
||||
511: .same(proto: "MAX"),
|
||||
|
|
|
|||
|
|
@ -46,7 +46,15 @@ struct Contacts: View {
|
|||
.padding(.trailing, 5)
|
||||
VStack {
|
||||
HStack {
|
||||
Text(String(channel.name ?? "Channel \(channel.index)").camelCaseToWords()).font(.headline)
|
||||
if channel.name?.isEmpty ?? false {
|
||||
if channel.role == 1 {
|
||||
Text(String("PrimaryChannel").camelCaseToWords()).font(.headline)
|
||||
} else {
|
||||
Text(String("Channel \(channel.index)").camelCaseToWords()).font(.headline)
|
||||
}
|
||||
} else {
|
||||
Text(String(channel.name ?? "Channel \(channel.index)").camelCaseToWords()).font(.headline)
|
||||
}
|
||||
Spacer()
|
||||
if channel.allPrivateMessages.count > 0 {
|
||||
VStack (alignment: .trailing) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ struct AboutMeshtastic: View {
|
|||
Link("GitHub Repository", destination: URL(string: "https://github.com/meshtastic/Meshtastic-Apple")!)
|
||||
.font(.title2)
|
||||
}
|
||||
if locale.region?.identifier == "US" {
|
||||
if locale.region?.identifier ?? "no locale" == "US" {
|
||||
Section(header: Text("Get Devices")) {
|
||||
Link("Buy Complete Radios", destination: URL(string: "https://www.etsy.com/shop/GarthVH")!)
|
||||
.font(.title2)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ struct BluetoothConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
|
@ -19,6 +20,8 @@ struct BluetoothConfig: View {
|
|||
@State var enabled = true
|
||||
@State var mode = 0
|
||||
@State var fixedPin = "123456"
|
||||
@State var shortPin = false
|
||||
var pinLength: Int = 6
|
||||
|
||||
let numberFormatter: NumberFormatter = {
|
||||
|
||||
|
|
@ -57,77 +60,66 @@ struct BluetoothConfig: View {
|
|||
TextField("Fixed PIN", text: $fixedPin)
|
||||
.foregroundColor(.gray)
|
||||
.onChange(of: fixedPin, perform: { value in
|
||||
|
||||
let digitCount = fixedPin.utf8.count
|
||||
// Only mess with the value if it is too big
|
||||
if digitCount > 6 || digitCount < 6 {
|
||||
|
||||
fixedPin = "123456"
|
||||
}
|
||||
|
||||
if digitCount < 6 {
|
||||
|
||||
fixedPin = "123456"
|
||||
//Require that pin is no more than 6 numbers and no less than 6 numbers
|
||||
if fixedPin.utf8.count == pinLength {
|
||||
shortPin = false
|
||||
} else if fixedPin.utf8.count > pinLength {
|
||||
shortPin = false
|
||||
fixedPin = String(fixedPin.prefix(pinLength))
|
||||
} else if fixedPin.utf8.count < pinLength {
|
||||
shortPin = true
|
||||
}
|
||||
})
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
.keyboardType(.decimalPad)
|
||||
if shortPin {
|
||||
|
||||
Text("BLE Pin must be 6 digits long.")
|
||||
.font(.callout)
|
||||
.foregroundColor(.red)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil)
|
||||
|
||||
Button {
|
||||
|
||||
isPresentingSaveConfirm = true
|
||||
|
||||
} label: {
|
||||
|
||||
Label("Save", systemImage: "square.and.arrow.down")
|
||||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil || !hasChanges)
|
||||
.disabled(bleManager.connectedPeripheral == nil || !hasChanges || shortPin)
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
.controlSize(.large)
|
||||
.padding()
|
||||
.confirmationDialog(
|
||||
|
||||
"Are you sure you want to save?",
|
||||
isPresented: $isPresentingSaveConfirm,
|
||||
titleVisibility: .visible
|
||||
) {
|
||||
Button("Save Config for \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")") {
|
||||
|
||||
var bc = Config.BluetoothConfig()
|
||||
bc.enabled = enabled
|
||||
bc.mode = BluetoothModes(rawValue: mode)?.protoEnumValue() ?? Config.BluetoothConfig.PairingMode.randomPin
|
||||
bc.fixedPin = UInt32(fixedPin) ?? 123456
|
||||
|
||||
let adminMessageId = bleManager.saveBluetoothConfig(config: bc, fromUser: node!.user!, toUser: node!.user!)
|
||||
|
||||
if adminMessageId > 0 {
|
||||
|
||||
// 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 {
|
||||
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
|
||||
} message: {
|
||||
|
||||
Text("After bluetooth config saves the node will reboot.")
|
||||
}
|
||||
}
|
||||
.navigationTitle("Bluetooth (BLE) Config")
|
||||
.navigationBarItems(trailing:
|
||||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
self.bleManager.context = context
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ struct DeviceConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
|
@ -165,15 +166,11 @@ struct DeviceConfig: View {
|
|||
dc.buzzerGpio = UInt32(buzzerGPIO)
|
||||
|
||||
let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: node!.user!, toUser: node!.user!)
|
||||
|
||||
if adminMessageId > 0 {
|
||||
|
||||
// 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 {
|
||||
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ struct DisplayConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
|
@ -115,9 +116,7 @@ struct DisplayConfig: View {
|
|||
// 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 {
|
||||
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ struct LoRaConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
|
@ -83,16 +84,12 @@ struct LoRaConfig: View {
|
|||
lc.txEnabled = true
|
||||
let adminMessageId = bleManager.saveLoRaConfig(config: lc, fromUser: node!.user!, toUser: node!.user!)
|
||||
if adminMessageId > 0 {
|
||||
|
||||
// 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 {
|
||||
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
|
||||
} message: {
|
||||
Text("After LoRa config saves the node will reboot.")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ struct CannedMessagesConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
|
@ -251,6 +252,7 @@ struct CannedMessagesConfig: View {
|
|||
// 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
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
if hasMessagesChanges {
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ struct ExternalNotificationConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
|
@ -148,8 +149,7 @@ struct ExternalNotificationConfig: View {
|
|||
// 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 {
|
||||
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ struct MQTTConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
var node: NodeInfoEntity?
|
||||
@State private var isPresentingSaveConfirm: Bool = false
|
||||
@State var hasChanges: Bool = false
|
||||
|
|
@ -103,8 +104,6 @@ struct MQTTConfig: View {
|
|||
}
|
||||
.keyboardType(.default)
|
||||
.scrollDismissesKeyboard(.interactively)
|
||||
|
||||
|
||||
HStack {
|
||||
Label("Password", systemImage: "wallet.pass")
|
||||
TextField("Server Password", text: $password)
|
||||
|
|
@ -153,13 +152,11 @@ struct MQTTConfig: View {
|
|||
.controlSize(.large)
|
||||
.padding()
|
||||
.confirmationDialog(
|
||||
|
||||
"Are you sure?",
|
||||
isPresented: $isPresentingSaveConfirm,
|
||||
titleVisibility: .visible
|
||||
) {
|
||||
Button("Save MQTT Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") {
|
||||
|
||||
var mqtt = ModuleConfig.MQTTConfig()
|
||||
mqtt.enabled = self.enabled
|
||||
mqtt.address = self.address
|
||||
|
|
@ -167,17 +164,12 @@ struct MQTTConfig: View {
|
|||
mqtt.password = self.password
|
||||
mqtt.encryptionEnabled = self.encryptionEnabled
|
||||
mqtt.jsonEnabled = self.jsonEnabled
|
||||
|
||||
let adminMessageId = bleManager.saveMQTTConfig(config: mqtt, fromUser: node!.user!, toUser: node!.user!)
|
||||
|
||||
if adminMessageId > 0 {
|
||||
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
self.hasChanges = false
|
||||
|
||||
} else {
|
||||
|
||||
hasChanges = false
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ struct RangeTestConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
|
@ -89,7 +90,7 @@ struct RangeTestConfig: View {
|
|||
} label: {
|
||||
Label("Save", systemImage: "square.and.arrow.down")
|
||||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil || !hasChanges || !(node!.myInfo?.hasWifi ?? false))
|
||||
.disabled(bleManager.connectedPeripheral == nil || !hasChanges || !(node?.myInfo?.hasWifi ?? false))
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
.controlSize(.large)
|
||||
|
|
@ -109,8 +110,7 @@ struct RangeTestConfig: View {
|
|||
// 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 {
|
||||
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ struct SerialConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
|
@ -142,9 +143,7 @@ struct SerialConfig: View {
|
|||
// 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 {
|
||||
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ struct TelemetryConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
|
@ -148,8 +149,7 @@ struct TelemetryConfig: View {
|
|||
// 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 {
|
||||
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ struct NetworkConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
|
@ -119,10 +120,8 @@ struct NetworkConfig: View {
|
|||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
self.hasChanges = false
|
||||
|
||||
} else {
|
||||
|
||||
hasChanges = false
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
} message: {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ struct PositionConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
|
@ -234,6 +235,7 @@ struct PositionConfig: View {
|
|||
// 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
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ struct ShareChannels: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@State var channelSet: ChannelSet = ChannelSet()
|
||||
@State var includeChannel0 = true
|
||||
@State var includeChannel1 = true
|
||||
|
|
@ -48,8 +49,6 @@ struct ShareChannels: View {
|
|||
var qrCodeImage = QrCodeImage()
|
||||
|
||||
var body: some View {
|
||||
|
||||
// VStack {
|
||||
GeometryReader { bounds in
|
||||
let smallest = min(bounds.size.width, bounds.size.height)
|
||||
ScrollView {
|
||||
|
|
@ -218,8 +217,6 @@ struct ShareChannels: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//}
|
||||
}
|
||||
.sheet(isPresented: $isPresentingHelp) {
|
||||
VStack {
|
||||
|
|
@ -244,6 +241,18 @@ struct ShareChannels: View {
|
|||
.padding()
|
||||
.presentationDetents([.large])
|
||||
.presentationDragIndicator(.automatic)
|
||||
|
||||
#if targetEnvironment(macCatalyst)
|
||||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Label("Close", systemImage: "xmark")
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
.controlSize(.large)
|
||||
.padding()
|
||||
#endif
|
||||
}
|
||||
.navigationTitle("Generate QR Code")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
|
|
@ -263,7 +272,6 @@ struct ShareChannels: View {
|
|||
.onChange(of: includeChannel6) { includeCh6 in GenerateChannelSet() }
|
||||
.onChange(of: includeChannel7) { includeCh7 in GenerateChannelSet() }
|
||||
}
|
||||
// }
|
||||
}
|
||||
func GenerateChannelSet() {
|
||||
channelSet = ChannelSet()
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ struct UserConfig: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
|
@ -90,6 +91,7 @@ struct UserConfig: View {
|
|||
let adminMessageId = bleManager.saveUser(config: u, fromUser: node!.user!, toUser: node!.user!)
|
||||
if adminMessageId > 0 {
|
||||
hasChanges = false
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
} message: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue