70 lines
1.7 KiB
Svelte
70 lines
1.7 KiB
Svelte
<script lang="ts">
|
|
import { onDestroy, onMount } from 'svelte';
|
|
import { buzzerState } from '../stores';
|
|
import { Button } from 'flowbite-svelte';
|
|
|
|
let timerStartedAt: bigint | undefined;
|
|
let timerStoppedAt: bigint | undefined;
|
|
|
|
let currentTimerValue: bigint | undefined;
|
|
|
|
let timerInterval: number | undefined;
|
|
|
|
onMount(() => {
|
|
timerInterval = setInterval(() => {
|
|
if (timerStartedAt) {
|
|
let now = BigInt(Math.floor(performance.now()));
|
|
const timerValue = (timerStoppedAt ?? now) - timerStartedAt;
|
|
currentTimerValue =
|
|
timerStoppedAt === undefined ? timerValue - (timerValue % 100n) : timerValue;
|
|
}
|
|
}, 100);
|
|
});
|
|
|
|
onDestroy(() => {
|
|
clearInterval(timerInterval);
|
|
});
|
|
|
|
const getTimerColor = (timerStartedAt?: bigint, timerStoppedAt?: bigint) => {
|
|
if (timerStartedAt === undefined) {
|
|
return 'white';
|
|
} else if (timerStartedAt !== undefined && timerStoppedAt === undefined) {
|
|
return 'red';
|
|
} else if (timerStartedAt !== undefined && timerStoppedAt !== undefined) {
|
|
return 'green';
|
|
} else {
|
|
return 'white';
|
|
}
|
|
};
|
|
|
|
$: {
|
|
if (!timerStartedAt || !$buzzerState.lastTriggerTime) {
|
|
break $;
|
|
}
|
|
|
|
if ($buzzerState.lastTriggerTime > timerStartedAt) {
|
|
timerStoppedAt = $buzzerState.lastTriggerTime;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div class="flex flex-col items-center gap-3">
|
|
<div class="w-full flex flex-row flex-wrap gap-3 justify-center">
|
|
<div class="flex flex-grow flex-col items-center">
|
|
<span
|
|
class="text-9xl font-bold"
|
|
style="color: {getTimerColor(timerStartedAt, timerStoppedAt)};"
|
|
>
|
|
{(Number(currentTimerValue ?? 0) / 1000).toFixed(3)}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<Button
|
|
on:click={() => {
|
|
timerStartedAt = BigInt(Math.floor(performance.now()));
|
|
timerStoppedAt = undefined;
|
|
}}>Start!</Button
|
|
>
|