Lint and format all files
This commit is contained in:
parent
3eaf897dbb
commit
d25284e3a4
@ -18,6 +18,9 @@ module.exports = {
|
|||||||
es2017: true,
|
es2017: true,
|
||||||
node: true
|
node: true
|
||||||
},
|
},
|
||||||
|
rules: {
|
||||||
|
'no-empty': ['error', { allowEmptyCatch: true }]
|
||||||
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
files: ['*.svelte'],
|
files: ['*.svelte'],
|
||||||
|
10
.github/workflows/workflow.yml
vendored
10
.github/workflows/workflow.yml
vendored
@ -3,7 +3,7 @@ name: BTClock WebUI CI
|
|||||||
on: [push]
|
on: [push]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
PUBLIC_BASE_URL: ""
|
PUBLIC_BASE_URL: ''
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-changes:
|
check-changes:
|
||||||
@ -12,13 +12,13 @@ jobs:
|
|||||||
all_changed_and_modified_files_count: ${{ steps.changed-files.outputs.all_changed_and_modified_files_count }}
|
all_changed_and_modified_files_count: ${{ steps.changed-files.outputs.all_changed_and_modified_files_count }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Get changed files count
|
- name: Get changed files count
|
||||||
id: changed-files
|
id: changed-files
|
||||||
uses: tj-actions/changed-files@v40.1.1
|
uses: tj-actions/changed-files@v40.1.1
|
||||||
with:
|
with:
|
||||||
files_ignore: "doc/**,README.md,Dockerfile,.*"
|
files_ignore: 'doc/**,README.md,Dockerfile,.*'
|
||||||
files_ignore_separator: ','
|
files_ignore_separator: ','
|
||||||
- name: Print changed files count
|
- name: Print changed files count
|
||||||
run: >
|
run: >
|
||||||
@ -33,7 +33,7 @@ jobs:
|
|||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
@ -84,7 +84,7 @@ jobs:
|
|||||||
tag: ${{ steps.getBlockHeight.outputs.blockHeight }}
|
tag: ${{ steps.getBlockHeight.outputs.blockHeight }}
|
||||||
commit: main
|
commit: main
|
||||||
name: release-${{ steps.getBlockHeight.outputs.blockHeight }}
|
name: release-${{ steps.getBlockHeight.outputs.blockHeight }}
|
||||||
artifacts: "littlefs.bin,webui.tgz"
|
artifacts: 'littlefs.bin,webui.tgz'
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
removeArtifacts: true
|
removeArtifacts: true
|
||||||
makeLatest: true
|
makeLatest: true
|
@ -8,7 +8,7 @@ node_modules
|
|||||||
!.env.example
|
!.env.example
|
||||||
dist/
|
dist/
|
||||||
build_gz
|
build_gz
|
||||||
|
dist/**
|
||||||
|
|
||||||
# Ignore files for PNPM, NPM and YARN
|
# Ignore files for PNPM, NPM and YARN
|
||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import type { Handle } from '@sveltejs/kit'
|
import type { Handle } from '@sveltejs/kit';
|
||||||
import { locale } from 'svelte-i18n'
|
import { locale } from 'svelte-i18n';
|
||||||
|
|
||||||
export const handle: Handle = async ({ event, resolve }) => {
|
export const handle: Handle = async ({ event, resolve }) => {
|
||||||
const lang = event.request.headers.get('accept-language')?.split(',')[0]
|
const lang = event.request.headers.get('accept-language')?.split(',')[0];
|
||||||
if (lang) {
|
if (lang) {
|
||||||
locale.set(lang)
|
locale.set(lang);
|
||||||
}
|
|
||||||
return resolve(event)
|
|
||||||
}
|
}
|
||||||
|
return resolve(event);
|
||||||
|
};
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
import { browser } from '$app/environment'
|
import { browser } from '$app/environment';
|
||||||
import { init, register } from 'svelte-i18n'
|
import { init, register } from 'svelte-i18n';
|
||||||
|
|
||||||
const defaultLocale = 'en'
|
const defaultLocale = 'en';
|
||||||
|
|
||||||
register('en', () => import('../locales/en.json'))
|
register('en', () => import('../locales/en.json'));
|
||||||
register('nl', () => import('../locales/nl.json'))
|
register('nl', () => import('../locales/nl.json'));
|
||||||
register('es', () => import('../locales/es.json'))
|
register('es', () => import('../locales/es.json'));
|
||||||
|
|
||||||
init({
|
init({
|
||||||
fallbackLocale: defaultLocale,
|
fallbackLocale: defaultLocale,
|
||||||
initialLocale: browser ? browser && localStorage.getItem('locale') ? localStorage.getItem('locale') : window.navigator.language : defaultLocale,
|
initialLocale: browser
|
||||||
})
|
? browser && localStorage.getItem('locale')
|
||||||
|
? localStorage.getItem('locale')
|
||||||
|
: window.navigator.language
|
||||||
|
: defaultLocale
|
||||||
|
});
|
||||||
|
@ -1,46 +1,46 @@
|
|||||||
@import "../node_modules/bootstrap/scss/functions";
|
@import '../node_modules/bootstrap/scss/functions';
|
||||||
@import "../node_modules/bootstrap/scss/variables";
|
@import '../node_modules/bootstrap/scss/variables';
|
||||||
@import "../node_modules/bootstrap/scss/variables-dark";
|
@import '../node_modules/bootstrap/scss/variables-dark';
|
||||||
|
|
||||||
//@import "@fontsource/antonio/latin-400.css";
|
//@import "@fontsource/antonio/latin-400.css";
|
||||||
@import "@fontsource/ubuntu/latin-400.css";
|
@import '@fontsource/ubuntu/latin-400.css';
|
||||||
@import "@fontsource/oswald/latin-400.css";
|
@import '@fontsource/oswald/latin-400.css';
|
||||||
|
|
||||||
$form-range-track-bg: #fff;
|
$form-range-track-bg: #fff;
|
||||||
$color-mode-type: media-query;
|
$color-mode-type: media-query;
|
||||||
$font-family-base: "Ubuntu";
|
$font-family-base: 'Ubuntu';
|
||||||
$font-size-base: 0.9rem;
|
$font-size-base: 0.9rem;
|
||||||
//$font-size-sm: $font-size-base * .875 !default;
|
//$font-size-sm: $font-size-base * .875 !default;
|
||||||
//$form-label-font-size: $font-size-base * .575 !default;
|
//$form-label-font-size: $font-size-base * .575 !default;
|
||||||
//$input-btn-font-size-sm: 0.4rem;
|
//$input-btn-font-size-sm: 0.4rem;
|
||||||
//$form-label-font-size: 0.4rem;
|
//$form-label-font-size: 0.4rem;
|
||||||
$input-font-size-sm: $font-size-base * .875;
|
$input-font-size-sm: $font-size-base * 0.875;
|
||||||
|
|
||||||
// $border-radius: .675rem;
|
// $border-radius: .675rem;
|
||||||
|
|
||||||
@import "../node_modules/bootstrap/scss/mixins";
|
@import '../node_modules/bootstrap/scss/mixins';
|
||||||
@import "../node_modules/bootstrap/scss/maps";
|
@import '../node_modules/bootstrap/scss/maps';
|
||||||
@import "../node_modules/bootstrap/scss/utilities";
|
@import '../node_modules/bootstrap/scss/utilities';
|
||||||
|
|
||||||
@import "../node_modules/bootstrap/scss/root";
|
@import '../node_modules/bootstrap/scss/root';
|
||||||
@import "../node_modules/bootstrap/scss/reboot";
|
@import '../node_modules/bootstrap/scss/reboot';
|
||||||
@import "../node_modules/bootstrap/scss/type";
|
@import '../node_modules/bootstrap/scss/type';
|
||||||
@import "../node_modules/bootstrap/scss/containers";
|
@import '../node_modules/bootstrap/scss/containers';
|
||||||
@import "../node_modules/bootstrap/scss/grid";
|
@import '../node_modules/bootstrap/scss/grid';
|
||||||
@import "../node_modules/bootstrap/scss/forms";
|
@import '../node_modules/bootstrap/scss/forms';
|
||||||
@import "../node_modules/bootstrap/scss/buttons";
|
@import '../node_modules/bootstrap/scss/buttons';
|
||||||
@import "../node_modules/bootstrap/scss/button-group";
|
@import '../node_modules/bootstrap/scss/button-group';
|
||||||
@import "../node_modules/bootstrap/scss/pagination";
|
@import '../node_modules/bootstrap/scss/pagination';
|
||||||
|
|
||||||
@import "../node_modules/bootstrap/scss/dropdown";
|
@import '../node_modules/bootstrap/scss/dropdown';
|
||||||
|
|
||||||
@import "../node_modules/bootstrap/scss/navbar";
|
@import '../node_modules/bootstrap/scss/navbar';
|
||||||
@import "../node_modules/bootstrap/scss/nav";
|
@import '../node_modules/bootstrap/scss/nav';
|
||||||
@import "../node_modules/bootstrap/scss/card";
|
@import '../node_modules/bootstrap/scss/card';
|
||||||
@import "../node_modules/bootstrap/scss/progress";
|
@import '../node_modules/bootstrap/scss/progress';
|
||||||
|
|
||||||
@import "../node_modules/bootstrap/scss/helpers";
|
@import '../node_modules/bootstrap/scss/helpers';
|
||||||
@import "../node_modules/bootstrap/scss/utilities/api";
|
@import '../node_modules/bootstrap/scss/utilities/api';
|
||||||
|
|
||||||
@include media-breakpoint-down(xl) {
|
@include media-breakpoint-down(xl) {
|
||||||
html {
|
html {
|
||||||
@ -48,10 +48,15 @@ $input-font-size-sm: $font-size-base * .875;
|
|||||||
}
|
}
|
||||||
|
|
||||||
button.btn,
|
button.btn,
|
||||||
input[type="button"].btn,
|
input[type='button'].btn,
|
||||||
input[type="submit"].btn,
|
input[type='submit'].btn,
|
||||||
input[type="reset"].btn {
|
input[type='reset'].btn {
|
||||||
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $font-size-sm, $btn-border-radius-sm);
|
@include button-size(
|
||||||
|
$btn-padding-y-sm,
|
||||||
|
$btn-padding-x-sm,
|
||||||
|
$font-size-sm,
|
||||||
|
$btn-border-radius-sm
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +66,6 @@ $input-font-size-sm: $font-size-base * .875;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
nav {
|
nav {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
@ -135,7 +139,7 @@ nav {
|
|||||||
|
|
||||||
.splitText {
|
.splitText {
|
||||||
@include media-breakpoint-up(sm) {
|
@include media-breakpoint-up(sm) {
|
||||||
font-size: 1.0rem;
|
font-size: 1rem;
|
||||||
padding-top: 8px !important;
|
padding-top: 8px !important;
|
||||||
padding-bottom: 9px !important;
|
padding-bottom: 9px !important;
|
||||||
}
|
}
|
||||||
@ -169,7 +173,7 @@ nav {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.digit-blank {
|
.digit-blank {
|
||||||
content: "abc";
|
content: 'abc';
|
||||||
}
|
}
|
||||||
|
|
||||||
#customText {
|
#customText {
|
||||||
|
@ -1,21 +1,19 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
import {
|
||||||
Navbar,
|
Collapse,
|
||||||
NavbarBrand,
|
Dropdown,
|
||||||
|
DropdownItem,
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownToggle,
|
||||||
Nav,
|
Nav,
|
||||||
NavItem,
|
NavItem,
|
||||||
NavLink,
|
NavLink,
|
||||||
Collapse,
|
Navbar,
|
||||||
Dropdown,
|
NavbarBrand
|
||||||
DropdownMenu,
|
|
||||||
DropdownItem,
|
|
||||||
DropdownToggle
|
|
||||||
} from 'sveltestrap';
|
} from 'sveltestrap';
|
||||||
|
|
||||||
import { locale, locales, waitLocale } from 'svelte-i18n';
|
|
||||||
import type { LayoutLoad } from './$types';
|
|
||||||
import { browser } from '$app/environment';
|
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
|
import { locale, locales } from 'svelte-i18n';
|
||||||
|
|
||||||
export const setLocale = (lang: string) => () => {
|
export const setLocale = (lang: string) => () => {
|
||||||
locale.set(lang);
|
locale.set(lang);
|
||||||
@ -33,7 +31,7 @@
|
|||||||
const lowercaseCode = languageCode.toLowerCase();
|
const lowercaseCode = languageCode.toLowerCase();
|
||||||
|
|
||||||
// Check if the language code is in the flagMap
|
// Check if the language code is in the flagMap
|
||||||
if (flagMap.hasOwnProperty(lowercaseCode)) {
|
if (Object.prototype.hasOwnProperty.call(flagMap, lowercaseCode)) {
|
||||||
return flagMap[lowercaseCode];
|
return flagMap[lowercaseCode];
|
||||||
} else {
|
} else {
|
||||||
// Return null for unsupported language codes
|
// Return null for unsupported language codes
|
||||||
@ -50,7 +48,7 @@
|
|||||||
|
|
||||||
const lowercaseCode = languageCode.toLowerCase();
|
const lowercaseCode = languageCode.toLowerCase();
|
||||||
|
|
||||||
return languageNames.hasOwnProperty(lowercaseCode)
|
return Object.prototype.hasOwnProperty.call(languageNames, lowercaseCode)
|
||||||
? languageNames[lowercaseCode][lowercaseCode]
|
? languageNames[lowercaseCode][lowercaseCode]
|
||||||
: null;
|
: null;
|
||||||
};
|
};
|
||||||
@ -71,7 +69,9 @@
|
|||||||
<DropdownToggle nav caret>{getFlagEmoji($locale)} {getLanguageName($locale)}</DropdownToggle>
|
<DropdownToggle nav caret>{getFlagEmoji($locale)} {getLanguageName($locale)}</DropdownToggle>
|
||||||
<DropdownMenu end>
|
<DropdownMenu end>
|
||||||
{#each $locales as locale}
|
{#each $locales as locale}
|
||||||
<DropdownItem on:click={setLocale(locale)}>{getFlagEmoji(locale)} {getLanguageName(locale)}</DropdownItem>
|
<DropdownItem on:click={setLocale(locale)}
|
||||||
|
>{getFlagEmoji(locale)} {getLanguageName(locale)}</DropdownItem
|
||||||
|
>
|
||||||
{/each}
|
{/each}
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
import "$lib/style/app.scss";
|
import '$lib/style/app.scss';
|
||||||
|
|
||||||
|
import { browser } from '$app/environment';
|
||||||
import { browser } from '$app/environment'
|
import '$lib/i18n'; // Import to initialize. Important :)
|
||||||
import '$lib/i18n' // Import to initialize. Important :)
|
import { locale, waitLocale } from 'svelte-i18n';
|
||||||
import { locale, waitLocale } from 'svelte-i18n'
|
import type { LayoutLoad } from './$types';
|
||||||
import type { LayoutLoad } from './$types'
|
|
||||||
|
|
||||||
export const load: LayoutLoad = async () => {
|
export const load: LayoutLoad = async () => {
|
||||||
if (browser && localStorage.getItem('locale')) {
|
if (browser && localStorage.getItem('locale')) {
|
||||||
locale.set(localStorage.getItem('locale'));
|
locale.set(localStorage.getItem('locale'));
|
||||||
} else if (browser) {
|
} else if (browser) {
|
||||||
locale.set(window.navigator.language)
|
locale.set(window.navigator.language);
|
||||||
}
|
}
|
||||||
await waitLocale();
|
await waitLocale();
|
||||||
}
|
};
|
||||||
|
|
||||||
export const prerender = true;
|
export const prerender = true;
|
||||||
export const ssr = false;
|
export const ssr = false;
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PUBLIC_BASE_URL } from '$env/static/public';
|
import { PUBLIC_BASE_URL } from '$env/static/public';
|
||||||
|
|
||||||
import { _ } from 'svelte-i18n';
|
import { Container, Row } from 'sveltestrap';
|
||||||
import { Col, Container, Row } from 'sveltestrap';
|
|
||||||
|
|
||||||
import Control from './Control.svelte';
|
|
||||||
import Status from './Status.svelte';
|
|
||||||
import Settings from './Settings.svelte';
|
|
||||||
import { writable } from 'svelte/store';
|
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
|
import { writable } from 'svelte/store';
|
||||||
|
import Control from './Control.svelte';
|
||||||
|
import Settings from './Settings.svelte';
|
||||||
|
import Status from './Status.svelte';
|
||||||
|
|
||||||
let settings = writable({
|
let settings = writable({
|
||||||
fgColor: "0"
|
fgColor: '0'
|
||||||
});
|
});
|
||||||
|
|
||||||
let status = writable({
|
let status = writable({
|
||||||
data: ["L", "O", "A", "D", "I", "N", "G"],
|
data: ['L', 'O', 'A', 'D', 'I', 'N', 'G'],
|
||||||
espFreeHeap: 0,
|
espFreeHeap: 0,
|
||||||
espHeapSize: 0,
|
espHeapSize: 0,
|
||||||
connectionStatus: {
|
connectionStatus: {
|
||||||
"price": false,
|
price: false,
|
||||||
"blocks": false
|
blocks: false
|
||||||
},
|
},
|
||||||
leds: []
|
leds: []
|
||||||
});
|
});
|
||||||
@ -34,11 +33,11 @@
|
|||||||
data.timePerScreen = data.timerSeconds / 60;
|
data.timePerScreen = data.timerSeconds / 60;
|
||||||
|
|
||||||
if (data.fgColor > 65535) {
|
if (data.fgColor > 65535) {
|
||||||
data.fgColor = "65535";
|
data.fgColor = '65535';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.bgColor > 65535) {
|
if (data.bgColor > 65535) {
|
||||||
data.bgColor = "65535";
|
data.bgColor = '65535';
|
||||||
}
|
}
|
||||||
settings.set(data);
|
settings.set(data);
|
||||||
});
|
});
|
||||||
@ -52,7 +51,7 @@
|
|||||||
const evtSource = new EventSource(`${PUBLIC_BASE_URL}/events`);
|
const evtSource = new EventSource(`${PUBLIC_BASE_URL}/events`);
|
||||||
|
|
||||||
evtSource.addEventListener('status', (e) => {
|
evtSource.addEventListener('status', (e) => {
|
||||||
let dataObj = (JSON.parse(e.data));
|
let dataObj = JSON.parse(e.data);
|
||||||
status.set(dataObj);
|
status.set(dataObj);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,17 +2,14 @@
|
|||||||
import { PUBLIC_BASE_URL } from '$env/static/public';
|
import { PUBLIC_BASE_URL } from '$env/static/public';
|
||||||
import { onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
import type { Subscriber, Unsubscriber } from 'svelte/motion';
|
|
||||||
import type { Writable } from 'svelte/store';
|
import type { Writable } from 'svelte/store';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
ButtonGroup,
|
|
||||||
Card,
|
Card,
|
||||||
CardTitle,
|
|
||||||
CardBody,
|
CardBody,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
Col,
|
Col,
|
||||||
Container,
|
|
||||||
Form,
|
Form,
|
||||||
Input,
|
Input,
|
||||||
Label,
|
Label,
|
||||||
@ -20,14 +17,14 @@ import {
|
|||||||
} from 'sveltestrap';
|
} from 'sveltestrap';
|
||||||
|
|
||||||
export let settings = {};
|
export let settings = {};
|
||||||
export let customText:String;
|
export let customText: string;
|
||||||
export let ledColor:String = "#FFCC00";
|
export let ledColor: string = '#FFCC00';
|
||||||
export let status: Writable<{ leds: [] }>;
|
export let status: Writable<{ leds: [] }>;
|
||||||
let ledStatus = [];
|
let ledStatus = [];
|
||||||
let keepLedsSameColor = false;
|
let keepLedsSameColor = false;
|
||||||
|
|
||||||
const setCustomText = () => {
|
const setCustomText = () => {
|
||||||
fetch(`${PUBLIC_BASE_URL}/api/show/text/${customText}`).catch(err => { });
|
fetch(`${PUBLIC_BASE_URL}/api/show/text/${customText}`).catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkSyncLeds = (e: Event) => {
|
const checkSyncLeds = (e: Event) => {
|
||||||
@ -41,7 +38,7 @@ const checkSyncLeds = (e:Event) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const setLEDcolor = () => {
|
const setLEDcolor = () => {
|
||||||
console.log(`${PUBLIC_BASE_URL}/api/lights/${ledColor}`);
|
console.log(`${PUBLIC_BASE_URL}/api/lights/${ledColor}`);
|
||||||
@ -51,30 +48,29 @@ const setLEDcolor = () => {
|
|||||||
},
|
},
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
body: JSON.stringify(ledStatus)
|
body: JSON.stringify(ledStatus)
|
||||||
}
|
}).catch(() => {});
|
||||||
).catch(err => { });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const turnOffLeds = () => {
|
const turnOffLeds = () => {
|
||||||
fetch(`${PUBLIC_BASE_URL}/api/lights/off`).catch(err => { });
|
fetch(`${PUBLIC_BASE_URL}/api/lights/off`).catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
const restartClock = () => {
|
const restartClock = () => {
|
||||||
fetch(`${PUBLIC_BASE_URL}/api/restart`).catch(err => { });
|
fetch(`${PUBLIC_BASE_URL}/api/restart`).catch(() => {});
|
||||||
}
|
};
|
||||||
|
|
||||||
const forceFullRefresh = () => {
|
const forceFullRefresh = () => {
|
||||||
fetch(`${PUBLIC_BASE_URL}/api/full_refresh`).catch(err => { });
|
fetch(`${PUBLIC_BASE_URL}/api/full_refresh`).catch(() => {});
|
||||||
}
|
};
|
||||||
|
|
||||||
let firstLedDataSubscription = () => {};
|
let firstLedDataSubscription = () => {};
|
||||||
|
|
||||||
firstLedDataSubscription = status.subscribe(async (val) => {
|
firstLedDataSubscription = status.subscribe(async (val) => {
|
||||||
if (val && val.leds) {
|
if (val && val.leds) {
|
||||||
ledStatus = val.leds.map((obj) => ({ ["hex"]: obj["hex"] }));
|
ledStatus = val.leds.map((obj) => ({ ['hex']: obj['hex'] }));
|
||||||
firstLedDataSubscription();
|
firstLedDataSubscription();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
onDestroy(firstLedDataSubscription);
|
onDestroy(firstLedDataSubscription);
|
||||||
</script>
|
</script>
|
||||||
@ -89,11 +85,16 @@ onDestroy(firstLedDataSubscription);
|
|||||||
<Row>
|
<Row>
|
||||||
<Label md={6} for="customText">{$_('section.control.text')}</Label>
|
<Label md={6} for="customText">{$_('section.control.text')}</Label>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<Input type="text" id="customText" bind:value={customText} bsSize="sm" maxLength="{$settings.numScreens}" />
|
<Input
|
||||||
|
type="text"
|
||||||
|
id="customText"
|
||||||
|
bind:value={customText}
|
||||||
|
bsSize="sm"
|
||||||
|
maxLength={$settings.numScreens}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Button color="primary" on:click={setCustomText}>{$_('section.control.showText')}</Button>
|
<Button color="primary" on:click={setCustomText}>{$_('section.control.showText')}</Button>
|
||||||
|
|
||||||
</Form>
|
</Form>
|
||||||
<hr />
|
<hr />
|
||||||
<h3>LEDs</h3>
|
<h3>LEDs</h3>
|
||||||
@ -105,17 +106,30 @@ onDestroy(firstLedDataSubscription);
|
|||||||
{#if ledStatus}
|
{#if ledStatus}
|
||||||
{#each ledStatus as led, i}
|
{#each ledStatus as led, i}
|
||||||
<Col>
|
<Col>
|
||||||
<Input type="color" id="ledColorPicker[{i}]" bind:value="{led.hex}" class="mx-auto" on:change="{checkSyncLeds}" />
|
<Input
|
||||||
|
type="color"
|
||||||
|
id="ledColorPicker[{i}]"
|
||||||
|
bind:value={led.hex}
|
||||||
|
class="mx-auto"
|
||||||
|
on:change={checkSyncLeds}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
<Col>
|
<Col>
|
||||||
<Input bind:checked={keepLedsSameColor} type="switch" class="mx-auto" label="{ $_('sections.control.keepSameColor') }" />
|
<Input
|
||||||
|
bind:checked={keepLedsSameColor}
|
||||||
|
type="switch"
|
||||||
|
class="mx-auto"
|
||||||
|
label={$_('sections.control.keepSameColor')}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Button color="secondary" id="turnOffLedsBtn" on:click={turnOffLeds}>{ $_('section.control.turnOff') }</Button>
|
<Button color="secondary" id="turnOffLedsBtn" on:click={turnOffLeds}
|
||||||
|
>{$_('section.control.turnOff')}</Button
|
||||||
|
>
|
||||||
<Button color="primary" on:click={setLEDcolor}>{$_('section.control.setColor')}</Button>
|
<Button color="primary" on:click={setLEDcolor}>{$_('section.control.setColor')}</Button>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
@ -123,12 +137,18 @@ onDestroy(firstLedDataSubscription);
|
|||||||
<h3>{$_('section.control.systemInfo')}</h3>
|
<h3>{$_('section.control.systemInfo')}</h3>
|
||||||
<ul class="small system_info">
|
<ul class="small system_info">
|
||||||
<li>{$_('section.control.version')}: {$settings.gitRev}</li>
|
<li>{$_('section.control.version')}: {$settings.gitRev}</li>
|
||||||
<li>{ $_('section.control.buildTime') }: {new Date(($settings.lastBuildTime * 1000)).toLocaleString()}</li>
|
<li>
|
||||||
|
{$_('section.control.buildTime')}: {new Date(
|
||||||
|
$settings.lastBuildTime * 1000
|
||||||
|
).toLocaleString()}
|
||||||
|
</li>
|
||||||
<li>IP: {$settings.ip}</li>
|
<li>IP: {$settings.ip}</li>
|
||||||
<li>{$_('section.control.hostname')}: {$settings.hostname}</li>
|
<li>{$_('section.control.hostname')}: {$settings.hostname}</li>
|
||||||
</ul>
|
</ul>
|
||||||
<Button color="danger" id="restartBtn" on:click="{restartClock}">{ $_('button.restart') }</Button>
|
<Button color="danger" id="restartBtn" on:click={restartClock}>{$_('button.restart')}</Button>
|
||||||
<Button color="warning" id="forceFullRefresh" on:click="{forceFullRefresh}">{ $_('button.forceFullRefresh') }</Button>
|
<Button color="warning" id="forceFullRefresh" on:click={forceFullRefresh}
|
||||||
|
>{$_('button.forceFullRefresh')}</Button
|
||||||
|
>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let status = {};
|
export let status = {};
|
||||||
|
|
||||||
const isSplitText = (str:String) => {
|
const isSplitText = (str: string) => {
|
||||||
return str.includes("/");
|
return str.includes('/');
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="btcclock-wrapper" id="btcclock-wrapper">
|
<div class="btcclock-wrapper" id="btcclock-wrapper">
|
||||||
@ -11,11 +11,11 @@
|
|||||||
{#each status.data as char}
|
{#each status.data as char}
|
||||||
{#if isSplitText(char)}
|
{#if isSplitText(char)}
|
||||||
<div class="splitText">
|
<div class="splitText">
|
||||||
{#each char.split("/") as part}
|
{#each char.split('/') as part}
|
||||||
<div class="flex-items">{part}</div>
|
<div class="flex-items">{part}</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{:else if char.length === 0 || char === " "}
|
{:else if char.length === 0 || char === ' '}
|
||||||
<div class="digit"> </div>
|
<div class="digit"> </div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="digit">{char}</div>
|
<div class="digit">{char}</div>
|
||||||
|
@ -1,26 +1,21 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PUBLIC_BASE_URL } from '$env/static/public';
|
import { PUBLIC_BASE_URL } from '$env/static/public';
|
||||||
|
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import { readonly, writable } from 'svelte/store';
|
|
||||||
|
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
import {
|
import {
|
||||||
Col,
|
Button,
|
||||||
Container,
|
|
||||||
Row,
|
|
||||||
Card,
|
Card,
|
||||||
CardTitle,
|
|
||||||
CardHeader,
|
|
||||||
CardBody,
|
CardBody,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
Col,
|
||||||
Form,
|
Form,
|
||||||
FormGroup,
|
|
||||||
FormText,
|
FormText,
|
||||||
Label,
|
|
||||||
Input,
|
Input,
|
||||||
InputGroup,
|
InputGroup,
|
||||||
InputGroupText,
|
InputGroupText,
|
||||||
Button
|
Label,
|
||||||
|
Row
|
||||||
} from 'sveltestrap';
|
} from 'sveltestrap';
|
||||||
|
|
||||||
export let settings;
|
export let settings;
|
||||||
@ -29,18 +24,18 @@
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let formSettings = $settings;
|
let formSettings = $settings;
|
||||||
|
|
||||||
delete formSettings["gitRev"];
|
delete formSettings['gitRev'];
|
||||||
delete formSettings["ip"];
|
delete formSettings['ip'];
|
||||||
delete formSettings["lastBuildTime"];
|
delete formSettings['lastBuildTime'];
|
||||||
|
|
||||||
const res = await fetch(`${PUBLIC_BASE_URL}/api/json/settings`, {
|
await fetch(`${PUBLIC_BASE_URL}/api/json/settings`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
body: JSON.stringify(formSettings)
|
body: JSON.stringify(formSettings)
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Col>
|
<Col>
|
||||||
@ -51,7 +46,9 @@
|
|||||||
<CardBody>
|
<CardBody>
|
||||||
<Form on:submit={onSave}>
|
<Form on:submit={onSave}>
|
||||||
<Row>
|
<Row>
|
||||||
<Label md={6} for="fgColor" size="sm">{$_('section.settings.textColor', { default: 'Text color' })}</Label>
|
<Label md={6} for="fgColor" size="sm"
|
||||||
|
>{$_('section.settings.textColor', { default: 'Text color' })}</Label
|
||||||
|
>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<Input
|
<Input
|
||||||
type="select"
|
type="select"
|
||||||
@ -92,7 +89,9 @@
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Label md={6} for="fullRefreshMin" size="sm">{ $_('section.settings.fullRefreshEvery') }</Label>
|
<Label md={6} for="fullRefreshMin" size="sm"
|
||||||
|
>{$_('section.settings.fullRefreshEvery')}</Label
|
||||||
|
>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<InputGroup size="sm">
|
<InputGroup size="sm">
|
||||||
<Input type="number" min={1} step="1" bind:value={$settings.fullRefreshMin} />
|
<Input type="number" min={1} step="1" bind:value={$settings.fullRefreshMin} />
|
||||||
@ -101,7 +100,9 @@
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Label md={6} for="minSecPriceUpd" size="sm">{ $_('section.settings.timeBetweenPriceUpdates') }</Label>
|
<Label md={6} for="minSecPriceUpd" size="sm"
|
||||||
|
>{$_('section.settings.timeBetweenPriceUpdates')}</Label
|
||||||
|
>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<InputGroup size="sm">
|
<InputGroup size="sm">
|
||||||
<Input type="number" min={1} step="1" bind:value={$settings.minSecPriceUpd} />
|
<Input type="number" min={1} step="1" bind:value={$settings.minSecPriceUpd} />
|
||||||
@ -142,7 +143,9 @@
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Label md={6} for="mempoolInstance" size="sm">{ $_('section.settings.mempoolnstance') }</Label>
|
<Label md={6} for="mempoolInstance" size="sm"
|
||||||
|
>{$_('section.settings.mempoolnstance')}</Label
|
||||||
|
>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
@ -150,12 +153,13 @@
|
|||||||
name="mempoolInstance"
|
name="mempoolInstance"
|
||||||
id="mempoolInstance"
|
id="mempoolInstance"
|
||||||
bsSize="sm"
|
bsSize="sm"
|
||||||
>
|
></Input>
|
||||||
</Input>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Label md={6} for="hostnamePrefix" size="sm">{ $_('section.settings.hostnamePrefix') }</Label>
|
<Label md={6} for="hostnamePrefix" size="sm"
|
||||||
|
>{$_('section.settings.hostnamePrefix')}</Label
|
||||||
|
>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
@ -163,31 +167,72 @@
|
|||||||
name="hostnamePrefix"
|
name="hostnamePrefix"
|
||||||
id="hostnamePrefix"
|
id="hostnamePrefix"
|
||||||
bsSize="sm"
|
bsSize="sm"
|
||||||
>
|
></Input>
|
||||||
</Input>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<Input id="ledTestOnPower" bind:checked={$settings.ledTestOnPower} type="switch" bsSize="sm" label="{ $_('section.settings.ledPowerOnTest') }" />
|
<Input
|
||||||
|
id="ledTestOnPower"
|
||||||
|
bind:checked={$settings.ledTestOnPower}
|
||||||
|
type="switch"
|
||||||
|
bsSize="sm"
|
||||||
|
label={$_('section.settings.ledPowerOnTest')}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<Input id="ledFlashOnUpd" bind:checked={$settings.ledFlashOnUpd} type="switch" bsSize="sm" label="{ $_('section.settings.ledFlashOnBlock') }" />
|
<Input
|
||||||
|
id="ledFlashOnUpd"
|
||||||
|
bind:checked={$settings.ledFlashOnUpd}
|
||||||
|
type="switch"
|
||||||
|
bsSize="sm"
|
||||||
|
label={$_('section.settings.ledFlashOnBlock')}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<Input id="stealFocus" bind:checked={$settings.stealFocus} type="switch" bsSize="sm" label="{ $_('section.settings.StealFocusOnNewBlock') }" />
|
<Input
|
||||||
|
id="stealFocus"
|
||||||
|
bind:checked={$settings.stealFocus}
|
||||||
|
type="switch"
|
||||||
|
bsSize="sm"
|
||||||
|
label={$_('section.settings.StealFocusOnNewBlock')}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<Input id="mcapBigChar" bind:checked={$settings.mcapBigChar} type="switch" bsSize="sm" label="{ $_('section.settings.useBigCharsMcap') }" />
|
<Input
|
||||||
|
id="mcapBigChar"
|
||||||
|
bind:checked={$settings.mcapBigChar}
|
||||||
|
type="switch"
|
||||||
|
bsSize="sm"
|
||||||
|
label={$_('section.settings.useBigCharsMcap')}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<Input id="otaEnabled" bind:checked={$settings.otaEnabled} type="switch" bsSize="sm" label="{ $_('section.settings.otaUpdates') } ({ $_('restartRequired') })" />
|
<Input
|
||||||
|
id="otaEnabled"
|
||||||
|
bind:checked={$settings.otaEnabled}
|
||||||
|
type="switch"
|
||||||
|
bsSize="sm"
|
||||||
|
label="{$_('section.settings.otaUpdates')} ({$_('restartRequired')})"
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<Input id="mdnsEnabled" bind:checked={$settings.mdnsEnabled} type="switch" bsSize="sm" label="{ $_('section.settings.enableMdns') } ({ $_('restartRequired') })" />
|
<Input
|
||||||
|
id="mdnsEnabled"
|
||||||
|
bind:checked={$settings.mdnsEnabled}
|
||||||
|
type="switch"
|
||||||
|
bsSize="sm"
|
||||||
|
label="{$_('section.settings.enableMdns')} ({$_('restartRequired')})"
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<Input id="fetchEurPrice" bind:checked={$settings.fetchEurPrice} type="switch" bsSize="sm" label="{ $_('section.settings.fetchEuroPrice') } ({ $_('restartRequired') })" />
|
<Input
|
||||||
|
id="fetchEurPrice"
|
||||||
|
bind:checked={$settings.fetchEurPrice}
|
||||||
|
type="switch"
|
||||||
|
bsSize="sm"
|
||||||
|
label="{$_('section.settings.fetchEuroPrice')} ({$_('restartRequired')})"
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
@ -196,7 +241,13 @@
|
|||||||
{#if $settings.screens}
|
{#if $settings.screens}
|
||||||
{#each $settings.screens as s}
|
{#each $settings.screens as s}
|
||||||
<Col md="6">
|
<Col md="6">
|
||||||
<Input id="screens_{s.id}" bind:checked={s.enabled} type="switch" bsSize="sm" label="{s.name}" />
|
<Input
|
||||||
|
id="screens_{s.id}"
|
||||||
|
bind:checked={s.enabled}
|
||||||
|
type="switch"
|
||||||
|
bsSize="sm"
|
||||||
|
label={s.name}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -1,16 +1,26 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PUBLIC_BASE_URL } from '$env/static/public';
|
import { PUBLIC_BASE_URL } from '$env/static/public';
|
||||||
|
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
import { writable, type Writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
import { Row, Input, Button, ButtonGroup, Card, CardBody, CardHeader, Col, Progress,CardTitle } from 'sveltestrap';
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonGroup,
|
||||||
|
Card,
|
||||||
|
CardBody,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
Col,
|
||||||
|
Input,
|
||||||
|
Progress,
|
||||||
|
Row
|
||||||
|
} from 'sveltestrap';
|
||||||
import Rendered from './Rendered.svelte';
|
import Rendered from './Rendered.svelte';
|
||||||
|
|
||||||
export let settings;
|
export let settings;
|
||||||
export let status:Writable<{}>;
|
export let status: writable<object>;
|
||||||
|
|
||||||
const toTime = (secs:Number) => {
|
const toTime = (secs: number) => {
|
||||||
var hours = Math.floor(secs / (60 * 60));
|
var hours = Math.floor(secs / (60 * 60));
|
||||||
|
|
||||||
var divisor_for_minutes = secs % (60 * 60);
|
var divisor_for_minutes = secs % (60 * 60);
|
||||||
@ -20,46 +30,42 @@
|
|||||||
var seconds = Math.ceil(divisor_for_seconds);
|
var seconds = Math.ceil(divisor_for_seconds);
|
||||||
|
|
||||||
var obj = {
|
var obj = {
|
||||||
"h": hours,
|
h: hours,
|
||||||
"m": minutes,
|
m: minutes,
|
||||||
"s": seconds
|
s: seconds
|
||||||
};
|
};
|
||||||
return obj;
|
return obj;
|
||||||
}
|
};
|
||||||
|
|
||||||
const toUptimeString = (secs:Number):String => {
|
const toUptimestring = (secs: number): string => {
|
||||||
let time = toTime(secs);
|
let time = toTime(secs);
|
||||||
|
|
||||||
return `${time.h}h ${time.m}m ${time.s}s`;
|
return `${time.h}h ${time.m}m ${time.s}s`;
|
||||||
}
|
};
|
||||||
|
|
||||||
let memoryFreePercent: number = 50;
|
let memoryFreePercent: number = 50;
|
||||||
let lightMode: boolean = false;
|
let lightMode: boolean = false;
|
||||||
|
|
||||||
status.subscribe((value: {}) => {
|
status.subscribe((value: object) => {
|
||||||
memoryFreePercent = Math.round(value.espFreeHeap / value.espHeapSize * 100);
|
memoryFreePercent = Math.round((value.espFreeHeap / value.espHeapSize) * 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
settings.subscribe((value: {}) => {
|
settings.subscribe((value: object) => {
|
||||||
lightMode = value.bgColor > value.fgColor;
|
lightMode = value.bgColor > value.fgColor;
|
||||||
});
|
});
|
||||||
|
|
||||||
const setScreen = (id: number) => () => {
|
const setScreen = (id: number) => () => {
|
||||||
fetch(`${PUBLIC_BASE_URL}/api/show/screen/${id}`).catch(err => { });
|
fetch(`${PUBLIC_BASE_URL}/api/show/screen/${id}`).catch(() => {});
|
||||||
}
|
};
|
||||||
|
|
||||||
const toggleTimer = (currentStatus:boolean) => () => {
|
const toggleTimer = (currentStatus: boolean) => (e: Event) => {
|
||||||
|
e.preventDefault();
|
||||||
if (currentStatus) {
|
if (currentStatus) {
|
||||||
fetch(`${PUBLIC_BASE_URL}/api/action/pause`);
|
fetch(`${PUBLIC_BASE_URL}/api/action/pause`);
|
||||||
} else {
|
} else {
|
||||||
fetch(`${PUBLIC_BASE_URL}/api/action/timer_restart`);
|
fetch(`${PUBLIC_BASE_URL}/api/action/timer_restart`);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const isLightMode = () => {
|
|
||||||
return $settings.bgColor > $settings.fgColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Col>
|
<Col>
|
||||||
@ -72,37 +78,60 @@
|
|||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<ButtonGroup size="sm">
|
<ButtonGroup size="sm">
|
||||||
{#each $settings.screens as s}
|
{#each $settings.screens as s}
|
||||||
<Button color="outline-primary" active={$status.currentScreen == s.id} on:click={setScreen(s.id)}>{s.name}</Button>
|
<Button
|
||||||
|
color="outline-primary"
|
||||||
|
active={$status.currentScreen == s.id}
|
||||||
|
on:click={setScreen(s.id)}>{s.name}</Button
|
||||||
|
>
|
||||||
{/each}
|
{/each}
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr />
|
||||||
{#if $status.data}
|
{#if $status.data}
|
||||||
<section class={lightMode ? 'lightMode' : ''}>
|
<section class={lightMode ? 'lightMode' : ''}>
|
||||||
<Rendered status="{$status}"></Rendered>
|
<Rendered status={$status}></Rendered>
|
||||||
</section>
|
</section>
|
||||||
{ $_('section.status.screenCycle') }: <a style="cursor: pointer" on:click="{toggleTimer($status.timerRunning)}">{#if $status.timerRunning}⏵ { $_('timer.running') }{:else}⏸ { $_('timer.stopped') }{/if}</a>
|
{$_('section.status.screenCycle')}:
|
||||||
|
<a
|
||||||
|
href={'#'}
|
||||||
|
style="cursor: pointer"
|
||||||
|
tabindex="0"
|
||||||
|
role="button"
|
||||||
|
aria-pressed="false"
|
||||||
|
on:click={toggleTimer($status.timerRunning)}
|
||||||
|
>{#if $status.timerRunning}⏵ {$_('timer.running')}{:else}⏸ {$_(
|
||||||
|
'timer.stopped'
|
||||||
|
)}{/if}</a
|
||||||
|
>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
<hr>
|
<hr />
|
||||||
<Row class="justify-content-evenly">
|
<Row class="justify-content-evenly">
|
||||||
{#if $status.leds}
|
{#if $status.leds}
|
||||||
{#each $status.leds as led}
|
{#each $status.leds as led}
|
||||||
<Col>
|
<Col>
|
||||||
<Input type="color" id="ledColorPicker" bind:value="{led.hex}" class="mx-auto" disabled />
|
<Input
|
||||||
|
type="color"
|
||||||
|
id="ledColorPicker"
|
||||||
|
bind:value={led.hex}
|
||||||
|
class="mx-auto"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
</Row>
|
</Row>
|
||||||
<hr>
|
<hr />
|
||||||
<Progress striped value={memoryFreePercent}>{memoryFreePercent}%</Progress>
|
<Progress striped value={memoryFreePercent}>{memoryFreePercent}%</Progress>
|
||||||
<div class="d-flex justify-content-between">
|
<div class="d-flex justify-content-between">
|
||||||
<div>{$_('section.status.memoryFree')}</div>
|
<div>{$_('section.status.memoryFree')}</div>
|
||||||
<div>{ Math.round($status.espFreeHeap / 1024) } / { Math.round($status.espHeapSize / 1024) } KiB</div>
|
<div>
|
||||||
|
{Math.round($status.espFreeHeap / 1024)} / {Math.round($status.espHeapSize / 1024)} KiB
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
</div>
|
||||||
{ $_('section.status.uptime') }: {toUptimeString($status.espUptime)}
|
<hr />
|
||||||
<br>
|
{$_('section.status.uptime')}: {toUptimestring($status.espUptime)}
|
||||||
|
<br />
|
||||||
<p>
|
<p>
|
||||||
{$_('section.status.wsPriceConnection')}:
|
{$_('section.status.wsPriceConnection')}:
|
||||||
<span>
|
<span>
|
||||||
@ -120,12 +149,11 @@
|
|||||||
{:else}
|
{:else}
|
||||||
❌
|
❌
|
||||||
{/if}
|
{/if}
|
||||||
</span><br>
|
</span><br />
|
||||||
{#if $settings.fetchEurPrice}
|
{#if $settings.fetchEurPrice}
|
||||||
<small>{$_('section.status.fetchEuroNote')}</small>
|
<small>{$_('section.status.fetchEuroNote')}</small>
|
||||||
{/if}
|
{/if}
|
||||||
</p>
|
</p>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
|
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -1,36 +1,31 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { _ } from 'svelte-i18n';
|
import { Button, Container } from 'sveltestrap';
|
||||||
import { Col, Container, Row, Button } from 'sveltestrap';
|
|
||||||
|
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
//import * as swaggerJson from '../../../static/swagger.json';
|
|
||||||
// import SwaggerUI from 'swagger-ui';
|
|
||||||
import 'swagger-ui/dist/swagger-ui.css';
|
|
||||||
|
|
||||||
let swaggerLoaded: boolean = false;
|
let swaggerLoaded: boolean = false;
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
// @ts-ignore
|
|
||||||
loadSwagger();
|
loadSwagger();
|
||||||
});
|
});
|
||||||
|
|
||||||
const loadSwagger = () => {
|
const loadSwagger = () => {
|
||||||
if (!SwaggerUIBundle)
|
// @ts-expect-error: SwaggerUIBundle is loaded from external script from CDN
|
||||||
return;
|
if (!SwaggerUIBundle) return; // eslint-disable-line
|
||||||
swaggerLoaded = true;
|
swaggerLoaded = true;
|
||||||
|
// @ts-expect-error: SwaggerUIBundle is loaded from external script from CDN
|
||||||
|
// eslint-disable-next-line
|
||||||
window.ui = SwaggerUIBundle({
|
window.ui = SwaggerUIBundle({
|
||||||
url: '/swagger.json',
|
url: '/swagger.json',
|
||||||
dom_id: '#swagger-ui-container',
|
dom_id: '#swagger-ui-container',
|
||||||
presets: [
|
presets: [
|
||||||
// @ts-ignore
|
// @ts-expect-error: SwaggerUIBundle is loaded from external script from CDN
|
||||||
SwaggerUIBundle.presets.apis,
|
SwaggerUIBundle.presets.apis, // eslint-disable-line
|
||||||
// @ts-ignore
|
// @ts-expect-error: SwaggerUIStandalonePreset is loaded from external script from CDN
|
||||||
SwaggerUIStandalonePreset
|
SwaggerUIStandalonePreset // eslint-disable-line
|
||||||
],
|
]
|
||||||
// layout: "StandaloneLayout",
|
// layout: "StandaloneLayout",
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@ -54,11 +49,9 @@
|
|||||||
crossorigin="anonymous"
|
crossorigin="anonymous"
|
||||||
referrerpolicy="no-referrer"
|
referrerpolicy="no-referrer"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<Container fluid class="bg-light">
|
<Container fluid class="bg-light">
|
||||||
<section class:invisible={swaggerLoaded}><Button on:click="{loadSwagger}">Load</Button></section>
|
<section class:invisible={swaggerLoaded}><Button on:click={loadSwagger}>Load</Button></section>
|
||||||
<div id="swagger-ui-container" />
|
<div id="swagger-ui-container" />
|
||||||
|
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -13,9 +13,7 @@
|
|||||||
"paths": {
|
"paths": {
|
||||||
"/status": {
|
"/status": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": ["system"],
|
||||||
"system"
|
|
||||||
],
|
|
||||||
"summary": "Get current status",
|
"summary": "Get current status",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
@ -26,9 +24,7 @@
|
|||||||
},
|
},
|
||||||
"/system_status": {
|
"/system_status": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": ["system"],
|
||||||
"system"
|
|
||||||
],
|
|
||||||
"summary": "Get system status",
|
"summary": "Get system status",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
@ -39,9 +35,7 @@
|
|||||||
},
|
},
|
||||||
"/settings": {
|
"/settings": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": ["system"],
|
||||||
"system"
|
|
||||||
],
|
|
||||||
"summary": "Get current settings",
|
"summary": "Get current settings",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
@ -57,9 +51,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": ["system"],
|
||||||
"system"
|
|
||||||
],
|
|
||||||
"summary": "Save current settings",
|
"summary": "Save current settings",
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"content": {
|
"content": {
|
||||||
@ -77,9 +69,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"patch": {
|
"patch": {
|
||||||
"tags": [
|
"tags": ["system"],
|
||||||
"system"
|
|
||||||
],
|
|
||||||
"summary": "Save current settings",
|
"summary": "Save current settings",
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"content": {
|
"content": {
|
||||||
@ -99,9 +89,7 @@
|
|||||||
},
|
},
|
||||||
"/action/pause": {
|
"/action/pause": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": ["timer"],
|
||||||
"timer"
|
|
||||||
],
|
|
||||||
"summary": "Pause screen rotation",
|
"summary": "Pause screen rotation",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
@ -112,9 +100,7 @@
|
|||||||
},
|
},
|
||||||
"/action/timer_restart": {
|
"/action/timer_restart": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": ["timer"],
|
||||||
"timer"
|
|
||||||
],
|
|
||||||
"summary": "Restart screen rotation",
|
"summary": "Restart screen rotation",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
@ -125,9 +111,7 @@
|
|||||||
},
|
},
|
||||||
"/show/screen/{id}": {
|
"/show/screen/{id}": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": ["screens"],
|
||||||
"screens"
|
|
||||||
],
|
|
||||||
"summary": "Set screen to show",
|
"summary": "Set screen to show",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
@ -150,9 +134,7 @@
|
|||||||
},
|
},
|
||||||
"/show/text/{text}": {
|
"/show/text/{text}": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": ["screens"],
|
||||||
"screens"
|
|
||||||
],
|
|
||||||
"summary": "Set text to show",
|
"summary": "Set text to show",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
@ -175,9 +157,7 @@
|
|||||||
},
|
},
|
||||||
"/show/custom": {
|
"/show/custom": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": ["screens"],
|
||||||
"screens"
|
|
||||||
],
|
|
||||||
"summary": "Set text to show (advanced)",
|
"summary": "Set text to show (advanced)",
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"content": {
|
"content": {
|
||||||
@ -197,9 +177,7 @@
|
|||||||
},
|
},
|
||||||
"/full_refresh": {
|
"/full_refresh": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": ["system"],
|
||||||
"system"
|
|
||||||
],
|
|
||||||
"summary": "Force full refresh of all displays",
|
"summary": "Force full refresh of all displays",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
@ -210,9 +188,7 @@
|
|||||||
},
|
},
|
||||||
"/lights": {
|
"/lights": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": ["lights"],
|
||||||
"lights"
|
|
||||||
],
|
|
||||||
"summary": "Get LEDs status",
|
"summary": "Get LEDs status",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
@ -228,9 +204,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"patch": {
|
"patch": {
|
||||||
"tags": [
|
"tags": ["lights"],
|
||||||
"lights"
|
|
||||||
],
|
|
||||||
"summary": "Set individual LEDs",
|
"summary": "Set individual LEDs",
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"content": {
|
"content": {
|
||||||
@ -253,9 +227,7 @@
|
|||||||
},
|
},
|
||||||
"/lights/{color}": {
|
"/lights/{color}": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": ["lights"],
|
||||||
"lights"
|
|
||||||
],
|
|
||||||
"summary": "Turn on LEDs with specific color",
|
"summary": "Turn on LEDs with specific color",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
@ -278,9 +250,7 @@
|
|||||||
},
|
},
|
||||||
"/lights/off": {
|
"/lights/off": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": ["lights"],
|
||||||
"lights"
|
|
||||||
],
|
|
||||||
"summary": "Turn LEDs off",
|
"summary": "Turn LEDs off",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
@ -291,9 +261,7 @@
|
|||||||
},
|
},
|
||||||
"/restart": {
|
"/restart": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": ["system"],
|
||||||
"system"
|
|
||||||
],
|
|
||||||
"summary": "Restart BTClock",
|
"summary": "Restart BTClock",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
|
@ -149,9 +149,9 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/ArrayOfLedsInput'
|
$ref: '#/components/schemas/ArrayOfLedsInput'
|
||||||
responses:
|
responses:
|
||||||
"200":
|
'200':
|
||||||
description: succesful operation
|
description: succesful operation
|
||||||
"400":
|
'400':
|
||||||
description: invalid colors or wrong amount of LEDs
|
description: invalid colors or wrong amount of LEDs
|
||||||
/lights/{color}:
|
/lights/{color}:
|
||||||
get:
|
get:
|
||||||
@ -211,7 +211,7 @@ components:
|
|||||||
hex:
|
hex:
|
||||||
type: string
|
type: string
|
||||||
pattern: ^#(?:[0-9a-fA-F]{3}){1,2}$
|
pattern: ^#(?:[0-9a-fA-F]{3}){1,2}$
|
||||||
example: "#FFCC00"
|
example: '#FFCC00'
|
||||||
RgbColorValueAndHex:
|
RgbColorValueAndHex:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/components/schemas/RgbColorValues'
|
- $ref: '#/components/schemas/RgbColorValues'
|
||||||
|
@ -5,9 +5,7 @@ import { vitePreprocess } from '@sveltejs/kit/vite';
|
|||||||
const config = {
|
const config = {
|
||||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||||
// for more information about preprocessors
|
// for more information about preprocessors
|
||||||
preprocess: vitePreprocess({
|
preprocess: vitePreprocess({}),
|
||||||
|
|
||||||
}),
|
|
||||||
build: {
|
build: {
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
output: {
|
output: {
|
||||||
@ -24,11 +22,11 @@ build: {
|
|||||||
// these options are set automatically — see below
|
// these options are set automatically — see below
|
||||||
pages: 'dist',
|
pages: 'dist',
|
||||||
assets: 'dist',
|
assets: 'dist',
|
||||||
fallback: "bundle.html",
|
fallback: 'bundle.html',
|
||||||
precompress: false,
|
precompress: false,
|
||||||
strict: true
|
strict: true
|
||||||
}),
|
}),
|
||||||
appDir: "build",
|
appDir: 'build'
|
||||||
// inlineStyleThreshold: 9999999999
|
// inlineStyleThreshold: 9999999999
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,61 +1,71 @@
|
|||||||
import { sveltekit } from '@sveltejs/kit/vite';
|
import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs';
|
||||||
import * as path from 'path'
|
import * as path from 'path';
|
||||||
|
|
||||||
const doRewrap = ({ cssClass }) => {
|
const doRewrap = ({ cssClass }) => {
|
||||||
try {
|
try {
|
||||||
if (fs.existsSync(path.resolve(__dirname, 'dist/bundle.js'))) {
|
if (fs.existsSync(path.resolve(__dirname, 'dist/bundle.js'))) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
console.log("\nStart re-wrapping...")
|
console.log('\nStart re-wrapping...');
|
||||||
fs.readFile(path.resolve(__dirname, 'dist/bundle.html'), 'utf8', function (err, data) {
|
fs.readFile(path.resolve(__dirname, 'dist/bundle.html'), 'utf8', function (err, data) {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
console.log(`[Error]: No bundle.html generated, check svelte.config.js -> config.kit.adapter -> fallback: "bundle.html"`)
|
console.log(
|
||||||
return
|
`[Error]: No bundle.html generated, check svelte.config.js -> config.kit.adapter -> fallback: "bundle.html"`
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
let matchData = data.match(/(?<=<script\b[^>]*>)([\s\S]*?)(?=<\/script>)/gm)
|
const matchData = data.match(/(?<=<script\b[^>]*>)([\s\S]*?)(?=<\/script>)/gm);
|
||||||
if (matchData) {
|
if (matchData) {
|
||||||
let cleanData = matchData[0].trim()
|
const cleanData = matchData[0]
|
||||||
.replace(`document.querySelector('[data-sveltekit-hydrate="45h"]').parentNode`, `document.querySelector(".${cssClass}")`)
|
.trim()
|
||||||
|
.replace(
|
||||||
|
`document.querySelector('[data-sveltekit-hydrate="45h"]').parentNode`,
|
||||||
|
`document.querySelector(".${cssClass}")`
|
||||||
|
);
|
||||||
fs.writeFile(path.resolve(__dirname, 'dist/bundle.js'), cleanData, (err) => {
|
fs.writeFile(path.resolve(__dirname, 'dist/bundle.js'), cleanData, (err) => {
|
||||||
if (err)
|
if (err) console.log(err);
|
||||||
console.log(err)
|
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
fs.rename(path.resolve(__dirname,'dist/index.page'), path.resolve(__dirname, 'dist/index.html'), (err) => { })
|
fs.rename(
|
||||||
|
path.resolve(__dirname, 'dist/index.page'),
|
||||||
|
path.resolve(__dirname, 'dist/index.html'),
|
||||||
|
() => {}
|
||||||
|
);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
try {
|
try {
|
||||||
fs.unlinkSync(path.resolve(__dirname, 'dist/bundle.html'))
|
fs.unlinkSync(path.resolve(__dirname, 'dist/bundle.html'));
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
console.log("Finished: bundle.js + index.html have been regenerated.\n")
|
console.log('Finished: bundle.js + index.html have been regenerated.\n');
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
} else
|
} else console.log(`[Error]: No proper <script> tag found in bundle.html`);
|
||||||
console.log(`[Error]: No proper <script> tag found in bundle.html`)
|
});
|
||||||
})
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [sveltekit(), {
|
plugins: [
|
||||||
|
sveltekit(),
|
||||||
|
{
|
||||||
name: 'postbuild-command',
|
name: 'postbuild-command',
|
||||||
closeBundle: {
|
closeBundle: {
|
||||||
order: 'post',
|
order: 'post',
|
||||||
handler() {
|
handler() {
|
||||||
setTimeout(() => doRewrap({ cssClass: "overlay" }), Math.random()*500+500)
|
setTimeout(() => doRewrap({ cssClass: 'overlay' }), Math.random() * 500 + 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}],
|
}
|
||||||
|
],
|
||||||
build: {
|
build: {
|
||||||
minify: true,
|
minify: true,
|
||||||
cssCodeSplit: false,
|
cssCodeSplit: false,
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
output: {
|
output: {
|
||||||
manualChunks: () => 'app',
|
manualChunks: () => 'app',
|
||||||
assetFileNames: "[name][extname]"
|
assetFileNames: '[name][extname]'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user