fix: add state to pause existing audio for demo menus, add support fo… (#10428)
This commit is contained in:
@@ -7,6 +7,26 @@ import { useSettings, monoFontFamily } from "@/context/settings"
|
|||||||
import { playSound, SOUND_OPTIONS } from "@/utils/sound"
|
import { playSound, SOUND_OPTIONS } from "@/utils/sound"
|
||||||
import { Link } from "./link"
|
import { Link } from "./link"
|
||||||
|
|
||||||
|
|
||||||
|
let demoSoundState = {
|
||||||
|
cleanup: undefined as (() => void) | undefined,
|
||||||
|
timeout: undefined as NodeJS.Timeout | undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
// To prevent audio from overlapping/playing very quickly when navigating the settings menus,
|
||||||
|
// delay the playback by 100ms during quick selection changes and pause existing sounds.
|
||||||
|
const playDemoSound = (src: string) => {
|
||||||
|
if (demoSoundState.cleanup) {
|
||||||
|
demoSoundState.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
clearTimeout(demoSoundState.timeout)
|
||||||
|
|
||||||
|
demoSoundState.timeout = setTimeout(() => {
|
||||||
|
demoSoundState.cleanup = playSound(src)
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
|
||||||
export const SettingsGeneral: Component = () => {
|
export const SettingsGeneral: Component = () => {
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const language = useLanguage()
|
const language = useLanguage()
|
||||||
@@ -211,12 +231,12 @@ export const SettingsGeneral: Component = () => {
|
|||||||
label={(o) => language.t(o.label)}
|
label={(o) => language.t(o.label)}
|
||||||
onHighlight={(option) => {
|
onHighlight={(option) => {
|
||||||
if (!option) return
|
if (!option) return
|
||||||
playSound(option.src)
|
playDemoSound(option.src)
|
||||||
}}
|
}}
|
||||||
onSelect={(option) => {
|
onSelect={(option) => {
|
||||||
if (!option) return
|
if (!option) return
|
||||||
settings.sounds.setAgent(option.id)
|
settings.sounds.setAgent(option.id)
|
||||||
playSound(option.src)
|
playDemoSound(option.src)
|
||||||
}}
|
}}
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
size="small"
|
size="small"
|
||||||
@@ -235,12 +255,12 @@ export const SettingsGeneral: Component = () => {
|
|||||||
label={(o) => language.t(o.label)}
|
label={(o) => language.t(o.label)}
|
||||||
onHighlight={(option) => {
|
onHighlight={(option) => {
|
||||||
if (!option) return
|
if (!option) return
|
||||||
playSound(option.src)
|
playDemoSound(option.src)
|
||||||
}}
|
}}
|
||||||
onSelect={(option) => {
|
onSelect={(option) => {
|
||||||
if (!option) return
|
if (!option) return
|
||||||
settings.sounds.setPermissions(option.id)
|
settings.sounds.setPermissions(option.id)
|
||||||
playSound(option.src)
|
playDemoSound(option.src)
|
||||||
}}
|
}}
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
size="small"
|
size="small"
|
||||||
@@ -259,12 +279,12 @@ export const SettingsGeneral: Component = () => {
|
|||||||
label={(o) => language.t(o.label)}
|
label={(o) => language.t(o.label)}
|
||||||
onHighlight={(option) => {
|
onHighlight={(option) => {
|
||||||
if (!option) return
|
if (!option) return
|
||||||
playSound(option.src)
|
playDemoSound(option.src)
|
||||||
}}
|
}}
|
||||||
onSelect={(option) => {
|
onSelect={(option) => {
|
||||||
if (!option) return
|
if (!option) return
|
||||||
settings.sounds.setErrors(option.id)
|
settings.sounds.setErrors(option.id)
|
||||||
playSound(option.src)
|
playDemoSound(option.src)
|
||||||
}}
|
}}
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
size="small"
|
size="small"
|
||||||
|
|||||||
@@ -106,5 +106,12 @@ export function soundSrc(id: string | undefined) {
|
|||||||
export function playSound(src: string | undefined) {
|
export function playSound(src: string | undefined) {
|
||||||
if (typeof Audio === "undefined") return
|
if (typeof Audio === "undefined") return
|
||||||
if (!src) return
|
if (!src) return
|
||||||
void new Audio(src).play().catch(() => undefined)
|
const audio = new Audio(src)
|
||||||
|
audio.play().catch(() => undefined)
|
||||||
|
|
||||||
|
// Return a cleanup function to pause the sound.
|
||||||
|
return () => {
|
||||||
|
audio.pause()
|
||||||
|
audio.currentTime = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ export function Select<T>(props: SelectProps<T> & Omit<ButtonProps, "children">)
|
|||||||
}}
|
}}
|
||||||
onPointerEnter={() => move(itemProps.item.rawValue)}
|
onPointerEnter={() => move(itemProps.item.rawValue)}
|
||||||
onPointerMove={() => move(itemProps.item.rawValue)}
|
onPointerMove={() => move(itemProps.item.rawValue)}
|
||||||
|
onFocus={() => move(itemProps.item.rawValue)}
|
||||||
>
|
>
|
||||||
<Kobalte.ItemLabel data-slot="select-select-item-label">
|
<Kobalte.ItemLabel data-slot="select-select-item-label">
|
||||||
{local.children
|
{local.children
|
||||||
|
|||||||
Reference in New Issue
Block a user