57 lines
1.8 KiB
Svelte
57 lines
1.8 KiB
Svelte
<script lang="ts">
|
|
import { onMount } from "svelte";
|
|
import { listen } from "@tauri-apps/api/event";
|
|
import { invoke } from "@tauri-apps/api/core";
|
|
import { loadConfig, config } from "../stores/config";
|
|
import type { TimerSnapshot } from "../stores/timer";
|
|
|
|
let breakTimeRemaining = $state(0);
|
|
let breakTotalDuration = $state(0);
|
|
|
|
const progress = $derived(breakTotalDuration > 0 ? breakTimeRemaining / breakTotalDuration : 0);
|
|
|
|
function formatTime(secs: number): string {
|
|
const m = Math.floor(secs / 60);
|
|
const s = secs % 60;
|
|
return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
|
|
}
|
|
|
|
onMount(async () => {
|
|
await loadConfig();
|
|
|
|
try {
|
|
const snap = await invoke<TimerSnapshot>("get_timer_state");
|
|
breakTimeRemaining = snap.breakTimeRemaining;
|
|
breakTotalDuration = snap.breakTotalDuration;
|
|
} catch {}
|
|
|
|
await listen<TimerSnapshot>("timer-tick", (event) => {
|
|
breakTimeRemaining = event.payload.breakTimeRemaining;
|
|
breakTotalDuration = event.payload.breakTotalDuration;
|
|
});
|
|
|
|
await listen("break-ended", () => {
|
|
// Window will be closed by backend
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<div
|
|
class="fixed inset-0 flex flex-col items-center justify-center"
|
|
style="background: rgba(0, 0, 0, {$config.backdrop_opacity});"
|
|
>
|
|
<p class="text-[16px] font-medium text-white mb-4">Break in progress</p>
|
|
|
|
<span class="text-[42px] font-semibold tabular-nums text-white leading-none mb-6">
|
|
{formatTime(breakTimeRemaining)}
|
|
</span>
|
|
|
|
<!-- Progress bar -->
|
|
<div class="w-48 h-[3px] rounded-full overflow-hidden" style="background: rgba(255,255,255,0.06);">
|
|
<div
|
|
class="h-full transition-[width] duration-1000 ease-linear"
|
|
style="width: {(1 - progress) * 100}%; background: {$config.break_color};"
|
|
></div>
|
|
</div>
|
|
</div>
|