From d202d7a61e4d7457a978dce5052f87e8bd0a48d1 Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Wed, 17 Jun 2026 02:02:11 +0800 Subject: [PATCH] feat(library): add Clear Pending action to transfer queue (#4617) * feat(library): add Clear Pending action to transfer queue Adds a "Clear Pending" button to the transfer queue panel that removes only pending (including retry-pending) transfers, leaving in-progress, completed, failed, and cancelled items intact. Wired through the store, manager (with queue persistence), and useTransferQueue hook. Co-Authored-By: Claude Opus 4.8 (1M context) * i18n: translate Clear Pending and reading-statistics strings across locales Adds translations for "Clear Pending" (transfer queue) and the two reading-statistics sync-category strings ("Reading statistics" and its description) across all 33 locales. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Opus 4.8 (1M context) --- .../public/locales/ar/translation.json | 1 + .../public/locales/bn/translation.json | 1 + .../public/locales/bo/translation.json | 1 + .../public/locales/de/translation.json | 1 + .../public/locales/el/translation.json | 1 + .../public/locales/es/translation.json | 1 + .../public/locales/fa/translation.json | 1 + .../public/locales/fr/translation.json | 1 + .../public/locales/he/translation.json | 1 + .../public/locales/hi/translation.json | 1 + .../public/locales/hu/translation.json | 1 + .../public/locales/id/translation.json | 1 + .../public/locales/it/translation.json | 1 + .../public/locales/ja/translation.json | 1 + .../public/locales/ko/translation.json | 1 + .../public/locales/ms/translation.json | 1 + .../public/locales/nl/translation.json | 1 + .../public/locales/pl/translation.json | 1 + .../public/locales/pt-BR/translation.json | 1 + .../public/locales/pt/translation.json | 1 + .../public/locales/ro/translation.json | 1 + .../public/locales/ru/translation.json | 1 + .../public/locales/si/translation.json | 1 + .../public/locales/sl/translation.json | 1 + .../public/locales/sv/translation.json | 1 + .../public/locales/ta/translation.json | 1 + .../public/locales/th/translation.json | 1 + .../public/locales/tr/translation.json | 1 + .../public/locales/uk/translation.json | 1 + .../public/locales/uz/translation.json | 1 + .../public/locales/vi/translation.json | 1 + .../public/locales/zh-CN/translation.json | 1 + .../public/locales/zh-TW/translation.json | 1 + .../services/transfer-manager.test.ts | 30 ++++++++++++++++ .../__tests__/store/transfer-store.test.ts | 34 +++++++++++++++++++ .../library/components/TransferQueuePanel.tsx | 7 ++++ .../readest-app/src/hooks/useTransferQueue.ts | 5 +++ .../src/services/transferManager.ts | 5 +++ apps/readest-app/src/store/transferStore.ts | 13 +++++++ 39 files changed, 127 insertions(+) diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 1a3b61ac..61921fb3 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -1886,6 +1886,7 @@ "Privacy": "الخصوصية", "No downloadable format available": "لا يتوفر تنسيق قابل للتنزيل", "Content is neither valid XML nor JSON": "المحتوى ليس بصيغة XML ولا JSON صالحة", + "Clear Pending": "مسح قيد الانتظار", "Reading statistics": "إحصائيات القراءة", "Reading time and pages read, synced across your devices and KOReader.": "وقت القراءة والصفحات المقروءة، تتم مزامنتها عبر أجهزتك و KOReader.", "Auto Sync": "مزامنة تلقائية" diff --git a/apps/readest-app/public/locales/bn/translation.json b/apps/readest-app/public/locales/bn/translation.json index 7f4be805..89e85565 100644 --- a/apps/readest-app/public/locales/bn/translation.json +++ b/apps/readest-app/public/locales/bn/translation.json @@ -1754,6 +1754,7 @@ "Privacy": "গোপনীয়তা", "No downloadable format available": "ডাউনলোডযোগ্য কোনো ফরম্যাট নেই", "Content is neither valid XML nor JSON": "বিষয়বস্তু বৈধ XML বা JSON কোনোটিই নয়", + "Clear Pending": "অপেক্ষমাণ মুছুন", "Reading statistics": "পড়ার পরিসংখ্যান", "Reading time and pages read, synced across your devices and KOReader.": "পড়ার সময় এবং পড়া পৃষ্ঠা, আপনার ডিভাইস এবং KOReader জুড়ে সিঙ্ক করা হয়।", "Auto Sync": "স্বয়ংক্রিয় সিঙ্ক" diff --git a/apps/readest-app/public/locales/bo/translation.json b/apps/readest-app/public/locales/bo/translation.json index 26980b2e..37aa361f 100644 --- a/apps/readest-app/public/locales/bo/translation.json +++ b/apps/readest-app/public/locales/bo/translation.json @@ -1721,6 +1721,7 @@ "Privacy": "གསང་དོན།", "No downloadable format available": "ཕབ་ལེན་བྱེད་ཆོག་པའི་རྣམ་པ་མི་འདུག", "Content is neither valid XML nor JSON": "ནང་དོན་ནི་ XML དང་ JSON གང་ཡང་ཚད་ལྡན་མིན།", + "Clear Pending": "སྒུག་བཞིན་པ་གསལ་བ་", "Reading statistics": "ཀློག་འདོན་གྱི་གྲངས་ཐོ།", "Reading time and pages read, synced across your devices and KOReader.": "ཀློག་འདོན་གྱི་དུས་ཚོད་དང་ཀློག་ཟིན་པའི་ཤོག་གྲངས། ཁྱེད་ཀྱི་སྒྲིག་ཆས་དང་ KOReader བར་མཉམ་སྒྲིག་བྱེད།", "Auto Sync": "རང་འགུལ་སྤྲི་དོན།" diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index 8585d6fc..c964ee9a 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -1754,6 +1754,7 @@ "Privacy": "Datenschutz", "No downloadable format available": "Kein herunterladbares Format verfügbar", "Content is neither valid XML nor JSON": "Inhalt ist weder gültiges XML noch JSON", + "Clear Pending": "Ausstehende löschen", "Reading statistics": "Lesestatistik", "Reading time and pages read, synced across your devices and KOReader.": "Lesezeit und gelesene Seiten, synchronisiert über deine Geräte und KOReader.", "Auto Sync": "Automatische Synchronisierung" diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index fb9d4267..0aa3ba83 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -1754,6 +1754,7 @@ "Privacy": "Απόρρητο", "No downloadable format available": "Δεν υπάρχει διαθέσιμη μορφή για λήψη", "Content is neither valid XML nor JSON": "Το περιεχόμενο δεν είναι ούτε έγκυρο XML ούτε JSON", + "Clear Pending": "Εκκαθάριση σε αναμονή", "Reading statistics": "Στατιστικά ανάγνωσης", "Reading time and pages read, synced across your devices and KOReader.": "Χρόνος ανάγνωσης και σελίδες που διαβάστηκαν, συγχρονισμένα στις συσκευές σας και το KOReader.", "Auto Sync": "Αυτόματος συγχρονισμός" diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index 9ab35682..93d28147 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -1787,6 +1787,7 @@ "Privacy": "Privacidad", "No downloadable format available": "No hay ningún formato descargable disponible", "Content is neither valid XML nor JSON": "El contenido no es XML ni JSON válido", + "Clear Pending": "Limpiar pendientes", "Reading statistics": "Estadísticas de lectura", "Reading time and pages read, synced across your devices and KOReader.": "Tiempo de lectura y páginas leídas, sincronizados entre tus dispositivos y KOReader.", "Auto Sync": "Sincronización automática" diff --git a/apps/readest-app/public/locales/fa/translation.json b/apps/readest-app/public/locales/fa/translation.json index 82c2a66b..c43b2cc3 100644 --- a/apps/readest-app/public/locales/fa/translation.json +++ b/apps/readest-app/public/locales/fa/translation.json @@ -1754,6 +1754,7 @@ "Privacy": "حریم خصوصی", "No downloadable format available": "هیچ قالب قابل دانلودی موجود نیست", "Content is neither valid XML nor JSON": "محتوا نه XML معتبر است و نه JSON", + "Clear Pending": "پاک کردن در انتظارها", "Reading statistics": "آمار مطالعه", "Reading time and pages read, synced across your devices and KOReader.": "زمان مطالعه و صفحات خوانده‌شده، همگام‌سازی‌شده در دستگاه‌های شما و KOReader.", "Auto Sync": "همگام‌سازی خودکار" diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index 960f6cec..3fe889ff 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -1787,6 +1787,7 @@ "Privacy": "Confidentialité", "No downloadable format available": "Aucun format téléchargeable disponible", "Content is neither valid XML nor JSON": "Le contenu n'est ni du XML ni du JSON valide", + "Clear Pending": "Effacer les en attente", "Reading statistics": "Statistiques de lecture", "Reading time and pages read, synced across your devices and KOReader.": "Temps de lecture et pages lues, synchronisés sur vos appareils et KOReader.", "Auto Sync": "Synchronisation automatique" diff --git a/apps/readest-app/public/locales/he/translation.json b/apps/readest-app/public/locales/he/translation.json index 1c56c78c..2feff2ed 100644 --- a/apps/readest-app/public/locales/he/translation.json +++ b/apps/readest-app/public/locales/he/translation.json @@ -1787,6 +1787,7 @@ "Privacy": "פרטיות", "No downloadable format available": "אין פורמט להורדה זמין", "Content is neither valid XML nor JSON": "התוכן אינו XML או JSON תקין", + "Clear Pending": "נקה בהמתנה", "Reading statistics": "סטטיסטיקת קריאה", "Reading time and pages read, synced across your devices and KOReader.": "זמן קריאה ועמודים שנקראו, מסונכרנים בין המכשירים שלך ו-KOReader.", "Auto Sync": "סנכרון אוטומטי" diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index 314a8cfa..d1bcd6b4 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -1754,6 +1754,7 @@ "Privacy": "गोपनीयता", "No downloadable format available": "कोई डाउनलोड करने योग्य प्रारूप उपलब्ध नहीं है", "Content is neither valid XML nor JSON": "सामग्री न तो मान्य XML है और न ही JSON", + "Clear Pending": "लंबित साफ़ करें", "Reading statistics": "पठन सांख्यिकी", "Reading time and pages read, synced across your devices and KOReader.": "पढ़ने का समय और पढ़े गए पृष्ठ, आपके डिवाइसों और KOReader के बीच सिंक किए गए।", "Auto Sync": "स्वतः सिंक" diff --git a/apps/readest-app/public/locales/hu/translation.json b/apps/readest-app/public/locales/hu/translation.json index 225502d6..9f1e6f0d 100644 --- a/apps/readest-app/public/locales/hu/translation.json +++ b/apps/readest-app/public/locales/hu/translation.json @@ -1754,6 +1754,7 @@ "Privacy": "Adatvédelem", "No downloadable format available": "Nincs letölthető formátum", "Content is neither valid XML nor JSON": "A tartalom sem érvényes XML, sem JSON", + "Clear Pending": "Függőben lévők törlése", "Reading statistics": "Olvasási statisztika", "Reading time and pages read, synced across your devices and KOReader.": "Olvasási idő és elolvasott oldalak, szinkronizálva az eszközei és a KOReader között.", "Auto Sync": "Automatikus szinkronizálás" diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index 7d52495b..30b13b0f 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -1721,6 +1721,7 @@ "Privacy": "Privasi", "No downloadable format available": "Tidak ada format yang dapat diunduh", "Content is neither valid XML nor JSON": "Konten bukan XML maupun JSON yang valid", + "Clear Pending": "Hapus Menunggu", "Reading statistics": "Statistik Bacaan", "Reading time and pages read, synced across your devices and KOReader.": "Waktu membaca dan halaman yang dibaca, disinkronkan di seluruh perangkat Anda dan KOReader.", "Auto Sync": "Sinkronisasi Otomatis" diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index ad9f769b..b208e768 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -1787,6 +1787,7 @@ "Privacy": "Privacy", "No downloadable format available": "Nessun formato scaricabile disponibile", "Content is neither valid XML nor JSON": "Il contenuto non è né XML né JSON valido", + "Clear Pending": "Cancella in attesa", "Reading statistics": "Statistiche di lettura", "Reading time and pages read, synced across your devices and KOReader.": "Tempo di lettura e pagine lette, sincronizzati tra i tuoi dispositivi e KOReader.", "Auto Sync": "Sincronizzazione automatica" diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index 767708bc..539bfdd4 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -1721,6 +1721,7 @@ "Privacy": "プライバシー", "No downloadable format available": "ダウンロード可能な形式がありません", "Content is neither valid XML nor JSON": "コンテンツが有効な XML でも JSON でもありません", + "Clear Pending": "待機中を消去", "Reading statistics": "読書統計", "Reading time and pages read, synced across your devices and KOReader.": "読書時間と読んだページ数。デバイス間および KOReader と同期されます。", "Auto Sync": "自動同期" diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index 049947f8..f50ed259 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -1721,6 +1721,7 @@ "Privacy": "개인정보 보호", "No downloadable format available": "다운로드 가능한 형식이 없습니다", "Content is neither valid XML nor JSON": "콘텐츠가 유효한 XML 또는 JSON이 아닙니다", + "Clear Pending": "대기 중 항목 지우기", "Reading statistics": "독서 통계", "Reading time and pages read, synced across your devices and KOReader.": "읽은 시간과 읽은 페이지 수로, 여러 기기와 KOReader 간에 동기화됩니다.", "Auto Sync": "자동 동기화" diff --git a/apps/readest-app/public/locales/ms/translation.json b/apps/readest-app/public/locales/ms/translation.json index 0a9b4c6e..49a89809 100644 --- a/apps/readest-app/public/locales/ms/translation.json +++ b/apps/readest-app/public/locales/ms/translation.json @@ -1721,6 +1721,7 @@ "Privacy": "Privasi", "No downloadable format available": "Tiada format yang boleh dimuat turun", "Content is neither valid XML nor JSON": "Kandungan bukan XML mahupun JSON yang sah", + "Clear Pending": "Kosongkan Menunggu", "Reading statistics": "Statistik Bacaan", "Reading time and pages read, synced across your devices and KOReader.": "Masa membaca dan halaman dibaca, disegerakkan merentas peranti anda dan KOReader.", "Auto Sync": "Segerak Automatik" diff --git a/apps/readest-app/public/locales/nl/translation.json b/apps/readest-app/public/locales/nl/translation.json index 97da610e..975a7d3a 100644 --- a/apps/readest-app/public/locales/nl/translation.json +++ b/apps/readest-app/public/locales/nl/translation.json @@ -1754,6 +1754,7 @@ "Privacy": "Privacy", "No downloadable format available": "Geen downloadbaar formaat beschikbaar", "Content is neither valid XML nor JSON": "Inhoud is geen geldige XML of JSON", + "Clear Pending": "Wachtende wissen", "Reading statistics": "Leesstatistieken", "Reading time and pages read, synced across your devices and KOReader.": "Leestijd en gelezen pagina's, gesynchroniseerd op je apparaten en KOReader.", "Auto Sync": "Automatische synchronisatie" diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index 5e1808ae..863ce8de 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -1820,6 +1820,7 @@ "Privacy": "Prywatność", "No downloadable format available": "Brak formatu do pobrania", "Content is neither valid XML nor JSON": "Treść nie jest prawidłowym XML ani JSON", + "Clear Pending": "Wyczyść oczekujące", "Reading statistics": "Statystyki czytania", "Reading time and pages read, synced across your devices and KOReader.": "Czas czytania i przeczytane strony, synchronizowane między Twoimi urządzeniami a KOReader.", "Auto Sync": "Automatyczna synchronizacja" diff --git a/apps/readest-app/public/locales/pt-BR/translation.json b/apps/readest-app/public/locales/pt-BR/translation.json index 045372ec..2088b0a6 100644 --- a/apps/readest-app/public/locales/pt-BR/translation.json +++ b/apps/readest-app/public/locales/pt-BR/translation.json @@ -1787,6 +1787,7 @@ "Privacy": "Privacidade", "No downloadable format available": "Nenhum formato disponível para download", "Content is neither valid XML nor JSON": "O conteúdo não é XML nem JSON válido", + "Clear Pending": "Limpar pendentes", "Reading statistics": "Estatísticas de leitura", "Reading time and pages read, synced across your devices and KOReader.": "Tempo de leitura e páginas lidas, sincronizados entre seus dispositivos e o KOReader.", "Auto Sync": "Sincronização automática" diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index e07bdde2..42c31761 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -1787,6 +1787,7 @@ "Privacy": "Privacidade", "No downloadable format available": "Nenhum formato disponível para download", "Content is neither valid XML nor JSON": "O conteúdo não é XML nem JSON válido", + "Clear Pending": "Limpar Pendentes", "Reading statistics": "Estatísticas de leitura", "Reading time and pages read, synced across your devices and KOReader.": "Tempo de leitura e páginas lidas, sincronizados entre os seus dispositivos e o KOReader.", "Auto Sync": "Sincronização Automática" diff --git a/apps/readest-app/public/locales/ro/translation.json b/apps/readest-app/public/locales/ro/translation.json index 31f5a6a8..b27afa1b 100644 --- a/apps/readest-app/public/locales/ro/translation.json +++ b/apps/readest-app/public/locales/ro/translation.json @@ -1787,6 +1787,7 @@ "Privacy": "Confidențialitate", "No downloadable format available": "Niciun format descărcabil disponibil", "Content is neither valid XML nor JSON": "Conținutul nu este nici XML, nici JSON valid", + "Clear Pending": "Șterge în așteptare", "Reading statistics": "Statistici de lectură", "Reading time and pages read, synced across your devices and KOReader.": "Timpul de citire și paginile citite, sincronizate pe dispozitivele tale și KOReader.", "Auto Sync": "Sincronizare automată" diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index 2b7b231a..3a021f36 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -1820,6 +1820,7 @@ "Privacy": "Конфиденциальность", "No downloadable format available": "Нет доступного формата для загрузки", "Content is neither valid XML nor JSON": "Содержимое не является ни корректным XML, ни JSON", + "Clear Pending": "Очистить ожидающие", "Reading statistics": "Статистика чтения", "Reading time and pages read, synced across your devices and KOReader.": "Время чтения и прочитанные страницы, синхронизируются между вашими устройствами и KOReader.", "Auto Sync": "Автосинхронизация" diff --git a/apps/readest-app/public/locales/si/translation.json b/apps/readest-app/public/locales/si/translation.json index 4d113883..3fb57c09 100644 --- a/apps/readest-app/public/locales/si/translation.json +++ b/apps/readest-app/public/locales/si/translation.json @@ -1754,6 +1754,7 @@ "Privacy": "පෞද්ගලිකත්වය", "No downloadable format available": "බාගත කළ හැකි ආකෘතියක් නොමැත", "Content is neither valid XML nor JSON": "අන්තර්ගතය වලංගු XML හෝ JSON නොවේ", + "Clear Pending": "බලාපොරොත්තුවේ ඇති ඒවා මකන්න", "Reading statistics": "කියවීමේ සංඛ්‍යාලේඛන", "Reading time and pages read, synced across your devices and KOReader.": "කියවීමේ කාලය සහ කියවූ පිටු, ඔබේ උපාංග සහ KOReader හරහා සමමුහුර්ත වේ.", "Auto Sync": "ස්වයංක්‍රීය සමමුහුර්තය" diff --git a/apps/readest-app/public/locales/sl/translation.json b/apps/readest-app/public/locales/sl/translation.json index 7f65dd7d..c91f1494 100644 --- a/apps/readest-app/public/locales/sl/translation.json +++ b/apps/readest-app/public/locales/sl/translation.json @@ -1820,6 +1820,7 @@ "Privacy": "Zasebnost", "No downloadable format available": "Na voljo ni nobene oblike za prenos", "Content is neither valid XML nor JSON": "Vsebina ni veljaven XML niti JSON", + "Clear Pending": "Počisti čakajoče", "Reading statistics": "Statistika branja", "Reading time and pages read, synced across your devices and KOReader.": "Čas branja in prebrane strani, sinhronizirano med vašimi napravami in KOReader.", "Auto Sync": "Samodejna sinhronizacija" diff --git a/apps/readest-app/public/locales/sv/translation.json b/apps/readest-app/public/locales/sv/translation.json index cbf07508..17606940 100644 --- a/apps/readest-app/public/locales/sv/translation.json +++ b/apps/readest-app/public/locales/sv/translation.json @@ -1754,6 +1754,7 @@ "Privacy": "Integritet", "No downloadable format available": "Inget nedladdningsbart format tillgängligt", "Content is neither valid XML nor JSON": "Innehållet är varken giltig XML eller JSON", + "Clear Pending": "Rensa väntande", "Reading statistics": "Lässtatistik", "Reading time and pages read, synced across your devices and KOReader.": "Lästid och lästa sidor, synkroniserat mellan dina enheter och KOReader.", "Auto Sync": "Automatisk synkronisering" diff --git a/apps/readest-app/public/locales/ta/translation.json b/apps/readest-app/public/locales/ta/translation.json index 60d95a20..51d23085 100644 --- a/apps/readest-app/public/locales/ta/translation.json +++ b/apps/readest-app/public/locales/ta/translation.json @@ -1754,6 +1754,7 @@ "Privacy": "தனியுரிமை", "No downloadable format available": "பதிவிறக்கம் செய்யக்கூடிய வடிவம் எதுவும் இல்லை", "Content is neither valid XML nor JSON": "உள்ளடக்கம் சரியான XML அல்லது JSON அல்ல", + "Clear Pending": "காத்திருப்பதை அழிக்கவும்", "Reading statistics": "வாசிப்பு புள்ளிவிவரங்கள்", "Reading time and pages read, synced across your devices and KOReader.": "வாசிப்பு நேரம் மற்றும் படித்த பக்கங்கள், உங்கள் சாதனங்கள் மற்றும் KOReader இடையே ஒத்திசைக்கப்படும்.", "Auto Sync": "தானியங்கு ஒத்திசைவு" diff --git a/apps/readest-app/public/locales/th/translation.json b/apps/readest-app/public/locales/th/translation.json index e61f85b2..49e0de70 100644 --- a/apps/readest-app/public/locales/th/translation.json +++ b/apps/readest-app/public/locales/th/translation.json @@ -1721,6 +1721,7 @@ "Privacy": "ความเป็นส่วนตัว", "No downloadable format available": "ไม่มีรูปแบบที่ดาวน์โหลดได้", "Content is neither valid XML nor JSON": "เนื้อหาไม่ใช่ทั้ง XML และ JSON ที่ถูกต้อง", + "Clear Pending": "ล้างที่รอดำเนินการ", "Reading statistics": "สถิติการอ่าน", "Reading time and pages read, synced across your devices and KOReader.": "เวลาในการอ่านและจำนวนหน้าที่อ่าน ซิงค์ข้ามอุปกรณ์ของคุณและ KOReader", "Auto Sync": "ซิงค์อัตโนมัติ" diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index 1a1380a0..e285f38f 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -1754,6 +1754,7 @@ "Privacy": "Gizlilik", "No downloadable format available": "İndirilebilir biçim yok", "Content is neither valid XML nor JSON": "İçerik geçerli XML veya JSON değil", + "Clear Pending": "Bekleyenleri Temizle", "Reading statistics": "Okuma İstatistikleri", "Reading time and pages read, synced across your devices and KOReader.": "Okuma süresi ve okunan sayfalar, cihazlarınız ve KOReader arasında senkronize edilir.", "Auto Sync": "Otomatik Senkronizasyon" diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index 38e04d30..c068dc66 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -1820,6 +1820,7 @@ "Privacy": "Конфіденційність", "No downloadable format available": "Немає доступного формату для завантаження", "Content is neither valid XML nor JSON": "Вміст не є дійсним XML чи JSON", + "Clear Pending": "Очистити очікувані", "Reading statistics": "Статистика читання", "Reading time and pages read, synced across your devices and KOReader.": "Час читання та прочитані сторінки, синхронізуються між вашими пристроями та KOReader.", "Auto Sync": "Автоматична синхронізація" diff --git a/apps/readest-app/public/locales/uz/translation.json b/apps/readest-app/public/locales/uz/translation.json index 7fc22f75..6444597b 100644 --- a/apps/readest-app/public/locales/uz/translation.json +++ b/apps/readest-app/public/locales/uz/translation.json @@ -1754,6 +1754,7 @@ "Privacy": "Maxfiylik", "No downloadable format available": "Yuklab olinadigan format mavjud emas", "Content is neither valid XML nor JSON": "Kontent yaroqli XML ham, JSON ham emas", + "Clear Pending": "Kutilayotganlarni tozalash", "Reading statistics": "Oʻqish statistikasi", "Reading time and pages read, synced across your devices and KOReader.": "Oʻqish vaqti va oʻqilgan sahifalar, qurilmalaringiz va KOReader oʻrtasida sinxronlanadi.", "Auto Sync": "Avtomatik sinxronlash" diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index ad389561..b0cad8a5 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -1721,6 +1721,7 @@ "Privacy": "Quyền riêng tư", "No downloadable format available": "Không có định dạng nào để tải xuống", "Content is neither valid XML nor JSON": "Nội dung không phải XML hay JSON hợp lệ", + "Clear Pending": "Xóa đang chờ", "Reading statistics": "Thống kê đọc", "Reading time and pages read, synced across your devices and KOReader.": "Thời gian đọc và số trang đã đọc, được đồng bộ trên các thiết bị của bạn và KOReader.", "Auto Sync": "Tự động đồng bộ" diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index 32d2495c..5b36ddab 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -1721,6 +1721,7 @@ "Privacy": "隐私", "No downloadable format available": "没有可下载的格式", "Content is neither valid XML nor JSON": "内容既不是有效的 XML 也不是 JSON", + "Clear Pending": "清除等待中", "Reading statistics": "阅读统计", "Reading time and pages read, synced across your devices and KOReader.": "阅读时间和已读页数,在您的设备和 KOReader 之间同步。", "Auto Sync": "自动同步" diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index 7fd312d0..be2be63b 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -1721,6 +1721,7 @@ "Privacy": "隱私", "No downloadable format available": "沒有可下載的格式", "Content is neither valid XML nor JSON": "內容既不是有效的 XML 也不是 JSON", + "Clear Pending": "清除等待中", "Reading statistics": "閱讀統計", "Reading time and pages read, synced across your devices and KOReader.": "閱讀時間與已讀頁數,在您的裝置與 KOReader 之間同步。", "Auto Sync": "自動同步" diff --git a/apps/readest-app/src/__tests__/services/transfer-manager.test.ts b/apps/readest-app/src/__tests__/services/transfer-manager.test.ts index 2d969ea0..140cfe5b 100644 --- a/apps/readest-app/src/__tests__/services/transfer-manager.test.ts +++ b/apps/readest-app/src/__tests__/services/transfer-manager.test.ts @@ -497,6 +497,36 @@ describe('TransferManager', () => { }); }); + // ── clearPending ───────────────────────────────────────────────── + describe('clearPending', () => { + test('removes pending transfers, keeps others, and persists the queue', async () => { + const book1 = makeBook({ hash: 'h1', title: 'B1' }); + const book2 = makeBook({ hash: 'h2', title: 'B2' }); + const appService = makeAppService(); + await transferManager.initialize( + appService as never, + () => [book1, book2], + vi.fn(), + translationFn, + ); + + // Pause first so queued items stay pending instead of being processed. + transferManager.pauseQueue(); + const id1 = transferManager.queueUpload(book1)!; + const id2 = transferManager.queueDownload(book2)!; + useTransferStore.getState().setTransferStatus(id2, 'completed'); + + transferManager.clearPending(); + + expect(useTransferStore.getState().transfers[id1]).toBeUndefined(); + expect(useTransferStore.getState().transfers[id2]).toBeDefined(); + + const stored = JSON.parse(localStorage.getItem('readest_transfer_queue')!); + expect(stored.transfers[id1]).toBeUndefined(); + expect(stored.transfers[id2]).toBeDefined(); + }); + }); + // ── Queue processing (integration-style) ───────────────────────── describe('queue processing', () => { test('successful upload calls appService.uploadBook and updates book', async () => { diff --git a/apps/readest-app/src/__tests__/store/transfer-store.test.ts b/apps/readest-app/src/__tests__/store/transfer-store.test.ts index 79bab174..77c225cd 100644 --- a/apps/readest-app/src/__tests__/store/transfer-store.test.ts +++ b/apps/readest-app/src/__tests__/store/transfer-store.test.ts @@ -226,6 +226,40 @@ describe('transferStore', () => { }); }); + // ── clearPending ───────────────────────────────────────────────── + describe('clearPending', () => { + test('removes only pending transfers', () => { + const id1 = useTransferStore.getState().addTransfer('h1', 'B1', 'upload'); + const id2 = useTransferStore.getState().addTransfer('h2', 'B2', 'download'); + const id3 = useTransferStore.getState().addTransfer('h3', 'B3', 'upload'); + const id4 = useTransferStore.getState().addTransfer('h4', 'B4', 'delete'); + const id5 = useTransferStore.getState().addTransfer('h5', 'B5', 'upload'); + useTransferStore.getState().setTransferStatus(id1, 'in_progress'); + useTransferStore.getState().setTransferStatus(id2, 'completed'); + useTransferStore.getState().setTransferStatus(id3, 'failed', 'err'); + useTransferStore.getState().setTransferStatus(id4, 'cancelled'); + // id5 remains pending + + useTransferStore.getState().clearPending(); + const transfers = useTransferStore.getState().transfers; + expect(transfers[id1]).toBeDefined(); // in_progress kept + expect(transfers[id2]).toBeDefined(); // completed kept + expect(transfers[id3]).toBeDefined(); // failed kept + expect(transfers[id4]).toBeDefined(); // cancelled kept + expect(transfers[id5]).toBeUndefined(); // pending removed + }); + + test('removes retry-pending transfers (status pending with an error message)', () => { + const id = useTransferStore.getState().addTransfer('h', 'B', 'upload'); + // mimic the retry path: failed -> back to pending with a "Retry x/y" note + useTransferStore.getState().setTransferStatus(id, 'pending', 'Retry 1/3'); + expect(useTransferStore.getState().transfers[id]!.status).toBe('pending'); + + useTransferStore.getState().clearPending(); + expect(useTransferStore.getState().transfers[id]).toBeUndefined(); + }); + }); + // ── clearAll ───────────────────────────────────────────────────── describe('clearAll', () => { test('removes all transfers', () => { diff --git a/apps/readest-app/src/app/library/components/TransferQueuePanel.tsx b/apps/readest-app/src/app/library/components/TransferQueuePanel.tsx index 7bbcb200..0ddefff1 100644 --- a/apps/readest-app/src/app/library/components/TransferQueuePanel.tsx +++ b/apps/readest-app/src/app/library/components/TransferQueuePanel.tsx @@ -166,6 +166,7 @@ const TransferQueuePanel: React.FC = () => { resumeQueue, clearCompleted, clearFailed, + clearPending, queueUpload, queueDownload, } = useTransferQueue(); @@ -335,6 +336,12 @@ const TransferQueuePanel: React.FC = () => { {_('Retry All')} )} + {stats.pending > 0 && ( + + )} {stats.completed > 0 && (