Files
orca/src/shared/dictation-transcript.ts
Kelvin Amoaba 1bf2276bdd fix(dictation): match the pill's Chinese and Japanese phrases to the inserted text, and space Korean ones (#40455)
* fix(dictation): join Chinese and Japanese phrases without a space, and space Korean ones

The shared transcript fold joined every phrase with a space, so the pill and
phone replies showed Chinese and Japanese text with spaces the inserted text
doesn't have. It now joins with the same rule as insertion. That rule treated
Hangul like Chinese and Japanese, so Korean phrases were inserted with no space
between sentences; Korean spaces words, so Hangul now spaces like Latin text.

* fix(dictation): don't space after Chinese and Japanese full-width punctuation

* fix(dictation): join retried phrases with the same spacing rule

* fix(dictation): escape the spacing rule's non-ASCII marks for the orcad bundle

The shared fold now pulls the spacing rule into the orcad server bundle, which
must stay ASCII. A rich-draft test pinned Hangul joining without a space; it
now expects the Korean spacing.
2026-11-09 19:39:34 +00:00

46 lines
1.4 KiB
TypeScript

import { appendDictationText } from './dictation-transcript-spacing'
/** The text so far mid-dictation, for the desktop pill and phone replies: committed text never changes, tentative text may still be revised. */
export type DictationTranscriptSnapshot = {
/** Grows with every change, so a client keeps the newest snapshot when replies arrive out of order. */
revision: number
committed: string
tentative: string
/** committed and tentative together, for clients that predate the split. */
text: string
}
/** One dictation's speech events folded into the snapshot its chunk replies report. */
export class DictationTranscript {
private committed = ''
private tentative = ''
private revisionCount = 0
get revision(): number {
return this.revisionCount
}
accept(event: { type: string; text?: string }): void {
if (event.type === 'partial') {
this.tentative = event.text ?? ''
this.revisionCount += 1
} else if (event.type === 'final') {
const text = event.text?.trim()
if (text) {
this.committed = appendDictationText(this.committed, text)
this.tentative = ''
this.revisionCount += 1
}
}
}
snapshot(): DictationTranscriptSnapshot {
return {
revision: this.revisionCount,
committed: this.committed,
tentative: this.tentative,
text: appendDictationText(this.committed, this.tentative.trim())
}
}
}