feat: support swap auto detected language in translate page (#9072)

* feat(translate): 支持自动检测语言时交换语言并添加异常处理

* fix(i18n): 更新翻译错误信息并添加缺失的翻译项

* docs(translate): 添加与自动检测相关的交换条件检查注释

* fix(translate): 为翻译结果添加类型声明
This commit is contained in:
Phantom 2025-08-12 11:20:18 +08:00 committed by GitHub
parent 1e8143eb8c
commit 4fd00af273
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 39 additions and 5 deletions

View File

@ -3612,8 +3612,10 @@
}, },
"empty": "Translation content is empty", "empty": "Translation content is empty",
"error": { "error": {
"detected_unknown": "Unknown language cannot be exchanged",
"empty": "The translation result is empty content", "empty": "The translation result is empty content",
"failed": "Translation failed", "failed": "Translation failed",
"invalid_source": "Invalid source language",
"not_configured": "Translation model is not configured", "not_configured": "Translation model is not configured",
"not_supported": "Unsupported language {{language}}", "not_supported": "Unsupported language {{language}}",
"unknown": "An unknown error occurred during translation" "unknown": "An unknown error occurred during translation"

View File

@ -3612,8 +3612,10 @@
}, },
"empty": "翻訳内容が空です", "empty": "翻訳内容が空です",
"error": { "error": {
"detected_unknown": "未知の言語は交換できません",
"empty": "翻訳結果が空の内容です", "empty": "翻訳結果が空の内容です",
"failed": "翻訳に失敗しました", "failed": "翻訳に失敗しました",
"invalid_source": "無効なソース言語",
"not_configured": "翻訳モデルが設定されていません", "not_configured": "翻訳モデルが設定されていません",
"not_supported": "サポートされていない言語 {{language}}", "not_supported": "サポートされていない言語 {{language}}",
"unknown": "翻訳中に不明なエラーが発生しました" "unknown": "翻訳中に不明なエラーが発生しました"

View File

@ -3612,8 +3612,10 @@
}, },
"empty": "Содержимое перевода пусто", "empty": "Содержимое перевода пусто",
"error": { "error": {
"detected_unknown": "Неизвестный язык не подлежит обмену",
"empty": "Результат перевода пуст", "empty": "Результат перевода пуст",
"failed": "Перевод не удалось", "failed": "Перевод не удалось",
"invalid_source": "Недопустимый исходный язык",
"not_configured": "Модель перевода не настроена", "not_configured": "Модель перевода не настроена",
"not_supported": "Язык не поддерживается {{language}}", "not_supported": "Язык не поддерживается {{language}}",
"unknown": "Во время перевода возникла неизвестная ошибка" "unknown": "Во время перевода возникла неизвестная ошибка"

View File

@ -3612,8 +3612,10 @@
}, },
"empty": "翻译内容为空", "empty": "翻译内容为空",
"error": { "error": {
"detected_unknown": "未知语言不可交换",
"empty": "翻译结果为空内容", "empty": "翻译结果为空内容",
"failed": "翻译失败", "failed": "翻译失败",
"invalid_source": "无效的源语言",
"not_configured": "翻译模型未配置", "not_configured": "翻译模型未配置",
"not_supported": "不支持的语言 {{language}}", "not_supported": "不支持的语言 {{language}}",
"unknown": "翻译过程中遇到未知错误" "unknown": "翻译过程中遇到未知错误"

View File

@ -3612,8 +3612,10 @@
}, },
"empty": "翻譯內容為空", "empty": "翻譯內容為空",
"error": { "error": {
"detected_unknown": "未知語言不可交換",
"empty": "翻译结果为空内容", "empty": "翻译结果为空内容",
"failed": "翻譯失敗", "failed": "翻譯失敗",
"invalid_source": "無效的源語言",
"not_configured": "翻譯模型未設定", "not_configured": "翻譯模型未設定",
"not_supported": "不支援的語言 {{language}}", "not_supported": "不支援的語言 {{language}}",
"unknown": "翻譯過程中遇到未知錯誤" "unknown": "翻譯過程中遇到未知錯誤"

View File

@ -3612,8 +3612,10 @@
}, },
"empty": "Το μεταφρασμένο κείμενο είναι κενό", "empty": "Το μεταφρασμένο κείμενο είναι κενό",
"error": { "error": {
"detected_unknown": "Άγνωστη γλώσσα μη ανταλλάξιμη",
"empty": "το αποτέλεσμα της μετάφρασης είναι κενό περιεχόμενο", "empty": "το αποτέλεσμα της μετάφρασης είναι κενό περιεχόμενο",
"failed": "Η μετάφραση απέτυχε", "failed": "Η μετάφραση απέτυχε",
"invalid_source": "Ακύρωση γλώσσας πηγής",
"not_configured": "Το μοντέλο μετάφρασης δεν είναι ρυθμισμένο", "not_configured": "Το μοντέλο μετάφρασης δεν είναι ρυθμισμένο",
"not_supported": "Μη υποστηριζόμενη γλώσσα {{language}}", "not_supported": "Μη υποστηριζόμενη γλώσσα {{language}}",
"unknown": "κατά τη μετάφραση παρουσιάστηκε άγνωστο σφάλμα" "unknown": "κατά τη μετάφραση παρουσιάστηκε άγνωστο σφάλμα"

View File

@ -3612,8 +3612,10 @@
}, },
"empty": "El contenido de traducción está vacío", "empty": "El contenido de traducción está vacío",
"error": { "error": {
"detected_unknown": "Idioma desconocido no intercambiable",
"empty": "El resultado de la traducción está vacío", "empty": "El resultado de la traducción está vacío",
"failed": "Fallo en la traducción", "failed": "Fallo en la traducción",
"invalid_source": "Invalid source language",
"not_configured": "El modelo de traducción no está configurado", "not_configured": "El modelo de traducción no está configurado",
"not_supported": "Idioma no compatible {{language}}", "not_supported": "Idioma no compatible {{language}}",
"unknown": "Se produjo un error desconocido durante la traducción" "unknown": "Se produjo un error desconocido durante la traducción"

View File

@ -3612,8 +3612,10 @@
}, },
"empty": "Le contenu à traduire est vide", "empty": "Le contenu à traduire est vide",
"error": { "error": {
"detected_unknown": "Langue inconnue non échangeable",
"empty": "Le résultat de la traduction est un contenu vide", "empty": "Le résultat de la traduction est un contenu vide",
"failed": "échec de la traduction", "failed": "échec de la traduction",
"invalid_source": "Langue source invalide",
"not_configured": "le modèle de traduction n'est pas configuré", "not_configured": "le modèle de traduction n'est pas configuré",
"not_supported": "Langue non prise en charge {{language}}", "not_supported": "Langue non prise en charge {{language}}",
"unknown": "Une erreur inconnue s'est produite lors de la traduction" "unknown": "Une erreur inconnue s'est produite lors de la traduction"

View File

@ -3612,8 +3612,10 @@
}, },
"empty": "O conteúdo de tradução está vazio", "empty": "O conteúdo de tradução está vazio",
"error": { "error": {
"detected_unknown": "Idioma desconhecido não pode ser trocado",
"empty": "Resultado da tradução está vazio", "empty": "Resultado da tradução está vazio",
"failed": "Tradução falhou", "failed": "Tradução falhou",
"invalid_source": "Idioma de origem inválido",
"not_configured": "Modelo de tradução não configurado", "not_configured": "Modelo de tradução não configurado",
"not_supported": "Idioma não suportado {{language}}", "not_supported": "Idioma não suportado {{language}}",
"unknown": "Ocorreu um erro desconhecido durante a tradução" "unknown": "Ocorreu um erro desconhecido durante a tradução"

View File

@ -116,7 +116,7 @@ const TranslatePage: FC = () => {
setTranslating(true) setTranslating(true)
let translated let translated: string
try { try {
translated = await translateText(text, actualTargetLanguage, throttle(setTranslatedContent, 100)) translated = await translateText(text, actualTargetLanguage, throttle(setTranslatedContent, 100))
} catch (e) { } catch (e) {
@ -224,17 +224,33 @@ const TranslatePage: FC = () => {
} }
// 控制语言切换按钮 // 控制语言切换按钮
const couldExchange = useMemo(() => sourceLanguage !== 'auto' && !isBidirectional, [isBidirectional, sourceLanguage]) /** 与自动检测相关的交换条件检查 */
const couldExchangeAuto = useMemo(
() =>
(sourceLanguage === 'auto' && detectedLanguage && detectedLanguage.langCode !== UNKNOWN.langCode) ||
sourceLanguage !== 'auto',
[detectedLanguage, sourceLanguage]
)
const couldExchange = useMemo(() => couldExchangeAuto && !isBidirectional, [couldExchangeAuto, isBidirectional])
const handleExchange = useCallback(() => { const handleExchange = useCallback(() => {
if (sourceLanguage === 'auto') { if (sourceLanguage === 'auto' && !couldExchangeAuto) {
return
}
const source = sourceLanguage === 'auto' ? detectedLanguage : sourceLanguage
if (!source) {
window.message.error(t('translate.error.invalid_source'))
return
}
if (source.langCode === UNKNOWN.langCode) {
window.message.error(t('translate.error.detected_unknown'))
return return
} }
const source = sourceLanguage
const target = targetLanguage const target = targetLanguage
setSourceLanguage(target) setSourceLanguage(target)
setTargetLanguage(source) setTargetLanguage(source)
}, [sourceLanguage, targetLanguage]) }, [couldExchangeAuto, detectedLanguage, sourceLanguage, t, targetLanguage])
useEffect(() => { useEffect(() => {
isEmpty(text) && setTranslatedContent('') isEmpty(text) && setTranslatedContent('')