mirror of
https://github.com/RoganDawes/P4wnP1_aloa.git
synced 2025-03-17 13:21:50 +01:00
Modified boilerplate code for web-client to allow changing USB gadget settings
This commit is contained in:
parent
b7d0885fd6
commit
579c2cb2ca
1
ToDo.txt
1
ToDo.txt
@ -51,6 +51,7 @@ LOGGING:
|
||||
|
||||
OTHER:
|
||||
- extend installer to movee HIDScripts to a fixed absolute path
|
||||
- proper error extraction from gRPC calls
|
||||
|
||||
TO FIX:
|
||||
- debug out of HIDScript puts way to much CPU load on journaling daemon (floods logs)
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# dependencies for the web app
|
||||
gopherjs build -o ../www/webapp.js main.go
|
||||
gopherjs build -o ../www/webapp.js #main.go
|
||||
|
@ -1,8 +1,18 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>gRPC test</title>
|
||||
<head>
|
||||
<title>P4wnP1 by MaMe82</title>
|
||||
<link rel="stylesheet" type="text/css" href="p4wnp1.css">
|
||||
</head>
|
||||
<body>
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
<body>
|
||||
|
||||
|
||||
<h1>P4wnP1 service - USB settings</h1>
|
||||
<p>See Javascript console for details, entry script is webapp.js (generated by gopherjs)</p>
|
||||
|
||||
<div id="app">
|
||||
<usb-settings></usb-settings>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="webapp.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -8,35 +8,52 @@ import (
|
||||
|
||||
pb "../proto/gopherjs"
|
||||
dom "honnef.co/go/js/dom"
|
||||
"github.com/oskca/gopherjs-vue"
|
||||
"github.com/gopherjs/gopherjs/js"
|
||||
)
|
||||
|
||||
var (
|
||||
document = dom.GetWindow().Document().(dom.HTMLDocument)
|
||||
serverAddr = "http://raspberrypi.local"
|
||||
serverAddr = GetBaseURL()
|
||||
Client = pb.NewP4WNP1Client(
|
||||
serverAddr + ":80",
|
||||
)
|
||||
GS *pb.GadgetSettings
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("Hello")
|
||||
func GetBaseURL() string {
|
||||
document := js.Global.Get("window").Get("document")
|
||||
location := document.Get("location")
|
||||
port := location.Get("port").String()
|
||||
url := location.Get("protocol").String() + "//" + location.Get("hostname").String()
|
||||
if len(port) > 0 {
|
||||
url = url + ":" + port
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
func main() {
|
||||
println(GetBaseURL())
|
||||
|
||||
|
||||
client := pb.NewP4WNP1Client(
|
||||
"http://raspberrypi.local:80",
|
||||
)
|
||||
fmt.Printf("Address %v\n", strings.TrimSuffix(document.BaseURI(), "/"))
|
||||
fmt.Printf("Client %v\n", client)
|
||||
fmt.Printf("Client %v\n", Client)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
gs, err := client.GetDeployedGadgetSetting(ctx, &pb.Empty{})
|
||||
gs, err := Client.GetDeployedGadgetSetting(ctx, &pb.Empty{})
|
||||
if err == nil {
|
||||
str:=fmt.Sprintf("Gs: %+v\n", gs)
|
||||
fmt.Println(str)
|
||||
div_cont:= dom.GetWindow().Document().GetElementByID("content").(*dom.HTMLDivElement)
|
||||
new_div := dom.GetWindow().Document().CreateElement("div").(*dom.HTMLDivElement)
|
||||
new_div.SetTextContent(fmt.Sprintf("Result of GetDeployedGadgetSetting gRPC-web call:\n%s ",str))
|
||||
div_cont.AppendChild(new_div)
|
||||
//export Gadget setting
|
||||
js.Global.Set("gs", gs)
|
||||
GS = gs
|
||||
} else {
|
||||
fmt.Printf("Error rpc call: %v\n", err)
|
||||
}
|
||||
|
||||
|
||||
vue.NewComponent(New, template).Register("usb-settings")
|
||||
vm := vue.New("#app", new(controller))
|
||||
js.Global.Set("vm", vm)
|
||||
println("vm:", vm)
|
||||
}
|
||||
|
150
web_client/p4wnp1.css
Normal file
150
web_client/p4wnp1.css
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox">
|
||||
<div>
|
||||
<span class="on">On</span>
|
||||
<span class="off">Off</span>
|
||||
</div>
|
||||
<span class="toggle-switch-slider"></span>
|
||||
</label>
|
||||
|
||||
*/
|
||||
|
||||
|
||||
.toggle-switch {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 80px;
|
||||
height: 30px;
|
||||
background-color: gray;
|
||||
background: linear-gradient(to top, #f4f4f4, #9e9e9e 20%);
|
||||
border-radius: 99999px;
|
||||
/* box-shadow: h-offset v-offset blur spread color inset initial inherit */
|
||||
box-shadow: 0 2px 0 0 #FFFFFF, 0 -2px 0 0 #f4f4f4; /* 2px offset gray to top, white to bottom */
|
||||
}
|
||||
|
||||
|
||||
.toggle-switch input[type="checkbox"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.toggle-switch div {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 80%;
|
||||
height: 60%;
|
||||
border-radius: 99999px;
|
||||
-moz-transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
position: absolute;
|
||||
background-color: #707070;
|
||||
box-shadow: inset 0 0 10px 0 rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
.toggle-switch input[type="checkbox"]:checked ~ div {
|
||||
/* box-shadow: h-offset v-offset blur spread color inset initial inherit */
|
||||
box-shadow: inset 0 0 9px 0 rgba(0, 100, 0, 0.8),0 0 11px 1px rgb(150,255,0);
|
||||
background-color: rgb(150,250,0);
|
||||
}
|
||||
|
||||
.toggle-switch input[type="checkbox"] ~ .toggle-switch-slider {
|
||||
display: block;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
position: absolute;
|
||||
background: linear-gradient(to top, #9e9e9e 20%, #f4f4f4);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.7);
|
||||
top: 0;
|
||||
left: 0;
|
||||
/*
|
||||
transition: all 0.3s ease-in 0s;
|
||||
*/
|
||||
transition: .25s;
|
||||
}
|
||||
|
||||
.toggle-switch input[type="checkbox"] ~ .toggle-switch-slider:after {
|
||||
content: "";
|
||||
display: block;
|
||||
left: 15%;
|
||||
top: 15%;
|
||||
width: 70%;
|
||||
height: 70%;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
background: linear-gradient(to top, #f4f4f4, #9e9e9e);
|
||||
/*
|
||||
z-index: 1;
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
.toggle-switch input[type="checkbox"]:checked ~ .toggle-switch-slider {
|
||||
-moz-transform: translate(-100%, 0);
|
||||
-ms-transform: translate(-100%, 0);
|
||||
-webkit-transform: translate(-100%, 0);
|
||||
transform: translate(-100%, 0);
|
||||
|
||||
|
||||
left: 100%;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.toggle-switch div > .on,.off {
|
||||
|
||||
|
||||
|
||||
|
||||
position: absolute;
|
||||
|
||||
|
||||
/*
|
||||
background-color: #34A7C1;
|
||||
*/
|
||||
|
||||
top: 50%;
|
||||
text-transform: uppercase;
|
||||
|
||||
-webkit-transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
font-size: 0.8em;
|
||||
font-weight: 600;
|
||||
z-index: 2;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
letter-spacing: 1px;
|
||||
|
||||
|
||||
transition: .25s;
|
||||
}
|
||||
|
||||
|
||||
.on {
|
||||
left: 10%;
|
||||
color: transparent;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0);
|
||||
}
|
||||
|
||||
.toggle-switch input[type="checkbox"]:checked ~ div > .on {
|
||||
color: rgb(0,154,0);
|
||||
text-shadow: 0px 1px 0px rgba(27,76,37, 0.5);
|
||||
}
|
||||
|
||||
.off {
|
||||
right: 10%;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.toggle-switch input[type="checkbox"]:checked + div > .off {
|
||||
color: transparent;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0);
|
||||
}
|
||||
|
||||
|
333
web_client/vueCompUSBSettings.go
Normal file
333
web_client/vueCompUSBSettings.go
Normal file
@ -0,0 +1,333 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gopherjs/gopherjs/js"
|
||||
pb "../proto/gopherjs"
|
||||
"fmt"
|
||||
"time"
|
||||
"context"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
|
||||
type VGadgetSettings struct {
|
||||
*js.Object
|
||||
Enabled bool `js:"Enabled"`
|
||||
Vid string `js:"Vid"`
|
||||
Pid string `js:"Pid"`
|
||||
Manufacturer string `js:"Manufacturer"`
|
||||
Product string `js:"Product"`
|
||||
Serial string `js:"Serial"`
|
||||
Use_CDC_ECM bool `js:"Use_CDC_ECM"`
|
||||
Use_RNDIS bool `js:"Use_RNDIS"`
|
||||
Use_HID_KEYBOARD bool `js:"Use_HID_KEYBOARD"`
|
||||
Use_HID_MOUSE bool `js:"Use_HID_MOUSE"`
|
||||
Use_HID_RAW bool `js:"Use_HID_RAW"`
|
||||
Use_UMS bool `js:"Use_UMS"`
|
||||
Use_SERIAL bool `js:"Use_SERIAL"`
|
||||
RndisSettings *VGadgetSettingsEthernet `js:"RndisSettings"`
|
||||
CdcEcmSettings *VGadgetSettingsEthernet `js:"CdcEcmSettings"`
|
||||
UmsSettings *VGadgetSettingsUMS `js:"UmsSettings"`
|
||||
}
|
||||
|
||||
type VGadgetSettingsEthernet struct {
|
||||
*js.Object
|
||||
HostAddr string `js:"HostAddr"`
|
||||
DevAddr string `js:"DevAddr"`
|
||||
}
|
||||
|
||||
|
||||
type VGadgetSettingsUMS struct {
|
||||
*js.Object
|
||||
Cdrom bool `js:"Cdrom"`
|
||||
File string `js:"File"`
|
||||
}
|
||||
|
||||
func (vGS VGadgetSettings) toGS() (gs *pb.GadgetSettings) {
|
||||
return &pb.GadgetSettings{
|
||||
Serial: vGS.Serial,
|
||||
Use_SERIAL: vGS.Use_SERIAL,
|
||||
Use_UMS: vGS.Use_UMS,
|
||||
Use_HID_RAW: vGS.Use_HID_RAW,
|
||||
Use_HID_MOUSE: vGS.Use_HID_MOUSE,
|
||||
Use_HID_KEYBOARD: vGS.Use_HID_KEYBOARD,
|
||||
Use_RNDIS: vGS.Use_RNDIS,
|
||||
Use_CDC_ECM: vGS.Use_CDC_ECM,
|
||||
Product: vGS.Product,
|
||||
Manufacturer: vGS.Manufacturer,
|
||||
Vid: vGS.Vid,
|
||||
Pid: vGS.Pid,
|
||||
Enabled: vGS.Enabled,
|
||||
UmsSettings: &pb.GadgetSettingsUMS{
|
||||
Cdrom: vGS.UmsSettings.Cdrom,
|
||||
File: vGS.UmsSettings.File,
|
||||
},
|
||||
CdcEcmSettings: &pb.GadgetSettingsEthernet{
|
||||
DevAddr: vGS.CdcEcmSettings.DevAddr,
|
||||
HostAddr: vGS.CdcEcmSettings.HostAddr,
|
||||
},
|
||||
RndisSettings: &pb.GadgetSettingsEthernet{
|
||||
DevAddr: vGS.RndisSettings.DevAddr,
|
||||
HostAddr: vGS.RndisSettings.HostAddr,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (vGS *VGadgetSettings) fromGS(gs *pb.GadgetSettings) {
|
||||
vGS.Enabled = gs.Enabled
|
||||
vGS.Vid = gs.Vid
|
||||
vGS.Pid = gs.Pid
|
||||
vGS.Manufacturer = gs.Manufacturer
|
||||
vGS.Product = gs.Product
|
||||
vGS.Serial = gs.Serial
|
||||
vGS.Use_CDC_ECM = gs.Use_CDC_ECM
|
||||
vGS.Use_RNDIS = gs.Use_RNDIS
|
||||
vGS.Use_HID_KEYBOARD = gs.Use_HID_KEYBOARD
|
||||
vGS.Use_HID_MOUSE = gs.Use_HID_MOUSE
|
||||
vGS.Use_HID_RAW = gs.Use_HID_RAW
|
||||
vGS.Use_UMS = gs.Use_UMS
|
||||
vGS.Use_SERIAL = gs.Use_SERIAL
|
||||
|
||||
vGS.RndisSettings = &VGadgetSettingsEthernet{
|
||||
Object: js.Global.Get("Object").New(),
|
||||
}
|
||||
if gs.RndisSettings != nil {
|
||||
vGS.RndisSettings.HostAddr = gs.RndisSettings.HostAddr
|
||||
vGS.RndisSettings.DevAddr = gs.RndisSettings.DevAddr
|
||||
}
|
||||
|
||||
vGS.CdcEcmSettings = &VGadgetSettingsEthernet{
|
||||
Object: js.Global.Get("Object").New(),
|
||||
}
|
||||
if gs.CdcEcmSettings != nil {
|
||||
vGS.CdcEcmSettings.HostAddr = gs.CdcEcmSettings.HostAddr
|
||||
vGS.CdcEcmSettings.DevAddr = gs.CdcEcmSettings.DevAddr
|
||||
}
|
||||
|
||||
vGS.UmsSettings = &VGadgetSettingsUMS{
|
||||
Object: js.Global.Get("Object").New(),
|
||||
}
|
||||
if gs.UmsSettings != nil {
|
||||
vGS.UmsSettings.File = gs.UmsSettings.File
|
||||
vGS.UmsSettings.Cdrom = gs.UmsSettings.Cdrom
|
||||
}
|
||||
}
|
||||
|
||||
// Note: internalize wouldn't work on this, as the nested structs don't translate back
|
||||
type Com struct {
|
||||
*js.Object
|
||||
|
||||
GadgetSettings *VGadgetSettings `js:"gadgetSettings"`
|
||||
}
|
||||
|
||||
|
||||
func (c *Com) UodateToDeployedGadgetSettings() {
|
||||
//gs := vue.GetVM(c).Get("gadgetSettings")
|
||||
println("Trying to fetch deployed GadgetSettings")
|
||||
|
||||
go func() {
|
||||
ctx,cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
fmt.Printf("Before client + request\n")
|
||||
deployedGs, err := pb.NewP4WNP1Client(serverAddr).GetDeployedGadgetSetting(ctx, &pb.Empty{})
|
||||
if err != nil { fmt.Println(err); return }
|
||||
|
||||
newGs := &VGadgetSettings{
|
||||
Object: js.Global.Get("Object").New(),
|
||||
}
|
||||
newGs.fromGS(deployedGs)
|
||||
c.GadgetSettings = newGs
|
||||
}()
|
||||
}
|
||||
|
||||
func (c *Com) ApplyGadgetSettings() {
|
||||
//gs := vue.GetVM(c).Get("gadgetSettings")
|
||||
println("Trying to deploy GadgetSettings: " + fmt.Sprintf("%+v",c.GadgetSettings.toGS()))
|
||||
|
||||
gs:=c.GadgetSettings.toGS()
|
||||
go func() {
|
||||
//ToDo: set apply button to inactive
|
||||
//ToDo: defer set apply button to active
|
||||
|
||||
ctx,cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
client := pb.NewP4WNP1Client(serverAddr)
|
||||
|
||||
//Set gadget settings
|
||||
settedGs, err := client.SetGadgetSettings(ctx, gs)
|
||||
if err != nil {
|
||||
js.Global.Call("alert", "Error setting given gadget settings: " + status.Convert(err).Message())
|
||||
fmt.Println(err)
|
||||
c.UodateToDeployedGadgetSettings()
|
||||
return
|
||||
}
|
||||
println(fmt.Sprintf("The following GadgetSettings have been set: %+v", settedGs))
|
||||
|
||||
|
||||
|
||||
//deploy the settings
|
||||
deployedGs,err := client.DeployGadgetSetting(ctx, &pb.Empty{})
|
||||
if err != nil {
|
||||
js.Global.Call("alert", "Error deploying gadget settings: " + status.Convert(err).Message())
|
||||
fmt.Println(err)
|
||||
c.UodateToDeployedGadgetSettings()
|
||||
return
|
||||
}
|
||||
println(fmt.Sprintf("The following GadgetSettings have been deployed: %+v", deployedGs))
|
||||
|
||||
js.Global.Call("alert", "New USB gadget settings deployed ")
|
||||
|
||||
newGs := &VGadgetSettings{
|
||||
Object: js.Global.Get("Object").New(),
|
||||
}
|
||||
newGs.fromGS(deployedGs)
|
||||
c.GadgetSettings = newGs
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
func New() interface{} {
|
||||
|
||||
cc := &Com{
|
||||
Object: js.Global.Get("Object").New(),
|
||||
}
|
||||
|
||||
cc.GadgetSettings = &VGadgetSettings{
|
||||
Object: js.Global.Get("Object").New(),
|
||||
}
|
||||
|
||||
|
||||
cc.UodateToDeployedGadgetSettings()
|
||||
|
||||
|
||||
|
||||
fmt.Printf("Client: %+v\n", Client)
|
||||
fmt.Printf("cc.gadgetSettings: %+v\n", cc.GadgetSettings)
|
||||
fmt.Printf("GS.Vid: %+v\n", GS.Vid)
|
||||
fmt.Printf("cc.gadgetSettings.Vid: %+v\n", cc.GadgetSettings.Vid)
|
||||
|
||||
return cc
|
||||
}
|
||||
|
||||
type controller struct {
|
||||
*js.Object
|
||||
}
|
||||
|
||||
const (
|
||||
template = `
|
||||
<div>
|
||||
<table>
|
||||
<tr> <td>USB gadget settings</td><td><button @click="ApplyGadgetSettings">Apply</button></td> </tr>
|
||||
|
||||
<tr>
|
||||
<td>Gadget enabled</td>
|
||||
<td>
|
||||
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" v-model="gadgetSettings.Enabled">
|
||||
<div><span class="on">On</span><span class="off">Off</span></div>
|
||||
<span class="toggle-switch-slider"></span>
|
||||
</label>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr> <td>Vendor ID</td><td><input v-model="gadgetSettings.Vid"/></td> </tr>
|
||||
<tr> <td>Product ID</td><td><input v-model="gadgetSettings.Pid"/></td> </tr>
|
||||
<tr> <td>Manufacturer Name</td><td><input v-model="gadgetSettings.Manufacturer"/></td> </tr>
|
||||
<tr> <td>Product Name</td><td><input v-model="gadgetSettings.Product"/></td> </tr>
|
||||
<tr> <td>Serial number</td><td><input v-model="gadgetSettings.Serial"/></td> </tr>
|
||||
|
||||
<tr>
|
||||
<td>CDC ECM</td>
|
||||
<td>
|
||||
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" v-model="gadgetSettings.Use_CDC_ECM">
|
||||
<div><span class="on">On</span><span class="off">Off</span></div>
|
||||
<span class="toggle-switch-slider"></span>
|
||||
</label>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RNDIS</td>
|
||||
<td>
|
||||
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" v-model="gadgetSettings.Use_RNDIS">
|
||||
<div><span class="on">On</span><span class="off">Off</span></div>
|
||||
<span class="toggle-switch-slider"></span>
|
||||
</label>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>HID Keyboard</td>
|
||||
<td>
|
||||
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" v-model="gadgetSettings.Use_HID_KEYBOARD">
|
||||
<div><span class="on">On</span><span class="off">Off</span></div>
|
||||
<span class="toggle-switch-slider"></span>
|
||||
</label>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>HID Mouse</td>
|
||||
<td>
|
||||
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" v-model="gadgetSettings.Use_HID_MOUSE">
|
||||
<div><span class="on">On</span><span class="off">Off</span></div>
|
||||
<span class="toggle-switch-slider"></span>
|
||||
</label>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>HID Raw</td>
|
||||
<td>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" v-model="gadgetSettings.Use_HID_RAW">
|
||||
<div><span class="on">On</span><span class="off">Off</span></div>
|
||||
<span class="toggle-switch-slider"></span>
|
||||
</label>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Serial</td>
|
||||
<td>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" v-model="gadgetSettings.Use_SERIAL">
|
||||
<div><span class="on">On</span><span class="off">Off</span></div>
|
||||
<span class="toggle-switch-slider"></span>
|
||||
</label>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mass Storage</td>
|
||||
<td>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" v-model="gadgetSettings.Use_UMS">
|
||||
<div><span class="on">On</span><span class="off">Off</span></div>
|
||||
<span class="toggle-switch-slider"></span>
|
||||
</label>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
`
|
||||
)
|
||||
|
@ -1,11 +1,18 @@
|
||||
<html>
|
||||
<head><title>Hello</title></head>
|
||||
<head>
|
||||
<title>P4wnP1 by MaMe82</title>
|
||||
<link rel="stylesheet" type="text/css" href="p4wnp1.css">
|
||||
</head>
|
||||
<body>
|
||||
<script src="webapp.js"></script>
|
||||
|
||||
<h1>Testpage for P4wnP1 service</h1>
|
||||
|
||||
<h1>P4wnP1 service - USB settings</h1>
|
||||
<p>See Javascript console for details, entry script is webapp.js (generated by gopherjs)</p>
|
||||
|
||||
<div id="content"></div>
|
||||
<div id="app">
|
||||
<usb-settings></usb-settings>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="webapp.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
194
www/p4wnp1.css
Normal file
194
www/p4wnp1.css
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox">
|
||||
<div>
|
||||
<span class="on">On</span>
|
||||
<span class="off">Off</span>
|
||||
</div>
|
||||
<span class="toggle-switch-slider"></span>
|
||||
</label>
|
||||
|
||||
*/
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
font-size: 1em;
|
||||
line-height: 1.6;
|
||||
background: linear-gradient(45deg, #9e9e9e, #c4c4c4 66%, #9e9e9e);
|
||||
}
|
||||
|
||||
input {
|
||||
/*border-radius: 99999px;*/
|
||||
background-color: #707070;
|
||||
background: linear-gradient(to top, #9e9e9e, #f4f4f4);
|
||||
height: 30px;
|
||||
box-shadow: inset 0 0 10px 0 rgba(0, 0, 0, 0.7);
|
||||
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
font-size: 0.9em;
|
||||
font-weight: 600;
|
||||
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 99999px;
|
||||
background-color: #707070;
|
||||
background: linear-gradient(to top, #f4f4f4, #9e9e9e);
|
||||
|
||||
height: 30px;
|
||||
width: 100px;
|
||||
|
||||
text-transform: uppercase;
|
||||
font-size: 0.9em;
|
||||
font-weight: 800;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
letter-spacing: 1px;
|
||||
|
||||
}
|
||||
|
||||
.toggle-switch {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 80px;
|
||||
height: 30px;
|
||||
background-color: gray;
|
||||
background: linear-gradient(to top, #f4f4f4, #9e9e9e 20%);
|
||||
border-radius: 99999px;
|
||||
/* box-shadow: h-offset v-offset blur spread color inset initial inherit */
|
||||
box-shadow: 1px 1px 1px 0 #3f3f3f, -1px -1px 1px 0 #ffffff; /* 2px offset gray to top, white to bottom */
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
.toggle-switch input[type="checkbox"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.toggle-switch div {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 80%;
|
||||
height: 60%;
|
||||
border-radius: 99999px;
|
||||
-moz-transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
position: absolute;
|
||||
background-color: #707070;
|
||||
box-shadow: inset 0 0 10px 0 rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
.toggle-switch input[type="checkbox"]:checked ~ div {
|
||||
/* box-shadow: h-offset v-offset blur spread color inset initial inherit */
|
||||
box-shadow: inset 0 0 9px 0 rgba(0, 100, 0, 0.8),0 0 11px 1px rgb(150,255,0);
|
||||
background-color: rgb(150,250,0);
|
||||
}
|
||||
|
||||
.toggle-switch input[type="checkbox"] ~ .toggle-switch-slider {
|
||||
display: block;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
position: absolute;
|
||||
background: linear-gradient(to top, #9e9e9e 20%, #f4f4f4);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.7);
|
||||
top: 0;
|
||||
left: 0;
|
||||
/*
|
||||
transition: all 0.3s ease-in 0s;
|
||||
*/
|
||||
transition: .25s;
|
||||
}
|
||||
|
||||
.toggle-switch input[type="checkbox"] ~ .toggle-switch-slider:after {
|
||||
content: "";
|
||||
display: block;
|
||||
left: 15%;
|
||||
top: 15%;
|
||||
width: 70%;
|
||||
height: 70%;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
background: linear-gradient(to top, #f4f4f4, #9e9e9e);
|
||||
/*
|
||||
z-index: 1;
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
.toggle-switch input[type="checkbox"]:checked ~ .toggle-switch-slider {
|
||||
-moz-transform: translate(-100%, 0);
|
||||
-ms-transform: translate(-100%, 0);
|
||||
-webkit-transform: translate(-100%, 0);
|
||||
transform: translate(-100%, 0);
|
||||
|
||||
|
||||
left: 100%;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.toggle-switch div > .on,.off {
|
||||
|
||||
|
||||
|
||||
|
||||
position: absolute;
|
||||
|
||||
|
||||
/*
|
||||
background-color: #34A7C1;
|
||||
*/
|
||||
|
||||
top: 50%;
|
||||
text-transform: uppercase;
|
||||
|
||||
-webkit-transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
font-size: 0.8em;
|
||||
font-weight: 600;
|
||||
z-index: 2;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
letter-spacing: 1px;
|
||||
|
||||
|
||||
transition: .25s;
|
||||
}
|
||||
|
||||
|
||||
.on {
|
||||
left: 10%;
|
||||
color: transparent;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0);
|
||||
}
|
||||
|
||||
.toggle-switch input[type="checkbox"]:checked ~ div > .on {
|
||||
color: rgb(0,154,0);
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.off {
|
||||
right: 10%;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.toggle-switch input[type="checkbox"]:checked + div > .off {
|
||||
color: transparent;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0);
|
||||
}
|
||||
|
||||
|
19065
www/webapp.js
19065
www/webapp.js
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
32051
www/webapp.js.old
32051
www/webapp.js.old
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user