Web interface: UART config

This commit is contained in:
SG 2023-08-14 19:37:24 +03:00
parent 8861ae4e7e
commit e640b27dcd
10 changed files with 140 additions and 26 deletions

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

View File

@ -103,6 +103,15 @@
user-select: none;
}
:global(.selectable) {
-moz-user-select: text;
-o-user-select: text;
-khtml-user-select: text;
-webkit-user-select: text;
-ms-user-select: text;
user-select: text;
}
:global(error) {
padding: 5px 10px;
background-color: rgb(255, 0, 0);

View File

@ -1,5 +1,6 @@
<script>
export let value = "";
export let type = "text";
export function set_value(new_value) {
value = new_value;
@ -19,9 +20,9 @@
autocorrect="off"
autocapitalize="none"
autocomplete="off"
type="text"
{type}
{value}
size={value.length > 3 ? value.length : 3}
size={(value + "").length > 3 ? (value + "").length : 3}
on:input={text_input}
/>

View File

@ -1,6 +1,14 @@
<script>
import { onMount } from "svelte";
import parseTerminal from "./terminal.js";
import Button from "./Button.svelte";
import Popup from "./Popup.svelte";
import Spinner from "./Spinner.svelte";
import SpinnerBig from "./SpinnerBig.svelte";
import { api } from "../lib/Api.svelte";
import Grid from "./Grid.svelte";
import Value from "./Value.svelte";
import Input from "./Input.svelte";
let bytes = [];
export function push(data) {
@ -51,15 +59,107 @@
return { update: scroll };
};
let popup = {
text: "",
self: null,
};
let config = {
popup: null,
bit_rate: null,
stop_bits: null,
parity: null,
data_bits: null,
};
async function config_apply() {
popup.text = "";
popup.self.show();
popup = popup;
config.popup.close();
await api
.post("/api/v1/uart/set_config", {
bit_rate: parseInt(config.bit_rate.get_value()),
stop_bits: parseInt(config.stop_bits.get_value()),
parity: parseInt(config.parity.get_value()),
data_bits: parseInt(config.data_bits.get_value()),
})
.then((json) => {
if (json.error) {
popup.text = json.error;
} else {
popup.text = "Saved!";
}
});
}
</script>
<div class="terminal" use:scrollToBottom={ready}>
{#each ready.lines as line}
<div class="line">{@html line}</div>
{/each}
{#if ready.last}
<div class="line">{@html ready.last}<span class="cursor">_</span></div>
{/if}
<div class="terminal-wrapper">
<div class="terminal selectable" use:scrollToBottom={ready}>
{#each ready.lines as line}
<div class="line">{@html line}</div>
{/each}
{#if ready.last}
<div class="line">
{@html ready.last}<span class="cursor">_</span>
</div>
{/if}
</div>
<div class="config">
<Button value="?" on:click={config.popup.show} />
</div>
<Popup bind:this={config.popup}>
{#await api.get("/api/v1/uart/get_config", {})}
<SpinnerBig />
{:then json}
<div>UART config</div>
<Grid>
<Value name="Rate">
<Input
type="number"
value={json.bit_rate}
bind:this={config.bit_rate}
/>
</Value>
<Value name="Stop">
<Input
type="number"
value={json.stop_bits}
bind:this={config.stop_bits}
/>
</Value>
<Value name="Prty">
<Input
type="number"
value={json.parity}
bind:this={config.parity}
/>
</Value>
<Value name="Data">
<Input
type="number"
value={json.data_bits}
bind:this={config.data_bits}
/>
</Value>
</Grid>
<div style="margin-top: 10px; text-align: center;">
<Button value="Save" on:click={config_apply} />
</div>
{:catch error}
<error>{error.message}</error>
{/await}
</Popup>
<Popup bind:this={popup.self}>
{#if popup.text != ""}
{popup.text}
{:else}
<Spinner />
{/if}
</Popup>
</div>
<style>
@ -89,18 +189,22 @@
display: block;
}
.terminal-wrapper {
position: relative;
}
.terminal {
height: calc(100vh - 20px * 4.5 - 1em);
overflow: scroll;
-moz-user-select: text;
-o-user-select: text;
-khtml-user-select: text;
-webkit-user-select: text;
-ms-user-select: text;
user-select: text;
font-size: 18px;
}
.config {
position: absolute;
top: 0;
right: 0;
}
:global(.terminal.bold) {
font-weight: bold;
}

View File

@ -1,11 +1,12 @@
<script>
export let name = "Name";
export let splitter = false;
export let selectable = false;
</script>
{#if !splitter}
<div class="value-name">{name}:</div>
<div class="value"><slot /></div>
<div class="value {selectable ? 'selectable' : ''}"><slot /></div>
{:else}
<div class="value-name splitter">{name}</div>
<div class="value mobile-hidden">&nbsp;<slot /></div>

View File

@ -219,11 +219,10 @@ export default function parseTerminal(text) {
} else {
if (state.classes.length > 0 || state.styles.length > 0) {
state.output += `<span class="${state
.classes
.join(' ')}" style="${state
.styles
.join(';')}">`;
state.output += `<span
class="${state.classes.join(' ')}"
style="${state.styles.join(';')}
">`;
state.classes = [];
state.styles = [];
state.spanCount++;

View File

@ -47,7 +47,7 @@
<Value name="Alloc"><Spinner /></Value>
<Value name="Max block"><Spinner /></Value>
{:then json}
<Value name="IP">{print_ip(json.ip)}</Value>
<Value name="IP" selectable="true">{print_ip(json.ip)}</Value>
<Value name="Mac">{print_mac(json.mac)}</Value>
<Value name="IDF ver">{json.idf_version}</Value>
<Value name="Model">

View File

@ -997,7 +997,7 @@ const httpd_uri_t uri_handlers[] = {
.is_websocket = false},
{.uri = "/api/v1/uart/set_config",
.method = HTTP_GET,
.method = HTTP_POST,
.handler = uart_set_config_handler,
.user_ctx = NULL,
.is_websocket = false},