🎨 format
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { isFullscreen, toggleFullscreen } from '$lib/stores';
|
||||
import { MdiFullscreenExit, MdiFullscreen } from '../icons';
|
||||
import { isFullscreen, toggleFullscreen } from '$lib/stores'
|
||||
import { MdiFullscreenExit, MdiFullscreen } from '../icons'
|
||||
|
||||
const SvelteComponent = $derived($isFullscreen ? MdiFullscreenExit : MdiFullscreen);
|
||||
const SvelteComponent = $derived($isFullscreen ? MdiFullscreenExit : MdiFullscreen)
|
||||
</script>
|
||||
|
||||
<button onclick={toggleFullscreen}>
|
||||
<SvelteComponent class="h-7 w-7" />
|
||||
</button>
|
||||
</button>
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
<script lang="ts">
|
||||
import { WiFi, WiFi0, WiFi1, WiFi2, WifiOff } from "../icons";
|
||||
import { WiFi, WiFi0, WiFi1, WiFi2, WifiOff } from '../icons'
|
||||
|
||||
interface Props {
|
||||
showDBm?: boolean;
|
||||
rssi?: number;
|
||||
}
|
||||
interface Props {
|
||||
showDBm?: boolean
|
||||
rssi?: number
|
||||
}
|
||||
|
||||
let { showDBm = false, rssi = 0 }: Props = $props();
|
||||
let { showDBm = false, rssi = 0 }: Props = $props()
|
||||
|
||||
const getWiFiIcon = () => {
|
||||
if (rssi === 0) return WifiOff;
|
||||
if (rssi >= -55) return WiFi;
|
||||
if (rssi >= -75) return WiFi2;
|
||||
if (rssi >= -85) return WiFi1;
|
||||
return WiFi0;
|
||||
};
|
||||
const getWiFiIcon = () => {
|
||||
if (rssi === 0) return WifiOff
|
||||
if (rssi >= -55) return WiFi
|
||||
if (rssi >= -75) return WiFi2
|
||||
if (rssi >= -85) return WiFi1
|
||||
return WiFi0
|
||||
}
|
||||
|
||||
const SvelteComponent = $derived(getWiFiIcon());
|
||||
const SvelteComponent = $derived(getWiFiIcon())
|
||||
</script>
|
||||
|
||||
<div class="indicator">
|
||||
<div class="tooltip tooltip-left" data-tip={rssi + " dBm"}>
|
||||
{#if showDBm}
|
||||
<span class="indicator-item indicator-start badge badge-accent badge-outline badge-xs">
|
||||
{rssi} dBm
|
||||
</span>
|
||||
{/if}
|
||||
<div class="h-7 w-7">
|
||||
<SvelteComponent class="absolute inset-0 h-full w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tooltip tooltip-left" data-tip={rssi + ' dBm'}>
|
||||
{#if showDBm}
|
||||
<span class="indicator-item indicator-start badge badge-accent badge-outline badge-xs">
|
||||
{rssi} dBm
|
||||
</span>
|
||||
{/if}
|
||||
<div class="h-7 w-7">
|
||||
<SvelteComponent class="absolute inset-0 h-full w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { useFeatureFlags } from '$lib/stores';
|
||||
import { modals } from 'svelte-modals';
|
||||
import ConfirmDialog from '$lib/components/ConfirmDialog.svelte';
|
||||
import { api } from '$lib/api';
|
||||
import { Cancel, Power } from '../icons';
|
||||
import { useFeatureFlags } from '$lib/stores'
|
||||
import { modals } from 'svelte-modals'
|
||||
import ConfirmDialog from '$lib/components/ConfirmDialog.svelte'
|
||||
import { api } from '$lib/api'
|
||||
import { Cancel, Power } from '../icons'
|
||||
|
||||
const features = useFeatureFlags();
|
||||
const features = useFeatureFlags()
|
||||
|
||||
const postSleep = async () => await api.post('/api/system/sleep');
|
||||
const postSleep = async () => await api.post('/api/system/sleep')
|
||||
|
||||
const confirmSleep = () => {
|
||||
modals.open(ConfirmDialog, {
|
||||
@@ -18,11 +18,11 @@
|
||||
confirm: { label: 'Switch Off', icon: Power }
|
||||
},
|
||||
onConfirm: () => {
|
||||
modals.close();
|
||||
postSleep();
|
||||
modals.close()
|
||||
postSleep()
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if $features.sleep}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { mode, modes } from "$lib/stores";
|
||||
import { mode, modes } from '$lib/stores'
|
||||
|
||||
const deactivate = async () => {
|
||||
mode.set(modes.indexOf('deactivated'));
|
||||
};
|
||||
mode.set(modes.indexOf('deactivated'))
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<button onclick={deactivate} class="bg-error text-white btn rounded-none">STOP</button>
|
||||
<button onclick={deactivate} class="bg-error text-white btn rounded-none">STOP</button>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { MdiWeatherSunny, MdiMoonAndStars } from "../icons";
|
||||
import { MdiWeatherSunny, MdiMoonAndStars } from '../icons'
|
||||
</script>
|
||||
|
||||
<label class="swap swap-rotate">
|
||||
<input type="checkbox" value="light" class="theme-controller" />
|
||||
<MdiWeatherSunny class="swap-off h-7 w-7" />
|
||||
<MdiMoonAndStars class="swap-on h-7 w-7" />
|
||||
</label>
|
||||
</label>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<script lang="ts">
|
||||
import {Hamburger} from '../icons'
|
||||
import { Hamburger } from '../icons'
|
||||
</script>
|
||||
|
||||
<div class="topbar absolute left-0 top-0 w-full z-20 flex justify-between bg-zinc-800">
|
||||
<div class="flex gap-2 p-2">
|
||||
<div class="flex gap-2 p-2">
|
||||
<a href="/">
|
||||
<Hamburger class="h-8 w-8"/>
|
||||
<Hamburger class="h-8 w-8" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.topbar {
|
||||
height: 50px;
|
||||
}
|
||||
.topbar {
|
||||
height: 50px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,109 +1,111 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/state'
|
||||
import { modals } from 'svelte-modals'
|
||||
import { notifications } from '$lib/components/toasts/notifications'
|
||||
import ConfirmDialog from '$lib/components/ConfirmDialog.svelte'
|
||||
import GithubUpdateDialog from '$lib/components/GithubUpdateDialog.svelte'
|
||||
import { compareVersions } from 'compare-versions'
|
||||
import { onMount } from 'svelte'
|
||||
import { api } from '$lib/api'
|
||||
import type { GithubRelease } from '$lib/types/models'
|
||||
import { useFeatureFlags } from '$lib/stores/featureFlags'
|
||||
import { Cancel, CloudDown, Firmware } from '../icons'
|
||||
import { page } from '$app/state'
|
||||
import { modals } from 'svelte-modals'
|
||||
import { notifications } from '$lib/components/toasts/notifications'
|
||||
import ConfirmDialog from '$lib/components/ConfirmDialog.svelte'
|
||||
import GithubUpdateDialog from '$lib/components/GithubUpdateDialog.svelte'
|
||||
import { compareVersions } from 'compare-versions'
|
||||
import { onMount } from 'svelte'
|
||||
import { api } from '$lib/api'
|
||||
import type { GithubRelease } from '$lib/types/models'
|
||||
import { useFeatureFlags } from '$lib/stores/featureFlags'
|
||||
import { Cancel, CloudDown, Firmware } from '../icons'
|
||||
|
||||
const features = useFeatureFlags()
|
||||
const features = useFeatureFlags()
|
||||
|
||||
interface Props {
|
||||
update?: boolean
|
||||
}
|
||||
|
||||
let { update = $bindable(false) }: Props = $props()
|
||||
|
||||
let firmwareVersion: string = $state('')
|
||||
let firmwareDownloadLink: string = $state('')
|
||||
|
||||
async function getGithubAPI() {
|
||||
const headers = {
|
||||
accept: 'application/vnd.github+json',
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
}
|
||||
const result = await api.get<GithubRelease>(
|
||||
`https://api.github.com/repos/${page.data.github}/releases/latest`,
|
||||
{ headers }
|
||||
)
|
||||
if (result.inner.message === '404' || result.inner.message == 'Not Found') {
|
||||
console.warn('Error: Could not find releases in the repository')
|
||||
return
|
||||
}
|
||||
if (result.isErr()) {
|
||||
console.error('Error:', result.inner)
|
||||
return
|
||||
interface Props {
|
||||
update?: boolean
|
||||
}
|
||||
|
||||
const results = result.inner
|
||||
update = false
|
||||
firmwareVersion = ''
|
||||
let { update = $bindable(false) }: Props = $props()
|
||||
|
||||
if (compareVersions(results.tag_name, $features.firmware_version as string) === 1) {
|
||||
// iterate over assets and find the correct one
|
||||
for (let i = 0; i < results.assets.length; i++) {
|
||||
// check if the asset is of type *.bin
|
||||
if (
|
||||
results.assets[i].name.includes('.bin') &&
|
||||
results.assets[i].name.includes($features.firmware_built_target as string)
|
||||
) {
|
||||
update = true
|
||||
firmwareVersion = results.tag_name
|
||||
firmwareDownloadLink = results.assets[i].browser_download_url
|
||||
notifications.info('Firmware update available.', 5000)
|
||||
let firmwareVersion: string = $state('')
|
||||
let firmwareDownloadLink: string = $state('')
|
||||
|
||||
async function getGithubAPI() {
|
||||
const headers = {
|
||||
accept: 'application/vnd.github+json',
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
}
|
||||
const result = await api.get<GithubRelease>(
|
||||
`https://api.github.com/repos/${page.data.github}/releases/latest`,
|
||||
{ headers }
|
||||
)
|
||||
if (result.inner.message === '404' || result.inner.message == 'Not Found') {
|
||||
console.warn('Error: Could not find releases in the repository')
|
||||
return
|
||||
}
|
||||
if (result.isErr()) {
|
||||
console.error('Error:', result.inner)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function postGithubDownload(url: string) {
|
||||
const result = await api.post('/api/downloadUpdate', { download_url: url })
|
||||
if (result.isErr()) {
|
||||
console.error('Error:', result.inner)
|
||||
return
|
||||
}
|
||||
}
|
||||
const results = result.inner
|
||||
update = false
|
||||
firmwareVersion = ''
|
||||
|
||||
onMount(async () => {
|
||||
if ($features.download_firmware) {
|
||||
await getGithubAPI()
|
||||
setInterval(async () => await getGithubAPI(), 60 * 60 * 1000) // once per hour
|
||||
if (compareVersions(results.tag_name, $features.firmware_version as string) === 1) {
|
||||
// iterate over assets and find the correct one
|
||||
for (let i = 0; i < results.assets.length; i++) {
|
||||
// check if the asset is of type *.bin
|
||||
if (
|
||||
results.assets[i].name.includes('.bin') &&
|
||||
results.assets[i].name.includes($features.firmware_built_target as string)
|
||||
) {
|
||||
update = true
|
||||
firmwareVersion = results.tag_name
|
||||
firmwareDownloadLink = results.assets[i].browser_download_url
|
||||
notifications.info('Firmware update available.', 5000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function confirmGithubUpdate(url: string) {
|
||||
modals.open(ConfirmDialog, {
|
||||
title: 'Confirm flashing new firmware to the device',
|
||||
message: 'Are you sure you want to overwrite the existing firmware with a new one?',
|
||||
labels: {
|
||||
cancel: { label: 'Abort', icon: Cancel },
|
||||
confirm: { label: 'Update', icon: CloudDown }
|
||||
},
|
||||
onConfirm: () => {
|
||||
postGithubDownload(url)
|
||||
modals.open(GithubUpdateDialog, {
|
||||
onConfirm: () => modals.closeAll()
|
||||
})
|
||||
}
|
||||
async function postGithubDownload(url: string) {
|
||||
const result = await api.post('/api/downloadUpdate', { download_url: url })
|
||||
if (result.isErr()) {
|
||||
console.error('Error:', result.inner)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
if ($features.download_firmware) {
|
||||
await getGithubAPI()
|
||||
setInterval(async () => await getGithubAPI(), 60 * 60 * 1000) // once per hour
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function confirmGithubUpdate(url: string) {
|
||||
modals.open(ConfirmDialog, {
|
||||
title: 'Confirm flashing new firmware to the device',
|
||||
message: 'Are you sure you want to overwrite the existing firmware with a new one?',
|
||||
labels: {
|
||||
cancel: { label: 'Abort', icon: Cancel },
|
||||
confirm: { label: 'Update', icon: CloudDown }
|
||||
},
|
||||
onConfirm: () => {
|
||||
postGithubDownload(url)
|
||||
modals.open(GithubUpdateDialog, {
|
||||
onConfirm: () => modals.closeAll()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if update}
|
||||
<div class="indicator flex-none">
|
||||
<button
|
||||
class="btn btn-square btn-ghost h-9 w-9"
|
||||
onclick={() => confirmGithubUpdate(firmwareDownloadLink)}>
|
||||
<span
|
||||
class="indicator-item indicator-top indicator-center badge badge-info badge-xs top-2 scale-75 lg:top-1">
|
||||
{firmwareVersion}
|
||||
</span>
|
||||
<Firmware class="h-7 w-7" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="indicator flex-none">
|
||||
<button
|
||||
class="btn btn-square btn-ghost h-9 w-9"
|
||||
onclick={() => confirmGithubUpdate(firmwareDownloadLink)}
|
||||
>
|
||||
<span
|
||||
class="indicator-item indicator-top indicator-center badge badge-info badge-xs top-2 scale-75 lg:top-1"
|
||||
>
|
||||
{firmwareVersion}
|
||||
</span>
|
||||
<Firmware class="h-7 w-7" />
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { selectedView, views } from "$lib/stores/application";
|
||||
import Selector from "../widget/Selector.svelte";
|
||||
import { selectedView, views } from '$lib/stores/application'
|
||||
import Selector from '../widget/Selector.svelte'
|
||||
</script>
|
||||
|
||||
<Selector bind:selectedOption={$selectedView} options={$views.map((v) => v.name)} />
|
||||
<Selector bind:selectedOption={$selectedView} options={$views.map(v => v.name)} />
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/state'
|
||||
import { telemetry } from '$lib/stores/telemetry'
|
||||
import { page } from '$app/state'
|
||||
import { telemetry } from '$lib/stores/telemetry'
|
||||
|
||||
import RssiIndicator from '$lib/components/statusbar/RSSIIndicator.svelte'
|
||||
import UpdateIndicator from '$lib/components/statusbar/UpdateIndicator.svelte'
|
||||
import SleepButton from './SleepButton.svelte'
|
||||
import ThemeButton from './ThemeButton.svelte'
|
||||
import FullscreenButton from './FullscreenButton.svelte'
|
||||
import StopButton from './StopButton.svelte'
|
||||
import ViewSelector from './ViewSelector.svelte'
|
||||
import { Hamburger } from '../icons'
|
||||
import RssiIndicator from '$lib/components/statusbar/RSSIIndicator.svelte'
|
||||
import UpdateIndicator from '$lib/components/statusbar/UpdateIndicator.svelte'
|
||||
import SleepButton from './SleepButton.svelte'
|
||||
import ThemeButton from './ThemeButton.svelte'
|
||||
import FullscreenButton from './FullscreenButton.svelte'
|
||||
import StopButton from './StopButton.svelte'
|
||||
import ViewSelector from './ViewSelector.svelte'
|
||||
import { Hamburger } from '../icons'
|
||||
</script>
|
||||
|
||||
<div class="navbar bg-base-300 sticky top-0 z-10 h-12 min-h-fit drop-shadow-lg lg:h-16 gap-2 pr-0">
|
||||
<div class="flex flex-1 gap-2">
|
||||
<label for="main-menu" class="btn btn-ghost btn-circle btn-sm drawer-button">
|
||||
<Hamburger class="h-6 w-auto" />
|
||||
</label>
|
||||
{#if page.data.title === 'Controller'}
|
||||
<ViewSelector />
|
||||
{:else}
|
||||
<h1 class="px-2 text-xl font-bold lg:text-2xl">{page.data.title}</h1>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex flex-1 gap-2">
|
||||
<label for="main-menu" class="btn btn-ghost btn-circle btn-sm drawer-button">
|
||||
<Hamburger class="h-6 w-auto" />
|
||||
</label>
|
||||
{#if page.data.title === 'Controller'}
|
||||
<ViewSelector />
|
||||
{:else}
|
||||
<h1 class="px-2 text-xl font-bold lg:text-2xl">{page.data.title}</h1>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<UpdateIndicator />
|
||||
<UpdateIndicator />
|
||||
|
||||
<FullscreenButton />
|
||||
<FullscreenButton />
|
||||
|
||||
<ThemeButton />
|
||||
<ThemeButton />
|
||||
|
||||
<RssiIndicator rssi={$telemetry.rssi.rssi} />
|
||||
<RssiIndicator rssi={$telemetry.rssi.rssi} />
|
||||
|
||||
<SleepButton />
|
||||
<SleepButton />
|
||||
|
||||
<StopButton />
|
||||
<StopButton />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user