(feat): add preview button to the call settings page
Some checks failed
/ build-desktop (linux) (push) Failing after 6m25s
/ build-web (push) Successful in 7m29s
/ build-mobile (push) Successful in 19m23s
/ release (push) Has been skipped

This commit is contained in:
Alois 2026-07-30 23:57:24 +02:00
commit 5a26c2d401
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24

View file

@ -1,4 +1,5 @@
import {
Button,
Label,
Select,
SelectContent,
@ -7,8 +8,10 @@ import {
SelectValue,
} from "@methanium/ui";
import { settingsStorageDefaults } from "@tensamin/shared/settings";
import { playSound, stopSound } from "@tensamin/shared/sounds";
import { useStorage } from "@tensamin/storage/context";
import { useEffect, useState } from "react";
import { Play, Square } from "lucide-react";
import { useEffect, useRef, useState } from "react";
type CallJingle = (typeof settingsStorageDefaults)["settings.call_jingle"];
@ -19,21 +22,33 @@ const jingleLabels: Record<CallJingle, string> = {
export default function Page() {
const { load, save } = useStorage();
const preview = useRef<HTMLAudioElement>(null);
const [jingle, setJingle] = useState<CallJingle>(
settingsStorageDefaults["settings.call_jingle"],
);
const [isPreviewing, setIsPreviewing] = useState(false);
function stopPreview() {
stopSound(preview.current);
preview.current = null;
setIsPreviewing(false);
}
useEffect(() => {
void load("settings.call_jingle").then(setJingle);
}, [load]);
useEffect(() => () => stopSound(preview.current), []);
return (
<div className="flex max-w-md flex-col gap-2">
<Label htmlFor="call-jingle">Outgoing call jingle</Label>
<div className="flex gap-2">
<Select
value={jingle}
onValueChange={(value) => {
const nextJingle = value ?? "jingle_1";
stopPreview();
setJingle(nextJingle);
void save("settings.call_jingle", nextJingle);
}}
@ -46,6 +61,33 @@ export default function Page() {
<SelectItem value="jingle_2">Jingle 2</SelectItem>
</SelectContent>
</Select>
<Button
variant="outline"
aria-label={isPreviewing ? "Stop jingle preview" : "Preview jingle"}
title={isPreviewing ? "Stop preview" : "Preview jingle"}
onClick={() => {
if (isPreviewing) {
stopPreview();
return;
}
const audio = playSound(
jingle === "jingle_2" ? "call_jingle_2" : "call_jingle_1",
);
preview.current = audio;
setIsPreviewing(true);
audio.addEventListener(
"ended",
() => {
if (preview.current === audio) stopPreview();
},
{ once: true },
);
}}
>
{isPreviewing ? <Square /> : <Play />}
</Button>
</div>
</div>
);
}