An American voice reading "comum" from the one button nobody had told
Reported as "Portuguese docs still use English voices". Not the server: piper-pt is up, has its own model loaded, and synthesizes "Ao fim da tarde fomos ver o mar" into 63KB of RIFF when asked directly. The request never asked it. The word card's pronounce buttons called speak(word) with no locale, which falls back to detectLang — a test that can only tell Han characters from letters. "comum", "carro", "gaivotas" all read as English, so every read-aloud from a word card in a Portuguese document came out in the en_US voice, and Piper's Portuguese sat idle behind a route nothing pointed at. The card was the last surface still guessing. The selection bubble and the garden both pass a locale decided from the document's verdict; WordCard was never given the document, so it had nothing to pass. It takes one now. This is the same mistake the "also in her language" block three elements below it was built to avoid — its comment says so outright, that an English voice reading "comum" is the thing that block exists to prevent — arriving through the button directly above it. A rule held in one place and not the other. Verified by intercepting /api/tts: both paths now ask for pt-PT. Claude-Session: https://claude.ai/code/session_01GJHNvirh7Hzhc9RL3HAvz7
This commit is contained in:
@@ -1582,6 +1582,7 @@ export function EditorCore({
|
|||||||
saved={wordInfo.saved}
|
saved={wordInfo.saved}
|
||||||
onToggleSave={toggleSaveWord}
|
onToggleSave={toggleSaveWord}
|
||||||
pinyin={wordInfo.pinyin}
|
pinyin={wordInfo.pinyin}
|
||||||
|
lang={docLocale(wordInfo.word, docLang)}
|
||||||
style={{ top: wordInfo.top, left: wordInfo.left }}
|
style={{ top: wordInfo.top, left: wordInfo.left }}
|
||||||
onReplace={replaceWord}
|
onReplace={replaceWord}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -22,11 +22,31 @@ interface Props {
|
|||||||
// is spelled in letters, and the slashes would say something untrue about it
|
// is spelled in letters, and the slashes would say something untrue about it
|
||||||
// in the one place a learner is looking for the truth about pronunciation.
|
// in the one place a learner is looking for the truth about pronunciation.
|
||||||
pinyin?: string
|
pinyin?: string
|
||||||
|
// The locale to pronounce the headword in — the document's language, decided
|
||||||
|
// by the caller (see docLang in audio/speech.ts).
|
||||||
|
//
|
||||||
|
// It has to be passed rather than guessed. `speak` falls back to detecting the
|
||||||
|
// script, and that test can only tell Han characters from letters: it reads
|
||||||
|
// "comum" and "casa" as English, so every read-aloud in a Portuguese document
|
||||||
|
// came out in the English voice. That is the same mistake the "also in" block
|
||||||
|
// below was built to avoid, arriving through the one button nobody had told
|
||||||
|
// about the document.
|
||||||
|
lang?: string
|
||||||
style: React.CSSProperties
|
style: React.CSSProperties
|
||||||
onReplace: (synonym: string) => void
|
onReplace: (synonym: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function WordCard({ word, info, loading, saved, onToggleSave, pinyin, style, onReplace }: Props) {
|
export function WordCard({
|
||||||
|
word,
|
||||||
|
info,
|
||||||
|
loading,
|
||||||
|
saved,
|
||||||
|
onToggleSave,
|
||||||
|
pinyin,
|
||||||
|
lang,
|
||||||
|
style,
|
||||||
|
onReplace,
|
||||||
|
}: Props) {
|
||||||
const t = usePack()
|
const t = usePack()
|
||||||
const definitions = info?.definitions ?? []
|
const definitions = info?.definitions ?? []
|
||||||
const synonyms = info?.synonyms ?? []
|
const synonyms = info?.synonyms ?? []
|
||||||
@@ -90,7 +110,7 @@ export function WordCard({ word, info, loading, saved, onToggleSave, pinyin, sty
|
|||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => speak(word)}
|
onClick={() => speak(word, lang)}
|
||||||
aria-label={`Pronounce ${word}`}
|
aria-label={`Pronounce ${word}`}
|
||||||
title={t.editor.readAloud}
|
title={t.editor.readAloud}
|
||||||
className="flex h-7 w-7 items-center justify-center rounded-full text-sm"
|
className="flex h-7 w-7 items-center justify-center rounded-full text-sm"
|
||||||
@@ -104,7 +124,7 @@ export function WordCard({ word, info, loading, saved, onToggleSave, pinyin, sty
|
|||||||
slowing the tape, so it stays a voice rather than a groan. */}
|
slowing the tape, so it stays a voice rather than a groan. */}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => speak(word, undefined, true)}
|
onClick={() => speak(word, lang, true)}
|
||||||
aria-label={`Pronounce ${word} slowly`}
|
aria-label={`Pronounce ${word} slowly`}
|
||||||
title={t.editor.readSlowly}
|
title={t.editor.readSlowly}
|
||||||
className="flex h-7 w-7 items-center justify-center rounded-full text-sm"
|
className="flex h-7 w-7 items-center justify-center rounded-full text-sm"
|
||||||
|
|||||||
Reference in New Issue
Block a user