2022-06-22 09:05:56 -07:00
//
// E x t e r n a l N o t i f i c a t i o n 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 6 / 2 2 / 2 2 .
//
import SwiftUI
struct ExternalNotificationConfig : View {
2023-03-06 10:33:18 -08:00
2022-06-22 09:05:56 -07:00
@ Environment ( \ . managedObjectContext ) var context
@ EnvironmentObject var bleManager : BLEManager
2022-12-09 18:19:00 -08:00
@ Environment ( \ . dismiss ) private var goBack
2023-03-06 10:33:18 -08:00
2022-07-07 00:29:52 -07:00
var node : NodeInfoEntity ?
2023-03-06 10:33:18 -08:00
2022-07-01 10:57:54 -07:00
@ State private var isPresentingSaveConfirm : Bool = false
@ State var hasChanges = false
2022-06-22 09:05:56 -07:00
@ State var enabled = false
@ State var alertBell = false
2022-12-23 11:30:55 -08:00
@ State var alertBellBuzzer = false
@ State var alertBellVibra = false
2022-07-01 10:57:54 -07:00
@ State var alertMessage = false
2022-12-23 11:30:55 -08:00
@ State var alertMessageBuzzer = false
@ State var alertMessageVibra = false
2022-07-01 10:57:54 -07:00
@ State var active = false
2022-12-23 14:00:48 -08:00
@ State var usePWM = false
2022-07-01 10:57:54 -07:00
@ State var output = 0
2022-12-23 11:30:55 -08:00
@ State var outputBuzzer = 0
@ State var outputVibra = 0
2022-07-01 10:57:54 -07:00
@ State var outputMilliseconds = 0
2022-12-23 11:30:55 -08:00
@ State var nagTimeout = 0
2023-03-06 10:33:18 -08:00
2022-06-22 09:05:56 -07:00
var body : some View {
2023-03-06 10:33:18 -08:00
2022-12-23 11:30:55 -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 ? . externalNotificationConfig = = nil {
2023-03-13 19:17:43 -07:00
Text ( " External notification 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 {
setExternalNotificationValues ( )
}
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-23 11:30:55 -08:00
Section ( header : Text ( " options " ) ) {
Toggle ( isOn : $ enabled ) {
Label ( " enabled " , systemImage : " megaphone " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
Toggle ( isOn : $ alertBell ) {
Label ( " Alert when receiving a bell " , systemImage : " bell " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
Toggle ( isOn : $ alertMessage ) {
Label ( " Alert when receiving a message " , systemImage : " message " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
Toggle ( isOn : $ usePWM ) {
Label ( " Use PWM Buzzer " , systemImage : " light.beacon.max.fill " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2022-12-23 14:00:48 -08:00
Text ( " Use a PWM output (like the RAK Buzzer) for tunes instead of an on/off output. This will ignore the output, output duration and active settings and use the device config buzzer GPIO option instead. " )
2022-12-23 11:30:55 -08:00
. font ( . caption )
}
2023-01-03 23:20:33 -08:00
Section ( header : Text ( " Advanced GPIO Options " ) ) {
Section ( header : Text ( " Primary GPIO " )
. font ( . caption )
. foregroundColor ( . gray )
2023-03-06 10:33:18 -08:00
. textCase ( . uppercase ) ) {
2022-12-23 11:30:55 -08:00
Toggle ( isOn : $ active ) {
Label ( " Active " , systemImage : " togglepower " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
Text ( " If enabled, the 'output' Pin will be pulled active high, disabled means active low. " )
. font ( . caption )
Picker ( " Output pin GPIO " , selection : $ output ) {
2023-04-03 17:48:58 -07:00
ForEach ( 0. . < 46 ) {
2022-12-23 11:30:55 -08:00
if $0 = = 0 {
2022-12-30 17:44:39 -08:00
Text ( " unset " )
2022-12-23 11:30:55 -08:00
} else {
Text ( " Pin \( $0 ) " )
}
}
}
. pickerStyle ( DefaultPickerStyle ( ) )
Picker ( " GPIO Output Duration " , selection : $ outputMilliseconds ) {
ForEach ( OutputIntervals . allCases ) { oi in
Text ( oi . description )
}
}
. pickerStyle ( DefaultPickerStyle ( ) )
Text ( " When using in GPIO mode, keep the output on for this long. " )
. font ( . caption )
2022-12-23 14:00:48 -08:00
Picker ( " Nag timeout " , selection : $ nagTimeout ) {
ForEach ( OutputIntervals . allCases ) { oi in
Text ( oi . description )
}
}
. pickerStyle ( DefaultPickerStyle ( ) )
Text ( " Specifies how long the monitored GPIO should output. " )
. font ( . caption )
2022-12-23 11:30:55 -08:00
}
2023-03-06 10:33:18 -08:00
2023-01-03 23:20:33 -08:00
Section ( header : Text ( " Optional GPIO " )
. font ( . caption )
. foregroundColor ( . gray )
2023-03-06 10:33:18 -08:00
. textCase ( . uppercase ) ) {
2022-12-23 11:30:55 -08:00
Toggle ( isOn : $ alertBellBuzzer ) {
Label ( " Alert GPIO buzzer when receiving a bell " , systemImage : " bell " )
2022-06-22 09:05:56 -07:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2022-12-23 11:30:55 -08:00
Toggle ( isOn : $ alertBellVibra ) {
Label ( " Alert GPIO vibra motor when receiving a bell " , systemImage : " bell " )
2022-06-22 09:05:56 -07:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2022-12-23 11:30:55 -08:00
Toggle ( isOn : $ alertMessageBuzzer ) {
2022-12-23 14:00:48 -08:00
Label ( " Alert GPIO buzzer when receiving a message " , systemImage : " message " )
2022-06-22 09:05:56 -07:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2022-12-23 11:30:55 -08:00
Toggle ( isOn : $ alertMessageBuzzer ) {
Label ( " Alert GPIO vibra motor when receiving a message " , systemImage : " message " )
2022-06-22 09:05:56 -07:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2022-12-23 11:30:55 -08:00
Picker ( " Output pin buzzer GPIO " , selection : $ outputBuzzer ) {
2023-04-03 17:48:58 -07:00
ForEach ( 0. . < 46 ) {
2022-12-23 11:30:55 -08:00
if $0 = = 0 {
2022-12-30 17:44:39 -08:00
Text ( " unset " )
2022-12-23 11:30:55 -08:00
} else {
Text ( " Pin \( $0 ) " )
2022-06-22 15:52:51 -07:00
}
2022-06-22 09:05:56 -07:00
}
2022-12-23 11:30:55 -08:00
}
. pickerStyle ( DefaultPickerStyle ( ) )
Picker ( " Output pin vibra GPIO " , selection : $ outputVibra ) {
2023-04-03 17:48:58 -07:00
ForEach ( 0. . < 46 ) {
2022-12-23 11:30:55 -08:00
if $0 = = 0 {
2022-12-30 17:44:39 -08:00
Text ( " unset " )
2022-12-23 11:30:55 -08:00
} else {
Text ( " Pin \( $0 ) " )
2022-11-29 21:24:20 -08:00
}
2022-06-29 20:04:20 -07:00
}
}
2022-12-23 11:30:55 -08:00
. pickerStyle ( DefaultPickerStyle ( ) )
2022-07-01 10:57:54 -07:00
}
}
2022-12-23 11:30:55 -08:00
}
2023-02-01 09:19:45 -08:00
. disabled ( self . bleManager . connectedPeripheral = = nil || node ? . externalNotificationConfig = = nil )
2022-12-23 11:30:55 -08:00
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 ,
titleVisibility : . visible
) {
2023-02-22 20:31:08 -08:00
let connectedNode = getNodeInfo ( id : bleManager . connectedPeripheral ? . num ? ? - 1 , context : context )
2023-02-06 18:45:03 -08:00
if connectedNode != nil {
let nodeName = node ? . user ? . longName ? ? NSLocalizedString ( " unknown " , comment : " Unknown " )
let buttonText = String . localizedStringWithFormat ( NSLocalizedString ( " save.config %@ " , comment : " Save Config for %@ " ) , nodeName )
Button ( buttonText ) {
var enc = ModuleConfig . ExternalNotificationConfig ( )
enc . enabled = enabled
enc . alertBell = alertBell
enc . alertBellBuzzer = alertBellBuzzer
enc . alertBellVibra = alertBellVibra
enc . alertMessage = alertMessage
enc . alertMessageBuzzer = alertMessageBuzzer
enc . alertMessageVibra = alertMessageVibra
enc . active = active
enc . output = UInt32 ( output )
2023-03-18 17:26:13 -07:00
enc . nagTimeout = UInt32 ( nagTimeout )
2023-02-06 18:45:03 -08:00
enc . outputBuzzer = UInt32 ( outputBuzzer )
enc . outputVibra = UInt32 ( outputVibra )
enc . outputMs = UInt32 ( outputMilliseconds )
enc . usePwm = usePWM
let adminMessageId = bleManager . saveExternalNotificationModuleConfig ( config : enc , fromUser : connectedNode ! . user ! , toUser : node ! . user ! , adminIndex : connectedNode ? . myInfo ? . adminIndex ? ? 0 )
2023-03-06 10:33:18 -08:00
if adminMessageId > 0 {
2023-02-06 18:45:03 -08:00
// 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-07-11 16:18:16 -07:00
}
2022-07-02 12:34:45 -07:00
}
2022-12-23 11:30:55 -08:00
}
2022-12-30 11:08:59 -08:00
message : {
Text ( " config.save.confirm " )
}
2022-12-23 11:30:55 -08:00
. navigationTitle ( " external.notification.config " )
. navigationBarItems ( trailing :
ZStack {
ConnectedDevice ( bluetoothOn : bleManager . isSwitchedOn , deviceConnected : bleManager . connectedPeripheral != nil , name : ( bleManager . connectedPeripheral != nil ) ? bleManager . connectedPeripheral . shortName : " ???? " )
} )
. onAppear {
self . bleManager . context = context
2023-03-19 18:37:23 -07:00
setExternalNotificationValues ( )
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
// N e e d t o r e q u e s t a T e l e m e t r y M o d u l e 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
if bleManager . connectedPeripheral != nil && node ? . externalNotificationConfig = = nil {
print ( " empty external notification module 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 . requestExternalNotificationModuleConfig ( fromUser : connectedNode ! . user ! , toUser : node ! . user ! , adminIndex : connectedNode ? . myInfo ? . adminIndex ? ? 0 )
2023-02-01 09:19:45 -08:00
}
}
2022-12-23 11:30:55 -08:00
}
. onChange ( of : enabled ) { newEnabled in
if node != nil && node ! . externalNotificationConfig != nil {
if newEnabled != node ! . externalNotificationConfig ! . enabled { hasChanges = true }
2022-07-02 12:34:45 -07:00
}
2022-12-23 11:30:55 -08:00
}
. onChange ( of : alertBell ) { newAlertBell in
if node != nil && node ! . externalNotificationConfig != nil {
if newAlertBell != node ! . externalNotificationConfig ! . alertBell { hasChanges = true }
2022-07-02 12:34:45 -07:00
}
2022-12-23 11:30:55 -08:00
}
. onChange ( of : alertBellBuzzer ) { newAlertBellBuzzer in
if node != nil && node ! . externalNotificationConfig != nil {
if newAlertBellBuzzer != node ! . externalNotificationConfig ! . alertBellBuzzer { hasChanges = true }
2022-07-02 12:34:45 -07:00
}
2022-12-23 11:30:55 -08:00
}
. onChange ( of : alertBellVibra ) { newAlertBellVibra in
if node != nil && node ! . externalNotificationConfig != nil {
if newAlertBellVibra != node ! . externalNotificationConfig ! . alertBellVibra { hasChanges = true }
2022-07-02 12:34:45 -07:00
}
2022-12-23 11:30:55 -08:00
}
. onChange ( of : alertMessage ) { newAlertMessage in
if node != nil && node ! . externalNotificationConfig != nil {
if newAlertMessage != node ! . externalNotificationConfig ! . alertMessage { hasChanges = true }
2022-06-22 09:05:56 -07:00
}
2022-12-23 11:30:55 -08:00
}
. onChange ( of : alertMessageBuzzer ) { newAlertMessageBuzzer in
if node != nil && node ! . externalNotificationConfig != nil {
if newAlertMessageBuzzer != node ! . externalNotificationConfig ! . alertMessageBuzzer { hasChanges = true }
}
}
. onChange ( of : alertMessageVibra ) { newAlertMessageVibra in
if node != nil && node ! . externalNotificationConfig != nil {
if newAlertMessageVibra != node ! . externalNotificationConfig ! . alertMessageVibra { hasChanges = true }
}
}
. onChange ( of : active ) { newActive in
if node != nil && node ! . externalNotificationConfig != nil {
if newActive != node ! . externalNotificationConfig ! . active { hasChanges = true }
}
}
. onChange ( of : output ) { newOutput in
if node != nil && node ! . externalNotificationConfig != nil {
if newOutput != node ! . externalNotificationConfig ! . output { hasChanges = true }
}
}
. onChange ( of : output ) { newOutputBuzzer in
if node != nil && node ! . externalNotificationConfig != nil {
if newOutputBuzzer != node ! . externalNotificationConfig ! . outputBuzzer { hasChanges = true }
}
}
. onChange ( of : output ) { newOutputVibra in
if node != nil && node ! . externalNotificationConfig != nil {
if newOutputVibra != node ! . externalNotificationConfig ! . outputVibra { hasChanges = true }
}
}
. onChange ( of : outputMilliseconds ) { newOutputMs in
if node != nil && node ! . externalNotificationConfig != nil {
if newOutputMs != node ! . externalNotificationConfig ! . outputMilliseconds { hasChanges = true }
}
}
. onChange ( of : usePWM ) { newUsePWM in
if node != nil && node ! . externalNotificationConfig != nil {
if newUsePWM != node ! . externalNotificationConfig ! . usePWM { hasChanges = true }
}
}
. onChange ( of : nagTimeout ) { newNagTimeout in
if node != nil && node ! . externalNotificationConfig != nil {
if newNagTimeout != node ! . externalNotificationConfig ! . nagTimeout { hasChanges = true }
2022-11-29 21:24:20 -08:00
}
2022-06-22 09:05:56 -07:00
}
}
2023-03-19 18:37:23 -07:00
func setExternalNotificationValues ( ) {
self . enabled = node ? . externalNotificationConfig ? . enabled ? ? false
self . alertBell = node ? . externalNotificationConfig ? . alertBell ? ? false
self . alertBellBuzzer = node ? . externalNotificationConfig ? . alertBellBuzzer ? ? false
self . alertBellVibra = node ? . externalNotificationConfig ? . alertBellVibra ? ? false
self . alertMessage = node ? . externalNotificationConfig ? . alertMessage ? ? false
self . alertMessageBuzzer = node ? . externalNotificationConfig ? . alertMessageBuzzer ? ? false
self . alertMessageVibra = node ? . externalNotificationConfig ? . alertMessageVibra ? ? false
self . active = node ? . externalNotificationConfig ? . active ? ? false
self . output = Int ( node ? . externalNotificationConfig ? . output ? ? 0 )
self . outputBuzzer = Int ( node ? . externalNotificationConfig ? . outputBuzzer ? ? 0 )
self . outputVibra = Int ( node ? . externalNotificationConfig ? . outputVibra ? ? 0 )
self . outputMilliseconds = Int ( node ? . externalNotificationConfig ? . outputMilliseconds ? ? 0 )
self . nagTimeout = Int ( node ? . externalNotificationConfig ? . nagTimeout ? ? 0 )
self . usePWM = node ? . externalNotificationConfig ? . usePWM ? ? false
self . hasChanges = false
}
2022-06-22 09:05:56 -07:00
}