diff --git a/public/global.css b/public/global.css
index 5da789b..faf38f0 100644
--- a/public/global.css
+++ b/public/global.css
@@ -12,7 +12,7 @@ body {
color: #ddd;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
- font-size: 1rem;
+ /* font-size: 1rem; */
user-select: none;
}
@@ -23,20 +23,49 @@ pre {
body {
margin: 0;
padding: 1rem;
+ border: 0.125rem solid #333;
}
+/* titlebar */
+
+.titlebar {
+ user-select: none;
+ background: #333;
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ padding: 0.25rem 0.5rem;
+ height: 2rem;
+}
+
+.header-icon {
+ max-height: 100%;
+}
+
+.header-icon img {
+ max-height: 1.5rem;
+ pointer-events: none;
+}
+
+.header {
+ font-size: 1.5rem;
+ font-weight: 500;
+}
+
+/* main */
+
.main {
+ margin-top: 2rem;
display: flex;
flex-flow: column nowrap;
align-items: stretch;
justify-content: flex-start;
}
-.header {
- font-size: 2rem;
- font-weight: 500;
-}
-
.row,
.row-2 {
margin: 0 0 0.5rem 0;
@@ -50,6 +79,14 @@ body {
flex: 1 1 0;
}
+.row .label[title] {
+ text-decoration: underline dotted;
+}
+
+.row .label[title]:hover {
+ text-decoration: underline;
+}
+
.row .input {
flex: 2 2 0;
}
@@ -58,9 +95,7 @@ body {
width: 100%;
max-height: 5rem;
overflow-x: auto;
-}
-.serverlist > pre {
- font-size: 0.75em;
+ font-size: 0.75rem;
}
input,
@@ -69,6 +104,7 @@ select {
background-color: #444;
color: #ddd;
border: none;
+ font-size: 1rem;
}
button {
@@ -92,6 +128,8 @@ button.primary {
background: rgb(35, 67, 211);
}
+/* Preview */
+
.preview {
width: 100%;
display: flex;
@@ -107,6 +145,9 @@ button.primary {
flex-flow: column-reverse nowrap;
align-items: stretch;
justify-content: flex-start;
+
+ border-radius: 0.5rem 0.5rem 0 0;
+ overflow: clip;
}
.air-data {
flex: 1 0;
@@ -121,6 +162,9 @@ button.primary {
.ground {
position: relative;
height: 3rem;
+
+ border-radius: 0 0 0.5rem 0.5rem;
+ overflow: clip;
}
.ground-btn,
@@ -176,7 +220,7 @@ button.primary {
display: flex;
flex-flow: row nowrap;
align-items: stretch;
- justify-content: flex-start;
+ justify-content: center;
}
.extra-data {
width: 1rem;
diff --git a/public/icon.png b/public/icon.png
new file mode 100644
index 0000000..4b6b3b9
Binary files /dev/null and b/public/icon.png differ
diff --git a/public/index.html b/public/index.html
index 5da7ed3..c05072b 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,18 +1,24 @@
-
-
-
+
+
+
- Svelte app
+ Svelte app
-
-
-
+
+
+
-
-
+
+
-
-
+
+
+
+
+
+
diff --git a/res/sshelper/index.html b/res/sshelper/index.html
new file mode 100644
index 0000000..23b27ec
--- /dev/null
+++ b/res/sshelper/index.html
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+ brokenithm-qr
+
+
+ slidershim brokenithm helper
+
+
+
+
diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock
index 45cf2d8..6caaae9 100644
--- a/src-tauri/Cargo.lock
+++ b/src-tauri/Cargo.lock
@@ -225,6 +225,12 @@ version = "3.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
+[[package]]
+name = "bytemuck"
+version = "1.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f"
+
[[package]]
name = "byteorder"
version = "1.4.3"
@@ -328,6 +334,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
+[[package]]
+name = "checked_int_cast"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17cc5e6b5ab06331c33589842070416baa137e8b0eb912b008cfd4a78ada7919"
+
[[package]]
name = "cocoa"
version = "0.24.0"
@@ -359,6 +371,12 @@ dependencies = [
"objc",
]
+[[package]]
+name = "color_quant"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
+
[[package]]
name = "com"
version = "0.2.0"
@@ -1073,6 +1091,16 @@ dependencies = [
"wasi 0.10.2+wasi-snapshot-preview1",
]
+[[package]]
+name = "gif"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b"
+dependencies = [
+ "color_quant",
+ "weezl",
+]
+
[[package]]
name = "gio"
version = "0.14.8"
@@ -1433,6 +1461,25 @@ dependencies = [
"winapi-util",
]
+[[package]]
+name = "image"
+version = "0.23.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1"
+dependencies = [
+ "bytemuck",
+ "byteorder",
+ "color_quant",
+ "gif",
+ "jpeg-decoder",
+ "num-iter",
+ "num-rational",
+ "num-traits",
+ "png 0.16.8",
+ "scoped_threadpool",
+ "tiff",
+]
+
[[package]]
name = "indexmap"
version = "1.8.0"
@@ -1537,6 +1584,15 @@ dependencies = [
"libc",
]
+[[package]]
+name = "jpeg-decoder"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2"
+dependencies = [
+ "rayon",
+]
+
[[package]]
name = "js-sys"
version = "0.3.56"
@@ -1872,6 +1928,17 @@ dependencies = [
"num-traits",
]
+[[package]]
+name = "num-rational"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
[[package]]
name = "num-traits"
version = "0.2.14"
@@ -2357,6 +2424,16 @@ dependencies = [
"unicode-xid",
]
+[[package]]
+name = "qrcode"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16d2f1455f3630c6e5107b4f2b94e74d76dea80736de0981fd27644216cff57f"
+dependencies = [
+ "checked_int_cast",
+ "image",
+]
+
[[package]]
name = "quote"
version = "1.0.15"
@@ -2649,6 +2726,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
+[[package]]
+name = "scoped_threadpool"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
+
[[package]]
name = "scopeguard"
version = "1.1.0"
@@ -2853,15 +2936,19 @@ name = "slidershim"
version = "0.1.1"
dependencies = [
"async-trait",
+ "base64",
"directories",
"env_logger",
"futures",
"futures-util",
"hyper",
+ "image",
"ipconfig",
"log",
+ "open",
"palette",
"path-clean",
+ "qrcode",
"rusb",
"serde",
"serde_json",
@@ -3336,6 +3423,17 @@ dependencies = [
"once_cell",
]
+[[package]]
+name = "tiff"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437"
+dependencies = [
+ "jpeg-decoder",
+ "miniz_oxide 0.4.4",
+ "weezl",
+]
+
[[package]]
name = "time"
version = "0.1.43"
@@ -3805,6 +3903,12 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "weezl"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e"
+
[[package]]
name = "widestring"
version = "0.5.1"
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index 0231800..9a5b3b2 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -20,6 +20,7 @@ serde = { version = "1.0", features = ["derive"] }
log = "0.4.14"
env_logger = "0.9.0"
simple-logging = "2.0.2"
+open = "2.0.2"
tauri = { version = "1.0.0-beta.8", features = ["shell-open", "system-tray"] }
futures = "0.3.19"
@@ -37,6 +38,9 @@ winapi = "0.3.9"
ipconfig = "0.3.0"
hyper = { version="0.14.16", features= ["server", "http1", "http2", "tcp", "stream", "runtime"] }
+base64 = "0.13.0"
+image = "0.23.14"
+qrcode = { version="0.12.0", features= ["image"] }
path-clean = "0.1.0"
tungstenite = { version="0.16.0", default-features=false }
tokio-tungstenite = "0.16.1"
diff --git a/src-tauri/res/www/app.js b/src-tauri/res/www/app.js
index 59828f1..de70579 100644
--- a/src-tauri/res/www/app.js
+++ b/src-tauri/res/www/app.js
@@ -1 +1 @@
-var throttle=function(e,t){var a=!0,n=null;return function o(){var s=this;a?(a=!1,setTimeout(function(){a=!0,n&&o.apply(s)},t),n?(e.apply(this,n),n=null):e.apply(this,arguments)):n=arguments}},keys=document.getElementsByClassName("key"),airKeys=[],midline=0,touchKeys=[],allKeys=[],topKeys=airKeys,bottomKeys=touchKeys,compileKey=function(e){var t=e.previousElementSibling,a=e.nextElementSibling;return{top:e.offsetTop,bottom:e.offsetTop+e.offsetHeight,left:e.offsetLeft,right:e.offsetLeft+e.offsetWidth,almostLeft:t?e.offsetLeft+e.offsetWidth/4:-99999,almostRight:a?e.offsetLeft+3*e.offsetWidth/4:99999,kflag:parseInt(e.dataset.kflag)+(parseInt(e.dataset.air)?32:0),isAir:!!parseInt(e.dataset.air),prevKeyRef:t,prevKeyKflag:t?parseInt(t.dataset.kflag)+(parseInt(t.dataset.air)?32:0):null,nextKeyRef:a,nextKeyKflag:a?parseInt(a.dataset.kflag)+(parseInt(a.dataset.air)?32:0):null,ref:e}},isInside=function(e,t,a){return a.left<=e&&e2)return wsTimeout=0,ws.close(),wsConnected=!1,void wsConnect();wsConnected&&ws.send("alive?")},canvas=document.getElementById("canvas"),canvasCtx=canvas.getContext("2d"),canvasData=canvasCtx.getImageData(0,0,33,1),setupLed=function(){for(var e=0;e<33;e++)canvasData.data[4*e+3]=255};setupLed();var updateLed=function(e){for(var t=new Uint8Array(e),a=0;a<32;a++)canvasData.data[4*a]=t[3*(31-a)+1],canvasData.data[4*a+1]=t[3*(31-a)+2],canvasData.data[4*a+2]=t[3*(31-a)+0];canvasData.data[128]=t[94],canvasData.data[129]=t[95],canvasData.data[130]=t[93],canvasCtx.putImageData(canvasData,0,0)},fs=document.getElementById("fullscreen"),requestFullscreen=function(){!document.fullscreenElement&&screen.height<=1024&&(fs.requestFullscreen?fs.requestFullscreen():fs.mozRequestFullScreen?fs.mozRequestFullScreen():fs.webkitRequestFullScreen&&fs.webkitRequestFullScreen())},throttledRequestFullscreen=throttle(requestFullscreen,3e3),cnt=document.getElementById("main");cnt.addEventListener("touchstart",updateTouches),cnt.addEventListener("touchmove",updateTouches),cnt.addEventListener("touchend",updateTouches);var readConfig=function(e){var t="";e.invert&&(t+=".container, .air-container {flex-flow: column-reverse nowrap;} ");var a=e.bgColor||"rbga(0, 0, 0, 0.9)";e.bgImage?t+="#fullscreen {background: ".concat(a,' url("').concat(e.bgImage,'") fixed center / cover!important; background-repeat: no-repeat;} '):t+="#fullscreen {background: ".concat(a,";} "),"number"==typeof e.ledOpacity&&(0===e.ledOpacity?t+="#canvas {display: none} ":t+="#canvas {opacity: ".concat(e.ledOpacity,"} ")),"string"==typeof e.keyColor&&(t+=".key[data-active] {background-color: ".concat(e.keyColor,";} ")),"string"==typeof e.keyColor&&(t+=".key.air[data-active] {background-color: ".concat(e.lkeyColor,";} ")),"string"==typeof e.keyBorderColor&&(t+=".key {border: 1px solid ".concat(e.keyBorderColor,";} ")),e.keyColorFade&&"number"==typeof e.keyColorFade&&(t+=".key:not([data-active]) {transition: background ".concat(e.keyColorFade,"ms ease-out;} ")),"number"==typeof e.keyHeight&&(0===e.keyHeight?t+=".touch-container {display: none;} ":t+=".touch-container {flex: ".concat(e.keyHeight,";} ")),"number"==typeof e.lkeyHeight&&(0===e.lkeyHeight?t+=".air-container {display: none;} ":t+=".air-container {flex: ".concat(e.keyHeight,";} "));var n=document.createElement("style");n.innerHTML=t,document.head.appendChild(n)},initialize=function(){readConfig(config),compileKeys(),wsConnect(),setInterval(wsWatch,1e3)};initialize(),window.onresize=compileKeys;
\ No newline at end of file
+const throttle=(e,t)=>{var a=!0,s=null;return function n(){var o=this;a?(a=!1,setTimeout(function(){a=!0,s&&n.apply(o)},t),s?(e.apply(this,s),s=null):e.apply(this,arguments)):s=arguments}};var keys=document.getElementsByClassName("key"),airKeys=[],midline=0,touchKeys=[],allKeys=[],topKeys=airKeys,bottomKeys=touchKeys;const compileKey=e=>{const t=e.previousElementSibling,a=e.nextElementSibling;return{top:e.offsetTop,bottom:e.offsetTop+e.offsetHeight,left:e.offsetLeft,right:e.offsetLeft+e.offsetWidth,almostLeft:t?e.offsetLeft+e.offsetWidth/4:-99999,almostRight:a?e.offsetLeft+3*e.offsetWidth/4:99999,kflag:parseInt(e.dataset.kflag)+(parseInt(e.dataset.air)?32:0),isAir:!!parseInt(e.dataset.air),prevKeyRef:t,prevKeyKflag:t?parseInt(t.dataset.kflag)+(parseInt(t.dataset.air)?32:0):null,nextKeyRef:a,nextKeyKflag:a?parseInt(a.dataset.kflag)+(parseInt(a.dataset.air)?32:0):null,ref:e}},isInside=(e,t,a)=>a.left<=e&&e{keys=document.getElementsByClassName("key"),airKeys=[],touchKeys=[];for(var e=0;e{if(t{var s=t;e[s]&&!a&&s++,e[s]=1},sendKeys=e=>{wsConnected&&ws.send("b"+e.join(""))},throttledSendKeys=throttle(sendKeys,10);var ws=null,wsTimeout=0,wsConnected=!1;const wsConnect=()=>{(ws=new WebSocket("ws://"+location.host+"/ws")).binaryType="arraybuffer",ws.onopen=(()=>{ws.send("alive?")}),ws.onmessage=(e=>{e.data.byteLength?updateLed(e.data):"alive"==e.data&&(wsTimeout=0,wsConnected=!0)})},wsWatch=()=>{if(wsTimeout++>2)return wsTimeout=0,ws.close(),wsConnected=!1,void wsConnect();wsConnected&&ws.send("alive?")};var canvas=document.getElementById("canvas"),canvasCtx=canvas.getContext("2d"),canvasData=canvasCtx.getImageData(0,0,33,1);const setupLed=()=>{for(var e=0;e<33;e++)canvasData.data[4*e+3]=255};setupLed();const updateLed=e=>{const t=new Uint8Array(e);for(var a=0;a<31;a++)canvasData.data[4*a+4]=t[3*a],canvasData.data[4*a+5]=t[3*a+1],canvasData.data[4*a+6]=t[3*a+2];canvasData.data[0]=t[0],canvasData.data[1]=t[1],canvasData.data[2]=t[2],canvasData.data[128]=t[90],canvasData.data[129]=t[91],canvasData.data[130]=t[92],canvasCtx.putImageData(canvasData,0,0)},fs=document.getElementById("fullscreen"),requestFullscreen=()=>{!document.fullscreenElement&&screen.height<=1024&&(fs.requestFullscreen?fs.requestFullscreen():fs.mozRequestFullScreen?fs.mozRequestFullScreen():fs.webkitRequestFullScreen&&fs.webkitRequestFullScreen())},throttledRequestFullscreen=throttle(requestFullscreen,3e3),cnt=document.getElementById("main");cnt.addEventListener("touchstart",updateTouches),cnt.addEventListener("touchmove",updateTouches),cnt.addEventListener("touchend",updateTouches);const readConfig=e=>{var t="";e.invert&&(t+=".container, .air-container {flex-flow: column-reverse nowrap;} ");var a=e.bgColor||"rbga(0, 0, 0, 0.9)";e.bgImage?t+=`#fullscreen {background: ${a} url("${e.bgImage}") fixed center / cover!important; background-repeat: no-repeat;} `:t+=`#fullscreen {background: ${a};} `,"number"==typeof e.ledOpacity&&(0===e.ledOpacity?t+="#canvas {display: none} ":t+=`#canvas {opacity: ${e.ledOpacity}} `),"string"==typeof e.keyColor&&(t+=`.key[data-active] {background-color: ${e.keyColor};} `),"string"==typeof e.keyColor&&(t+=`.key.air[data-active] {background-color: ${e.lkeyColor};} `),"string"==typeof e.keyBorderColor&&(t+=`.key {border: 1px solid ${e.keyBorderColor};} `),e.keyColorFade&&"number"==typeof e.keyColorFade&&(t+=`.key:not([data-active]) {transition: background ${e.keyColorFade}ms ease-out;} `),"number"==typeof e.keyHeight&&(0===e.keyHeight?t+=".touch-container {display: none;} ":t+=`.touch-container {flex: ${e.keyHeight};} `),"number"==typeof e.lkeyHeight&&(0===e.lkeyHeight?t+=".air-container {display: none;} ":t+=`.air-container {flex: ${e.keyHeight};} `);var s=document.createElement("style");s.innerHTML=t,document.head.appendChild(s)},initialize=()=>{readConfig(config),compileKeys(),wsConnect(),setInterval(wsWatch,1e3)};readConfig(config),compileKeys(),wsConnect(),setInterval(wsWatch,1e3),window.onresize=compileKeys;
\ No newline at end of file
diff --git a/src-tauri/res/www/index-go.html b/src-tauri/res/www/index-go.html
index 67d85f4..8a3db37 100644
--- a/src-tauri/res/www/index-go.html
+++ b/src-tauri/res/www/index-go.html
@@ -67,6 +67,9 @@
}
canvas {
+ -ms-interpolation-mode: nearest-neighbor;
+ image-rendering: crisp-edges;
+ image-rendering: pixelated;
touch-action: none;
margin: 0px -1.5625vw;
}
@@ -112,6 +115,6 @@
-
+