diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml new file mode 100644 index 0000000..a1e59a8 --- /dev/null +++ b/.forgejo/workflows/build.yaml @@ -0,0 +1,121 @@ +on: [push] +jobs: + check-changes: + runs-on: docker + outputs: + all_changed_and_modified_files_count: ${{ steps.changed-files.outputs.all_changed_and_modified_files_count }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Get changed files count + id: changed-files + uses: tj-actions/changed-files@v45 + with: + files_ignore: 'doc/**,README.md,Dockerfile,.*' + files_ignore_separator: ',' + - name: Print changed files count + run: > + echo "Changed files count: ${{ + steps.changed-files.outputs.all_changed_and_modified_files_count }}" + + build: + needs: check-changes + runs-on: docker + container: + image: ghcr.io/catthehacker/ubuntu:js-22.04 + if: ${{ needs.check-changes.outputs.all_changed_and_modified_files_count >= 1 }} + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: actions/setup-node@v4 + with: + node-version: lts/* + cache: yarn + cache-dependency-path: '**/yarn.lock' + - uses: actions/cache@v4 + with: + path: | + ~/.cache/pip + ~/node_modules + key: ${{ runner.os }}-pio + - uses: actions/setup-python@v5 + with: + python-version: '>=3.10' + - name: Get current date + id: dateAndTime + run: echo "dateAndTime=$(date +'%Y-%m-%d-%H:%M')" >> $GITHUB_OUTPUT + - name: Install mklittlefs + run: > + git clone https://github.com/earlephilhower/mklittlefs.git /tmp/mklittlefs && + cd /tmp/mklittlefs && + git submodule update --init && + make dist + - name: Install yarn + run: yarn && yarn postinstall + - name: Run linter + run: yarn lint + - name: Run vitest tests + run: yarn vitest run + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + run: npx playwright test + - name: Build WebUI + run: yarn build + - name: Get current block + id: getBlockHeight + run: echo "blockHeight=$(curl -s https://mempool.space/api/blocks/tip/height)" >> $GITHUB_OUTPUT + - name: Write block height to file + env: + BLOCK_HEIGHT: ${{ steps.getBlockHeight.outputs.blockHeight }} + run: mkdir -p output && echo "$BLOCK_HEIGHT" > output/version.txt + - name: gzip build for LittleFS + run: find dist -type f ! -name ".*" -exec sh -c 'mkdir -p "build_gz/$(dirname "${1#dist/}")" && gzip -k "$1" -c > "build_gz/${1#dist/}".gz' _ {} \; + - name: Write git rev to file + run: echo "$GITHUB_SHA" > build_gz/fs_hash.txt && echo "$GITHUB_SHA" > output/commit.txt + - name: Check GZipped directory size + run: | + # Set the threshold size in bytes + THRESHOLD=410000 + + # Calculate the total size of files in the directory + DIRECTORY_SIZE=$(du -b -s build_gz | awk '{print $1}') + + # Fail the workflow if the size exceeds the threshold + if [ "$DIRECTORY_SIZE" -gt "$THRESHOLD" ]; then + echo "Directory size exceeds the threshold of $THRESHOLD bytes" + exit 1 + else + echo "Directory size is within the threshold $DIRECTORY_SIZE" + fi + - name: Create tarball + run: tar czf webui.tgz --strip-components=1 dist + - name: Build LittleFS + run: | + set -e + /tmp/mklittlefs/mklittlefs -c build_gz -s 410000 output/littlefs.bin + - name: Upload artifacts + uses: https://code.forgejo.org/forgejo/upload-artifact@v4 + with: + path: | + webui.tgz + output/littlefs.bin + - name: Create release + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: https://code.forgejo.org/actions/forgejo-release@v2.4.0 + with: + url: 'https://git.btclock.dev/' + repo: '${{ github.repository }}' + direction: upload + tag: ${{ steps.getBlockHeight.outputs.blockHeight }} + sha: '${{ github.sha }}' + release-dir: output + token: ${{ secrets.TOKEN }} + override: false + verbose: false + release-notes-assistant: false diff --git a/package.json b/package.json index 9c4937d..44cc323 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "postinstall": "patch-package", "test": "npm run test:integration && npm run test:unit", "test:integration": "playwright test", + "test:screenshots": "playwright test -c playwright.screenshot.config.ts", "test:unit": "vitest" }, "devDependencies": { @@ -58,6 +59,7 @@ "msgpack-es": "^0.0.5", "nostr-tools": "^2.7.1", "patch-package": "^8.0.0", + "svelte-bootstrap-icons": "^3.1.1", "svelte-i18n": "^4.0.0" }, "resolutions": { diff --git a/patches/@sveltejs+kit+2.8.5.patch b/patches/@sveltejs+kit+2.8.5.patch new file mode 100644 index 0000000..80f5dba --- /dev/null +++ b/patches/@sveltejs+kit+2.8.5.patch @@ -0,0 +1,17 @@ +diff --git a/node_modules/@sveltejs/kit/src/exports/vite/index.js b/node_modules/@sveltejs/kit/src/exports/vite/index.js +index e6521e9..f31c28b 100644 +--- a/node_modules/@sveltejs/kit/src/exports/vite/index.js ++++ b/node_modules/@sveltejs/kit/src/exports/vite/index.js +@@ -639,9 +639,9 @@ async function kit({ svelte_config }) { + input, + output: { + format: 'esm', +- entryFileNames: ssr ? '[name].js' : `${prefix}/[name].[hash].${ext}`, +- chunkFileNames: ssr ? 'chunks/[name].js' : `${prefix}/chunks/[name].[hash].${ext}`, +- assetFileNames: `${prefix}/assets/[name].[hash][extname]`, ++ entryFileNames: ssr ? '[name].js' : `${prefix}/[hash].${ext}`, ++ chunkFileNames: ssr ? 'chunks/[name].js' : `${prefix}/chunks/[hash].${ext}`, ++ assetFileNames: `${prefix}/assets/[hash][extname]`, + hoistTransitiveImports: false, + sourcemapIgnoreList + }, diff --git a/playwright.config.ts b/playwright.config.ts index d60d61c..bf148ce 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -10,7 +10,7 @@ const config: PlaywrightTestConfig = { port: 4173 }, reporter: process.env.CI ? 'github' : 'list', - testDir: 'tests', + testDir: 'tests/playwright', testMatch: /(.+\.)?(test|spec)\.[jt]s/ }; diff --git a/playwright.screenshot.config.ts b/playwright.screenshot.config.ts new file mode 100644 index 0000000..81264a4 --- /dev/null +++ b/playwright.screenshot.config.ts @@ -0,0 +1,51 @@ +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + reporter: 'html', + use: { + locale: 'en-GB', + timezoneId: 'Europe/Amsterdam' + }, + webServer: { + command: 'npm run build && npm run preview', + port: 4173 + }, + testDir: './tests/screenshots', + outputDir: './test-results/screenshots', + projects: [ + { + name: 'MacBook Air 13 inch', + use: { + viewport: { width: 1440, height: 900 } + } + }, + { + name: 'iPhone 14 Pro', + use: { ...devices['iPhone 14 Pro'] } + }, + { + name: 'iPhone 15 Pro Landscape', + use: { ...devices['iPhone 15 Pro Landscape'] } + }, + { + name: 'MacBook Pro 14 inch', + use: { + viewport: { width: 1512, height: 982 } + } + }, + { + name: 'MacBook Pro 14 inch', + use: { + viewport: { width: 1512, height: 982 } + } + }, + { + name: 'MacBook Pro 14 inch Firefox HiDPI', + use: { ...devices['Desktop Firefox HiDPI'], viewport: { width: 1512, height: 982 } } + }, + { + name: 'MacBook Pro 14 inch Safari', + use: { ...devices['Desktop Safari'], viewport: { width: 1512, height: 982 } } + } + ] +}); diff --git a/src/components/ColorSchemeSwitcher.svelte b/src/components/ColorSchemeSwitcher.svelte new file mode 100644 index 0000000..9d7e32a --- /dev/null +++ b/src/components/ColorSchemeSwitcher.svelte @@ -0,0 +1,53 @@ + + + + + {theme === 'auto' ? '🌗' : theme === 'dark' ? '🌙' : '☀️'} + + + setTheme('light')} + >☀️ Light + setTheme('dark')}>🌙 Dark + setTheme('auto')}>🌗 Auto + + diff --git a/src/components/ToggleHeader.svelte b/src/components/ToggleHeader.svelte new file mode 100644 index 0000000..acc8d3b --- /dev/null +++ b/src/components/ToggleHeader.svelte @@ -0,0 +1,28 @@ + + +

+ (isOpen = !isOpen)} + tabindex="0" + on:keypress={() => (isOpen = !isOpen)} + > + {#if isOpen} + + {:else} + + {/if} + {header} + +

+ + + diff --git a/src/icons/EyeIcon.svelte b/src/icons/EyeIcon.svelte deleted file mode 100644 index dd7513a..0000000 --- a/src/icons/EyeIcon.svelte +++ /dev/null @@ -1,13 +0,0 @@ - - - - diff --git a/src/icons/EyeSlashIcon.svelte b/src/icons/EyeSlashIcon.svelte deleted file mode 100644 index bf45888..0000000 --- a/src/icons/EyeSlashIcon.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - - - - diff --git a/src/lib/locales/de.json b/src/lib/locales/de.json index 946b962..e9756ff 100644 --- a/src/lib/locales/de.json +++ b/src/lib/locales/de.json @@ -42,7 +42,23 @@ "httpAuthUser": "WebUI-Benutzername", "httpAuthPass": "WebUI-Passwort", "httpAuthText": "Schützt nur die WebUI mit einem Passwort, nicht API-Aufrufe.", - "currencies": "Währungen" + "currencies": "Währungen", + "mowMode": "Mow suffixmodus", + "suffixShareDot": "Kompakte Suffix-Notation", + "section": { + "displaysAndLed": "Anzeigen und LEDs", + "screenSettings": "Infospezifisch", + "dataSource": "Datenquelle", + "extraFeatures": "Zusätzliche Funktionen", + "system": "System" + }, + "ledFlashOnZap": "LED blinkt bei Nostr Zap", + "flFlashOnZap": "Displaybeleuchting bei Nostr Zap", + "showAll": "Alle anzeigen", + "hideAll": "Alles ausblenden", + "flOffWhenDark": "Displaybeleuchtung aus, wenn es dunkel ist", + "luxLightToggleText": "Zum Deaktivieren auf 0 setzen", + "verticalDesc": "Vrtikale Bildschirmbeschreibung" }, "control": { "systemInfo": "Systeminfo", diff --git a/src/lib/locales/en.json b/src/lib/locales/en.json index a9ba033..3ab90ed 100644 --- a/src/lib/locales/en.json +++ b/src/lib/locales/en.json @@ -41,7 +41,7 @@ "nostrZapKey": "Nostr zap pubkey", "nostrRelay": "Nostr Relay", "nostrZapNotify": "Nostr Zap Notifications", - "useNostr": "Use Nostr datasource", + "useNostr": "Use Nostr data source", "bitaxeHostname": "BitAxe hostname or IP", "bitaxeEnabled": "Enable BitAxe", "nostrZapPubkey": "Nostr Zap pubkey", @@ -53,8 +53,24 @@ "httpAuthPass": "WebUI Password", "httpAuthText": "Only password-protects WebUI, not API-calls.", "currencies": "Currencies", - "stagingSource": "Use Staging datasource (for development)", - "useNostrTooltip": "Very experimental and unstable. Nostr data source is not required for Nostr Zap notifications." + "stagingSource": "Use Staging data source (for development)", + "useNostrTooltip": "Very experimental and unstable. Nostr data source is not required for Nostr Zap notifications.", + "mowMode": "Mow Suffix Mode", + "suffixShareDot": "Suffix compact notation", + "section": { + "displaysAndLed": "Displays and LEDs", + "screenSettings": "Screen specific", + "dataSource": "Data source", + "extraFeatures": "Extra features", + "system": "System" + }, + "ledFlashOnZap": "LED flash on Nostr Zap", + "flFlashOnZap": "Frontlight flash on Nostr Zap", + "showAll": "Show all", + "hideAll": "Hide all", + "flOffWhenDark": "Frontlight off when dark", + "luxLightToggleText": "Set to 0 to disable", + "verticalDesc": "Use vertical screen description" }, "control": { "systemInfo": "System info", diff --git a/src/lib/locales/es.json b/src/lib/locales/es.json index 5eced4c..79b6673 100644 --- a/src/lib/locales/es.json +++ b/src/lib/locales/es.json @@ -41,7 +41,23 @@ "httpAuthUser": "Nombre de usuario WebUI", "httpAuthPass": "Contraseña WebUI", "httpAuthText": "Solo la WebUI está protegida con contraseña, no las llamadas API.", - "currencies": "Monedas" + "currencies": "Monedas", + "mowMode": "Modo de sufijo Mow", + "suffixShareDot": "Notación compacta de sufijo", + "section": { + "displaysAndLed": "Pantallas y LED", + "screenSettings": "Específico de la pantalla", + "dataSource": "fuente de datos", + "extraFeatures": "Funciones adicionales", + "system": "Sistema" + }, + "ledFlashOnZap": "LED parpadeante con Nostr Zap", + "flFlashOnZap": "Flash de luz frontal con Nostr Zap", + "showAll": "Mostrar todo", + "hideAll": "Ocultar todo", + "flOffWhenDark": "Luz de la pantalla cuando está oscuro", + "luxLightToggleText": "Establecer en 0 para desactivar", + "verticalDesc": "Descripción de pantalla vertical" }, "control": { "turnOff": "Apagar", diff --git a/src/lib/locales/nl.json b/src/lib/locales/nl.json index f126bcf..eb5b5af 100644 --- a/src/lib/locales/nl.json +++ b/src/lib/locales/nl.json @@ -42,7 +42,23 @@ "httpAuthUser": "WebUI-gebruikersnaam", "httpAuthPass": "WebUI-wachtwoord", "httpAuthText": "Beveiligd enkel WebUI, niet de API.", - "currencies": "Valuta's" + "currencies": "Valuta's", + "mowMode": "Mow achtervoegsel", + "suffixShareDot": "Achtervoegsel compacte notatie", + "section": { + "displaysAndLed": "Displays en LED's", + "screenSettings": "Schermspecifiek", + "dataSource": "Gegevensbron", + "extraFeatures": "Extra functies", + "system": "Systeem" + }, + "ledFlashOnZap": "Knipper LED bij Nostr Zap", + "flFlashOnZap": "Knipper displaylicht bij Nostr Zap", + "showAll": "Toon alles", + "hideAll": "Alles verbergen", + "flOffWhenDark": "Displaylicht uit als het donker is", + "luxLightToggleText": "Stel in op 0 om uit te schakelen", + "verticalDesc": "Verticale schermbeschrijving" }, "control": { "systemInfo": "Systeeminformatie", diff --git a/src/lib/style/app.scss b/src/lib/style/app.scss index 00bf40b..53eeee8 100644 --- a/src/lib/style/app.scss +++ b/src/lib/style/app.scss @@ -1,6 +1,4 @@ @import '../node_modules/bootstrap/scss/functions'; -@import '../node_modules/bootstrap/scss/variables'; -@import '../node_modules/bootstrap/scss/variables-dark'; //@import "@fontsource/antonio/latin-400.css"; @import '@fontsource/ubuntu/latin-400.css'; @@ -9,11 +7,13 @@ @import './satsymbol'; -$color-mode-type: media-query; +$color-mode-type: data; $font-family-base: 'Ubuntu'; $font-size-base: 0.9rem; $input-font-size-sm: $font-size-base * 0.875; +@import '../node_modules/bootstrap/scss/variables'; +@import '../node_modules/bootstrap/scss/variables-dark'; // $border-radius: .675rem; @import '../node_modules/bootstrap/scss/mixins'; @@ -43,6 +43,40 @@ $input-font-size-sm: $font-size-base * 0.875; @import '../node_modules/bootstrap/scss/helpers'; @import '../node_modules/bootstrap/scss/utilities/api'; +/* Default state (xs) - sticky */ +.sticky-xs-top { + position: sticky; + top: 0; + z-index: 1020; +} + +@media (max-width: 576px) { + main { + margin-top: 25px; + } +} + +/* Remove sticky behavior for larger screens */ +@media (min-width: 576px) { + .sticky-xs-top { + position: relative; + } +} + +@include color-mode(dark) { + .navbar { + --bs-navbar-color: $light; + background-color: $dark; + } +} + +@include color-mode(light) { + .navbar { + --bs-navbar-color: $dark; + background-color: $light; + } +} + nav { margin-bottom: 15px; } @@ -53,6 +87,23 @@ nav { .btn-group-sm .btn { font-size: 0.8rem; + // text-overflow: ellipsis; + // white-space: nowrap; + // overflow: hidden; + // width: 4rem; +} + +.btn-group-sm { + display: flex !important; + flex-wrap: wrap !important; + gap: 0.25rem !important; +} + +/* Remove the border radius override that Bootstrap applies */ +.btn-group-sm > .btn { + border-radius: 0.25rem !important; + margin: 0 !important; + position: relative !important; } #customText { @@ -63,7 +114,7 @@ nav { .btclock { background: #000; display: flex; - font-size: calc(3vw + 3vh); + font-size: calc(2vw + 2vh); font-family: 'Antonio', sans-serif; font-weight: 400; padding: 10px; @@ -104,19 +155,25 @@ nav { flex-direction: column; /* Stack the text and line vertically */ align-items: center; justify-content: space-around; /* Distribute items with space between */ - padding: 10px; + padding: 5px; } - .splitText div:first-child::after { + &.verticalDesc > .splitText:first-child { + .textcontainer { + transform: rotate(-90deg); + } + } + + .splitText .textcontainer :first-child::after { display: block; content: ''; margin-top: 0px; border-bottom: 2px solid; - margin-bottom: 3px; + // margin-bottom: 3px; } .splitText { - font-size: calc(0.5vw + 1vh); + font-size: calc(0.3vw + 1vh); .top-text, .bottom-text { @@ -242,3 +299,7 @@ nav { input[type='number'] { text-align: right; } + +.lightMode .bitaxelogo { + filter: brightness(0) saturate(100%); +} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index a34ea20..e421f5a 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -12,9 +12,11 @@ NavbarBrand, NavbarToggler } from '@sveltestrap/sveltestrap'; + import { _ } from 'svelte-i18n'; import { page } from '$app/stores'; import { locale, locales, isLoading } from 'svelte-i18n'; + import ColorSchemeSwitcher from '../components/ColorSchemeSwitcher.svelte'; export const setLocale = (lang: string) => () => { locale.set(lang); @@ -37,7 +39,7 @@ return flagMap[lowercaseCode]; } else { // Return null for unsupported language codes - return null; + return flagMap['en']; } }; @@ -60,8 +62,23 @@ }; - - ₿TClock + + ₿TClock + + @@ -77,7 +94,7 @@ {#if !$isLoading} - + {getFlagEmoji($locale)} {languageNames[$locale]} {#each $locales as locale} @@ -88,8 +105,11 @@ {/if} + - +
+ +
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index b37ab13..c2e4e3b 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -3,6 +3,7 @@ import { screenSize, updateScreenSize } from '$lib/screen'; import { Container, Row, Toast, ToastBody } from '@sveltestrap/sveltestrap'; + import { replaceState } from '$app/navigation'; import { onMount } from 'svelte'; import { writable } from 'svelte/store'; @@ -16,12 +17,6 @@ bgColor: '0' }); - // let uiSettings = writable({ - // inputSize: 'sm', - // selectClass: '', - // btnSize: 'lg' - // }); - let status = writable({ data: ['L', 'O', 'A', 'D', 'I', 'N', 'G'], espFreeHeap: 0, @@ -60,7 +55,43 @@ }); }; + let sections: (HTMLElement | null)[]; + let observer: IntersectionObserver; + const SM_BREAKPOINT = 576; + + const setupObserver = () => { + if (window.innerWidth < SM_BREAKPOINT) { + observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + const id = entry.target.id; + replaceState(`#${id}`); + + // Update nav pills + document.querySelectorAll('.nav-link').forEach((link) => { + link.classList.remove('active'); + if (link.getAttribute('href') === `#${id}`) { + link.classList.add('active'); + } + }); + } + }); + }, + { + threshold: 0.25 // Trigger when section is 50% visible + } + ); + + sections = ['control', 'status', 'settings'].map((id) => document.getElementById(id)); + + sections.forEach((section) => observer.observe(section!)); + } + }; + onMount(() => { + setupObserver(); + fetchSettingsData(); fetchStatusData(); @@ -72,6 +103,11 @@ }); function handleResize() { + if (observer) { + observer.disconnect(); + } + setupObserver(); + updateScreenSize(); } @@ -125,7 +161,9 @@ + + diff --git a/src/routes/Control.svelte b/src/routes/Control.svelte index d89ee10..25f5a44 100644 --- a/src/routes/Control.svelte +++ b/src/routes/Control.svelte @@ -105,8 +105,8 @@ export let xxl = xl; - - + + {$_('section.control.title', { default: 'Control' })} diff --git a/src/routes/FirmwareUpdater.svelte b/src/routes/FirmwareUpdater.svelte index 22843bf..a9a3229 100644 --- a/src/routes/FirmwareUpdater.svelte +++ b/src/routes/FirmwareUpdater.svelte @@ -145,7 +145,7 @@ onMount(async () => { try { const response = await fetch( - 'https://api.github.com/repos/btclock/btclock_v3/releases/latest' + 'https://git.btclock.dev/api/v1/repos/btclock/btclock_v3/releases/latest' ); if (!response.ok) { @@ -200,7 +200,7 @@

Loading...

{/if}
-
+
Update firmware
-
+
-
+
{#each status.data as char} {#if isSplitText(char)}
- {#if char.split('/').length} - {char.split('/')[0]} -
- {char.split('/')[1]} - {/if} +
+ {#if char.split('/').length} + {char.split('/')[0]} + {char.split('/')[1]} + {/if} +
{:else if char.startsWith('mdi')} -
+
{#if char.endsWith('rocket')} {/if} @@ -68,6 +69,9 @@ {#if char.endsWith('bolt')} {/if} + {#if char.endsWith('bitaxe')} + + {/if}
{:else if char === 'STS'}
S
@@ -82,8 +86,22 @@
- diff --git a/src/routes/Settings.svelte b/src/routes/Settings.svelte index 40df8d3..8130940 100644 --- a/src/routes/Settings.svelte +++ b/src/routes/Settings.svelte @@ -21,9 +21,12 @@ Tooltip, Row } from '@sveltestrap/sveltestrap'; - import EyeIcon from '../icons/EyeIcon.svelte'; - import EyeSlashIcon from '../icons/EyeSlashIcon.svelte'; + + import EyeIcon from 'svelte-bootstrap-icons/lib/Eye.svelte'; + import EyeSlashIcon from 'svelte-bootstrap-icons/lib/EyeSlash.svelte'; + import { derived } from 'svelte/store'; + import ToggleHeader from '../components/ToggleHeader.svelte'; export let settings; @@ -196,637 +199,769 @@ } }; + const showAll = (show: boolean) => { + screenSettingsIsOpen = show; + displaysAndLedIsOpen = show; + dataSourceIsOpen = show; + extraFeaturesIsOpen = show; + systemIsOpen = show; + }; + export let xs = 12; export let sm = xs; export let md = sm; export let lg = md; export let xl = lg; export let xxl = xl; + + let screenSettingsIsOpen: boolean, + displaysAndLedIsOpen: boolean, + dataSourceIsOpen: boolean, + extraFeaturesIsOpen: boolean, + systemIsOpen: boolean; - - + + +
+ + | + +
{$_('section.settings.title', { default: 'Settings' })}
-
+ - - - - - - - - - - - - - - - {$_('time.minutes')} - - - - - - - - - {$_('time.minutes')} - - - - - - - - - {$_('time.seconds')} - - {$_('section.settings.shortAmountsWarning')} - - - - - - - - {$_('time.minutes')} - - - {$_('section.settings.tzOffsetHelpText')} - - - - - - - - - {#if $settings.hasFrontlight && !$settings.flDisable} - - - - - - - - - - - - - {/if} - {#if !$settings.flDisable && $settings.hasLightLevel} - - - - - - - {/if} - {#if $settings.bitaxeEnabled} - - - - - - - - - - {/if} - {#if 'nostrZapNotify' in $settings && $settings['nostrZapNotify']} - - - - checkValidNostrPubkey('nostrZapPubkey')} - invalid={!isValidHexPubKey($settings.nostrZapPubkey)} - bsSize={$uiSettings.inputSize} - required - minlength="64" - > - {#if !isValidHexPubKey($settings.nostrZapPubkey)} - {$_('section.settings.invalidNostrPubkey')} - {/if} - - - {/if} - {#if $settings.useNostr} - - - - checkValidNostrPubkey('nostrPubKey')} - invalid={!isValidHexPubKey($settings.nostrPubKey)} - bsSize={$uiSettings.inputSize} - > - {#if !isValidHexPubKey($settings.nostrPubKey)} - {$_('section.settings.invalidNostrPubkey')} - {/if} - - - {/if} - {#if 'nostrZapNotify' in $settings || $settings.useNostr} - - - - - - - - - - {/if} - - - - - - - - HTTPS - - - {$_('section.settings.mempoolInstanceHelpText')} - - - {#if $settings.httpAuthEnabled} - - - - - - - - - - - - - - {$_('section.settings.httpAuthText')} - - - {/if} - - - - - - - - - - - {#each wifiTxPowerMap as [key, value]} - - {/each} - - {$_('section.settings.wifiTxPowerText')} - - - - - - - - {$_('time.seconds')} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {#if $settings.hasFrontlight} - - - - {/if} - {#if $settings.hasFrontlight && !$settings.flDisable} - - - - - - - {/if} - {#if !$settings.actCurrencies} - - - - {/if} - - - - {#if $settings.nostrRelay} - - - - {$_('section.settings.useNostrTooltip')} - - - {/if} - {#if 'nostrZapNotify' in $settings} - - - - {/if} - {#if 'bitaxeEnabled' in $settings} - - - - {/if} - - - - - - - - - - {#if 'stagingSource' in $settings} - - - - {/if} - - - -

{$_('section.settings.screens')}

- {#if $settings.screens} - {#each $settings.screens as s} + - {/each} - {/if} - - {#if $settings.actCurrencies && $settings.useNostr !== true} - -

{$_('section.settings.currencies')}

- {$_('restartRequired')} - {#if $settings.availableCurrencies} - {#each $settings.availableCurrencies as c} + + + + + + + + + + + + + + + + + + + + + + + + {#if !$settings.actCurrencies} -
- - -
+ - {/each} + {/if} +
+ +
{$_('section.settings.screens')}
+ {#if $settings.screens} + {#each $settings.screens as s} + + + + {/each} + {/if} +
+ {#if $settings.actCurrencies && $settings.useNostr !== true} + +
{$_('section.settings.currencies')}
+ {$_('restartRequired')} + {#if $settings.availableCurrencies} + {#each $settings.availableCurrencies as c} + +
+ + +
+ + {/each} + {/if} +
{/if} -
- {/if} + + + + + + + + + + + + + + + + + + + {$_('time.minutes')} + + + + + + + + + {$_('time.minutes')} + + + + + + + + + {$_('time.seconds')} + + {$_('section.settings.shortAmountsWarning')} + + + + + + + + + {#if $settings.hasFrontlight && !$settings.flDisable} + + + + + + + + + + + + + {/if} + {#if !$settings.flDisable && $settings.hasLightLevel} + + + + + {$_('section.settings.luxLightToggleText')} + + + {/if} + + + + + + + + + + + {#if $settings.hasFrontlight} + + + + {/if} + {#if $settings.hasFrontlight && !$settings.flDisable} + + + + + + + + + + {/if} + + + + + + + + + + + + HTTPS + + + {$_('section.settings.mempoolInstanceHelpText')} + + + + + + + {#if $settings.nostrRelay} + + + + {$_('section.settings.useNostrTooltip')} + + + {/if} + {#if 'stagingSource' in $settings} + + + + {/if} + + + + + {#if $settings.bitaxeEnabled} + + + + + + + + + + {/if} + {#if 'nostrZapNotify' in $settings && $settings['nostrZapNotify']} + + + + checkValidNostrPubkey('nostrZapPubkey')} + invalid={!isValidHexPubKey($settings.nostrZapPubkey)} + bsSize={$uiSettings.inputSize} + required + minlength="64" + > + {#if !isValidHexPubKey($settings.nostrZapPubkey)} + {$_('section.settings.invalidNostrPubkey')} + {/if} + + + {/if} + {#if $settings.useNostr} + + + + checkValidNostrPubkey('nostrPubKey')} + invalid={!isValidHexPubKey($settings.nostrPubKey)} + bsSize={$uiSettings.inputSize} + > + {#if !isValidHexPubKey($settings.nostrPubKey)} + {$_('section.settings.invalidNostrPubkey')} + {/if} + + + {/if} + {#if 'nostrZapNotify' in $settings || $settings.useNostr} + + + + + + + + + + {/if} + + {#if 'bitaxeEnabled' in $settings} + + + + {/if} + {#if 'nostrZapNotify' in $settings} + + + + + + + {#if $settings.hasFrontlight && !$settings.flDisable} + + + + {/if} + {/if} + + + + + + + + + + {$_('time.minutes')} + + + {$_('section.settings.tzOffsetHelpText')} + + + {#if $settings.httpAuthEnabled} + + + + + + + + + + + + + + {$_('section.settings.httpAuthText')} + + + {/if} + + + + + + + + + + + {#each wifiTxPowerMap as [key, value]} + + {/each} + + {$_('section.settings.wifiTxPowerText')} + + + + + + + + {$_('time.seconds')} + + + + + + + + + + + + + + + + + diff --git a/src/routes/Status.svelte b/src/routes/Status.svelte index 7121106..812ee68 100644 --- a/src/routes/Status.svelte +++ b/src/routes/Status.svelte @@ -104,8 +104,8 @@ export let xxl = xl; - - + + {$_('section.status.title', { default: 'Status' })} @@ -136,7 +136,7 @@
{#if $settings.actCurrencies && $settings.ownDataSource} -
+
{#each $settings.actCurrencies as c}