Files
ODIAN_Launcher/src/components/ProgressBar.svelte
T
Kelorastus b7f3061be3 ODIAN Launcher: hub, installer, local stack and remembered sign-in (M2)
- Tauri 2 + Svelte 5 hub in ODIAN dark: patch notes and roadmap, install and
  update progress, local stack status, settings with DHP and MCP addresses.
- crates/odian-packs: Rust installer for pack format v1 (signed manifests,
  resumable verified downloads from a DHP or an ODIAN drive), byte-compatible
  with ODIAN_MCP_Server's Python odian_packs.
- Local stack on 127.0.0.1: Postgres -> Engine API -> tile server -> Odian.exe,
  one Job Object, clean shutdown; database snapshot restore on a fresh PC only.
- Keycloak sign-in through the DHP's MCP, remembered until Sign out with a
  launcher session that renews the Engine token silently.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 15:23:17 +02:00

81 lines
1.6 KiB
Svelte

<script lang="ts">
interface Props {
/** 0..1, or null for indeterminate. */
value: number | null;
label: string;
valueText?: string;
}
let { value, label, valueText }: Props = $props();
const percent = $derived(value === null ? null : Math.round(Math.min(1, Math.max(0, value)) * 1000) / 10);
</script>
<div
class="bar"
class:indeterminate={percent === null}
role="progressbar"
aria-label={label}
aria-valuemin={0}
aria-valuemax={100}
aria-valuenow={percent ?? undefined}
aria-valuetext={valueText}
>
{#if percent === null}
<span class="sweep"></span>
{:else}
<span class="fill" style:width="{percent}%"></span>
{/if}
</div>
<style>
.bar {
position: relative;
height: 4px;
overflow: hidden;
background: var(--line);
}
.fill {
position: absolute;
inset: 0 auto 0 0;
background: var(--accent);
box-shadow: 0 0 14px rgba(91, 140, 255, 0.6);
transition: width var(--dur) linear;
}
.fill::after {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 2px;
background: #d6e2ff;
}
.sweep {
position: absolute;
top: 0;
bottom: 0;
left: -35%;
width: 35%;
background: linear-gradient(90deg, transparent, var(--accent), transparent);
animation: sweep 1.8s var(--ease) infinite;
}
@keyframes sweep {
to {
left: 100%;
}
}
@media (prefers-reduced-motion: reduce) {
.sweep {
left: 0;
width: 100%;
opacity: 0.5;
background: repeating-linear-gradient(90deg, var(--accent) 0 10px, transparent 10px 18px);
}
}
</style>