Add a "Refresh Metadata" option under Advanced Settings that re-parses book files to update metadata (series info, language, etc.) for books imported before these fields were supported. - Add refreshBookMetadata() in bookService that opens a book file, re-parses with DocumentLoader, and updates metadata/metaHash/series without touching updatedAt or user-edited fields - Add menu item in SettingsMenu with progress display - Add unit tests for single-book metadata refresh - Translate new i18n strings across all 29 locales Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1145,5 +1145,14 @@
|
||||
"Restore completed successfully!": "تمت الاستعادة بنجاح!",
|
||||
"Your library has been saved to the selected location.": "تم حفظ مكتبتك في الموقع المحدد.",
|
||||
"{{added}} books added, {{updated}} books updated.": "تمت إضافة {{added}} كتب، وتحديث {{updated}} كتب.",
|
||||
"Operation failed": "فشلت العملية"
|
||||
"Operation failed": "فشلت العملية",
|
||||
"Loading library...": "جارٍ تحميل المكتبة...",
|
||||
"{{count}} books refreshed_zero": "لم يتم تحديث أي كتاب",
|
||||
"{{count}} books refreshed_one": "تم تحديث كتاب واحد",
|
||||
"{{count}} books refreshed_two": "تم تحديث كتابين",
|
||||
"{{count}} books refreshed_few": "تم تحديث {{count}} كتب",
|
||||
"{{count}} books refreshed_many": "تم تحديث {{count}} كتابًا",
|
||||
"{{count}} books refreshed_other": "تم تحديث {{count}} كتاب",
|
||||
"Failed to refresh metadata": "فشل تحديث البيانات الوصفية",
|
||||
"Refresh Metadata": "تحديث البيانات الوصفية"
|
||||
}
|
||||
|
||||
@@ -1097,5 +1097,10 @@
|
||||
"Restore completed successfully!": "পুনরুদ্ধার সফলভাবে সম্পন্ন!",
|
||||
"Your library has been saved to the selected location.": "আপনার লাইব্রেরি নির্বাচিত স্থানে সংরক্ষিত হয়েছে।",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}}টি বই যোগ হয়েছে, {{updated}}টি বই আপডেট হয়েছে।",
|
||||
"Operation failed": "অপারেশন ব্যর্থ"
|
||||
"Operation failed": "অপারেশন ব্যর্থ",
|
||||
"Loading library...": "লাইব্রেরি লোড হচ্ছে...",
|
||||
"{{count}} books refreshed_one": "{{count}}টি বইয়ের মেটাডেটা রিফ্রেশ হয়েছে",
|
||||
"{{count}} books refreshed_other": "{{count}}টি বইয়ের মেটাডেটা রিফ্রেশ হয়েছে",
|
||||
"Failed to refresh metadata": "মেটাডেটা রিফ্রেশ ব্যর্থ",
|
||||
"Refresh Metadata": "মেটাডেটা রিফ্রেশ"
|
||||
}
|
||||
|
||||
@@ -1085,5 +1085,9 @@
|
||||
"Restore completed successfully!": "སླར་གསོ་ལེགས་གྲུབ་བྱུང་!",
|
||||
"Your library has been saved to the selected location.": "ཁྱོད་ཀྱི་དཔེ་མཛོད་འདེམས་ས་དེར་ཉར་ཟིན།",
|
||||
"{{added}} books added, {{updated}} books updated.": "དཔེ་དེབ {{added}} བསྣན་ཟིན, {{updated}} གསར་བསྒྱུར་བྱས་ཟིན།",
|
||||
"Operation failed": "བཀོལ་སྤྱོད་བྱེད་མ་ཐུབ"
|
||||
"Operation failed": "བཀོལ་སྤྱོད་བྱེད་མ་ཐུབ",
|
||||
"Loading library...": "དཔེ་མཛོད་འཇུག་བཞིན་པ...",
|
||||
"{{count}} books refreshed_other": "تم تحديث {{count}} كتب",
|
||||
"Failed to refresh metadata": "མེ་ཊ་ཌེ་ཊ་གསར་བསྒྱུར་བྱེད་མ་ཐུབ",
|
||||
"Refresh Metadata": "མེ་ཊ་ཌེ་ཊ་གསར་བསྒྱུར"
|
||||
}
|
||||
|
||||
@@ -1097,5 +1097,10 @@
|
||||
"Restore completed successfully!": "Wiederherstellung erfolgreich abgeschlossen!",
|
||||
"Your library has been saved to the selected location.": "Ihre Bibliothek wurde am ausgewählten Ort gespeichert.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} Bücher hinzugefügt, {{updated}} Bücher aktualisiert.",
|
||||
"Operation failed": "Vorgang fehlgeschlagen"
|
||||
"Operation failed": "Vorgang fehlgeschlagen",
|
||||
"Loading library...": "Bibliothek wird geladen...",
|
||||
"{{count}} books refreshed_one": "{{count}} Buch aktualisiert",
|
||||
"{{count}} books refreshed_other": "{{count}} Bücher aktualisiert",
|
||||
"Failed to refresh metadata": "Metadaten-Aktualisierung fehlgeschlagen",
|
||||
"Refresh Metadata": "Metadaten aktualisieren"
|
||||
}
|
||||
|
||||
@@ -1097,5 +1097,10 @@
|
||||
"Restore completed successfully!": "Η επαναφορά ολοκληρώθηκε!",
|
||||
"Your library has been saved to the selected location.": "Η βιβλιοθήκη σας αποθηκεύτηκε στην επιλεγμένη τοποθεσία.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} βιβλία προστέθηκαν, {{updated}} βιβλία ενημερώθηκαν.",
|
||||
"Operation failed": "Η λειτουργία απέτυχε"
|
||||
"Operation failed": "Η λειτουργία απέτυχε",
|
||||
"Loading library...": "Φόρτωση βιβλιοθήκης...",
|
||||
"{{count}} books refreshed_one": "{{count}} βιβλίο ανανεώθηκε",
|
||||
"{{count}} books refreshed_other": "{{count}} βιβλία ανανεώθηκαν",
|
||||
"Failed to refresh metadata": "Αποτυχία ανανέωσης μεταδεδομένων",
|
||||
"Refresh Metadata": "Ανανέωση μεταδεδομένων"
|
||||
}
|
||||
|
||||
@@ -1109,5 +1109,11 @@
|
||||
"Restore completed successfully!": "¡Restauración completada!",
|
||||
"Your library has been saved to the selected location.": "Tu biblioteca se ha guardado en la ubicación seleccionada.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} libros añadidos, {{updated}} libros actualizados.",
|
||||
"Operation failed": "La operación falló"
|
||||
"Operation failed": "La operación falló",
|
||||
"Loading library...": "Cargando biblioteca...",
|
||||
"{{count}} books refreshed_one": "{{count}} libro actualizado",
|
||||
"{{count}} books refreshed_many": "{{count}} libros actualizados",
|
||||
"{{count}} books refreshed_other": "{{count}} libros actualizados",
|
||||
"Failed to refresh metadata": "Error al actualizar metadatos",
|
||||
"Refresh Metadata": "Actualizar metadatos"
|
||||
}
|
||||
|
||||
@@ -1097,5 +1097,10 @@
|
||||
"Restore completed successfully!": "بازیابی با موفقیت انجام شد!",
|
||||
"Your library has been saved to the selected location.": "کتابخانه شما در مکان انتخابشده ذخیره شد.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} کتاب اضافه شد، {{updated}} کتاب بهروزرسانی شد.",
|
||||
"Operation failed": "عملیات ناموفق"
|
||||
"Operation failed": "عملیات ناموفق",
|
||||
"Loading library...": "در حال بارگذاری کتابخانه...",
|
||||
"{{count}} books refreshed_one": "{{count}} کتاب بهروزرسانی شد",
|
||||
"{{count}} books refreshed_other": "{{count}} کتاب بهروزرسانی شد",
|
||||
"Failed to refresh metadata": "بهروزرسانی فراداده ناموفق",
|
||||
"Refresh Metadata": "بهروزرسانی فراداده"
|
||||
}
|
||||
|
||||
@@ -1109,5 +1109,11 @@
|
||||
"Restore completed successfully!": "Restauration terminée avec succès !",
|
||||
"Your library has been saved to the selected location.": "Votre bibliothèque a été enregistrée à l'emplacement sélectionné.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} livres ajoutés, {{updated}} livres mis à jour.",
|
||||
"Operation failed": "L'opération a échoué"
|
||||
"Operation failed": "L'opération a échoué",
|
||||
"Loading library...": "Chargement de la bibliothèque...",
|
||||
"{{count}} books refreshed_one": "{{count}} livre rafraîchi",
|
||||
"{{count}} books refreshed_many": "{{count}} livres rafraîchis",
|
||||
"{{count}} books refreshed_other": "{{count}} livres rafraîchis",
|
||||
"Failed to refresh metadata": "Échec du rafraîchissement des métadonnées",
|
||||
"Refresh Metadata": "Rafraîchir les métadonnées"
|
||||
}
|
||||
|
||||
@@ -1109,5 +1109,11 @@
|
||||
"Restore completed successfully!": "השחזור הושלם בהצלחה!",
|
||||
"Your library has been saved to the selected location.": "הספרייה שלך נשמרה במיקום שנבחר.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} ספרים נוספו, {{updated}} ספרים עודכנו.",
|
||||
"Operation failed": "הפעולה נכשלה"
|
||||
"Operation failed": "הפעולה נכשלה",
|
||||
"Loading library...": "טוען ספרייה...",
|
||||
"{{count}} books refreshed_one": "ספר {{count}} רוענן",
|
||||
"{{count}} books refreshed_two": "{{count}} ספרים רועננו",
|
||||
"{{count}} books refreshed_other": "{{count}} ספרים רועננו",
|
||||
"Failed to refresh metadata": "רענון המטא-נתונים נכשל",
|
||||
"Refresh Metadata": "רענון מטא-נתונים"
|
||||
}
|
||||
|
||||
@@ -1097,5 +1097,10 @@
|
||||
"Restore completed successfully!": "पुनर्स्थापना सफलतापूर्वक पूर्ण!",
|
||||
"Your library has been saved to the selected location.": "आपकी लाइब्रेरी चयनित स्थान पर सहेजी गई है।",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} पुस्तकें जोड़ी गईं, {{updated}} पुस्तकें अपडेट की गईं।",
|
||||
"Operation failed": "ऑपरेशन विफल"
|
||||
"Operation failed": "ऑपरेशन विफल",
|
||||
"Loading library...": "लाइब्रेरी लोड हो रही है...",
|
||||
"{{count}} books refreshed_one": "{{count}} पुस्तक रिफ्रेश हुई",
|
||||
"{{count}} books refreshed_other": "{{count}} पुस्तकें रिफ्रेश हुईं",
|
||||
"Failed to refresh metadata": "मेटाडेटा रिफ्रेश विफल",
|
||||
"Refresh Metadata": "मेटाडेटा रिफ्रेश करें"
|
||||
}
|
||||
|
||||
@@ -1085,5 +1085,9 @@
|
||||
"Restore completed successfully!": "Pemulihan berhasil!",
|
||||
"Your library has been saved to the selected location.": "Perpustakaan Anda telah disimpan di lokasi yang dipilih.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} buku ditambahkan, {{updated}} buku diperbarui.",
|
||||
"Operation failed": "Operasi gagal"
|
||||
"Operation failed": "Operasi gagal",
|
||||
"Loading library...": "Memuat perpustakaan...",
|
||||
"{{count}} books refreshed_other": "{{count}} buku diperbarui",
|
||||
"Failed to refresh metadata": "Gagal memperbarui metadata",
|
||||
"Refresh Metadata": "Perbarui Metadata"
|
||||
}
|
||||
|
||||
@@ -1109,5 +1109,11 @@
|
||||
"Restore completed successfully!": "Ripristino completato con successo!",
|
||||
"Your library has been saved to the selected location.": "La tua libreria è stata salvata nella posizione selezionata.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} libri aggiunti, {{updated}} libri aggiornati.",
|
||||
"Operation failed": "Operazione fallita"
|
||||
"Operation failed": "Operazione fallita",
|
||||
"Loading library...": "Caricamento libreria...",
|
||||
"{{count}} books refreshed_one": "{{count}} libro aggiornato",
|
||||
"{{count}} books refreshed_many": "{{count}} libri aggiornati",
|
||||
"{{count}} books refreshed_other": "{{count}} libri aggiornati",
|
||||
"Failed to refresh metadata": "Aggiornamento metadati fallito",
|
||||
"Refresh Metadata": "Aggiorna metadati"
|
||||
}
|
||||
|
||||
@@ -1085,5 +1085,9 @@
|
||||
"Restore completed successfully!": "復元が完了しました!",
|
||||
"Your library has been saved to the selected location.": "ライブラリが選択した場所に保存されました。",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}}冊追加、{{updated}}冊更新されました。",
|
||||
"Operation failed": "操作に失敗しました"
|
||||
"Operation failed": "操作に失敗しました",
|
||||
"Loading library...": "ライブラリを読み込み中...",
|
||||
"{{count}} books refreshed_other": "{{count}}冊のメタデータを更新しました",
|
||||
"Failed to refresh metadata": "メタデータの更新に失敗しました",
|
||||
"Refresh Metadata": "メタデータを更新"
|
||||
}
|
||||
|
||||
@@ -1085,5 +1085,9 @@
|
||||
"Restore completed successfully!": "복원이 완료되었습니다!",
|
||||
"Your library has been saved to the selected location.": "라이브러리가 선택한 위치에 저장되었습니다.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}}권 추가, {{updated}}권 업데이트되었습니다.",
|
||||
"Operation failed": "작업 실패"
|
||||
"Operation failed": "작업 실패",
|
||||
"Loading library...": "라이브러리 로딩 중...",
|
||||
"{{count}} books refreshed_other": "{{count}}권 새로고침됨",
|
||||
"Failed to refresh metadata": "메타데이터 새로고침 실패",
|
||||
"Refresh Metadata": "메타데이터 새로고침"
|
||||
}
|
||||
|
||||
@@ -1085,5 +1085,9 @@
|
||||
"Restore completed successfully!": "Pemulihan berjaya!",
|
||||
"Your library has been saved to the selected location.": "Perpustakaan anda telah disimpan di lokasi yang dipilih.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} buku ditambah, {{updated}} buku dikemas kini.",
|
||||
"Operation failed": "Operasi gagal"
|
||||
"Operation failed": "Operasi gagal",
|
||||
"Loading library...": "Memuatkan perpustakaan...",
|
||||
"{{count}} books refreshed_other": "{{count}} buku dimuat semula",
|
||||
"Failed to refresh metadata": "Gagal memuat semula metadata",
|
||||
"Refresh Metadata": "Muat Semula Metadata"
|
||||
}
|
||||
|
||||
@@ -1097,5 +1097,10 @@
|
||||
"Restore completed successfully!": "Herstel succesvol voltooid!",
|
||||
"Your library has been saved to the selected location.": "Uw bibliotheek is opgeslagen op de geselecteerde locatie.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} boeken toegevoegd, {{updated}} boeken bijgewerkt.",
|
||||
"Operation failed": "Bewerking mislukt"
|
||||
"Operation failed": "Bewerking mislukt",
|
||||
"Loading library...": "Bibliotheek laden...",
|
||||
"{{count}} books refreshed_one": "{{count}} boek vernieuwd",
|
||||
"{{count}} books refreshed_other": "{{count}} boeken vernieuwd",
|
||||
"Failed to refresh metadata": "Metadata vernieuwen mislukt",
|
||||
"Refresh Metadata": "Metadata vernieuwen"
|
||||
}
|
||||
|
||||
@@ -1121,5 +1121,12 @@
|
||||
"Restore completed successfully!": "Przywracanie ukończone!",
|
||||
"Your library has been saved to the selected location.": "Biblioteka została zapisana w wybranej lokalizacji.",
|
||||
"{{added}} books added, {{updated}} books updated.": "Dodano {{added}} książek, zaktualizowano {{updated}} książek.",
|
||||
"Operation failed": "Operacja nie powiodła się"
|
||||
"Operation failed": "Operacja nie powiodła się",
|
||||
"Loading library...": "Wczytywanie biblioteki...",
|
||||
"{{count}} books refreshed_one": "Odświeżono {{count}} książkę",
|
||||
"{{count}} books refreshed_few": "Odświeżono {{count}} książki",
|
||||
"{{count}} books refreshed_many": "Odświeżono {{count}} książek",
|
||||
"{{count}} books refreshed_other": "Odświeżono {{count}} książek",
|
||||
"Failed to refresh metadata": "Nie udało się odświeżyć metadanych",
|
||||
"Refresh Metadata": "Odśwież metadane"
|
||||
}
|
||||
|
||||
@@ -1109,5 +1109,11 @@
|
||||
"Restore completed successfully!": "Restauração concluída com sucesso!",
|
||||
"Your library has been saved to the selected location.": "Sua biblioteca foi salva no local selecionado.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} livros adicionados, {{updated}} livros atualizados.",
|
||||
"Operation failed": "Operação falhou"
|
||||
"Operation failed": "Operação falhou",
|
||||
"Loading library...": "Carregando biblioteca...",
|
||||
"{{count}} books refreshed_one": "{{count}} livro atualizado",
|
||||
"{{count}} books refreshed_many": "{{count}} livros atualizados",
|
||||
"{{count}} books refreshed_other": "{{count}} livros atualizados",
|
||||
"Failed to refresh metadata": "Falha ao atualizar metadados",
|
||||
"Refresh Metadata": "Atualizar metadados"
|
||||
}
|
||||
|
||||
@@ -1121,5 +1121,12 @@
|
||||
"Restore completed successfully!": "Восстановление завершено!",
|
||||
"Your library has been saved to the selected location.": "Ваша библиотека сохранена в выбранном месте.",
|
||||
"{{added}} books added, {{updated}} books updated.": "Добавлено {{added}} книг, обновлено {{updated}} книг.",
|
||||
"Operation failed": "Операция не удалась"
|
||||
"Operation failed": "Операция не удалась",
|
||||
"Loading library...": "Загрузка библиотеки...",
|
||||
"{{count}} books refreshed_one": "Обновлена {{count}} книга",
|
||||
"{{count}} books refreshed_few": "Обновлено {{count}} книги",
|
||||
"{{count}} books refreshed_many": "Обновлено {{count}} книг",
|
||||
"{{count}} books refreshed_other": "Обновлено {{count}} книг",
|
||||
"Failed to refresh metadata": "Не удалось обновить метаданные",
|
||||
"Refresh Metadata": "Обновить метаданные"
|
||||
}
|
||||
|
||||
@@ -1097,5 +1097,10 @@
|
||||
"Restore completed successfully!": "ප්රතිසාධනය සාර්ථකව සම්පූර්ණයි!",
|
||||
"Your library has been saved to the selected location.": "ඔබේ පුස්තකාලය තෝරාගත් ස්ථානයේ සුරැකිණි.",
|
||||
"{{added}} books added, {{updated}} books updated.": "පොත් {{added}}ක් එකතු විය, {{updated}}ක් යාවත්කාලීන විය.",
|
||||
"Operation failed": "මෙහෙයුම අසාර්ථකයි"
|
||||
"Operation failed": "මෙහෙයුම අසාර්ථකයි",
|
||||
"Loading library...": "පුස්තකාලය පූරණය වෙමින්...",
|
||||
"{{count}} books refreshed_one": "පොත් {{count}}ක් යාවත්කාලීන විය",
|
||||
"{{count}} books refreshed_other": "පොත් {{count}}ක් යාවත්කාලීන විය",
|
||||
"Failed to refresh metadata": "පාරදත්ත යාවත්කාලීන කිරීම අසාර්ථකයි",
|
||||
"Refresh Metadata": "පාරදත්ත යාවත්කාලීන කරන්න"
|
||||
}
|
||||
|
||||
@@ -1121,5 +1121,12 @@
|
||||
"Restore completed successfully!": "Obnovitev uspešno zaključena!",
|
||||
"Your library has been saved to the selected location.": "Vaša knjižnica je shranjena na izbrani lokaciji.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} knjig dodanih, {{updated}} knjig posodobljenih.",
|
||||
"Operation failed": "Operacija ni uspela"
|
||||
"Operation failed": "Operacija ni uspela",
|
||||
"Loading library...": "Nalaganje knjižnice...",
|
||||
"{{count}} books refreshed_one": "Osvežena {{count}} knjiga",
|
||||
"{{count}} books refreshed_two": "Osveženi {{count}} knjigi",
|
||||
"{{count}} books refreshed_few": "Osvežene {{count}} knjige",
|
||||
"{{count}} books refreshed_other": "Osveženih {{count}} knjig",
|
||||
"Failed to refresh metadata": "Osveževanje metapodatkov ni uspelo",
|
||||
"Refresh Metadata": "Osveži metapodatke"
|
||||
}
|
||||
|
||||
@@ -1097,5 +1097,10 @@
|
||||
"Restore completed successfully!": "Återställningen slutförd!",
|
||||
"Your library has been saved to the selected location.": "Ditt bibliotek har sparats på den valda platsen.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} böcker tillagda, {{updated}} böcker uppdaterade.",
|
||||
"Operation failed": "Åtgärden misslyckades"
|
||||
"Operation failed": "Åtgärden misslyckades",
|
||||
"Loading library...": "Laddar bibliotek...",
|
||||
"{{count}} books refreshed_one": "{{count}} bok uppdaterad",
|
||||
"{{count}} books refreshed_other": "{{count}} böcker uppdaterade",
|
||||
"Failed to refresh metadata": "Kunde inte uppdatera metadata",
|
||||
"Refresh Metadata": "Uppdatera metadata"
|
||||
}
|
||||
|
||||
@@ -1097,5 +1097,10 @@
|
||||
"Restore completed successfully!": "மீட்டமைப்பு வெற்றிகரமாக முடிந்தது!",
|
||||
"Your library has been saved to the selected location.": "உங்கள் நூலகம் தேர்ந்தெடுக்கப்பட்ட இடத்தில் சேமிக்கப்பட்டது.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} புத்தகங்கள் சேர்க்கப்பட்டன, {{updated}} புத்தகங்கள் புதுப்பிக்கப்பட்டன.",
|
||||
"Operation failed": "செயல்பாடு தோல்வி"
|
||||
"Operation failed": "செயல்பாடு தோல்வி",
|
||||
"Loading library...": "நூலகம் ஏற்றப்படுகிறது...",
|
||||
"{{count}} books refreshed_one": "{{count}} புத்தகம் புதுப்பிக்கப்பட்டது",
|
||||
"{{count}} books refreshed_other": "{{count}} புத்தகங்கள் புதுப்பிக்கப்பட்டன",
|
||||
"Failed to refresh metadata": "மெட்டாடேட்டா புதுப்பிப்பு தோல்வி",
|
||||
"Refresh Metadata": "மெட்டாடேட்டா புதுப்பிக்கவும்"
|
||||
}
|
||||
|
||||
@@ -1085,5 +1085,9 @@
|
||||
"Restore completed successfully!": "กู้คืนสำเร็จ!",
|
||||
"Your library has been saved to the selected location.": "ห้องสมุดของคุณถูกบันทึกไปยังตำแหน่งที่เลือก",
|
||||
"{{added}} books added, {{updated}} books updated.": "เพิ่ม {{added}} เล่ม, อัปเดต {{updated}} เล่ม",
|
||||
"Operation failed": "การดำเนินการล้มเหลว"
|
||||
"Operation failed": "การดำเนินการล้มเหลว",
|
||||
"Loading library...": "กำลังโหลดห้องสมุด...",
|
||||
"{{count}} books refreshed_other": "รีเฟรชแล้ว {{count}} เล่ม",
|
||||
"Failed to refresh metadata": "รีเฟรชข้อมูลเมตาล้มเหลว",
|
||||
"Refresh Metadata": "รีเฟรชข้อมูลเมตา"
|
||||
}
|
||||
|
||||
@@ -1097,5 +1097,10 @@
|
||||
"Restore completed successfully!": "Geri yükleme başarıyla tamamlandı!",
|
||||
"Your library has been saved to the selected location.": "Kütüphaneniz seçilen konuma kaydedildi.",
|
||||
"{{added}} books added, {{updated}} books updated.": "{{added}} kitap eklendi, {{updated}} kitap güncellendi.",
|
||||
"Operation failed": "İşlem başarısız"
|
||||
"Operation failed": "İşlem başarısız",
|
||||
"Loading library...": "Kütüphane yükleniyor...",
|
||||
"{{count}} books refreshed_one": "{{count}} kitap yenilendi",
|
||||
"{{count}} books refreshed_other": "{{count}} kitap yenilendi",
|
||||
"Failed to refresh metadata": "Meta veri yenileme başarısız",
|
||||
"Refresh Metadata": "Meta Verileri Yenile"
|
||||
}
|
||||
|
||||
@@ -1121,5 +1121,12 @@
|
||||
"Restore completed successfully!": "Відновлення завершено!",
|
||||
"Your library has been saved to the selected location.": "Вашу бібліотеку збережено у вибраному місці.",
|
||||
"{{added}} books added, {{updated}} books updated.": "Додано {{added}} книг, оновлено {{updated}} книг.",
|
||||
"Operation failed": "Операція не вдалася"
|
||||
"Operation failed": "Операція не вдалася",
|
||||
"Loading library...": "Завантаження бібліотеки...",
|
||||
"{{count}} books refreshed_one": "Оновлено {{count}} книгу",
|
||||
"{{count}} books refreshed_few": "Оновлено {{count}} книги",
|
||||
"{{count}} books refreshed_many": "Оновлено {{count}} книг",
|
||||
"{{count}} books refreshed_other": "Оновлено {{count}} книг",
|
||||
"Failed to refresh metadata": "Не вдалося оновити метадані",
|
||||
"Refresh Metadata": "Оновити метадані"
|
||||
}
|
||||
|
||||
@@ -1085,5 +1085,9 @@
|
||||
"Restore completed successfully!": "Khôi phục thành công!",
|
||||
"Your library has been saved to the selected location.": "Thư viện của bạn đã được lưu tại vị trí đã chọn.",
|
||||
"{{added}} books added, {{updated}} books updated.": "Đã thêm {{added}} sách, cập nhật {{updated}} sách.",
|
||||
"Operation failed": "Thao tác thất bại"
|
||||
"Operation failed": "Thao tác thất bại",
|
||||
"Loading library...": "Đang tải thư viện...",
|
||||
"{{count}} books refreshed_other": "Đã làm mới {{count}} sách",
|
||||
"Failed to refresh metadata": "Không thể làm mới siêu dữ liệu",
|
||||
"Refresh Metadata": "Làm mới siêu dữ liệu"
|
||||
}
|
||||
|
||||
@@ -1085,5 +1085,9 @@
|
||||
"Restore completed successfully!": "恢复成功!",
|
||||
"Your library has been saved to the selected location.": "您的书库已保存到所选位置。",
|
||||
"{{added}} books added, {{updated}} books updated.": "新增 {{added}} 本书,更新 {{updated}} 本书。",
|
||||
"Operation failed": "操作失败"
|
||||
"Operation failed": "操作失败",
|
||||
"Loading library...": "正在加载书库...",
|
||||
"{{count}} books refreshed_other": "已刷新 {{count}} 本书",
|
||||
"Failed to refresh metadata": "刷新元数据失败",
|
||||
"Refresh Metadata": "刷新元数据"
|
||||
}
|
||||
|
||||
@@ -1085,5 +1085,9 @@
|
||||
"Restore completed successfully!": "還原成功!",
|
||||
"Your library has been saved to the selected location.": "您的書庫已儲存至所選位置。",
|
||||
"{{added}} books added, {{updated}} books updated.": "新增 {{added}} 本書,更新 {{updated}} 本書。",
|
||||
"Operation failed": "操作失敗"
|
||||
"Operation failed": "操作失敗",
|
||||
"Loading library...": "正在載入書庫...",
|
||||
"{{count}} books refreshed_other": "已重新整理 {{count}} 本書",
|
||||
"Failed to refresh metadata": "重新整理中繼資料失敗",
|
||||
"Refresh Metadata": "重新整理中繼資料"
|
||||
}
|
||||
|
||||
@@ -213,4 +213,32 @@ export function bookTests(
|
||||
expect(loaded.progress).toEqual([10, 200]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Refresh metadata', () => {
|
||||
it('should refresh metadata for a single book', async () => {
|
||||
const service = getService();
|
||||
const books: Book[] = [];
|
||||
const book = await service.importBook(await getBookFile('sample-alice.epub'), books);
|
||||
expect(book).not.toBeNull();
|
||||
|
||||
// Clear metadata to simulate a book imported before metadata parsing was added
|
||||
book!.metadata = undefined;
|
||||
book!.primaryLanguage = undefined;
|
||||
|
||||
const result = await service.refreshBookMetadata(book!);
|
||||
expect(result).toBe(true);
|
||||
expect(book!.metadata).toBeDefined();
|
||||
});
|
||||
|
||||
it('should not update updatedAt', async () => {
|
||||
const service = getService();
|
||||
const books: Book[] = [];
|
||||
const book = await service.importBook(await getBookFile('sample-alice.epub'), books);
|
||||
expect(book).not.toBeNull();
|
||||
|
||||
const oldUpdatedAt = book!.updatedAt;
|
||||
await service.refreshBookMetadata(book!);
|
||||
expect(book!.updatedAt).toBe(oldUpdatedAt);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -67,7 +67,9 @@ const SettingsMenu: React.FC<SettingsMenuProps> = ({ onPullLibrary, setIsDropdow
|
||||
);
|
||||
const iconSize = useResponsiveSize(16);
|
||||
|
||||
const { isSyncing } = useLibraryStore();
|
||||
const [isRefreshingMetadata, setIsRefreshingMetadata] = useState(false);
|
||||
const [refreshMetadataProgress, setRefreshMetadataProgress] = useState('');
|
||||
const { isSyncing, setLibrary } = useLibraryStore();
|
||||
const { stats, hasActiveTransfers, setIsTransferQueueOpen } = useTransferQueue();
|
||||
|
||||
const openTransferQueue = () => {
|
||||
@@ -189,6 +191,42 @@ const SettingsMenu: React.FC<SettingsMenuProps> = ({ onPullLibrary, setIsDropdow
|
||||
setBackupDialogVisible(true);
|
||||
};
|
||||
|
||||
const handleRefreshMetadata = async () => {
|
||||
if (!appService || isRefreshingMetadata) return;
|
||||
setIsRefreshingMetadata(true);
|
||||
setRefreshMetadataProgress(_('Loading library...'));
|
||||
try {
|
||||
const books = await appService.loadLibraryBooks();
|
||||
const activeBooks = books.filter((b) => !b.deletedAt);
|
||||
let refreshed = 0;
|
||||
for (let i = 0; i < activeBooks.length; i++) {
|
||||
setRefreshMetadataProgress(`${i + 1} / ${activeBooks.length}`);
|
||||
try {
|
||||
if (await appService.refreshBookMetadata(activeBooks[i]!)) {
|
||||
refreshed++;
|
||||
}
|
||||
} catch {
|
||||
// Skip books whose files can't be opened
|
||||
}
|
||||
}
|
||||
setLibrary(books);
|
||||
await appService.saveLibraryBooks(books);
|
||||
setRefreshMetadataProgress(_('{{count}} books refreshed', { count: refreshed }));
|
||||
onPullLibrary(true);
|
||||
setTimeout(() => {
|
||||
setIsRefreshingMetadata(false);
|
||||
setRefreshMetadataProgress('');
|
||||
}, 2000);
|
||||
} catch (error) {
|
||||
console.error('Failed to refresh metadata:', error);
|
||||
setRefreshMetadataProgress(_('Failed to refresh metadata'));
|
||||
setTimeout(() => {
|
||||
setIsRefreshingMetadata(false);
|
||||
setRefreshMetadataProgress('');
|
||||
}, 2000);
|
||||
}
|
||||
};
|
||||
|
||||
const openSettingsDialog = () => {
|
||||
setIsDropdownOpen?.(false);
|
||||
setSettingsDialogOpen(true);
|
||||
@@ -381,6 +419,12 @@ const SettingsMenu: React.FC<SettingsMenuProps> = ({ onPullLibrary, setIsDropdow
|
||||
<MenuItem label={_('Change Data Location')} onClick={handleSetRootDir} />
|
||||
)}
|
||||
<MenuItem label={_('Backup & Restore')} onClick={handleBackupRestore} />
|
||||
<MenuItem
|
||||
label={_('Refresh Metadata')}
|
||||
description={refreshMetadataProgress}
|
||||
onClick={handleRefreshMetadata}
|
||||
disabled={isRefreshingMetadata}
|
||||
/>
|
||||
{appService?.isAndroidApp && appService?.distChannel !== 'playstore' && (
|
||||
<MenuItem
|
||||
label={_('Save Book Cover')}
|
||||
|
||||
@@ -301,6 +301,10 @@ export abstract class BaseAppService implements AppService {
|
||||
);
|
||||
}
|
||||
|
||||
async refreshBookMetadata(book: Book): Promise<boolean> {
|
||||
return BookSvc.refreshBookMetadata(this.fs, book);
|
||||
}
|
||||
|
||||
async isBookAvailable(book: Book): Promise<boolean> {
|
||||
return BookSvc.isBookAvailable(this.fs, book);
|
||||
}
|
||||
|
||||
@@ -527,6 +527,37 @@ export async function fetchBookDetails(
|
||||
return bookDoc.metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh metadata for a single book by re-opening and re-parsing its file.
|
||||
* Updates series info, language, and other metadata fields without modifying
|
||||
* user-edited titles or reading progress.
|
||||
* Returns true if the metadata was successfully refreshed.
|
||||
*/
|
||||
export async function refreshBookMetadata(fs: FileSystem, book: Book): Promise<boolean> {
|
||||
const { file } = await loadBookContent(fs, book);
|
||||
const { book: bookDoc } = await new DocumentLoader(file).open();
|
||||
if (!bookDoc) return false;
|
||||
|
||||
book.metadata = bookDoc.metadata;
|
||||
book.metaHash = getMetadataHash(bookDoc.metadata);
|
||||
const primaryLanguage = getPrimaryLanguage(bookDoc.metadata.language);
|
||||
if (primaryLanguage) {
|
||||
book.primaryLanguage = primaryLanguage;
|
||||
}
|
||||
|
||||
// Update series info from metadata
|
||||
if (book.metadata?.belongsTo?.series) {
|
||||
const belongsTo = book.metadata.belongsTo.series;
|
||||
const series = Array.isArray(belongsTo) ? belongsTo[0] : belongsTo;
|
||||
if (series) {
|
||||
book.metadata.series = formatTitle(series.name);
|
||||
book.metadata.seriesIndex = parseFloat(series.position || '0');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function exportBook(
|
||||
fs: FileSystem,
|
||||
book: Book,
|
||||
|
||||
@@ -133,6 +133,7 @@ export interface AppService {
|
||||
overwrite?: boolean,
|
||||
transient?: boolean,
|
||||
): Promise<Book | null>;
|
||||
refreshBookMetadata(book: Book): Promise<boolean>;
|
||||
deleteBook(book: Book, deleteAction: DeleteAction): Promise<void>;
|
||||
uploadBook(book: Book, onProgress?: ProgressHandler): Promise<void>;
|
||||
downloadBook(
|
||||
|
||||
Reference in New Issue
Block a user