feat: mcp and backfill fixes

This commit is contained in:
hh committed 2026-06-02 01:02:08 +02:00
1 parent c6984a7286
commit 17cd31c41e
20 files changed
+566 -37

No files matched your search

@@ -1,18 +1,51 @@
<script lang="ts">
import { requestTranscription } from "$lib/api/media";
import Icon from "$lib/components/ui/Icon.svelte";
import Spinner from "$lib/components/ui/Spinner.svelte";
import { formatDuration } from "$lib/format/duration";
import { claimPlayback, releasePlayback } from "$lib/media/playback";
import { computeWaveform, flatWaveform } from "$lib/media/waveform";
import { toasts } from "$lib/stores/toasts.svelte";
interface Props {
chatId: number;
messageId: number;
own: boolean;
transcript?: string | null;
url: string;
}
let { url, own, transcript = null }: Props = $props();
let { url, own, transcript = null, chatId, messageId }: Props = $props();
let fetched = $state<string | null>(null);
let pending = $state(false);
const text = $derived(fetched ?? transcript);
let showTranscript = $state(false);
async function onTranscribe() {
if (text) {
showTranscript = !showTranscript;
return;
}
if (pending) {
return;
}
pending = true;
try {
const result = await requestTranscription(chatId, messageId);
if (result) {
fetched = result;
showTranscript = true;
} else {
toasts.error("Не удалось расшифровать");
}
} catch {
toasts.error("Не удалось расшифровать");
} finally {
pending = false;
}
}
let element = $state<HTMLAudioElement>();
let peaks = $state<number[]>(flatWaveform());
let currentTime = $state(0);
@@ -68,7 +101,11 @@
type="button"
aria-label="Play voice"
>
<Icon name={paused ? "play" : "pause"} size="1.5rem" />
<Icon
name={paused ? "play" : "pause"}
size="1.5rem"
class={paused ? "nudge" : ""}
/>
</button>
<div class="body">
<!-- svelte-ignore a11y_no_static_element_interactions -->
@@ -83,17 +120,20 @@
</div>
<div class="time">{formatDuration(elapsed)}</div>
</div>
{#if transcript}
<button
class="transcribe"
class:active={showTranscript}
onclick={() => (showTranscript = !showTranscript)}
type="button"
aria-label="Show transcription"
>
<button
class="transcribe"
class:active={showTranscript && Boolean(text)}
disabled={pending}
onclick={onTranscribe}
type="button"
aria-label="Show transcription"
>
{#if pending}
<Spinner color={own ? "white" : "gray"} size="1rem" />
{:else}
<Icon name="transcribe" size="1.125rem" />
</button>
{/if}
{/if}
</button>
<!-- biome-ignore lint/a11y/useMediaCaption: archived voice note has no captions -->
<audio
bind:this={element}
@@ -106,8 +146,8 @@
src={url}
></audio>
</div>
{#if transcript && showTranscript}
<div class="transcript">{transcript}</div>
{#if text && showTranscript}
<div class="transcript">{text}</div>
{/if}
</div>
@@ -158,6 +198,10 @@
color: var(--toggle-fg);
background-color: var(--active);
}
&:disabled {
cursor: default;
}
}
.transcript {
@@ -187,6 +231,10 @@
color: var(--toggle-fg);
background-color: var(--active);
:global(.nudge) {
transform: translateX(0.0625rem);
}
}
.body {