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) <noreply@anthropic.com>

* 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) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Huang Xin
2026-06-17 02:02:11 +08:00
committed by GitHub
parent 480ab5b71e
commit d202d7a61e
39 changed files with 127 additions and 0 deletions
@@ -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": "مزامنة تلقائية"
@@ -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": "স্বয়ংক্রিয় সিঙ্ক"
@@ -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": "རང་འགུལ་སྤྲི་དོན།"
@@ -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"
@@ -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": "Αυτόματος συγχρονισμός"
@@ -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"
@@ -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": "همگام‌سازی خودکار"
@@ -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"
@@ -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": "סנכרון אוטומטי"
@@ -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": "स्वतः सिंक"
@@ -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"
@@ -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"
@@ -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"
@@ -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": "自動同期"
@@ -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": "자동 동기화"
@@ -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"
@@ -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"
@@ -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"
@@ -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"
@@ -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"
@@ -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ă"
@@ -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": "Автосинхронизация"
@@ -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": "ස්වයංක්‍රීය සමමුහුර්තය"
@@ -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"
@@ -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"
@@ -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": "தானியங்கு ஒத்திசைவு"
@@ -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": "ซิงค์อัตโนมัติ"
@@ -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"
@@ -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": "Автоматична синхронізація"
@@ -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"
@@ -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ộ"
@@ -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": "自动同步"
@@ -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": "自動同步"
@@ -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 () => {
@@ -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', () => {
@@ -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')}
</button>
)}
{stats.pending > 0 && (
<button onClick={clearPending} className='btn btn-ghost btn-sm gap-1'>
<MdDeleteSweep size={iconSize - 2} />
{_('Clear Pending')}
</button>
)}
{stats.completed > 0 && (
<button onClick={clearCompleted} className='btn btn-ghost btn-sm gap-1'>
<MdDeleteSweep size={iconSize - 2} />
@@ -74,6 +74,10 @@ export function useTransferQueue(libraryLoaded = true, delayInit = 0) {
useTransferStore.getState().clearFailed();
}, []);
const clearPending = useCallback(() => {
transferManager.clearPending();
}, []);
const clearAll = useCallback(() => {
useTransferStore.getState().clearAll();
}, []);
@@ -136,6 +140,7 @@ export function useTransferQueue(libraryLoaded = true, delayInit = 0) {
resumeQueue,
clearCompleted,
clearFailed,
clearPending,
clearAll,
getTransferProgress,
};
@@ -254,6 +254,11 @@ class TransferManager {
this.persistQueue();
}
clearPending(): void {
useTransferStore.getState().clearPending();
this.persistQueue();
}
private async processQueue(): Promise<void> {
if (this.isProcessing) return;
@@ -85,6 +85,7 @@ interface TransferState {
resumeQueue: () => void;
clearCompleted: () => void;
clearFailed: () => void;
clearPending: () => void;
clearAll: () => void;
// Getters
@@ -303,6 +304,18 @@ export const useTransferStore = create<TransferState>((set, get) => ({
});
},
clearPending: () => {
set((state) => {
const remaining: Record<string, TransferItem> = {};
Object.entries(state.transfers).forEach(([id, transfer]) => {
if (transfer.status !== 'pending') {
remaining[id] = transfer;
}
});
return { transfers: remaining };
});
},
clearAll: () => set({ transfers: {} }),
getPendingTransfers: () => {