Update svelte portal

This commit is contained in:
DrZlo13 2021-11-22 21:24:38 +10:00
parent 279a5c66a3
commit 14724b2654
18 changed files with 662 additions and 31 deletions

View File

@ -1,5 +1,5 @@
idf_component_register(
EMBED_TXTFILES "public/index.html" "public/build/bundle.css" "public/build/bundle.js"
EMBED_FILES "public/index.html" "public/build/bundle.css" "public/build/bundle.js" "public/assets/ega8.otf" "public/assets/favicon.ico"
INCLUDE_DIRS ".")
# add_custom_command(OUTPUT "public/build/bundle.css" "public/build/bundle.js"

View File

@ -4,7 +4,7 @@
"private": true,
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"dev": "set \"HOST=0.0.0.0\" && rollup -c -w",
"start": "sirv public --no-clear"
},
"devDependencies": {

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1 +1 @@
main.svelte-1tky8bj{text-align:center;padding:1em;max-width:240px;margin:0 auto}h1.svelte-1tky8bj{color:#ff3e00;text-transform:uppercase;font-size:4em;font-weight:100}@media(min-width: 640px){main.svelte-1tky8bj{max-width:none}}
main.svelte-2vj2xw.svelte-2vj2xw{border:4px dashed #000;margin:10px auto;padding:10px;max-width:500px}.svelte-2vj2xw.svelte-2vj2xw{-moz-user-select:none;-o-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}tabs.svelte-2vj2xw.svelte-2vj2xw{border-bottom:4px dashed #000;width:100%;display:block}tab.svelte-2vj2xw.svelte-2vj2xw{margin-right:10px;padding:5px 10px;margin-bottom:5px;display:inline-block}tab.svelte-2vj2xw.svelte-2vj2xw:hover,tab.selected.svelte-2vj2xw.svelte-2vj2xw:hover{background:rgb(255, 255, 255);color:#000000}tab.selected.svelte-2vj2xw.svelte-2vj2xw{background-color:black;color:white}tabs-content.svelte-2vj2xw.svelte-2vj2xw{display:block;margin-top:10px}error.svelte-2vj2xw.svelte-2vj2xw{padding:5px 10px;background-color:rgb(255, 0, 0);color:black}@font-face{font-family:"DOS";src:url("../assets/ega8.otf") format("opentype");font-weight:normal;font-style:normal;-webkit-font-kerning:none;font-kerning:none;font-synthesis:none;-webkit-font-variant-ligatures:none;font-variant-ligatures:none;font-variant-numeric:tabular-nums}body{padding:0;margin:0;background-color:#ffa21c;color:#000;font-size:28px;font-family:"DOS", monospace;line-height:1;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0, 0, 0, 0)}.grid.svelte-2vj2xw.svelte-2vj2xw{display:inline-grid;grid-template-columns:auto auto}.grid.svelte-2vj2xw>div.svelte-2vj2xw{margin-top:10px}.value-name.svelte-2vj2xw.svelte-2vj2xw{text-align:right}.button-css.svelte-yar6m3{background-color:black;color:white;font-size:28px;font-family:"DOS", monospace;line-height:1;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0, 0, 0, 0);border:0;padding:5px 10px;display:inline-block;max-width:100%}.button-css.svelte-yar6m3:hover{background:rgb(255, 255, 255);color:#000000}popup-wrapper.svelte-1ufadaz{background-color:rgba(0, 0, 0, 0.863);width:100%;height:100%;display:table;table-layout:fixed;z-index:999;overflow:auto;position:fixed;top:0;left:0;right:0;bottom:0}popup-body.svelte-1ufadaz{margin:auto;display:table-cell;text-align:center;vertical-align:middle;width:100%}popup-content.svelte-1ufadaz{background-color:#ffa21c;display:inline-block;outline:none;position:relative;text-align:initial;max-width:100vw}popup-border.svelte-1ufadaz{display:block;border:4px dashed #000;margin:10px;padding:10px}popup-close.svelte-1ufadaz{background-color:#000;display:inline-block;color:#ffa21c;position:absolute;width:24px;right:0px;top:0px;text-align:center}popup-close.svelte-1ufadaz:hover{background-color:#fff;color:#000}.input-text-css.svelte-4h7oz2{display:inline-block;color:#000;font-size:28px;font-family:"DOS", monospace;line-height:1;box-sizing:border-box;margin:0;border:0;border-bottom:4px solid #000;padding:0 5px 0 5px;box-shadow:none;border-radius:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;background-color:#ffa21c;height:32px}.input-text-css.svelte-4h7oz2:focus-visible,.input-text-css.svelte-4h7oz2:hover{outline:0;background-color:white}@keyframes svelte-1471rey-spinner-animation{0%{content:"|"}25%{content:"/"}50%{content:"-"}75%{content:"\\"}100%{content:"|"}}spinner.svelte-1471rey::after{display:inline-block;animation:svelte-1471rey-spinner-animation 0.6s linear infinite alternate;content:"|"}.button.svelte-3ci2n2{box-sizing:border-box;display:inline-block;font-size:28px;font-family:"DOS", monospace;line-height:1;border:0;padding:0 5px 0 5px;box-shadow:none;border-radius:0;display:inline-block}.black.svelte-3ci2n2{color:white;background-color:black;border-bottom:4px solid #000}.black.svelte-3ci2n2:hover{background:#fff;color:#000}.normal.svelte-3ci2n2{color:#000;background-color:#ffa21c;border-bottom:4px solid #ffa21c}.normal.svelte-3ci2n2:hover{background:#000;color:#fff}select.svelte-1rf61qb.svelte-1rf61qb{display:inline-block;color:#000;font-size:28px;font-family:"DOS", monospace;line-height:1;box-sizing:border-box;margin:0;border:0;border-bottom:4px solid #000;padding:0 5px 0 5px;box-shadow:none;border-radius:0;-moz-appearance:none;-webkit-appearance:none;appearance:none;background-color:#ffa21c}select.svelte-1rf61qb.svelte-1rf61qb::-ms-expand{display:none}select.svelte-1rf61qb.svelte-1rf61qb:hover{background:rgb(255, 255, 255);color:#000000}select.svelte-1rf61qb.svelte-1rf61qb:focus{box-shadow:none;outline:none;background:rgb(255, 255, 255);color:#000000}select.svelte-1rf61qb option.svelte-1rf61qb{font-weight:normal}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,9 +5,10 @@
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Blackmagic for Flipper</title>
<link rel='stylesheet' href='/build/bundle.css'>
<link rel='icon' type='image/x-icon' href='/assets/favicon.ico'>
<script defer src='/build/bundle.js'></script>
</head>
<body>
</body>
</html>
</html>

View File

@ -1,30 +1,224 @@
<script>
export let name;
import Button from "./Button.svelte";
import Popup from "./Popup.svelte";
import Input from "./Input.svelte";
import Spinner from "./Spinner.svelte";
import SpinnerBig from "./SpinnerBig.svelte";
import Select from "./Select.svelte";
import { onMount } from "svelte";
import ButtonInline from "./ButtonInline.svelte";
let server = "";
// let server = "http://192.168.31.235";
async function api_post(api, data) {
const res = await fetch(api, {
method: "POST",
body: JSON.stringify(data),
});
const json = await res.json();
return json;
}
async function api_get(api) {
const res = await fetch(api, {
method: "GET",
});
const json = await res.json();
return json;
}
let popup_select_net;
let popup_message;
let popup_message_text;
let mode_select;
let ssid_input;
let password_input;
onMount(() => {
//popup_select_net.show();
});
async function save_settings() {
popup_message_text = "";
popup_message.show();
await api_post(server + "/api/v1/wifi/set_credenitals", {
mode: mode_select.get_value(),
ssid: ssid_input.get_value(),
pass: password_input.get_value(),
}).then(() => {
popup_message_text = "Saved!";
});
}
</script>
<main>
<h1>Hello {name}!</h1>
<p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p>
<tabs><tab class="selected">WiFi</tab><tab>SYS</tab><tab>GDB</tab></tabs>
<tabs-content>
<tab-content>
<div class="grid">
{#await api_get(server + "/api/v1/wifi/get_credenitals")}
<div class="value-name">Mode:</div>
<div><Spinner /></div>
<div class="value-name">SSID:</div>
<div><Spinner /></div>
<div class="value-name">Pass:</div>
<div><Spinner /></div>
{:then json}
<div class="value-name">Mode:</div>
<div>
<Select
bind:this={mode_select}
items={[
{ text: "STA", value: "STA" },
{ text: "AP", value: "AP" },
]}
value={json.mode}
/>
</div>
<div class="value-name">SSID:</div>
<div>
<Input value={json.ssid} bind:this={ssid_input} /><ButtonInline
value="+"
on:click={popup_select_net.show}
/>
</div>
<div class="value-name">Pass:</div>
<div>
<Input value={json.pass} bind:this={password_input} />
</div>
{:catch error}
<error>{error.message}</error>
{/await}
</div>
<div style="margin-top: 10px;">
<Button value="SAVE" on:click={save_settings} />
</div>
</tab-content>
</tabs-content>
<Popup bind:this={popup_select_net}>
{#await api_get(server + "/api/v1/wifi/list", {})}
<div>Nets: <SpinnerBig /></div>
{:then json}
<div>Nets:</div>
{#each json.net_list as net}
<ButtonInline
style="normal"
value="[{net.ssid} {net.channel}ch {net.rssi}db {net.auth}]"
on:click={() => {
popup_select_net.close();
ssid_input.set_value(net.ssid);
}}
/>
{/each}
{:catch error}
<error>{error.message}</error>
{/await}
</Popup>
<Popup bind:this={popup_message}>
{#if popup_message_text != ""}
{popup_message_text}
{:else}
<Spinner />
{/if}
</Popup>
</main>
<style>
main {
text-align: center;
padding: 1em;
max-width: 240px;
margin: 0 auto;
}
main {
border: 4px dashed #000;
margin: 10px auto;
padding: 10px;
max-width: 500px;
}
h1 {
color: #ff3e00;
text-transform: uppercase;
font-size: 4em;
font-weight: 100;
}
* {
-moz-user-select: none;
-o-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
@media (min-width: 640px) {
main {
max-width: none;
}
}
</style>
tabs {
border-bottom: 4px dashed #000;
width: 100%;
display: block;
}
tab {
margin-right: 10px;
padding: 5px 10px;
margin-bottom: 5px;
display: inline-block;
}
tab:hover,
tab.selected:hover {
background: rgb(255, 255, 255);
color: #000000;
}
tab.selected {
background-color: black;
color: white;
}
tabs-content {
display: block;
margin-top: 10px;
}
error {
padding: 5px 10px;
background-color: rgb(255, 0, 0);
color: black;
}
@font-face {
font-family: "DOS";
src: url("../assets/ega8.otf") format("opentype");
font-weight: normal;
font-style: normal;
-webkit-font-kerning: none;
font-kerning: none;
font-synthesis: none;
-webkit-font-variant-ligatures: none;
font-variant-ligatures: none;
font-variant-numeric: tabular-nums;
}
:global(body) {
padding: 0;
margin: 0;
background-color: #ffa21c;
color: #000;
font-size: 28px;
font-family: "DOS", monospace;
line-height: 1;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.grid {
display: inline-grid;
grid-template-columns: auto auto;
}
.grid > div {
margin-top: 10px;
}
.value-name {
text-align: right;
}
</style>

View File

@ -0,0 +1,73 @@
<script>
export let value = "Value";
//export let click;
let left = "";
let right = "";
let timer = null;
function reset_brace() {
left = "[";
right = "]";
}
function set_brace() {
left = ">";
right = "<";
}
function timer_click() {
if (left == "[") {
set_brace();
} else {
reset_brace();
}
}
function mouseenter() {
if (timer == null) {
timer = setInterval(timer_click, 400);
}
set_brace();
}
function mouseleave() {
if (timer != null) {
clearInterval(timer);
timer = null;
}
reset_brace();
}
reset_brace();
</script>
<input
type="button"
value={left + value + right}
class="button-css"
on:mouseenter={mouseenter}
on:mouseleave={mouseleave}
on:click
/>
<style>
.button-css {
background-color: black;
color: white;
font-size: 28px;
font-family: "DOS", monospace;
line-height: 1;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
border: 0;
padding: 5px 10px;
display: inline-block;
max-width: 100%;
}
.button-css:hover {
background: rgb(255, 255, 255);
color: #000000;
}
</style>

View File

@ -0,0 +1,43 @@
<script>
export let value = "Value";
export let style = "black";
</script>
<input type="button" {value} class="button {style}" on:click />
<style>
.button {
box-sizing: border-box;
display: inline-block;
font-size: 28px;
font-family: "DOS", monospace;
line-height: 1;
border: 0;
padding: 0 5px 0 5px;
box-shadow: none;
border-radius: 0;
display: inline-block;
}
.black {
color: white;
background-color: black;
border-bottom: 4px solid #000;
}
.black:hover {
background: #fff;
color: #000;
}
.normal {
color: #000;
background-color: #ffa21c;
border-bottom: 4px solid #ffa21c;
}
.normal:hover {
background: #000;
color: #fff;
}
</style>

View File

@ -0,0 +1,52 @@
<script>
export let value = "";
export function set_value(new_value) {
value = new_value;
}
export function get_value() {
return value;
}
function text_input() {
this.size = this.value.length > 3 ? this.value.length : 3;
value = this.value;
}
</script>
<input
type="text"
{value}
class="input-text-css"
size={value.length > 3 ? value.length : 3}
on:input={text_input}
/>
<style>
.input-text-css {
display: inline-block;
color: #000;
font-size: 28px;
font-family: "DOS", monospace;
line-height: 1;
box-sizing: border-box;
margin: 0;
border: 0;
border-bottom: 4px solid #000;
padding: 0 5px 0 5px;
box-shadow: none;
border-radius: 0;
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
background-color: #ffa21c;
height: 32px;
}
.input-text-css:focus-visible,
.input-text-css:hover {
outline: 0;
background-color: white;
}
</style>

View File

@ -0,0 +1,80 @@
<script>
let closed = true;
export function close() {
closed = true;
}
export function show() {
closed = false;
}
</script>
{#if !closed}
<popup-wrapper>
<popup-body>
<popup-content>
<popup-close on:click={close}>X</popup-close>
<popup-border>
<slot />
</popup-border>
</popup-content>
</popup-body>
</popup-wrapper>
{/if}
<style>
popup-wrapper {
background-color: rgba(0, 0, 0, 0.863);
width: 100%;
height: 100%;
display: table;
table-layout: fixed;
z-index: 999;
overflow: auto;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
popup-body {
margin: auto;
display: table-cell;
text-align: center;
vertical-align: middle;
width: 100%;
}
popup-content {
background-color: #ffa21c;
display: inline-block;
outline: none;
position: relative;
text-align: initial;
max-width: 100vw;
}
popup-border {
display: block;
border: 4px dashed #000;
margin: 10px;
padding: 10px;
}
popup-close {
background-color: #000;
display: inline-block;
color: #ffa21c;
position: absolute;
width: 24px;
right: 0px;
top: 0px;
text-align: center;
}
popup-close:hover {
background-color: #fff;
color: #000;
}
</style>

View File

@ -0,0 +1,58 @@
<script>
export let items = [];
export let value = "";
export function get_value() {
return value;
}
function on_change() {
value = this.value;
}
</script>
<select bind:value on:change={on_change}>
{#each items as item}
<option value={item.value}>
{item.text}
</option>
{/each}
</select>
<style>
select {
display: inline-block;
color: #000;
font-size: 28px;
font-family: "DOS", monospace;
line-height: 1;
box-sizing: border-box;
margin: 0;
border: 0;
border-bottom: 4px solid #000;
padding: 0 5px 0 5px;
box-shadow: none;
border-radius: 0;
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
background-color: #ffa21c;
}
select::-ms-expand {
display: none;
}
select:hover {
background: rgb(255, 255, 255);
color: #000000;
}
select:focus {
box-shadow: none;
outline: none;
background: rgb(255, 255, 255);
color: #000000;
}
select option {
font-weight: normal;
}
</style>

View File

@ -0,0 +1,30 @@
<script>
</script>
<spinner />
<style>
@keyframes spinner-animation {
0% {
content: "|";
}
25% {
content: "/";
}
50% {
content: "-";
}
75% {
content: "\\";
}
100% {
content: "|";
}
}
spinner::after {
display: inline-block;
animation: spinner-animation 0.6s linear infinite alternate;
content: "|";
}
</style>

View File

@ -0,0 +1,99 @@
<script>
import { onMount } from "svelte";
const items = [
[
[".", "o", "O", " "],
[" ", " ", " ", " "],
[" ", " ", " ", " "],
[" ", " ", " ", " "],
],
[
[" ", ".", "o", "O"],
[" ", " ", " ", " "],
[" ", " ", " ", " "],
[" ", " ", " ", " "],
],
[
[" ", " ", ".", "o"],
[" ", " ", " ", "O"],
[" ", " ", " ", " "],
[" ", " ", " ", " "],
],
[
[" ", " ", " ", "."],
[" ", " ", " ", "o"],
[" ", " ", " ", "O"],
[" ", " ", " ", " "],
],
[
[" ", " ", " ", " "],
[" ", " ", " ", "."],
[" ", " ", " ", "o"],
[" ", " ", " ", "O"],
],
[
[" ", " ", " ", " "],
[" ", " ", " ", " "],
[" ", " ", " ", "."],
[" ", " ", "O", "o"],
],
[
[" ", " ", " ", " "],
[" ", " ", " ", " "],
[" ", " ", " ", " "],
[" ", "O", "o", "."],
],
[
[" ", " ", " ", " "],
[" ", " ", " ", " "],
[" ", " ", " ", " "],
["O", "o", ".", " "],
],
[
[" ", " ", " ", " "],
[" ", " ", " ", " "],
["O", " ", " ", " "],
["o", ".", " ", " "],
],
[
[" ", " ", " ", " "],
["O", " ", " ", " "],
["o", " ", " ", " "],
[".", " ", " ", " "],
],
[
["O", " ", " ", " "],
["o", " ", " ", " "],
[".", " ", " ", " "],
[" ", " ", " ", " "],
],
[
["o", "O", " ", " "],
[".", " ", " ", " "],
[" ", " ", " ", " "],
[" ", " ", " ", " "],
],
];
let index = 0;
let text_pointer = items[index];
function timer_tick() {
index++;
if (index >= items.length) index = 0;
text_pointer = items[index];
}
onMount(() => setInterval(timer_tick, 100));
</script>
<div>
{#each text_pointer as text_line}
{#each text_line as text, i}
{#if text == " "}&nbsp;{:else}{text}{/if}
{#if i < 3}&nbsp;{/if}
{/each}
<br />
{/each}
</div>

View File

@ -2,9 +2,6 @@ import App from './App.svelte';
const app = new App({
target: document.body,
props: {
name: 'world'
}
});
export default app;

View File

@ -6,4 +6,8 @@ extern const uint8_t index_html_end[] asm("_binary_index_html_end");
extern const uint8_t build_bundle_css_start[] asm("_binary_bundle_css_start");
extern const uint8_t build_bundle_css_end[] asm("_binary_bundle_css_end");
extern const uint8_t build_bundle_js_start[] asm("_binary_bundle_js_start");
extern const uint8_t build_bundle_js_end[] asm("_binary_bundle_js_end");
extern const uint8_t build_bundle_js_end[] asm("_binary_bundle_js_end");
extern const uint8_t assets_ega8_otf_start[] asm("_binary_ega8_otf_start");
extern const uint8_t assets_ega8_otf_end[] asm("_binary_ega8_otf_end");
extern const uint8_t assets_favicon_ico_start[] asm("_binary_favicon_ico_start");
extern const uint8_t assets_favicon_ico_end[] asm("_binary_favicon_ico_end");