Render live STT without finalize

This commit is contained in:
dsyoon
2026-01-28 23:04:40 +09:00
parent b4f26ddfb7
commit 17e61f4b18

View File

@@ -58,20 +58,7 @@ function App() {
return () => window.clearInterval(intervalId)
}, [isRecording])
const commitLiveIfAny = async () => {
const text = liveTextRef.current.trim()
if (!text) return
const ts = new Date().toISOString()
setTranscriptLines((prev) => {
const last = prev[prev.length - 1]
if (last && !last.isFinal) {
return [
...prev.slice(0, -1),
{ ...last, text, ts, isFinal: true },
]
}
return [...prev, { id: lineIdRef.current++, ts, text, isFinal: true }]
})
const persistFinal = async (ts: string, text: string) => {
if (!meetingIdRef.current) {
pendingUtterancesRef.current.push({ ts, text })
return
@@ -83,6 +70,29 @@ function App() {
}
}
const updateTranscript = (text: string, isFinal: boolean) => {
const trimmed = text.trim()
if (!trimmed) return
const ts = new Date().toISOString()
liveTextRef.current = isFinal ? '' : trimmed
setTranscriptLines((prev) => {
const last = prev[prev.length - 1]
if (last && !last.isFinal) {
return [
...prev.slice(0, -1),
{ ...last, text: trimmed, ts, isFinal },
]
}
if (last && last.isFinal && isFinal && last.text.trim() === trimmed) {
return prev
}
return [...prev, { id: lineIdRef.current++, ts, text: trimmed, isFinal }]
})
if (isFinal) {
void persistFinal(ts, trimmed)
}
}
const startRecognition = () => {
const SpeechRecognitionConstructor =
window.SpeechRecognition || window.webkitSpeechRecognition
@@ -100,34 +110,10 @@ function App() {
recognition.onresult = (event) => {
lastResultAtRef.current = Date.now()
let interim = ''
for (let i = event.resultIndex; i < event.results.length; i += 1) {
const result = event.results[i]
const text = result[0].transcript
if (result.isFinal) {
handleFinalTranscript(text)
} else {
interim += text
}
}
const interimText = interim.trim()
if (interimText) {
liveTextRef.current = interimText
setTranscriptLines((prev) => {
const last = prev[prev.length - 1]
if (last && !last.isFinal) {
return [...prev.slice(0, -1), { ...last, text: interimText }]
}
return [
...prev,
{
id: lineIdRef.current++,
ts: new Date().toISOString(),
text: interimText,
isFinal: false,
},
]
})
updateTranscript(text, result.isFinal)
}
}
@@ -161,41 +147,6 @@ function App() {
}
}
const handleFinalTranscript = async (text: string) => {
const trimmed = text.trim()
if (!trimmed) return
lastResultAtRef.current = Date.now()
const ts = new Date().toISOString()
liveTextRef.current = ''
let nextLines: { id: number; ts: string; text: string; isFinal: boolean }[] = []
setTranscriptLines((prev) => {
const last = prev[prev.length - 1]
if (last && !last.isFinal) {
nextLines = [
...prev.slice(0, -1),
{ ...last, text: trimmed, ts, isFinal: true },
]
return nextLines
}
nextLines = [
...prev,
{ id: lineIdRef.current++, ts, text: trimmed, isFinal: true },
]
return nextLines
})
if (!meetingIdRef.current) {
pendingUtterancesRef.current.push({ ts, text: trimmed })
return
}
try {
await saveUtterance(meetingIdRef.current, trimmed, ts)
} catch (err) {
setErrorMessage((err as Error).message)
}
}
const handleStart = async () => {
setErrorMessage(null)
lineIdRef.current = 1
@@ -225,7 +176,6 @@ function App() {
if (!meetingIdRef.current) return
setErrorMessage(null)
recognitionRef.current?.stop()
await commitLiveIfAny()
liveTextRef.current = ''
setIsRecording(false)
isRecordingRef.current = false