mirror of
https://github.com/RoganDawes/P4wnP1_aloa.git
synced 2025-03-18 05:41:55 +01:00
Continued working on global state exposed to Vuex
This commit is contained in:
parent
0a2a826223
commit
04c6f0d397
@ -51,8 +51,8 @@ func InitCompHIDScript() {
|
||||
func(vm *hvue.VM) interface{} {
|
||||
return vm.Store.Get("state").Get("currentHIDScriptSource")
|
||||
},
|
||||
func(vm *hvue.VM, newValue *js.Object) {
|
||||
vm.Store.Call("commit", "setCurrentHIDScriptSource", newValue)
|
||||
func(vm *hvue.VM, newScriptContent *js.Object) {
|
||||
vm.Store.Call("commit", VUEX_MUTATION_SET_CURRENT_HID_SCRIPT_SOURCE_TO, newScriptContent)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
@ -1 +1,57 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/mame82/hvue"
|
||||
)
|
||||
|
||||
/*
|
||||
type CompModalData struct {
|
||||
*js.Object
|
||||
ShowModal bool `js:"showModal"`
|
||||
}
|
||||
|
||||
func NewCompModalData(vm *hvue.VM) interface{} {
|
||||
d:= &CompModalData{Object:O()}
|
||||
d.ShowModal = false
|
||||
return d
|
||||
}
|
||||
*/
|
||||
func InitCompModal() {
|
||||
hvue.NewComponent(
|
||||
"modal",
|
||||
// hvue.DataFunc(NewCompModalData),
|
||||
hvue.Template(compModalTemplate),
|
||||
)
|
||||
}
|
||||
|
||||
const compModalTemplate = `
|
||||
<transition name="modal">
|
||||
<div class="modal-mask">
|
||||
<div class="modal-wrapper">
|
||||
<div class="modal-container">
|
||||
|
||||
<div class="modal-header">
|
||||
<slot name="header">
|
||||
Modal window header
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<slot name="body">
|
||||
body
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<slot name="footer">
|
||||
footer
|
||||
<button class="modal-default-button" @click="$emit('close')">
|
||||
OK
|
||||
</button>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
`
|
@ -2,10 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"github.com/gopherjs/gopherjs/js"
|
||||
pb "../proto/gopherjs"
|
||||
"time"
|
||||
"context"
|
||||
"google.golang.org/grpc/status"
|
||||
"github.com/mame82/hvue"
|
||||
)
|
||||
|
||||
@ -19,69 +15,28 @@ type CompUSBSettingsData struct {
|
||||
RndisDetails bool `js:"rndisDetails"`
|
||||
}
|
||||
|
||||
//ToDo: Reimplement with Action on global state
|
||||
//This becomes a method of the Vue Component and encapsulates dispatching of a Vuex action
|
||||
func (c *CompUSBSettingsData) UpdateFromDeployedGadgetSettings(vm *hvue.VM) {
|
||||
vm.Store.Call("commit", "setCurrentGadgetSettingsFromDeployed")
|
||||
vm.Store.Call("dispatch", VUEX_ACTION_UPDATE_GADGET_SETTINGS_FROM_DEPLOYED)
|
||||
}
|
||||
|
||||
//ToDo: Reimplement with actions on global state
|
||||
//This becomes a method of the Vue Component and encapsulates dispatching of a Vuex action
|
||||
func (c *CompUSBSettingsData) ApplyGadgetSettings(vm *hvue.VM) {
|
||||
//println("Trying to deploy GadgetSettings: " + fmt.Sprintf("%+v",c.GadgetSettings.toGS()))
|
||||
println("Trying to deploy GadgetSettings...")
|
||||
//gs:=c.GadgetSettings.toGS()
|
||||
gs := jsGadgetSettings{Object: vm.Store.Get("state").Get("currentGadgetSettings")}.toGS()
|
||||
|
||||
go func() {
|
||||
c.DeployPending = true
|
||||
defer func() {c.DeployPending = false}()
|
||||
|
||||
ctx,cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
//Set gadget settings
|
||||
_, err := Client.Client.SetGadgetSettings(ctx, gs)
|
||||
if err != nil {
|
||||
js.Global.Call("alert", "Error setting given gadget settings: " + status.Convert(err).Message())
|
||||
println(err)
|
||||
c.UpdateFromDeployedGadgetSettings(vm)
|
||||
return
|
||||
}
|
||||
println("New GadgetSettings have been set")
|
||||
|
||||
|
||||
|
||||
//deploy the settings
|
||||
deployedGs,err := Client.Client.DeployGadgetSetting(ctx, &pb.Empty{})
|
||||
if err != nil {
|
||||
js.Global.Call("alert", "Error deploying gadget settings: " + status.Convert(err).Message())
|
||||
println(err)
|
||||
c.UpdateFromDeployedGadgetSettings(vm)
|
||||
return
|
||||
}
|
||||
println("New GadgetSettings have been deployed")
|
||||
|
||||
js.Global.Call("alert", "New USB gadget settings deployed ")
|
||||
|
||||
newGs := &jsGadgetSettings{
|
||||
Object: js.Global.Get("Object").New(),
|
||||
}
|
||||
newGs.fromGS(deployedGs)
|
||||
c.GadgetSettings = newGs
|
||||
}()
|
||||
vm.Store.Call("dispatch", VUEX_ACTION_DEPLOY_CURRENT_GADGET_SETTINGS)
|
||||
}
|
||||
|
||||
func InitCompUSBSettings() {
|
||||
|
||||
hvue.NewComponent(
|
||||
"usb-settings",
|
||||
hvue.Template(compUSBSettingsTemplate),
|
||||
hvue.DataFunc(newCompUSBSettingsData),
|
||||
hvue.MethodsOf(&CompUSBSettingsData{}),
|
||||
hvue.MethodsOf(&CompUSBSettingsData{}), // Add the methods of CompUSBSettingsData to the Vue Component instance
|
||||
hvue.Computed(
|
||||
"currentGadgetSettings",
|
||||
func(vm *hvue.VM) interface{} {
|
||||
return vm.Store.Get("state").Get("currentGadgetSettings")
|
||||
}),
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
@ -90,10 +45,8 @@ func newCompUSBSettingsData(vm *hvue.VM) interface{} {
|
||||
cc := &CompUSBSettingsData{
|
||||
Object: js.Global.Get("Object").New(),
|
||||
}
|
||||
|
||||
cc.GadgetSettings = NewUSBGadgetSettings()
|
||||
|
||||
cc.UpdateFromDeployedGadgetSettings(vm)
|
||||
cc.DeployPending = false
|
||||
cc.RndisDetails = false
|
||||
cc.CdcEcmDetails = false
|
||||
@ -177,4 +130,3 @@ const (
|
||||
</div>
|
||||
`
|
||||
)
|
||||
|
||||
|
@ -8,8 +8,11 @@ import (
|
||||
"sync"
|
||||
"context"
|
||||
"io"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var eNoLogEvent = errors.New("No log event")
|
||||
|
||||
/* USB Gadget types corresponding to gRPC messages */
|
||||
|
||||
type jsGadgetSettings struct {
|
||||
@ -129,8 +132,41 @@ func NewUSBGadgetSettings() *jsGadgetSettings {
|
||||
|
||||
/** Events **/
|
||||
|
||||
type jsEvent struct {
|
||||
*js.Object
|
||||
Type int64 `js:"type"`
|
||||
Values []interface{}
|
||||
JSValues *js.Object `js:"values"`
|
||||
}
|
||||
|
||||
|
||||
func NewJsEventFromNative(event *pb.Event) (res *jsEvent) {
|
||||
res = &jsEvent{Object:O()}
|
||||
res.JSValues = js.Global.Get("Array").New()
|
||||
res.Type = event.Type
|
||||
res.Values = make([]interface{}, len(event.Values))
|
||||
for idx,val := range event.Values {
|
||||
switch valT := val.Val.(type) {
|
||||
case *pb.EventValue_Tint64:
|
||||
res.Values[idx] = valT.Tint64
|
||||
res.JSValues.Call("push", valT.Tint64)
|
||||
case *pb.EventValue_Tstring:
|
||||
res.Values[idx] = valT.Tstring
|
||||
res.JSValues.Call("push", valT.Tstring)
|
||||
case *pb.EventValue_Tbool:
|
||||
res.Values[idx] = valT.Tbool
|
||||
res.JSValues.Call("push", valT.Tbool)
|
||||
default:
|
||||
println("error parsing event value", valT)
|
||||
}
|
||||
}
|
||||
println("result",res)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
//Log event
|
||||
type jsEventLog struct {
|
||||
type jsLogEvent struct {
|
||||
*js.Object
|
||||
EvLogSource string `js:"source"`
|
||||
EvLogLevel int `js:"level"`
|
||||
@ -138,10 +174,32 @@ type jsEventLog struct {
|
||||
EvLogTime string `js:"time"`
|
||||
}
|
||||
|
||||
func DeconstructEventLog(gRPCEv *pb.Event) (res *jsEventLog, err error) {
|
||||
func (jsEv *jsEvent) toLogEvent() (res *jsLogEvent, err error) {
|
||||
if jsEv.Type != common.EVT_LOG || len(jsEv.Values) != 4 { return nil,eNoLogEvent}
|
||||
res = &jsLogEvent{Object:O()}
|
||||
|
||||
var ok bool
|
||||
res.EvLogSource,ok = jsEv.Values[0].(string)
|
||||
if !ok { return nil,eNoLogEvent }
|
||||
|
||||
ll,ok := jsEv.Values[1].(int64)
|
||||
if !ok { return nil,eNoLogEvent}
|
||||
res.EvLogLevel = int(ll)
|
||||
|
||||
res.EvLogMessage,ok = jsEv.Values[2].(string)
|
||||
if !ok { return nil,eNoLogEvent}
|
||||
|
||||
res.EvLogTime,ok = jsEv.Values[3].(string)
|
||||
if !ok { return nil,eNoLogEvent}
|
||||
|
||||
return res,nil
|
||||
}
|
||||
|
||||
/*
|
||||
func DeconstructEventLog(gRPCEv *pb.Event) (res *jsLogEvent, err error) {
|
||||
if gRPCEv.Type != common.EVT_LOG { return nil,errors.New("No log event")}
|
||||
|
||||
res = &jsEventLog{Object:O()}
|
||||
res = &jsLogEvent{Object:O()}
|
||||
switch vT := gRPCEv.Values[0].Val.(type) {
|
||||
case *pb.EventValue_Tstring:
|
||||
res.EvLogSource = vT.Tstring
|
||||
@ -169,18 +227,31 @@ func DeconstructEventLog(gRPCEv *pb.Event) (res *jsEventLog, err error) {
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/* EVENT LOGGER */
|
||||
|
||||
type jsLoggerData struct {
|
||||
*js.Object
|
||||
LogArray *js.Object `js:"logArray"`
|
||||
EventArray *js.Object `js:"eventArray"`
|
||||
cancel context.CancelFunc
|
||||
*sync.Mutex
|
||||
MaxEntries int `js:"maxEntries"`
|
||||
}
|
||||
|
||||
func NewLogger(maxEntries int) *jsLoggerData {
|
||||
loggerVmData := &jsLoggerData{
|
||||
Object: js.Global.Get("Object").New(),
|
||||
}
|
||||
|
||||
loggerVmData.Mutex = &sync.Mutex{}
|
||||
loggerVmData.LogArray = js.Global.Get("Array").New()
|
||||
loggerVmData.EventArray = js.Global.Get("Array").New()
|
||||
loggerVmData.MaxEntries = maxEntries
|
||||
|
||||
return loggerVmData
|
||||
}
|
||||
|
||||
/* This method gets internalized and therefor the mutex won't be accessible*/
|
||||
func (data *jsLoggerData) AddEntry(ev *pb.Event ) {
|
||||
@ -191,6 +262,23 @@ func (data *jsLoggerData) AddEntry(ev *pb.Event ) {
|
||||
defer data.Unlock()
|
||||
*/
|
||||
|
||||
fmt.Println("LOOOOOG ENTRYYYYYYYYYYYYYYYYY")
|
||||
|
||||
//if LOG event add to logArray
|
||||
jsEv := NewJsEventFromNative(ev)
|
||||
println("JS from native", jsEv)
|
||||
if jsEv.Type == common.EVT_LOG {
|
||||
if logEv,err := jsEv.toLogEvent(); err == nil {
|
||||
data.LogArray.Call("push", logEv)
|
||||
} else {
|
||||
println("couldn't convert to LogEvent: ", jsEv)
|
||||
}
|
||||
} else {
|
||||
data.EventArray.Call("push", jsEv)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
logEv, err := DeconstructEventLog(ev)
|
||||
if err != nil {
|
||||
println("Logger: Error adding log entry, provided event couldn't be converted to log event")
|
||||
@ -198,11 +286,15 @@ func (data *jsLoggerData) AddEntry(ev *pb.Event ) {
|
||||
}
|
||||
|
||||
data.LogArray.Call("push", logEv)
|
||||
*/
|
||||
|
||||
//reduce to length (note: kebab case 'max-entries' is translated to camel case 'maxEntries' by vue)
|
||||
for data.LogArray.Length() > data.MaxEntries {
|
||||
data.LogArray.Call("shift") // remove first element
|
||||
}
|
||||
for data.EventArray.Length() > data.MaxEntries {
|
||||
data.EventArray.Call("shift") // remove first element
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
@ -224,6 +316,7 @@ func (data *jsLoggerData) StartListening() {
|
||||
|
||||
go func() {
|
||||
defer cancel()
|
||||
println("EVENTLISTENING ENTERING LOOP")
|
||||
for {
|
||||
event, err := evStream.Recv()
|
||||
if err == io.EOF { break }
|
||||
@ -231,8 +324,9 @@ func (data *jsLoggerData) StartListening() {
|
||||
|
||||
//println("Event: ", event)
|
||||
data.AddEntry(event)
|
||||
|
||||
println(event)
|
||||
}
|
||||
println("EVENTLISTENING ABORTED")
|
||||
return
|
||||
}()
|
||||
}
|
||||
@ -242,14 +336,3 @@ func (data *jsLoggerData) StopListening() {
|
||||
data.cancel()
|
||||
}
|
||||
|
||||
func NewLogger(maxEntries int) *jsLoggerData {
|
||||
loggerVmData := &jsLoggerData{
|
||||
Object: js.Global.Get("Object").New(),
|
||||
}
|
||||
|
||||
loggerVmData.Mutex = &sync.Mutex{}
|
||||
loggerVmData.LogArray = js.Global.Get("Array").New()
|
||||
loggerVmData.MaxEntries = maxEntries
|
||||
|
||||
return loggerVmData
|
||||
}
|
@ -69,6 +69,7 @@ func main() {
|
||||
|
||||
InitGlobalState() //sets Vuex store in JS window.store
|
||||
|
||||
InitCompModal()
|
||||
InitCompEthernetAddresses2()
|
||||
InitCompToggleSwitch()
|
||||
InitCompUSBSettings()
|
||||
|
@ -52,24 +52,6 @@ type GlobalState struct {
|
||||
Text string `js:"text"`
|
||||
}
|
||||
|
||||
/*
|
||||
func (state *GlobalState) UpdateGadgetSettingsFromDeployed(jsGS *jsGadgetSettings) {
|
||||
//gs := vue.GetVM(c).Get("gadgetSettings")
|
||||
println("UpdateGadgetSettingsFromDeployed called")
|
||||
|
||||
|
||||
|
||||
ctx,cancel := context.WithTimeout(context.Background(), time.Second*3)
|
||||
defer cancel()
|
||||
|
||||
|
||||
deployedGs, err := Client.Client.GetDeployedGadgetSetting(ctx, &pb.Empty{})
|
||||
if err != nil { println(err); return } // ToDo: change to alert with parsed status
|
||||
|
||||
jsGS.fromGS(deployedGs)
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
func createGlobalStateStruct() GlobalState {
|
||||
state := GlobalState{Object:O()}
|
||||
@ -115,7 +97,7 @@ func actionDeployCurrentGadgetSettings(store *mvuex.Store, context *mvuex.Action
|
||||
err := RpcSetRemoteGadgetSettings(curGS, time.Second)
|
||||
if err != nil {
|
||||
//ToDo: use global store to return something, or allow actions to return promises (latter is too much JavaScript)
|
||||
Alert(err)
|
||||
Alert(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@ -123,7 +105,7 @@ func actionDeployCurrentGadgetSettings(store *mvuex.Store, context *mvuex.Action
|
||||
_,err = RpcDeployRemoteGadgetSettings(time.Second*10)
|
||||
if err != nil {
|
||||
//ToDo: use global store to return something, or allow actions to return promises (latter is too much JavaScript)
|
||||
Alert(err)
|
||||
Alert(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,9 @@ package main
|
||||
import (
|
||||
pb "../proto/gopherjs"
|
||||
"context"
|
||||
"io"
|
||||
"sync"
|
||||
"errors"
|
||||
"github.com/johanbrandhorst/protobuf/grpcweb"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Rpc struct {
|
||||
@ -17,6 +16,7 @@ type Rpc struct {
|
||||
eventListeningCancel *context.CancelFunc
|
||||
}
|
||||
|
||||
/*
|
||||
func (rpc *Rpc) StartListenEvents(evtType int64) (err error) {
|
||||
rpc.Lock()
|
||||
if rpc.eventListeningOn {
|
||||
@ -65,6 +65,7 @@ func (rpc *Rpc) StopEventListening() {
|
||||
rpc.eventListeningOn = false
|
||||
rpc.Unlock()
|
||||
}
|
||||
*/
|
||||
|
||||
func NewRpcClient(addr string) Rpc {
|
||||
rcl := Rpc{}
|
||||
@ -73,3 +74,48 @@ func NewRpcClient(addr string) Rpc {
|
||||
rcl.Client = cl
|
||||
return rcl
|
||||
}
|
||||
|
||||
func RpcGetDeployedGadgetSettings(timeout time.Duration) (*pb.GadgetSettings, error) {
|
||||
//gs := vue.GetVM(c).Get("gadgetSettings")
|
||||
println("RpcGetDeployedGadgetSettings called")
|
||||
|
||||
ctx,cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
|
||||
return Client.Client.GetDeployedGadgetSetting(ctx, &pb.Empty{})
|
||||
|
||||
}
|
||||
|
||||
|
||||
func RpcSetRemoteGadgetSettings(targetGS *pb.GadgetSettings, timeout time.Duration) (err error) {
|
||||
//gs := vue.GetVM(c).Get("gadgetSettings")
|
||||
println("RpcSetRemoteGadgetSettings called")
|
||||
|
||||
ctx,cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
|
||||
//Set gadget settings
|
||||
_, err = Client.Client.SetGadgetSettings(ctx, targetGS)
|
||||
if err != nil {
|
||||
//js.Global.Call("alert", "Error setting given gadget settings: " + status.Convert(err).Message())
|
||||
//println(err)
|
||||
//c.UpdateFromDeployedGadgetSettings(vm)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func RpcDeployRemoteGadgetSettings(timeout time.Duration) (*pb.GadgetSettings, error) {
|
||||
//gs := vue.GetVM(c).Get("gadgetSettings")
|
||||
println("RpcDeployRemoteGadgetSettings called")
|
||||
|
||||
ctx,cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
|
||||
return Client.Client.DeployGadgetSetting(ctx, &pb.Empty{})
|
||||
|
||||
}
|
||||
|
@ -7,8 +7,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="codemirror/lib/codemirror.js"></script>
|
||||
<link rel="stylesheet" href="codemirror/lib/codemirror.css">
|
||||
<script src="codemirror/mode/javascript/javascript.js"></script>
|
||||
@ -24,6 +22,70 @@
|
||||
height: 60%;
|
||||
}
|
||||
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
z-index: 9998;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, .5);
|
||||
display: table;
|
||||
transition: opacity .3s ease;
|
||||
}
|
||||
|
||||
.modal-wrapper {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
width: 300px;
|
||||
margin: 0px auto;
|
||||
padding: 20px 30px;
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, .33);
|
||||
transition: all .3s ease;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.modal-header h3 {
|
||||
margin-top: 0;
|
||||
color: #42b983;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.modal-default-button {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following styles are auto-applied to elements with
|
||||
* transition="modal" when their visibility is toggled
|
||||
* by Vue.js.
|
||||
*
|
||||
* You can easily play with the modal transition by editing
|
||||
* these styles.
|
||||
*/
|
||||
|
||||
.modal-enter {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.modal-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.modal-enter .modal-container,
|
||||
.modal-leave-active .modal-container {
|
||||
-webkit-transform: scale(1.1);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
@ -41,6 +103,10 @@
|
||||
<td><state></state></td>
|
||||
</tr>
|
||||
</table>
|
||||
<modal v-if="$store.state.isModalEnabled" @close="$store.commit('setModalEnabled',false)">
|
||||
<h3 slot="header">My header</h3>
|
||||
<p slot="body">Some body text</p>
|
||||
</modal>
|
||||
|
||||
<tabs>
|
||||
<tab header="USB">
|
||||
|
1033
www/webapp.js
1033
www/webapp.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user