// +build js package main import ( "github.com/gopherjs/gopherjs/js" "github.com/mame82/hvue" "strconv" ) func generateSelectOptionsTrigger() *js.Object { tts := js.Global.Get("Array").New() type option struct { *js.Object Label string `js:"label"` Value triggerType `js:"value"` } for _,triggerVal := range availableTriggers { triggerLabel := triggerNames[triggerVal] o := option{Object:O()} o.Value = triggerVal o.Label = triggerLabel tts.Call("push", o) } return tts } func generateSelectOptionsAction() *js.Object { tts := js.Global.Get("Array").New() type option struct { *js.Object Label string `js:"label"` Value actionType `js:"value"` } for _, actionVal := range availableActions { actionLabel := actionNames[actionVal] o := option{Object:O()} o.Value = actionVal o.Label = actionLabel tts.Call("push", o) } return tts } func generateSelectOptionsGroupReceiveMultiType() *js.Object { tts := js.Global.Get("Array").New() type option struct { *js.Object Label string `js:"label"` Value GroupReceiveMultiType `js:"value"` } for _, value := range availableGroupReceiveMulti { label := groupReceiveMultiNames[value] o := option{Object:O()} o.Value = value o.Label = label tts.Call("push", o) } return tts } func generateSelectOptionsGPIOOutValue() *js.Object { tts := js.Global.Get("Array").New() type option struct { *js.Object Label string `js:"label"` Value GPIOOutValue `js:"value"` } for _, value := range availableGPIOOutValues { label := gpioOutValueNames[value] o := option{Object:O()} o.Value = value o.Label = label tts.Call("push", o) } return tts } func generateSelectOptionsGPIONames(vm *hvue.VM) *js.Object { tts := js.Global.Get("Array").New() type option struct { *js.Object Label string `js:"label"` Value string `js:"value"` } gpioNames := vm.Store.Get("state").Get("GpioNamesList") for i := 0; i < gpioNames.Length(); i++ { gpioName := gpioNames.Index(i).String() o := option{Object:O()} o.Value = gpioName o.Label = gpioName tts.Call("push", o) } return tts } func generateSelectOptionsGPIOInPullUpDown() *js.Object { tts := js.Global.Get("Array").New() type option struct { *js.Object Label string `js:"label"` Value GPIOInPullUpDown `js:"value"` } for _, value := range availableGPIOInPullUpDowns { label := gpioInPullUpDownNames[value] o := option{Object:O()} o.Value = value o.Label = label tts.Call("push", o) } return tts } func generateSelectOptionsGPIOInEdges() *js.Object { tts := js.Global.Get("Array").New() type option struct { *js.Object Label string `js:"label"` Value GPIOInEdge `js:"value"` } for _, value := range availableGPIOInEdges { label := gpioInEdgeNames[value] o := option{Object:O()} o.Value = value o.Label = label tts.Call("push", o) } return tts } func generateSelectOptionsTemplateTypes() *js.Object { tts := js.Global.Get("Array").New() type option struct { *js.Object Label string `js:"label"` Value TemplateType `js:"value"` } for _, value := range availableTemplateTypes { label := templateTypeNames[value] o := option{Object:O()} o.Value = value o.Label = label tts.Call("push", o) } return tts } /* type TriggerActionCompData struct { *js.Object Edit bool `js:"Edit"` } */ func InitComponentsTriggerActions() { hvue.NewComponent( "triggeraction-manager", hvue.Template(templateTriggerActionManager), hvue.DataFunc(func(vm *hvue.VM) interface{} { data := struct { *js.Object ShowReplaceTASModal bool `js:"showReplaceTASModal"` ShowAddTASModal bool `js:"showAddTASModal"` ShowStoreTASModal bool `js:"showStoreTASModal"` TemplateName string `js:"templateName"` }{Object: O()} data.ShowReplaceTASModal = false data.ShowAddTASModal = false data.ShowStoreTASModal = false data.TemplateName = "" return &data }), hvue.Method("editTa", func(vm *hvue.VM, taID *js.Object) { vm.Get("$refs").Index(taID.Int()).Index(0).Call("setEditMode", true) }), hvue.Method("addTA", func(vm *hvue.VM) { promise := vm.Get("$store").Call("dispatch", VUEX_ACTION_ADD_NEW_TRIGGER_ACTION) promise.Call("then", func(value *js.Object) { // set the trigger action into edit mode vm.Call("editTa", value) }, func(reason *js.Object) { println("add TriggerAction failed", reason) }, ) }), hvue.Method("storeTAS", func(vm *hvue.VM, name *js.Object) { tas_obj := vm.Get("$store").Get("state").Get("triggerActionList") current_tas := jsTriggerActionSet{Object:tas_obj}.toGo() store_tas := NewTriggerActionSet() store_tas.Name = name.String() for _,ta := range current_tas.TriggerActions { if ta.IsActive && !ta.Immutable { jsTa := &jsTriggerAction{Object:O()} jsTa.fromGo(ta) store_tas.UpdateEntry(jsTa) } } vm.Get("$store").Call("dispatch", VUEX_ACTION_STORE_TRIGGER_ACTION_SET, store_tas) }), hvue.Method("replaceCurrentTAS", func(vm *hvue.VM, storedTASName *js.Object) { //vm.Get("$q").Call("notify", "Replacing TAS with '" + storedTASName.String() +"'") vm.Get("$store").Call("dispatch", VUEX_ACTION_DEPLOY_STORED_TRIGGER_ACTION_SET_REPLACE, storedTASName) }), hvue.Method("addToCurrentTAS", func(vm *hvue.VM, storedTASName *js.Object) { //vm.Get("$q").Call("notify", "Add '" + storedTASName.String() +"' to current TAS") vm.Get("$store").Call("dispatch", VUEX_ACTION_DEPLOY_STORED_TRIGGER_ACTION_SET_ADD, storedTASName) }), hvue.Method("deleteStored", func(vm *hvue.VM, storedTASName *js.Object) { //vm.Get("$q").Call("notify", "Add '" + storedTASName.String() +"' to current TAS") vm.Get("$store").Call("dispatch", VUEX_ACTION_DELETE_STORED_TRIGGER_ACTION_SET, storedTASName) }), hvue.Method("updateStoredTriggerActionSetsList", func(vm *hvue.VM) { vm.Store.Call("dispatch", VUEX_ACTION_UPDATE_STORED_TRIGGER_ACTION_SETS_LIST) }), hvue.Mounted(func(vm *hvue.VM) { vm.Store.Call("dispatch", VUEX_ACTION_UPDATE_CURRENT_TRIGGER_ACTIONS_FROM_SERVER) vm.Store.Call("dispatch", VUEX_ACTION_UPDATE_GPIO_NAMES_LIST) js.Global.Set("tam",vm) }), ) hvue.NewComponent( "TriggerAction", hvue.Template(templateTriggerAction), hvue.DataFunc(func(vm *hvue.VM) interface{} { data := &struct { *js.Object Edit bool `js:"Edit"` }{Object:O()} data.Edit = false return data }), hvue.PropObj("ta"), hvue.PropObj("edit", hvue.Types(hvue.PBoolean), ), hvue.Method("setEditMode", func(vm *hvue.VM, enabled bool) { vm.Data.Set("Edit", enabled) }), hvue.Mounted(func(vm *hvue.VM) { vm.Set("Edit", vm.Get("edit")) }), ) hvue.NewComponent( "TriggerActionOverview", hvue.Template(templateTriggerActionOverview), hvue.PropObj("ta"), hvue.PropObj("edit", hvue.Types(hvue.PBoolean), ), /* hvue.Mounted(func(vm *hvue.VM) { data := TriggerActionCompData{Object: vm.Data} data.Edit = vm.Get("edit").Bool() }), */ /* hvue.DataFunc(func(vm *hvue.VM) interface{} { data := &TriggerActionCompData{Object: O()} data.Edit = false return data }), */ hvue.ComputedWithGetSet("EditMode", func(vm *hvue.VM) interface{} { /* data := TriggerActionCompData{Object: vm.Data} return data.Edit */ return vm.Get("edit") }, func(vm *hvue.VM, newValue *js.Object) { /* data := TriggerActionCompData{Object: vm.Data} data.Edit = newValue.Bool() */ // Emit event for editmode change vm.Emit("edit", newValue) }), hvue.Computed("computedColor", func(vm *hvue.VM) interface{} { ta := &jsTriggerAction{Object: vm.Get("ta")} switch { case ta.Immutable: return "dark" /* case !ta.IsActive: return "light" */ default: return "" } }), hvue.Computed("strTrigger", func(vm *hvue.VM) interface{} { ta := &jsTriggerAction{Object: vm.Get("ta")} strTrigger := triggerNames[ta.TriggerType] switch { case ta.IsTriggerGroupReceive(): t := jsTriggerGroupReceive{Object: ta.TriggerData} strTrigger += " (" strTrigger += t.GroupName strTrigger += ": " + strconv.Itoa(int(t.Value)) strTrigger += ")" case ta.IsTriggerGroupReceiveMulti(): t := jsTriggerGroupReceiveMulti{Object: ta.TriggerData} strTrigger += " (" strTrigger += t.GroupName + ": " switch t.Type { case GroupReceiveMultiType_SEQUENCE: strTrigger += "sequence of" case GroupReceiveMultiType_EXACT_SEQUENCE: strTrigger += "exact sequence of" case GroupReceiveMultiType_OR: strTrigger += "one of" case GroupReceiveMultiType_AND: strTrigger += "all from" } strTrigger += " [" for idx,val := range t.Values { if idx != 0 { strTrigger += ", " } strTrigger += strconv.Itoa(int(val)) } strTrigger += "]" strTrigger += ")" case ta.IsTriggerGPIOIn(): t := jsTriggerGPIOIn{Object: ta.TriggerData} strTrigger += " (" strTrigger += t.GpioName strTrigger += ": " + gpioInEdgeNames[t.Edge] strTrigger += ", resistor: " + gpioInPullUpDownNames[t.PullUpDown] strTrigger += ", debounce: " + strconv.Itoa(int(t.DebounceMillis)) + "ms" strTrigger += ")" } return strTrigger }), hvue.Computed("strAction", func(vm *hvue.VM) interface{} { ta := &jsTriggerAction{Object: vm.Get("ta")} strAction := actionNames[ta.ActionType] switch { case ta.IsActionGroupSend(): tgs := jsActionGroupSend{Object: ta.ActionData} strAction += " (" strAction += tgs.GroupName strAction += ": " + strconv.Itoa(int(tgs.Value)) strAction += ")" case ta.IsActionGPIOOut(): a := jsActionGPIOOut{Object: ta.ActionData} strAction += " (" strAction += a.GpioName strAction += ": " + gpioOutValueNames[a.Value] strAction += ")" case ta.IsActionBashScript(): a := jsActionStartBashScript{Object: ta.ActionData} strAction += " ('" strAction += a.ScriptName strAction += "')" case ta.IsActionDeploySettingsTemplate(): a := jsActionDeploySettingsTemplate{Object: ta.ActionData} strAction += " (" strAction += templateTypeNames[a.Type] strAction += ": '" + a.TemplateName strAction += "')" case ta.IsActionHidScript(): a := jsActionStartHIDScript{Object: ta.ActionData} strAction += " ('" strAction += a.ScriptName strAction += "')" } return strAction }), hvue.Method( "updateTA", func(vm *hvue.VM) { ta_obj := vm.Get("ta") println("update ta: ", ta_obj) /* //Replace the whole TriggerActionSet of server with the current one from vuex store // ToDo: This has to be changed to update a single action (inconssistnecy with multiple clients, all TA IDs change, overhead of transferring a whole set) -> has to be implemented like deleteTA logic currentTas := vm.Get("$store").Get("state").Get("triggerActionList") //Current TriggerActionSet of ViewModel vm.Get("$store").Call("dispatch", VUEX_ACTION_DEPLOY_TRIGGER_ACTION_SET_REPLACE, currentTas) */ updateTas := NewTriggerActionSet() updateTas.UpdateEntry(&jsTriggerAction{Object: ta_obj}) vm.Get("$store").Call("dispatch", VUEX_ACTION_UPDATE_TRIGGER_ACTIONS, updateTas) }), hvue.Method( "cancelUpdateTA", func(vm *hvue.VM) { println("cancel update ta: ", vm.Get("ta")) //Reload the whole TriggerActionSet from server and overwrite the current one of vuex store vm.Get("$store").Call("dispatch", VUEX_ACTION_UPDATE_CURRENT_TRIGGER_ACTIONS_FROM_SERVER) }), hvue.Method( "deleteTA", func(vm *hvue.VM) { ta_obj := vm.Get("ta") println("delete ta: ", ta_obj) delTas := NewTriggerActionSet() delTas.UpdateEntry(&jsTriggerAction{Object: ta_obj}) vm.Get("$store").Call("dispatch", VUEX_ACTION_REMOVE_TRIGGER_ACTIONS, delTas) }), ) hvue.NewComponent( "TriggerActionEdit", hvue.Template(templateTriggerActionEdit), hvue.PropObj("ta"), ) hvue.NewComponent( "trigger", hvue.Props("ta"), hvue.Template(templateTrigger), hvue.Computed("triggertypes", func(vm *hvue.VM) interface{} { return generateSelectOptionsTrigger() }), hvue.Computed("pullupdown", func(vm *hvue.VM) interface{} { return generateSelectOptionsGPIOInPullUpDown() }), hvue.Computed("groupReceiveMultiSelect", func(vm *hvue.VM) interface{} { return generateSelectOptionsGroupReceiveMultiType() }), hvue.Computed("edge", func(vm *hvue.VM) interface{} { return generateSelectOptionsGPIOInEdges() }), hvue.Computed("gpioname", func(vm *hvue.VM) interface{} { return generateSelectOptionsGPIONames(vm) }), hvue.ComputedWithGetSet( "triggerType", func(vm *hvue.VM) interface{} { return vm.Get("ta").Get("TriggerType") }, func(vm *hvue.VM, newValue *js.Object) { tType := triggerType(newValue.Int()) ta := &jsTriggerAction{Object: vm.Get("ta")} ta.ChangeTriggerType(tType) }), hvue.Method( "TriggerGroupReceiveMultiAddValue", func(vm *hvue.VM, newVal *js.Object) { println("Force add", newVal) ta := &jsTriggerAction{Object: vm.Get("ta")} if !ta.IsTriggerGroupReceiveMulti() { return } // cast data Object to jsTriggerGroupReceiveMulti tgrs := &jsTriggerGroupReceiveMulti{Object: ta.TriggerData} strVal := newVal.String() if intVal,errconv := strconv.Atoi(strVal); errconv == nil { //append to Values tgrs.Values = append(tgrs.Values, int32(intVal)) } }), hvue.ComputedWithGetSet( "TriggerGroupReceiveMultiValues", func(vm *hvue.VM) interface{} { ta := &jsTriggerAction{Object: vm.Get("ta")} if !ta.IsTriggerGroupReceiveMulti() { return []string{} } // cast data Object to jsTriggerGroupReceiveMulti tgrs := &jsTriggerGroupReceiveMulti{Object: ta.TriggerData} res := make([]string, len(tgrs.Values)) for idx,intVal := range tgrs.Values { res[idx] = strconv.Itoa(int(intVal)) } return res }, func(vm *hvue.VM, newValue *js.Object) { ta := &jsTriggerAction{Object: vm.Get("ta")} if !ta.IsTriggerGroupReceiveMulti() { return } // cast data Object to jsTriggerGroupReceiveMulti tgrs := &jsTriggerGroupReceiveMulti{Object: ta.TriggerData} // clear old array tgrs.Values = []int32{} // iterate over newValue, which is assumed to be an Array of strings for idx := 0; idx < newValue.Length(); idx++ { //fetch value strVal := newValue.Index(idx).String() // try to cast to int if intVal,errconv := strconv.Atoi(strVal); errconv == nil { //append to Values tgrs.Values = append(tgrs.Values, int32(intVal)) } } }), hvue.Computed("isTriggerGPIOIn", func(vm *hvue.VM) interface{} { return (&jsTriggerAction{Object: vm.Get("ta")}).IsTriggerGPIOIn() }), hvue.Computed("isTriggerGroupReceive", func(vm *hvue.VM) interface{} { return (&jsTriggerAction{Object: vm.Get("ta")}).IsTriggerGroupReceive() }), hvue.Computed("isTriggerGroupReceiveMulti", func(vm *hvue.VM) interface{} { return (&jsTriggerAction{Object: vm.Get("ta")}).IsTriggerGroupReceiveMulti() }), ) hvue.NewComponent( "action", hvue.Props("ta"), hvue.Template(templateAction), hvue.DataFunc(func(vm *hvue.VM) interface{} { data := struct { *js.Object ShowSelectHIDScriptModal bool `js:"ShowSelectHIDScriptModal"` ShowSelectBashScriptModal bool `js:"ShowSelectBashScriptModal"` ShowSelectTemplateModal bool `js:"ShowSelectTemplateModal"` }{Object: O()} data.ShowSelectHIDScriptModal = false data.ShowSelectBashScriptModal = false data.ShowSelectTemplateModal = false return &data }), hvue.Method("updateStoredHIDScriptsList", func(vm *hvue.VM) { vm.Store.Call("dispatch", VUEX_ACTION_UPDATE_STORED_HID_SCRIPTS_LIST) }), hvue.Method("updateStoredBashScriptsList", func(vm *hvue.VM) { vm.Store.Call("dispatch", VUEX_ACTION_UPDATE_STORED_BASH_SCRIPTS_LIST) }), hvue.Computed( "typedTemplateList", func(vm *hvue.VM) interface{} { // template type: ta.ActionData.Type ta:=&jsTriggerAction{Object: vm.Get("ta")} if !ta.IsActionDeploySettingsTemplate() { return []string{} } aData := &jsActionDeploySettingsTemplate{Object: ta.ActionData} switch aData.Type { case TemplateTypeFullSettings: return vm.Store.Get("state").Get("StoredMasterTemplateList") case TemplateTypeBluetooth: return vm.Store.Get("state").Get("StoredBluetoothSettingsList") case TemplateTypeUSB: //return USB list return vm.Store.Get("state").Get("StoredUSBSettingsList") case TemplateTypeTriggerActions: //return TriggerAction list return vm.Store.Get("state").Get("StoredTriggerActionSetsList") case TemplateTypeWifi: //return WiFi settings list return vm.Store.Get("state").Get("StoredWifiSettingsList") case TemplateTypeNetwork: //return ethernet interface settings list return vm.Store.Get("state").Get("StoredEthernetInterfaceSettingsList") } return []string{} //empty list }), hvue.Method( "actionTemplateTypeUpdate", func(vm *hvue.VM) interface{} { // template type: ta.ActionData.Type ta:=&jsTriggerAction{Object: vm.Get("ta")} if !ta.IsActionDeploySettingsTemplate() { return []string{} } aData := &jsActionDeploySettingsTemplate{Object: ta.ActionData} switch aData.Type { case TemplateTypeFullSettings: vm.Store.Call("dispatch", VUEX_ACTION_UPDATE_STORED_MASTER_TEMPLATE_LIST) case TemplateTypeBluetooth: vm.Store.Call("dispatch", VUEX_ACTION_UPDATE_STORED_BLUETOOTH_SETTINGS_LIST) case TemplateTypeUSB: //update USB list vm.Store.Call("dispatch", VUEX_ACTION_UPDATE_STORED_USB_SETTINGS_LIST) case TemplateTypeTriggerActions: //update TriggerAction list vm.Store.Call("dispatch", VUEX_ACTION_UPDATE_STORED_TRIGGER_ACTION_SETS_LIST) case TemplateTypeWifi: //update WiFi settings template list vm.Store.Call("dispatch", VUEX_ACTION_UPDATE_STORED_WIFI_SETTINGS_LIST) case TemplateTypeNetwork: //update ethernet interface settings template list vm.Store.Call("dispatch", VUEX_ACTION_UPDATE_STORED_ETHERNET_INTERFACE_SETTINGS_LIST) } return []string{} //empty list }), hvue.Computed("actiontypes", func(vm *hvue.VM) interface{} { return generateSelectOptionsAction() }), hvue.Computed("gpiooutvalues", func(vm *hvue.VM) interface{} { return generateSelectOptionsGPIOOutValue() }), hvue.Computed("gpioname", func(vm *hvue.VM) interface{} { return generateSelectOptionsGPIONames(vm) }), hvue.Computed("templatetypes", func(vm *hvue.VM) interface{} { return generateSelectOptionsTemplateTypes() }), hvue.ComputedWithGetSet( "actionType", func(vm *hvue.VM) interface{} { return vm.Get("ta").Get("ActionType") }, func(vm *hvue.VM, newValue *js.Object) { aType := actionType(newValue.Int()) ta := &jsTriggerAction{Object: vm.Get("ta")} ta.ChangeActionType(aType) }), hvue.Computed("isActionLog", func(vm *hvue.VM) interface{} { return (&jsTriggerAction{Object: vm.Get("ta")}).IsActionLog() }), hvue.Computed("isActionHidScript", func(vm *hvue.VM) interface{} { return (&jsTriggerAction{Object: vm.Get("ta")}).IsActionHidScript() }), hvue.Computed("isActionDeploySettingsTemplate", func(vm *hvue.VM) interface{} { return (&jsTriggerAction{Object: vm.Get("ta")}).IsActionDeploySettingsTemplate() }), hvue.Computed("isActionBashScript", func(vm *hvue.VM) interface{} { return (&jsTriggerAction{Object: vm.Get("ta")}).IsActionBashScript() }), hvue.Computed("isActionGPIOOut", func(vm *hvue.VM) interface{} { return (&jsTriggerAction{Object: vm.Get("ta")}).IsActionGPIOOut() }), hvue.Computed("isActionGroupSend", func(vm *hvue.VM) interface{} { return (&jsTriggerAction{Object: vm.Get("ta")}).IsActionGroupSend() }), ) } const templateTriggerAction = `
` const templateTriggerActionOverview = `
{{ ta.Immutable ? "immutable, " : "" }} {{ ta.IsActive ? "enabled" : "disabled" }} TriggerAction (ID {{ ta.Id }}) {{ strTrigger }}
{{ strAction }}{{ta.OneShot ? " only once" : "" }}
` const templateTriggerActionEdit = ` TriggerAction ID {{ ta.Id }} Enabled If not enabled, the triggered action is ignored One shot The trigger fires every time the respective event occurs. If "one shot" is enabled it fires only once.
` const templateTrigger = ` Trigger Chose the event which has to occur to start the selected action Group name Only values send for this group name are regarded Value The numeric value which has to be received to activate the trigger Values The numeric values which has to be received to activate the trigger Type Chose how values should be checked (logical OR, logical AND, sequence or exact sequence GPIO Number The number of the GPIO to monitor Pull resistor Chose if internal Pull-up/down resistor should be used Edge What edge (level change) has to occur to fire the trigger Debounce duration Successive edge events in this duration are ignored ` const templateAction = ` Action Chose the action which should be started when the trigger fired Script path Path to the BashScript which should be issued Script name Name of a stored HIDScript GPIO Number The number of the GPIO to output on Output Output low/high on the given GPIO or toggle the output Group name The name of the group to send to (has to match respective listeners) Value The numeric value which is sent to the group channel Type Select the type of the template to load Template name Name of the stored settings template to load ` const templateTriggerActionManager = `
TriggerAction Manager
`