"use client"; import { useEffect, useState } from "react"; import { IconVolume } from "@tabler/icons-react"; import { useTranslation } from "react-i18next"; import { Button } from "@kandev/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@kandev/ui/select"; import { Switch } from "@kandev/ui/switch"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@kandev/ui/tooltip"; import { getSoundPreferences, isSoundPresetId, playSoundPreset, setSoundPreferences, SOUND_PRESETS, type SoundPreferences, type SoundPresetId, } from "@/lib/notifications/sound"; import { useSettingsSaveContributor } from "./settings-save-provider"; import { SettingsGroup } from "./settings-group"; import { GENERAL_SETTINGS_TARGETS } from "@/lib/settings-discovery/catalog/preferences"; /** * Catalog keys for the preset names, keyed by the preset id — the id is the * persisted sentinel and must never be translated. Keys, not `t()` calls: a * module-scope `t` would freeze the names at the boot locale (docs/i18n.md). */ const SOUND_PRESET_LABEL_KEYS: Record = { plim: "settings:soundPresetPlim", chime: "settings:soundPresetChime", ding: "settings:soundPresetDing", pop: "settings:soundPresetPop", }; export function NotificationSoundSection({ onDirtyChange, }: { onDirtyChange?: (isDirty: boolean) => void; }) { const { t } = useTranslation(); const [saved, setSaved] = useState(getSoundPreferences); const [prefs, setPrefs] = useState(saved); const revision = JSON.stringify(prefs); const isDirty = revision !== JSON.stringify(saved); useEffect(() => onDirtyChange?.(isDirty), [isDirty, onDirtyChange]); useSettingsSaveContributor({ id: "general-notification-sound", revision, isDirty, save: () => { const submitted = prefs; setSoundPreferences(submitted); setSaved(submitted); }, discard: () => setPrefs(saved), }); return (
setPrefs({ ...prefs, enabled })} aria-label={t("settings:enableNotificationSound")} className="cursor-pointer" />
{prefs.enabled && (
{t("settings:previewSound")}
)}
); }