feat(tts): Phase 4 — Read Page Aloud with OS-native voices
Platform-dispatched TTS (spd-say + espeak-ng fallback on Linux, say on macOS, PowerShell System.Speech on Windows) with a shared SpeakerButton component. Tap to speak, tap again to stop; only one button speaks at a time so two surfaces don't talk over each other. Text always travels via argv (or a PowerShell here-string delivered through -EncodedCommand on Windows) so user content never enters a shell string. Mount points: DictationPage transcript footer, transcript viewer header, per-step in MicroSteps. Settings gains a "Read aloud" accordion with voice picker (lazy-loaded from the OS synth), rate slider 0.5-2.0x, and a British-English test utterance. Rust tests cover rate mapping, NaN handling, and Windows here-string terminator safety. No pause/resume, no SSML, no cloud voices — that stays out of scope per the Layer-1 roadmap.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
import { FEEDBACK_TIMEOUT_MS } from "$lib/utils/constants.js";
|
||||
import { Mic, Loader2, SquareCheck, AlertTriangle } from 'lucide-svelte';
|
||||
import EmptyState from '$lib/components/EmptyState.svelte';
|
||||
import SpeakerButton from '$lib/components/SpeakerButton.svelte';
|
||||
import { getPreferences } from '$lib/stores/preferences.svelte.js';
|
||||
import { bionicReading } from '$lib/actions/bionicReading.js';
|
||||
import { measurePreWrap } from '$lib/utils/textMeasure.js';
|
||||
@@ -1069,6 +1070,9 @@
|
||||
<span class="text-[11px] text-text-tertiary">
|
||||
{settings.formatMode} · {page.activeProfile === "None" ? "No profile" : page.activeProfile}
|
||||
</span>
|
||||
{#if transcript.trim()}
|
||||
<SpeakerButton text={transcript} label="Read transcript aloud" size={12} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
Reference in New Issue
Block a user