Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
if (!finalAudio) throw new Error('No audio to download');
const url = URL.createObjectURL(finalAudio);
try {
//todo only works on desktop, not mobile
const a = document.createElement('a');
a.href = url;
a.download = `${finalAudio.name}`;
Expand Down
53 changes: 39 additions & 14 deletions frontend/viewer/src/lib/components/field-editors/audio-input.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@
loader = defaultLoader,
audioId = $bindable(),
onchange = () => {},
readonly = false,
}: {
loader?: (audioId: string) => Promise<ReadableStream | undefined | typeof handled>,
loader?: (audioId: string) => Promise<{stream: ReadableStream, filename: string} | undefined | typeof handled>,
audioId: string | undefined,
onchange?: (audioId: string | undefined) => void;
readonly?: boolean;
} = $props();

const projectContext = useProjectContext();
Expand All @@ -87,23 +89,24 @@

return handled;
}
return await file.stream.stream();
return {stream: await file.stream.stream(), filename: file.fileName ?? ''};
}

async function load() {
if (!audio || loadedAudioId === audioId || !audioId) return !!audioId;
playerState = 'loading';
try {
const stream = await loader(audioId);
if (stream === handled) return false;
if (!stream) {
const result = await loader(audioId);
if (result === handled) return false;
if (!result) {
AppNotification.error(`Failed to load audio ${audioId}`);
return;
}
let blob = await new Response(stream).blob();
let blob = await new Response(result.stream).blob();
if (audio.src) URL.revokeObjectURL(audio.src);
loadedAudioId = undefined;
audio.src = URL.createObjectURL(blob);
filename = result.filename;
loadedAudioId = audioId;
return true;
} finally {
Expand Down Expand Up @@ -182,6 +185,7 @@


let loadedAudioId = $state<string>();
let filename = $state('');
let audio = $state<HTMLAudioElement>();
let audioRuned = $derived(audio ? new AudioRuned(audio) : null);
useEventListener(() => audio, 'ended', () => playerState = 'paused');
Expand Down Expand Up @@ -233,6 +237,16 @@
}
}

async function onSaveAs() {
if (!audio) return;
await load();
//todo sadly this only works on desktop, not mobile, but it's the same with save as with the audio editor.
const a = document.createElement('a');
a.href = audio.src;
a.download = filename;
a.click();
}

function onAudioError(event: Event) {
if (audioHasKnownFlacSeekError()) {
console.log('Ignoring known FLAC seek error. Will try to recover on next play.');
Expand All @@ -253,9 +267,15 @@
</script>
{#if supportsAudio}
{#if !audioId}
<Button variant="secondary" icon="i-mdi-microphone-plus" size="sm" iconProps={{class: 'size-5'}} onclick={onGetAudioClick}>
{$t`Add audio`}
</Button>
{#if !readonly}
<Button variant="secondary" icon="i-mdi-microphone-plus" size="sm" iconProps={{class: 'size-5'}} onclick={onGetAudioClick}>
{$t`Add audio`}
</Button>
{:else}
<div class="text-muted-foreground p-1">
{$t`No audio`}
</div>
{/if}
{:else if isNotFoundAudioId(audioId)}
<div class="text-muted-foreground p-1">
{$t`Audio file not included in Send & Receive`}
Expand Down Expand Up @@ -301,11 +321,16 @@
{/snippet}
</ResponsiveMenu.Trigger>
<ResponsiveMenu.Content>
<ResponsiveMenu.Item icon="i-mdi-microphone-plus" onSelect={onGetAudioClick}>
{$t`Replace audio`}
</ResponsiveMenu.Item>
<ResponsiveMenu.Item icon="i-mdi-delete" onSelect={onRemoveAudio}>
{$t`Remove audio`}
{#if !readonly}
<ResponsiveMenu.Item icon="i-mdi-microphone-plus" onSelect={onGetAudioClick}>
{$t`Replace audio`}
</ResponsiveMenu.Item>
<ResponsiveMenu.Item icon="i-mdi-delete" onSelect={onRemoveAudio}>
{$t`Remove audio`}
</ResponsiveMenu.Item>
{/if}
<ResponsiveMenu.Item icon="i-mdi-download" onSelect={onSaveAs}>
{$t`Save As`}
</ResponsiveMenu.Item>
</ResponsiveMenu.Content>
</ResponsiveMenu.Root>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@
autocapitalize="off"
onchange={() => onchange?.(ws.wsId, value[ws.wsId], value)} />
{:else}
<AudioInput bind:audioId={value[ws.wsId]} onchange={() => onchange?.(ws.wsId, value[ws.wsId], value)}/>
<AudioInput
bind:audioId={value[ws.wsId]} onchange={() => onchange?.(ws.wsId, value[ws.wsId], value)}
{readonly} />
{/if}
</div>
{/each}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@
aria-label={ws.abbreviation}
/>
{:else}
<AudioInput bind:audioId={() => getAudioId(value[ws.wsId]), audioId => setAudioId(audioId, ws.wsId)}/>
<AudioInput
bind:audioId={() => getAudioId(value[ws.wsId]), audioId => setAudioId(audioId, ws.wsId)}
{readonly} />
{/if}
</div>
{/each}
Expand Down
8 changes: 8 additions & 0 deletions frontend/viewer/src/locales/en.po
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,10 @@ msgstr "New Word"
msgid "No activity found"
msgstr "No activity found"

#: src/lib/components/field-editors/audio-input.svelte
msgid "No audio"
msgstr "No audio"

#: src/lib/history/HistoryView.svelte
msgid "No change name"
msgstr "No change name"
Expand Down Expand Up @@ -811,6 +815,10 @@ msgstr "Reopen"
msgid "Replace audio"
msgstr "Replace audio"

#: src/lib/components/field-editors/audio-input.svelte
msgid "Save As"
msgstr "Save As"

#: src/lib/components/audio/AudioDialog.svelte
msgid "Save audio"
msgstr "Save audio"
Expand Down
8 changes: 8 additions & 0 deletions frontend/viewer/src/locales/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,10 @@ msgstr "Nueva palabra"
msgid "No activity found"
msgstr "No se ha encontrado actividad"

#: src/lib/components/field-editors/audio-input.svelte
msgid "No audio"
msgstr ""

#: src/lib/history/HistoryView.svelte
msgid "No change name"
msgstr "Sin cambio de nombre"
Expand Down Expand Up @@ -816,6 +820,10 @@ msgstr "Vuelva a abrir"
msgid "Replace audio"
msgstr "Sustituir audio"

#: src/lib/components/field-editors/audio-input.svelte
msgid "Save As"
msgstr ""

#: src/lib/components/audio/AudioDialog.svelte
msgid "Save audio"
msgstr "Guardar audio"
Expand Down
8 changes: 8 additions & 0 deletions frontend/viewer/src/locales/fr.po
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,10 @@ msgstr "Nouveau mot"
msgid "No activity found"
msgstr "Aucune activité trouvée"

#: src/lib/components/field-editors/audio-input.svelte
msgid "No audio"
msgstr ""

#: src/lib/history/HistoryView.svelte
msgid "No change name"
msgstr "Pas de changement de nom"
Expand Down Expand Up @@ -816,6 +820,10 @@ msgstr "Réouverture"
msgid "Replace audio"
msgstr "Remplacer l'audio"

#: src/lib/components/field-editors/audio-input.svelte
msgid "Save As"
msgstr ""

#: src/lib/components/audio/AudioDialog.svelte
msgid "Save audio"
msgstr "Sauvegarder l'audio"
Expand Down
8 changes: 8 additions & 0 deletions frontend/viewer/src/locales/id.po
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,10 @@ msgstr "Kata Baru"
msgid "No activity found"
msgstr "Tidak ada aktivitas yang ditemukan"

#: src/lib/components/field-editors/audio-input.svelte
msgid "No audio"
msgstr ""

#: src/lib/history/HistoryView.svelte
msgid "No change name"
msgstr "Tidak ada perubahan nama"
Expand Down Expand Up @@ -816,6 +820,10 @@ msgstr "Buka kembali"
msgid "Replace audio"
msgstr "Mengganti audio"

#: src/lib/components/field-editors/audio-input.svelte
msgid "Save As"
msgstr ""

#: src/lib/components/audio/AudioDialog.svelte
msgid "Save audio"
msgstr "Menyimpan audio"
Expand Down
8 changes: 8 additions & 0 deletions frontend/viewer/src/locales/ko.po
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,10 @@ msgstr "새 단어"
msgid "No activity found"
msgstr "활동을 찾을 수 없습니다."

#: src/lib/components/field-editors/audio-input.svelte
msgid "No audio"
msgstr ""

#: src/lib/history/HistoryView.svelte
msgid "No change name"
msgstr "이름 변경 안 함"
Expand Down Expand Up @@ -816,6 +820,10 @@ msgstr "다시 열기"
msgid "Replace audio"
msgstr "오디오 교체"

#: src/lib/components/field-editors/audio-input.svelte
msgid "Save As"
msgstr ""

#: src/lib/components/audio/AudioDialog.svelte
msgid "Save audio"
msgstr "오디오 저장"
Expand Down
Loading