58 lines
1.2 KiB
Svelte
58 lines
1.2 KiB
Svelte
<script lang="ts">
|
|
import { onDestroy } from 'svelte';
|
|
import { i18n } from '$lib/i18n';
|
|
|
|
interface Props {
|
|
element: HTMLElement;
|
|
}
|
|
|
|
let { element }: Props = $props();
|
|
|
|
let cycling = $state(false);
|
|
let currentChannel: HTMLAudioElement | undefined;
|
|
async function cycleChannels() {
|
|
cycling = true;
|
|
const buttons = element.querySelectorAll('button');
|
|
buttons.forEach((button) => (button.disabled = true));
|
|
const channels = element.querySelectorAll('audio');
|
|
while (cycling) {
|
|
for (const channel of channels) {
|
|
currentChannel = channel;
|
|
await channel.play();
|
|
await new Promise((resolve) => {
|
|
channel.onended = resolve;
|
|
});
|
|
if (!cycling) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
buttons.forEach((button) => (button.disabled = false));
|
|
}
|
|
|
|
function onClick() {
|
|
cycling = !cycling;
|
|
if (cycling) {
|
|
cycleChannels();
|
|
} else {
|
|
if (currentChannel) {
|
|
currentChannel.pause();
|
|
currentChannel.currentTime = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
onDestroy(() => {
|
|
cycling = false;
|
|
currentChannel?.pause();
|
|
});
|
|
</script>
|
|
|
|
<button onclick={onClick}>
|
|
<i class="ti ti-refresh"></i>
|
|
{#if cycling}
|
|
{$i18n.t('Stop Cycling')}
|
|
{:else}
|
|
{$i18n.t('Cycle through')}
|
|
{/if}
|
|
</button>
|