fix(dub): preserve complete speech and reject silent partial output
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import i18next from 'i18next';
|
||||
import { cleanup, render, screen } from '@testing-library/react';
|
||||
import { afterEach, expect, it, vi } from 'vitest';
|
||||
import { publicFailureFromEvent } from '@/lib/api/failure';
|
||||
@@ -39,3 +40,21 @@ it('rejects a non-web documentation URL and uses the shared safe fallback', () =
|
||||
'https://github.com/debpalash/VoiceStudio/blob/main/docs/install/troubleshooting.md',
|
||||
);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['dub_speech_missing', 'dubIntegrity.missingSpeech'],
|
||||
['dub_timing_overflow', 'dubIntegrity.timingOverflow'],
|
||||
])('localizes %s while retaining diagnostics', (errorCode, key) => {
|
||||
const translate = vi.spyOn(i18next, 't').mockReturnValue('Localized recovery instructions');
|
||||
try {
|
||||
const failure = publicFailureFromEvent(
|
||||
{ error_code: errorCode, reason: 'Raw engine error', diagnostic: 'segment a' },
|
||||
'Fallback',
|
||||
);
|
||||
expect(failure.reason).toBe('Localized recovery instructions');
|
||||
expect(failure.diagnostic).toBe('segment a');
|
||||
expect(translate).toHaveBeenCalledWith(key);
|
||||
} finally {
|
||||
translate.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2578,5 +2578,9 @@
|
||||
"captured": "تم التقاط {{count}} من أسطر سجل المشكلات",
|
||||
"contextNotice": "يتلقى الوكيل المحدد هذا البلاغ والشاشة الحالية وسجلات التطبيق والخلفية الحديثة وتشخيصات النظام.",
|
||||
"complete": "مكتمل"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "الكلام مفقود أو غير قابل للقراءة. أعد توليد المقطع المتأثر قبل التصدير.",
|
||||
"timingOverflow": "يتجاوز الكلام الوقت المخصص له. اختصر الترجمة أو اختر التوقيت الصارم أو تمديد الفيديو."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,5 +2570,9 @@
|
||||
"captured": "{{count}} problematische Protokollzeilen erfasst",
|
||||
"contextNotice": "Der ausgewählte Agent erhält diesen Bericht, die aktuelle Ansicht, aktuelle App- und Backend-Protokolle sowie Systemdiagnosen.",
|
||||
"complete": "Abgeschlossen"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "Sprache fehlt oder ist nicht lesbar. Erzeuge das betroffene Segment vor dem Export erneut.",
|
||||
"timingOverflow": "Die Sprache überschreitet ihr Zeitfenster. Kürze die Übersetzung oder wähle ein festes Zeitfenster oder die Videostreckung."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,5 +2570,9 @@
|
||||
"captured": "Captured {{count}} problem log lines",
|
||||
"contextNotice": "The selected agent receives this report, the current screen, recent app and backend logs, and system diagnostics.",
|
||||
"complete": "Complete"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "Speech is missing or unreadable. Regenerate the affected segment before exporting.",
|
||||
"timingOverflow": "Speech exceeds its time slot. Shorten the translation or choose Strict Slot or Stretch Video."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2572,5 +2572,9 @@
|
||||
"captured": "Se capturaron {{count}} líneas de registro con problemas",
|
||||
"contextNotice": "El agente seleccionado recibe este informe, la pantalla actual, los registros recientes de la aplicación y del backend, y los diagnósticos del sistema.",
|
||||
"complete": "Completado"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "Falta audio de voz o no se puede leer. Regenera el segmento afectado antes de exportar.",
|
||||
"timingOverflow": "La voz supera su intervalo de tiempo. Acorta la traducción o elige un intervalo estricto o alargar el vídeo."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2572,5 +2572,9 @@
|
||||
"captured": "{{count}} lignes de journal problématiques capturées",
|
||||
"contextNotice": "L’agent sélectionné reçoit ce rapport, l’écran actuel, les journaux récents de l’application et du backend, ainsi que les diagnostics système.",
|
||||
"complete": "Complet"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "La parole est absente ou illisible. Régénérez le segment concerné avant l’exportation.",
|
||||
"timingOverflow": "La parole dépasse son créneau. Raccourcissez la traduction ou choisissez un créneau strict ou l’étirement vidéo."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,5 +2570,9 @@
|
||||
"captured": "समस्या वाली {{count}} लॉग पंक्तियाँ कैप्चर की गईं",
|
||||
"contextNotice": "चुने गए एजेंट को यह रिपोर्ट, वर्तमान स्क्रीन, हाल के ऐप और बैकएंड लॉग तथा सिस्टम निदान मिलते हैं।",
|
||||
"complete": "पूरा"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "बोली गायब है या पढ़ी नहीं जा सकती। निर्यात से पहले प्रभावित खंड दोबारा बनाएँ।",
|
||||
"timingOverflow": "बोली अपने समय खंड से लंबी है। अनुवाद छोटा करें या सख्त समय खंड अथवा वीडियो खिंचाव चुनें।"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,5 +2570,9 @@
|
||||
"captured": "{{count}} baris log bermasalah ditangkap",
|
||||
"contextNotice": "Agen yang dipilih menerima laporan ini, layar saat ini, log aplikasi dan backend terbaru, serta diagnostik sistem.",
|
||||
"complete": "Selesai"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "Audio ucapan hilang atau tidak dapat dibaca. Buat ulang segmen terkait sebelum mengekspor.",
|
||||
"timingOverflow": "Ucapan melebihi jatah waktunya. Persingkat terjemahan atau pilih slot ketat atau rentangkan video."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2572,5 +2572,9 @@
|
||||
"captured": "Acquisite {{count}} righe di log problematiche",
|
||||
"contextNotice": "L’agente selezionato riceve questa segnalazione, la schermata corrente, i log recenti dell’app e del backend e la diagnostica di sistema.",
|
||||
"complete": "Completato"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "Il parlato manca o non è leggibile. Rigenera il segmento interessato prima di esportare.",
|
||||
"timingOverflow": "Il parlato supera il tempo disponibile. Accorcia la traduzione oppure scegli uno slot rigoroso o estendi il video."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,5 +2570,9 @@
|
||||
"captured": "問題のあるログを{{count}}行取得しました",
|
||||
"contextNotice": "選択したエージェントには、この報告、現在の画面、最近のアプリとバックエンドのログ、システム診断が渡されます。",
|
||||
"complete": "完了"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "音声がないか読み取れません。書き出す前に該当セグメントを再生成してください。",
|
||||
"timingOverflow": "音声が割り当て時間を超えています。翻訳を短くするか、厳密な時間枠または動画の引き伸ばしを選んでください。"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,5 +2570,9 @@
|
||||
"captured": "문제 로그 {{count}}줄을 수집했습니다",
|
||||
"contextNotice": "선택한 에이전트는 이 보고서, 현재 화면, 최근 앱 및 백엔드 로그와 시스템 진단 정보를 받습니다.",
|
||||
"complete": "완료"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "음성이 없거나 읽을 수 없습니다. 내보내기 전에 해당 구간을 다시 생성하세요.",
|
||||
"timingOverflow": "음성이 할당된 시간을 초과합니다. 번역을 줄이거나 엄격한 시간 구간 또는 비디오 늘이기를 선택하세요."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,5 +2570,9 @@
|
||||
"captured": "{{count}} problematische logregels vastgelegd",
|
||||
"contextNotice": "De geselecteerde agent ontvangt dit rapport, het huidige scherm, recente app- en backendlogboeken en systeemdiagnostiek.",
|
||||
"complete": "Voltooid"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "Spraak ontbreekt of is onleesbaar. Genereer het betreffende segment opnieuw voordat je exporteert.",
|
||||
"timingOverflow": "De spraak overschrijdt het tijdvak. Verkort de vertaling of kies een strikt tijdvak of het uitrekken van de video."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2574,5 +2574,9 @@
|
||||
"captured": "Przechwycono {{count}} problematycznych wierszy dziennika",
|
||||
"contextNotice": "Wybrany agent otrzyma to zgłoszenie, bieżący ekran, ostatnie dzienniki aplikacji i backendu oraz diagnostykę systemu.",
|
||||
"complete": "Zakończono"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "Brak mowy lub nie można jej odczytać. Przed eksportem wygeneruj ponownie dany segment.",
|
||||
"timingOverflow": "Mowa przekracza przydzielony czas. Skróć tłumaczenie albo wybierz ścisły przedział czasu lub wydłużenie filmu."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2572,5 +2572,9 @@
|
||||
"captured": "{{count}} linhas de log com problemas capturadas",
|
||||
"contextNotice": "O agente selecionado recebe este relatório, a tela atual, os logs recentes do aplicativo e do backend e os diagnósticos do sistema.",
|
||||
"complete": "Completo"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "A fala está ausente ou ilegível. Gere novamente o segmento afetado antes de exportar.",
|
||||
"timingOverflow": "A fala excede o intervalo de tempo. Encurte a tradução ou escolha um intervalo estrito ou estique o vídeo."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2574,5 +2574,9 @@
|
||||
"captured": "Собрано строк журнала с проблемами: {{count}}",
|
||||
"contextNotice": "Выбранный агент получит этот отчёт, текущий экран, последние журналы приложения и бэкенда, а также диагностику системы.",
|
||||
"complete": "Завершено"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "Речь отсутствует или не читается. Перед экспортом заново сгенерируйте этот сегмент.",
|
||||
"timingOverflow": "Речь выходит за отведённое время. Сократите перевод или выберите строгий интервал либо растяжение видео."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,5 +2570,9 @@
|
||||
"captured": "{{count}} problemrader i loggen samlades in",
|
||||
"contextNotice": "Den valda agenten får den här rapporten, den aktuella vyn, aktuella app- och backendloggar samt systemdiagnostik.",
|
||||
"complete": "Klart"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "Tal saknas eller kan inte läsas. Generera det berörda segmentet på nytt före export.",
|
||||
"timingOverflow": "Talet överskrider sin tidslucka. Korta översättningen eller välj strikt tidslucka eller sträck ut videon."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,5 +2570,9 @@
|
||||
"captured": "บันทึกบรรทัดปัญหาจากล็อกแล้ว {{count}} บรรทัด",
|
||||
"contextNotice": "เอเจนต์ที่เลือกจะได้รับรายงานนี้ หน้าจอปัจจุบัน บันทึกล่าสุดของแอปและแบ็กเอนด์ และข้อมูลวินิจฉัยระบบ",
|
||||
"complete": "เสร็จสิ้น"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "เสียงพูดหายไปหรืออ่านไม่ได้ สร้างช่วงที่มีปัญหาใหม่ก่อนส่งออก",
|
||||
"timingOverflow": "เสียงพูดยาวเกินช่วงเวลาที่กำหนด ย่อคำแปลหรือเลือกช่วงเวลาแบบเคร่งครัดหรือยืดวิดีโอ"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,5 +2570,9 @@
|
||||
"captured": "{{count}} sorunlu günlük satırı yakalandı",
|
||||
"contextNotice": "Seçilen aracı bu raporu, mevcut ekranı, son uygulama ve arka uç günlüklerini ve sistem tanılamasını alır.",
|
||||
"complete": "Tamamlandı"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "Konuşma eksik veya okunamıyor. Dışa aktarmadan önce ilgili bölümü yeniden oluşturun.",
|
||||
"timingOverflow": "Konuşma ayrılan süreyi aşıyor. Çeviriyi kısaltın veya kesin zaman aralığını ya da videoyu uzatmayı seçin."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2574,5 +2574,9 @@
|
||||
"captured": "Зібрано рядків журналу з проблемами: {{count}}",
|
||||
"contextNotice": "Вибраний агент отримає цей звіт, поточний екран, останні журнали застосунку й бекенду та діагностику системи.",
|
||||
"complete": "Завершено"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "Мовлення відсутнє або не читається. Перед експортом повторно згенеруйте цей сегмент.",
|
||||
"timingOverflow": "Мовлення перевищує відведений час. Скоротіть переклад або виберіть строгий інтервал чи розтягнення відео."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,5 +2570,9 @@
|
||||
"captured": "Đã thu thập {{count}} dòng nhật ký có vấn đề",
|
||||
"contextNotice": "Tác nhân đã chọn nhận báo cáo này, màn hình hiện tại, nhật ký ứng dụng và backend gần đây cùng thông tin chẩn đoán hệ thống.",
|
||||
"complete": "Hoàn thành"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "Lời nói bị thiếu hoặc không đọc được. Hãy tạo lại đoạn bị ảnh hưởng trước khi xuất.",
|
||||
"timingOverflow": "Lời nói vượt quá thời gian được phân bổ. Hãy rút ngắn bản dịch hoặc chọn khung thời gian nghiêm ngặt hay kéo dài video."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2574,5 +2574,9 @@
|
||||
"captured": "已捕获 {{count}} 行问题日志",
|
||||
"contextNotice": "所选代理将收到此报告、当前界面、最近的应用与后端日志以及系统诊断信息。",
|
||||
"complete": "已完成"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "语音缺失或无法读取。请在导出前重新生成受影响的片段。",
|
||||
"timingOverflow": "语音超出分配的时长。请缩短译文,或选择严格时间段或拉伸视频。"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,5 +2570,9 @@
|
||||
"captured": "已擷取 {{count}} 行問題日誌",
|
||||
"contextNotice": "所選代理將收到此報告、目前畫面、最近的應用程式與後端記錄以及系統診斷資訊。",
|
||||
"complete": "已完成"
|
||||
},
|
||||
"dubIntegrity": {
|
||||
"missingSpeech": "語音缺失或無法讀取。請在匯出前重新產生受影響的片段。",
|
||||
"timingOverflow": "語音超出分配的時長。請縮短譯文,或選擇嚴格時間區段或延展影片。"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import i18next from 'i18next';
|
||||
export interface PublicFailure {
|
||||
reason: string;
|
||||
errorClass?: string;
|
||||
@@ -16,6 +17,8 @@ export function publicFailureFromEvent(
|
||||
): PublicFailure {
|
||||
return {
|
||||
reason:
|
||||
(event.error_code === 'dub_speech_missing' ? i18next.t('dubIntegrity.missingSpeech') :
|
||||
event.error_code === 'dub_timing_overflow' ? i18next.t('dubIntegrity.timingOverflow') : undefined) ||
|
||||
text(event.reason) ||
|
||||
text(event.detail) ||
|
||||
text(event.error) ||
|
||||
|
||||
Reference in New Issue
Block a user