2022-08-18 08:46:10 -07:00
//
// B l u e t o o t h C o n f i g . s w i f t
// M e s h t a s t i c A p p l e
//
// C o p y r i g h t ( c ) G a r t h V a n d e r H o u w e n 8 / 1 8 / 2 2 .
//
import SwiftUI
struct BluetoothConfig : View {
@ Environment ( \ . managedObjectContext ) var context
@ EnvironmentObject var bleManager : BLEManager
2022-12-09 18:19:00 -08:00
@ Environment ( \ . dismiss ) private var goBack
2022-08-18 08:46:10 -07:00
var node : NodeInfoEntity ?
@ State private var isPresentingSaveConfirm : Bool = false
@ State var hasChanges = false
@ State var enabled = true
@ State var mode = 0
2022-08-20 12:15:14 -07:00
@ State var fixedPin = " 123456 "
2022-12-09 18:19:00 -08:00
@ State var shortPin = false
var pinLength : Int = 6
2022-08-20 12:15:14 -07:00
let numberFormatter : NumberFormatter = {
2022-09-10 17:38:10 -07:00
let formatter = NumberFormatter ( )
formatter . numberStyle = . none
2022-08-20 12:15:14 -07:00
return formatter
2022-09-10 17:38:10 -07:00
} ( )
2022-08-18 08:46:10 -07:00
var body : some View {
2022-12-30 11:08:59 -08:00
Form {
2023-03-13 19:17:43 -07:00
if node != nil && node ? . metadata = = nil && node ? . num ? ? 0 != bleManager . connectedPeripheral ? . num ? ? 0 {
Text ( " There has been no response to a request for device metadata over the admin channel for this node. " )
. font ( . callout )
. foregroundColor ( . orange )
2023-03-14 12:44:10 -07:00
2023-03-13 19:17:43 -07:00
} else if node != nil && node ? . num ? ? 0 != bleManager . connectedPeripheral ? . num ? ? 0 {
// L e t u s e r s k n o w w h a t i s g o i n g o n i f t h e y a r e u s i n g r e m o t e a d m i n a n d d o n ' t h a v e t h e c o n f i g y e t
2023-03-14 12:44:10 -07:00
if node ? . bluetoothConfig = = nil {
2023-03-13 19:17:43 -07:00
Text ( " Bluetooth config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log. " )
. font ( . callout )
. foregroundColor ( . orange )
} else {
Text ( " Remote administration for: \( node ? . user ? . longName ? ? " Unknown " ) " )
. font ( . title3 )
2023-03-19 18:37:23 -07:00
. onAppear {
setBluetoothValues ( )
}
2023-03-13 19:17:43 -07:00
}
2023-03-14 12:44:10 -07:00
} else if node != nil && node ? . num ? ? 0 = = bleManager . connectedPeripheral ? . num ? ? 0 {
2023-03-13 19:17:43 -07:00
Text ( " Configuration for: \( node ? . user ? . longName ? ? " Unknown " ) " )
. font ( . title3 )
} else {
Text ( " Please connect to a radio to configure settings. " )
. font ( . callout )
. foregroundColor ( . orange )
}
2022-12-30 11:08:59 -08:00
Section ( header : Text ( " options " ) ) {
Toggle ( isOn : $ enabled ) {
Label ( " enabled " , systemImage : " antenna.radiowaves.left.and.right " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
Picker ( " bluetooth.pairingmode " , selection : $ mode ) {
ForEach ( BluetoothModes . allCases ) { bm in
Text ( bm . description )
2022-08-18 08:46:10 -07:00
}
2022-12-30 11:08:59 -08:00
}
. pickerStyle ( DefaultPickerStyle ( ) )
if mode = = 1 {
HStack {
Label ( " bluetooth.mode.fixedpin " , systemImage : " wallet.pass " )
TextField ( " bluetooth.mode.fixedpin " , text : $ fixedPin )
. foregroundColor ( . gray )
2023-03-06 10:33:18 -08:00
. onChange ( of : fixedPin , perform : { _ in
2023-01-09 18:01:27 -08:00
// D o n ' t l e t t h e f i r s t c h a r a c t e r b e 0 b e c a u s e i t w i l l g e t s t r i p p e d w h e n s a v i n g a U I n t 3 2
if fixedPin . first = = " 0 " {
fixedPin = fixedPin . replacing ( " 0 " , with : " " )
}
2023-03-06 10:33:18 -08:00
// R e q u i r e t h a t p i n i s n o m o r e t h a n 6 n u m b e r s a n d n o l e s s t h a n 6 n u m b e r s
2022-12-30 11:08:59 -08:00
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 )
2022-08-18 08:46:10 -07:00
}
2022-12-30 11:08:59 -08:00
. keyboardType ( . decimalPad )
if shortPin {
2023-01-01 14:48:50 -08:00
Text ( " bluetooth.pin.validation " )
2022-12-30 11:08:59 -08:00
. font ( . callout )
. foregroundColor ( . red )
2022-08-18 08:46:10 -07:00
}
}
}
2022-12-30 11:08:59 -08:00
}
2023-01-31 22:59:43 -08:00
. disabled ( self . bleManager . connectedPeripheral = = nil || node ? . bluetoothConfig = = nil )
2022-12-30 11:08:59 -08:00
Button {
isPresentingSaveConfirm = true
} label : {
Label ( " save " , systemImage : " square.and.arrow.down " )
}
. disabled ( bleManager . connectedPeripheral = = nil || ! hasChanges || shortPin )
. buttonStyle ( . bordered )
. buttonBorderShape ( . capsule )
. controlSize ( . large )
. padding ( )
. confirmationDialog (
" are.you.sure " ,
isPresented : $ isPresentingSaveConfirm ,
titleVisibility : . visible
) {
2023-05-05 09:27:24 -07:00
let nodeName = node ? . user ? . longName ? ? " unknown " . localized
let buttonText = String . localizedStringWithFormat ( " save.config %@ " . localized , nodeName )
2023-01-09 18:34:43 -08:00
Button ( buttonText ) {
2023-01-31 22:08:03 -08:00
let connectedNode = getNodeInfo ( id : bleManager . connectedPeripheral . num , context : context )
2023-02-06 18:45:03 -08:00
if connectedNode != nil {
var bc = Config . BluetoothConfig ( )
bc . enabled = enabled
bc . mode = BluetoothModes ( rawValue : mode ) ? . protoEnumValue ( ) ? ? Config . BluetoothConfig . PairingMode . randomPin
bc . fixedPin = UInt32 ( fixedPin ) ? ? 123456
2023-03-15 09:27:33 -07:00
let adminMessageId = bleManager . saveBluetoothConfig ( config : bc , fromUser : connectedNode ! . user ! , toUser : node ! . user ! , adminIndex : connectedNode ? . myInfo ? . adminIndex ? ? 0 )
2023-02-06 18:45:03 -08:00
if adminMessageId > 0 {
// S h o u l d s h o w a s a v e d s u c c e s s f u l l y a l e r t o n c e I k n o w t h a t t o b e t r u e
// f o r n o w j u s t d i s a b l e t h e b u t t o n a f t e r a s u c c e s s f u l s a v e
hasChanges = false
goBack ( )
}
2022-08-18 08:46:10 -07:00
}
}
2022-12-30 11:08:59 -08:00
} message : {
Text ( " config.save.confirm " )
2022-08-18 08:46:10 -07:00
}
2022-12-13 07:49:46 -08:00
. navigationTitle ( " bluetooth.config " )
2022-08-18 08:46:10 -07:00
. navigationBarItems ( trailing :
ZStack {
2022-12-09 18:19:00 -08:00
ConnectedDevice ( bluetoothOn : bleManager . isSwitchedOn , deviceConnected : bleManager . connectedPeripheral != nil , name : ( bleManager . connectedPeripheral != nil ) ? bleManager . connectedPeripheral . shortName : " ???? " )
2022-08-18 08:46:10 -07:00
} )
. onAppear {
2022-11-12 08:48:01 -08:00
self . bleManager . context = context
2023-03-19 18:37:23 -07:00
setBluetoothValues ( )
2023-01-29 00:16:17 -08:00
// N e e d t o r e q u e s t a B l u e t o o t h C o n f i g f r o m t h e r e m o t e n o d e b e f o r e a l l o w i n g c h a n g e s
2023-02-03 10:15:11 -08:00
if bleManager . connectedPeripheral != nil && node ? . bluetoothConfig = = nil {
2023-01-31 22:08:03 -08:00
print ( " empty bluetooth config " )
let connectedNode = getNodeInfo ( id : bleManager . connectedPeripheral . num , context : context )
2023-03-05 14:40:07 -08:00
if node != nil && connectedNode != nil {
2023-02-06 18:45:03 -08:00
_ = bleManager . requestBluetoothConfig ( fromUser : connectedNode ! . user ! , toUser : node ! . user ! , adminIndex : connectedNode ? . myInfo ? . adminIndex ? ? 0 )
2023-01-31 22:08:03 -08:00
}
2023-01-29 00:16:17 -08:00
}
2022-08-18 08:46:10 -07:00
}
. onChange ( of : enabled ) { newEnabled in
if node != nil && node ! . bluetoothConfig != nil {
if newEnabled != node ! . bluetoothConfig ! . enabled { hasChanges = true }
}
}
. onChange ( of : mode ) { newMode in
if node != nil && node ! . bluetoothConfig != nil {
if newMode != node ! . bluetoothConfig ! . mode { hasChanges = true }
}
}
. onChange ( of : fixedPin ) { newFixedPin in
if node != nil && node ! . bluetoothConfig != nil {
2022-08-20 12:15:14 -07:00
if newFixedPin != String ( node ! . bluetoothConfig ! . fixedPin ) { hasChanges = true }
2022-08-18 08:46:10 -07:00
}
}
}
2023-03-19 18:37:23 -07:00
func setBluetoothValues ( ) {
self . enabled = node ? . bluetoothConfig ? . enabled ? ? true
self . mode = Int ( node ? . bluetoothConfig ? . mode ? ? 0 )
self . fixedPin = String ( node ? . bluetoothConfig ? . fixedPin ? ? 123456 )
self . hasChanges = false
}
2022-08-18 08:46:10 -07:00
}