diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 601d02d9..284dfc4b 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -356,5 +356,6 @@ "Login Required": "يلزم الدخول", "Quota Exceeded": "تجاوز السعة", "{{percentage}}% of Daily Translation Characters Used.": "تم استخدام {{percentage}}% من أحرف الترجمة اليومية.", - "Translation Characters": "أحرف الترجمة" + "Translation Characters": "أحرف الترجمة", + "Daily translation quota reached. Select another translate service to proceed.": "تم الوصول إلى حصة الترجمة اليومية. اختر خدمة ترجمة أخرى للمتابعة." } diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index a1a6322e..98cb9b6e 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -348,5 +348,6 @@ "Login Required": "Anmeldung nötig", "Quota Exceeded": "Limit überschritten", "{{percentage}}% of Daily Translation Characters Used.": "{{percentage}}% der täglichen Übersetzungszeichen verwendet.", - "Translation Characters": "Übersetzungszeichen" + "Translation Characters": "Übersetzungszeichen", + "Daily translation quota reached. Select another translate service to proceed.": "Das tägliche Übersetzungslimit wurde erreicht. Wählen Sie einen anderen Übersetzungsdienst, um fortzufahren." } diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index b59f27ec..652c857e 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -348,5 +348,6 @@ "Login Required": "Απαιτείται σύνδεση", "Quota Exceeded": "Υπέρβαση ορίου", "{{percentage}}% of Daily Translation Characters Used.": "{{percentage}}% των ημερήσιων χαρακτήρων μετάφρασης χρησιμοποιήθηκαν.", - "Translation Characters": "Χαρακτήρες μετάφρασης" + "Translation Characters": "Χαρακτήρες μετάφρασης", + "Daily translation quota reached. Select another translate service to proceed.": "Έχετε φτάσει το ημερήσιο όριο χαρακτήρων μετάφρασης. Επιλέξτε άλλη υπηρεσία μετάφρασης για να συνεχίσετε." } diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index 7b2724c3..16695260 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -350,5 +350,6 @@ "Login Required": "Iniciar sesión", "Quota Exceeded": "Límite superado", "{{percentage}}% of Daily Translation Characters Used.": "{{percentage}}% de caracteres de traducción diarios utilizados.", - "Translation Characters": "Caracteres de traducción" + "Translation Characters": "Caracteres de traducción", + "Daily translation quota reached. Select another translate service to proceed.": "Cuota diaria de traducción alcanzada. Selecciona otro servicio de traducción para continuar." } diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index 49686bb3..c65eaf15 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -350,5 +350,6 @@ "Login Required": "Connexion requise", "Quota Exceeded": "Quota dépassé", "{{percentage}}% of Daily Translation Characters Used.": "{{percentage}}% des caractères de traduction quotidiens utilisés.", - "Translation Characters": "Caractères de traduction" + "Translation Characters": "Caractères de traduction", + "Daily translation quota reached. Select another translate service to proceed.": "Quota de traduction quotidien atteint. Sélectionnez un autre service de traduction pour continuer." } diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index 1c5e09a9..eb19ecc7 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -348,5 +348,6 @@ "Login Required": "लॉगिन ज़रूरी", "Quota Exceeded": "सीमा पार", "{{percentage}}% of Daily Translation Characters Used.": "{{percentage}}% दैनिक अनुवाद वर्णों का उपयोग किया गया है।", - "Translation Characters": "अनुवाद वर्ण" + "Translation Characters": "अनुवाद वर्ण", + "Daily translation quota reached. Select another translate service to proceed.": "दैनिक अनुवाद कोटा पूरा हो गया है। आगे बढ़ने के लिए कोई अन्य अनुवाद सेवा चुनें।" } diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index b05eb7b9..a9c8a841 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -346,5 +346,6 @@ "Login Required": "Perlu masuk", "Quota Exceeded": "Kuota terlampaui", "{{percentage}}% of Daily Translation Characters Used.": "{{percentage}}% dari Karakter Terjemahan Harian Digunakan.", - "Translation Characters": "Karakter Terjemahan" + "Translation Characters": "Karakter Terjemahan", + "Daily translation quota reached. Select another translate service to proceed.": "Kuota terjemahan harian tercapai. Pilih layanan terjemahan lain untuk melanjutkan." } diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index d3b7669e..5a4cce11 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -350,5 +350,6 @@ "Login Required": "Accesso richiesto", "Quota Exceeded": "Limite superato", "{{percentage}}% of Daily Translation Characters Used.": "{{percentage}}% dei caratteri di traduzione giornalieri utilizzati.", - "Translation Characters": "Caratteri di traduzione" + "Translation Characters": "Caratteri di traduzione", + "Daily translation quota reached. Select another translate service to proceed.": "Quota di traduzione giornaliera raggiunta. Seleziona un altro servizio di traduzione per procedere." } diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index c8757573..d871122d 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -346,5 +346,6 @@ "Login Required": "ログイン必須", "Quota Exceeded": "上限超過", "{{percentage}}% of Daily Translation Characters Used.": "日次翻訳文字数の使用量は{{percentage}}%です。", - "Translation Characters": "翻訳文字数" + "Translation Characters": "翻訳文字数", + "Daily translation quota reached. Select another translate service to proceed.": "日次翻訳クォータに達しました。続行するには別の翻訳サービスを選択してください。" } diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index 0ab2a538..ec0c8daa 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -346,5 +346,6 @@ "Login Required": "로그인 필요", "Quota Exceeded": "한도 초과", "{{percentage}}% of Daily Translation Characters Used.": "일일 번역 문자 사용량 {{percentage}}%.", - "Translation Characters": "번역 문자" + "Translation Characters": "번역 문자", + "Daily translation quota reached. Select another translate service to proceed.": "일일 번역 할당량에 도달했습니다. 계속 진행하려면 다른 번역 서비스를 선택하세요." } diff --git a/apps/readest-app/public/locales/nl/translation.json b/apps/readest-app/public/locales/nl/translation.json index d02c5c3e..4489fe62 100644 --- a/apps/readest-app/public/locales/nl/translation.json +++ b/apps/readest-app/public/locales/nl/translation.json @@ -348,5 +348,6 @@ "Login Required": "Inloggen vereist", "Quota Exceeded": "Limiet overschreden", "{{percentage}}% of Daily Translation Characters Used.": "{{percentage}}% van de dagelijkse vertaaltekens gebruikt.", - "Translation Characters": "Vertaaltekens" + "Translation Characters": "Vertaaltekens", + "Daily translation quota reached. Select another translate service to proceed.": "Dagelijkse vertaalquotum bereikt. Selecteer een andere vertaalservice om door te gaan." } diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index 054d0c17..d5eecfa1 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -352,5 +352,6 @@ "Login Required": "Wymagane logowanie", "Quota Exceeded": "Limit przekroczony", "{{percentage}}% of Daily Translation Characters Used.": "{{percentage}}% użytych znaków tłumaczenia dziennego.", - "Translation Characters": "Znaki tłumaczenia" + "Translation Characters": "Znaki tłumaczenia", + "Daily translation quota reached. Select another translate service to proceed.": "Przekroczono dzienny limit znaków tłumaczenia. Wybierz inną usługę tłumaczenia, aby kontynuować." } diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index bf117711..588c5e8b 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -350,5 +350,6 @@ "Login Required": "Login necessário", "Quota Exceeded": "Limite excedido", "{{percentage}}% of Daily Translation Characters Used.": "{{percentage}}% dos caracteres de tradução diários usados.", - "Translation Characters": "Caracteres de Tradução" + "Translation Characters": "Caracteres de Tradução", + "Daily translation quota reached. Select another translate service to proceed.": "Quota diária de tradução atingida. Selecione outro serviço de tradução para continuar." } diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index 82c2cb95..c1b05d3c 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -352,5 +352,6 @@ "Login Required": "Требуется вход", "Quota Exceeded": "Лимит превышен", "{{percentage}}% of Daily Translation Characters Used.": "Использовано {{percentage}}% от суточного лимита символов перевода.", - "Translation Characters": "Символы перевода" + "Translation Characters": "Символы перевода", + "Daily translation quota reached. Select another translate service to proceed.": "Достигнут суточный лимит символов перевода. Выберите другой сервис перевода для продолжения." } diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index a53adf12..155deb65 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -348,5 +348,6 @@ "Login Required": "Giriş gerekli", "Quota Exceeded": "Kota aşıldı", "{{percentage}}% of Daily Translation Characters Used.": "Çeviri için günlük karakterlerin %{{percentage}}'si kullanıldı.", - "Translation Characters": "Çeviri Karakterleri" + "Translation Characters": "Çeviri Karakterleri", + "Daily translation quota reached. Select another translate service to proceed.": "Günlük çeviri kotası aşıldı. Devam etmek için başka bir çeviri hizmeti seçin." } diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index 769d3cff..35fb5405 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -352,5 +352,6 @@ "Login Required": "Потрібен вхід", "Quota Exceeded": "Перевищено ліміт", "{{percentage}}% of Daily Translation Characters Used.": "Використано {{percentage}}% символів перекладу за день.", - "Translation Characters": "Символи перекладу" + "Translation Characters": "Символи перекладу", + "Daily translation quota reached. Select another translate service to proceed.": "Досягнуто добового ліміту перекладу. Виберіть іншу службу перекладу для продовження." } diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index ff6719bf..80d683b2 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -346,5 +346,6 @@ "Login Required": "Cần đăng nhập", "Quota Exceeded": "Vượt hạn mức", "{{percentage}}% of Daily Translation Characters Used.": "{{percentage}}% số ký tự dịch hàng ngày đã sử dụng.", - "Translation Characters": "Những ký tự dịch" + "Translation Characters": "Những ký tự dịch", + "Daily translation quota reached. Select another translate service to proceed.": "Đã đạt hạn mức dịch hàng ngày. Chọn dịch vụ dịch khác để tiếp tục." } diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index 6d79bfc1..d4619c45 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -346,5 +346,6 @@ "Login Required": "需登录", "Quota Exceeded": "额度不足", "{{percentage}}% of Daily Translation Characters Used.": "已使用 {{percentage}}% 的每日翻译字符数", - "Translation Characters": "翻译字数" + "Translation Characters": "翻译字数", + "Daily translation quota reached. Select another translate service to proceed.": "已达到每日翻译配额,请选择其他翻译服务继续。" } diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index cb4e9e4a..4ba27fe6 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -346,5 +346,6 @@ "Login Required": "需登入", "Quota Exceeded": "額度不足", "{{percentage}}% of Daily Translation Characters Used.": "已使用 {{percentage}}% 的每日翻譯字數", - "Translation Characters": "翻譯字數" + "Translation Characters": "翻譯字數", + "Daily translation quota reached. Select another translate service to proceed.": "已達到每日翻譯字數限制,請選擇其他翻譯服務繼續。" } diff --git a/apps/readest-app/src/hooks/useTranslator.ts b/apps/readest-app/src/hooks/useTranslator.ts index 9ee49538..01163935 100644 --- a/apps/readest-app/src/hooks/useTranslator.ts +++ b/apps/readest-app/src/hooks/useTranslator.ts @@ -1,7 +1,9 @@ import { useState, useCallback, useEffect } from 'react'; import { useAuth } from '@/context/AuthContext'; -import { getTranslator, getTranslators, TranslatorName } from '@/services/translators'; +import { ErrorCodes, getTranslator, getTranslators, TranslatorName } from '@/services/translators'; import { getFromCache, storeInCache, polish, UseTranslatorOptions } from '@/services/translators'; +import { eventDispatcher } from '@/utils/event'; +import { useTranslation } from './useTranslation'; export function useTranslator({ provider = 'deepl', @@ -9,6 +11,7 @@ export function useTranslator({ targetLang = 'EN', enablePolishing = true, }: UseTranslatorOptions = {}) { + const _ = useTranslation(); const { token } = useAuth(); const [loading, setLoading] = useState(false); const [selectedProvider, setSelectedProvider] = useState(provider); @@ -132,7 +135,15 @@ export function useTranslator({ setLoading(false); return enablePolishing ? polish(results, targetLanguage) : results; } catch (err) { - console.error('Translation error:', err); + if (err instanceof Error && err.message.includes(ErrorCodes.DAILY_QUOTA_EXCEEDED)) { + eventDispatcher.dispatch('toast', { + message: _( + 'Daily translation quota reached. Select another translate service to proceed.', + ), + type: 'error', + }); + setSelectedProvider('azure'); + } setLoading(false); throw err instanceof Error ? err : new Error(String(err)); } diff --git a/apps/readest-app/src/services/translators/providers/deepl.ts b/apps/readest-app/src/services/translators/providers/deepl.ts index ae7b9a71..f1891f3a 100644 --- a/apps/readest-app/src/services/translators/providers/deepl.ts +++ b/apps/readest-app/src/services/translators/providers/deepl.ts @@ -48,6 +48,12 @@ export const deeplProvider: TranslationProvider = { const response = await fetch(DEEPL_API_ENDPOINT, { method: 'POST', headers, body }); if (!response.ok) { + const data = await response.json(); + if (data && data.error && data.error === ErrorCodes.DAILY_QUOTA_EXCEEDED) { + saveDailyUsage(quota); + deeplProvider.quotaExceeded = true; + throw new Error(ErrorCodes.DAILY_QUOTA_EXCEEDED); + } throw new Error(`Translation failed with status ${response.status}`); } @@ -68,10 +74,6 @@ export const deeplProvider: TranslationProvider = { return translation?.text || line; }); } catch (error) { - if (error instanceof Error && error.message.includes(ErrorCodes.DAILY_QUOTA_EXCEEDED)) { - saveDailyUsage(quota); - deeplProvider.quotaExceeded = true; - } throw error; } }, diff --git a/apps/readest-app/src/services/translators/providers/index.ts b/apps/readest-app/src/services/translators/providers/index.ts index e7eb1b43..8aa96413 100644 --- a/apps/readest-app/src/services/translators/providers/index.ts +++ b/apps/readest-app/src/services/translators/providers/index.ts @@ -12,7 +12,7 @@ function createTranslator( `Translator name "${name}" does not match implementation name "${implementation.name}"`, ); } - return { ...implementation, name }; + return implementation as TranslationProvider & { name: T }; } const deeplTranslator = createTranslator('deepl', deeplProvider);