diff --git a/agents/expo/quickstart/example/package.json b/agents/expo/quickstart/example/package.json index 51c62f25..c0d512a9 100644 --- a/agents/expo/quickstart/example/package.json +++ b/agents/expo/quickstart/example/package.json @@ -32,5 +32,13 @@ "@types/react": "latest", "babel-plugin-module-resolver": "latest", "typescript": "latest" + }, + "overrides": { + "livekit-client": "2.16.1" + }, + "pnpm": { + "overrides": { + "livekit-client": "2.16.1" + } } } diff --git a/speech-to-text/nextjs/realtime/example/app/page.tsx b/speech-to-text/nextjs/realtime/example/app/page.tsx index 992acccb..794e2ad7 100644 --- a/speech-to-text/nextjs/realtime/example/app/page.tsx +++ b/speech-to-text/nextjs/realtime/example/app/page.tsx @@ -1,9 +1,29 @@ "use client"; -import { useState, useCallback, useEffect } from "react"; -import { useScribe, CommitStrategy } from "@elevenlabs/react"; +import { useCallback, useEffect, useState } from "react"; +import { CommitStrategy, useScribe } from "@elevenlabs/react"; import { LiveWaveform } from "@/components/ui/live-waveform"; +function statusLabel( + status: string, + isConnecting: boolean, + isActive: boolean +): string { + if (isConnecting) { + return "Connecting"; + } + if (status === "transcribing") { + return "Transcribing"; + } + if (isActive) { + return "Connected"; + } + if (status === "error") { + return "Error"; + } + return "Disconnected"; +} + export default function Home() { const [error, setError] = useState(null); const [partialTranscript, setPartialTranscript] = useState(""); @@ -35,7 +55,6 @@ export default function Home() { } }, [scribe.status]); - // Check both connected and transcribing states to properly show active status const isActive = scribe.status === "connected" || scribe.status === "transcribing"; const isConnecting = scribe.status === "connecting"; @@ -45,16 +64,18 @@ export default function Home() { setError(null); setPartialTranscript(""); - // Fetch a fresh single-use token from our API const response = await fetch("/api/scribe-token"); - if (!response.ok) { - throw new Error("Failed to get transcription token"); + const data = (await response.json().catch(() => ({}))) as { + token?: string; + error?: string; + }; + + if (!response.ok || !data.token) { + throw new Error(data.error || "Failed to get transcription token"); } - const { token } = await response.json(); - // Connect with microphone access await scribe.connect({ - token, + token: data.token, microphone: { echoCancellation: true, noiseSuppression: true, @@ -64,7 +85,9 @@ export default function Home() { } catch (err) { console.error("Failed to start transcription:", err); setError( - "Failed to start transcription. Please check your permissions and try again." + err instanceof Error + ? err.message + : "Failed to start transcription. Please check your permissions and try again." ); } }, [scribe]); @@ -78,14 +101,10 @@ export default function Home() { if (isActive) { handleStop(); } else { - handleStart(); + void handleStart(); } }; - const handleClearHistory = () => { - setCommittedHistory([]); - }; - return (
@@ -98,105 +117,61 @@ export default function Home() {

-
- {/* Controls */} -
-
- - {committedHistory.length > 0 && ( - - )} -
-
- {isActive ? ( - - - {scribe.status === "transcribing" - ? "Transcribing" - : "Connected"} - - ) : ( - Disconnected - )} -
+
+
+ + + {statusLabel(scribe.status, isConnecting, isActive)} +
- {/* Error message */} - {error && ( -
+ {error ? ( +

{error} -

- )} +

+ ) : null} - {/* Live waveform */} -
- -
+ - {/* Partial transcript */} {(isActive || partialTranscript) && ( -
-

- Live Transcript -

-
-

- {partialTranscript || ( - Listening... - )} -

-
+
+

Live transcript

+

+ {partialTranscript || "Listening..."} +

)} - {/* Committed transcript history */} {committedHistory.length > 0 && ( -
-

- History -

-
+
+

History

+
{committedHistory.map((text, index) => ( -
+

{text} -

+

))}
)} - {/* Instructions when not started */} {!isActive && !isConnecting && committedHistory.length === 0 && ( -
- Click "Start" to begin transcribing audio from your microphone. -
+

+ Click Start to begin transcribing audio from your microphone. +

)}
diff --git a/speech-to-text/nextjs/realtime/review-screenshots/README.md b/speech-to-text/nextjs/realtime/review-screenshots/README.md new file mode 100644 index 00000000..70c022f4 --- /dev/null +++ b/speech-to-text/nextjs/realtime/review-screenshots/README.md @@ -0,0 +1,45 @@ +# STT realtime UI before vs after + +Rendered from `speech-to-text/nextjs/realtime` using the page markup on `main` (before) and this PR (after). History, error, and listening states use the same sample data. + +Review-only. Drop this folder before merge if you do not want screenshots in the repo. + +## Idle + +**Before** — status is right-aligned; hint is centered. + +![Before idle](stt_realtime_before_idle.png) + +**After** — status sits next to Start; hint is left-aligned and tighter. + +![After idle](stt_realtime_after_idle.png) + +## History + +**Before** — Clear History button, uppercase HISTORY label, each line in a bordered card. + +![Before history](stt_realtime_before_history.png) + +**After** — no Clear History; history is plain text. + +![After history](stt_realtime_after_history.png) + +## Error + +**Before** — generic permission message in a red box. + +![Before error](stt_realtime_before_error.png) + +**After** — status can read Error; API error text is shown inline. + +![After error](stt_realtime_after_error.png) + +## Listening + +**Before** — red Stop button, green status dot, boxed live transcript. + +![Before listening](stt_realtime_before_listening.png) + +**After** — same black button for Start/Stop; live transcript is italic, no box. + +![After listening](stt_realtime_after_listening.png) diff --git a/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_after_error.png b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_after_error.png new file mode 100644 index 00000000..0e3cb1f2 Binary files /dev/null and b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_after_error.png differ diff --git a/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_after_history.png b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_after_history.png new file mode 100644 index 00000000..b98f85af Binary files /dev/null and b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_after_history.png differ diff --git a/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_after_idle.png b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_after_idle.png new file mode 100644 index 00000000..9685646f Binary files /dev/null and b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_after_idle.png differ diff --git a/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_after_listening.png b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_after_listening.png new file mode 100644 index 00000000..6f40e907 Binary files /dev/null and b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_after_listening.png differ diff --git a/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_before_error.png b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_before_error.png new file mode 100644 index 00000000..0bfa850f Binary files /dev/null and b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_before_error.png differ diff --git a/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_before_history.png b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_before_history.png new file mode 100644 index 00000000..ea8489b0 Binary files /dev/null and b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_before_history.png differ diff --git a/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_before_idle.png b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_before_idle.png new file mode 100644 index 00000000..15e14e8c Binary files /dev/null and b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_before_idle.png differ diff --git a/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_before_listening.png b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_before_listening.png new file mode 100644 index 00000000..12ee961f Binary files /dev/null and b/speech-to-text/nextjs/realtime/review-screenshots/stt_realtime_before_listening.png differ