feat: added option to delete only the local copy of a book (#1773)

* feat: added button to delete the local copy of a book

* refactor: merged deletion api and messages

* fix: included translations for deletion messages

* updated translations

* refactor the deletion dropdown menu

---------

Co-authored-by: Huang Xin <chrox.huang@gmail.com>
This commit is contained in:
arutonee1
2025-08-11 04:38:34 -04:00
committed by GitHub
parent 5671460618
commit 4298213ce4
27 changed files with 364 additions and 157 deletions
@@ -425,7 +425,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "احفظ واوصل لمجموعة قراءتك كاملة بـ 5 جيجابايت تخزين سحابي آمن.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "احفظ واوصل لمجموعة قراءتك كاملة بـ 20 جيجابايت تخزين سحابي آمن.",
"Deleted cloud backup of the book: {{title}}": "تم حذف النسخة الاحتياطية السحابية للكتاب: {{title}}",
"Failed to delete cloud backup of the book": "فشل في حذف النسخة الاحتياطية السحابية للكتاب",
"Are you sure to delete the cloud backup of the selected book?": "هل أنت متأكد من حذف النسخة الاحتياطية السحابية للكتاب المحدد؟",
"What's New in Readest": "ما الجديد في Readest",
"Enter book title": "أدخل عنوان الكتاب",
@@ -481,5 +480,12 @@
"Show Reading Progress": "إظهار تقدم القراءة",
"Reading Progress Style": "نمط تقدم القراءة",
"Page Number": "رقم الصفحة",
"Percentage": "النسبة المئوية"
"Percentage": "النسبة المئوية",
"Deleted local copy of the book: {{title}}": "تم حذف النسخة المحلية للكتاب: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "فشل في حذف النسخة الاحتياطية السحابية للكتاب: {{title}}",
"Failed to delete local copy of the book: {{title}}": "فشل في حذف النسخة المحلية للكتاب: {{title}}",
"Are you sure to delete the local copy of the selected book?": "هل أنت متأكد من حذف النسخة المحلية للكتاب المحدد؟",
"Remove from Cloud & Device": "إزالة من السحابة والجهاز",
"Remove from Cloud Only": "إزالة من السحابة فقط",
"Remove from Device Only": "إزالة من الجهاز فقط"
}
@@ -409,7 +409,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Speichern und greifen Sie sicher auf Ihre gesamte Lesekollektion mit bis zu 5 GB Cloud-Speicher zu.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Speichern und greifen Sie sicher auf Ihre gesamte Lesekollektion mit bis zu 20 GB Cloud-Speicher zu.",
"Deleted cloud backup of the book: {{title}}": "Gelöschte Cloud-Sicherung des Buches: {{title}}",
"Failed to delete cloud backup of the book": "Fehler beim Löschen der Cloud-Sicherung des Buches",
"Are you sure to delete the cloud backup of the selected book?": "Sind Sie sicher, dass Sie die Cloud-Sicherung des ausgewählten Buches löschen möchten?",
"What's New in Readest": "Was gibt es Neues in Readest",
"Enter book title": "Buchtitel eingeben",
@@ -465,5 +464,12 @@
"Show Reading Progress": "Lesefortschritt anzeigen",
"Reading Progress Style": "Lesefortschritt-Stil",
"Page Number": "Seitenzahl",
"Percentage": "Prozentsatz"
"Percentage": "Prozentsatz",
"Deleted local copy of the book: {{title}}": "Gelöschte lokale Kopie des Buches: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Fehler beim Löschen der Cloud-Sicherung des Buches: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Fehler beim Löschen der lokalen Kopie des Buches: {{title}}",
"Are you sure to delete the local copy of the selected book?": "Sind Sie sicher, dass Sie die lokale Kopie des ausgewählten Buches löschen möchten?",
"Remove from Cloud & Device": "Aus Cloud & Gerät entfernen",
"Remove from Cloud Only": "Nur aus der Cloud entfernen",
"Remove from Device Only": "Nur vom Gerät entfernen"
}
@@ -409,7 +409,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Αποθηκεύστε και αποκτήστε πρόσβαση στη συλλογή ανάγνωσης με έως 5 GB ασφαλή cloud αποθήκευση.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Αποθηκεύστε και αποκτήστε πρόσβαση στη συλλογή ανάγνωσης με έως 20 GB ασφαλή cloud αποθήκευση.",
"Deleted cloud backup of the book: {{title}}": "Διαγράφηκε το αντίγραφο ασφαλείας του βιβλίου: {{title}}",
"Failed to delete cloud backup of the book": "Αποτυχία διαγραφής του αντιγράφου ασφαλείας του βιβλίου",
"Are you sure to delete the cloud backup of the selected book?": "Είστε σίγουροι ότι θέλετε να διαγράψετε το αντίγραφο ασφαλείας του επιλεγμένου βιβλίου;",
"What's New in Readest": "Τι νέο υπάρχει στο Readest",
"Enter book title": "Εισάγετε τίτλο βιβλίου",
@@ -465,5 +464,12 @@
"Show Reading Progress": "Εμφάνιση προόδου ανάγνωσης",
"Reading Progress Style": "Στυλ προόδου ανάγνωσης",
"Page Number": "Αριθμός σελίδας",
"Percentage": "Ποσοστό"
"Percentage": "Ποσοστό",
"Deleted local copy of the book: {{title}}": "Διαγράφηκε το τοπικό αντίγραφο του βιβλίου: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Αποτυχία διαγραφής του αντιγράφου ασφαλείας του βιβλίου: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Αποτυχία διαγραφής της τοπικής αντιγράφου του βιβλίου: {{title}}",
"Are you sure to delete the local copy of the selected book?": "Είστε σίγουροι ότι θέλετε να διαγράψετε την τοπική αντιγραφή του επιλεγμένου βιβλίου;",
"Remove from Cloud & Device": "Αφαίρεση από το Cloud & Device",
"Remove from Cloud Only": "Αφαίρεση μόνο από το Cloud",
"Remove from Device Only": "Αφαίρεση μόνο από το Device"
}
@@ -413,7 +413,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Almacena y accede de forma segura a toda tu colección de lectura con hasta 5 GB de almacenamiento en la nube.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Almacena y accede de forma segura a toda tu colección de lectura con hasta 20 GB de almacenamiento en la nube.",
"Deleted cloud backup of the book: {{title}}": "Respaldo en la nube del libro eliminado: {{title}}",
"Failed to delete cloud backup of the book": "Fallo al eliminar el respaldo en la nube del libro",
"Are you sure to delete the cloud backup of the selected book?": "¿Estás seguro de que deseas eliminar el respaldo en la nube del libro seleccionado?",
"What's New in Readest": "¿Qué hay de nuevo en Readest",
"Enter book title": "Ingresa el título del libro",
@@ -469,5 +468,12 @@
"Reading Progress Style": "Estilo de progreso de lectura",
"Percentage": "Porcentaje",
"Show Reading Progress": "Mostrar progreso de lectura",
"Page Number": "Número de página"
"Page Number": "Número de página",
"Deleted local copy of the book: {{title}}": "Se eliminó la copia local del libro: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Error al eliminar la copia de seguridad en la nube del libro: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Error al eliminar la copia local del libro: {{title}}",
"Are you sure to delete the local copy of the selected book?": "¿Está seguro de que desea eliminar la copia local del libro seleccionado?",
"Remove from Cloud & Device": "Eliminar de la nube y del dispositivo",
"Remove from Cloud Only": "Eliminar solo de la nube",
"Remove from Device Only": "Eliminar solo del dispositivo"
}
@@ -412,7 +412,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Stockez et accédez en sécurité à votre collection de lecture avec jusqu'à 5 GB de stockage cloud.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Stockez et accédez en sécurité à votre collection de lecture avec jusqu'à 20 GB de stockage cloud.",
"Deleted cloud backup of the book: {{title}}": "Suppression de la sauvegarde cloud du livre : {{title}}",
"Failed to delete cloud backup of the book": "Échec de la suppression de la sauvegarde cloud du livre",
"Are you sure to delete the cloud backup of the selected book?": "Êtes-vous sûr de vouloir supprimer la sauvegarde cloud du livre sélectionné ?",
"Don't have an account? Sign up": "Vous n'avez pas de compte ? Inscrivez-vous",
"What's New in Readest": "Quoi de neuf dans Readest",
@@ -469,5 +468,12 @@
"Show Reading Progress": "Afficher la progression",
"Reading Progress Style": "Style de progression",
"Page Number": "Numéro de page",
"Percentage": "Pourcentage"
"Percentage": "Pourcentage",
"Deleted local copy of the book: {{title}}": "Suppression de la copie locale du livre : {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Échec de la suppression de la sauvegarde cloud du livre : {{title}}",
"Failed to delete local copy of the book: {{title}}": "Échec de la suppression de la copie locale du livre : {{title}}",
"Are you sure to delete the local copy of the selected book?": "Êtes-vous sûr de vouloir supprimer la copie locale du livre sélectionné ?",
"Remove from Cloud & Device": "Supprimer du Cloud & de l'appareil",
"Remove from Cloud Only": "Supprimer uniquement du Cloud",
"Remove from Device Only": "Supprimer uniquement de l'appareil"
}
@@ -409,7 +409,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "5 GB सुरक्षित क्लाउड स्टोरेज के साथ अपना संपूर्ण पठन संग्रह संग्रहीत करें।",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "20 GB सुरक्षित क्लाउड स्टोरेज के साथ अपना संपूर्ण पठन संग्रह संग्रहीत करें।",
"Deleted cloud backup of the book: {{title}}": "पुस्तक का क्लाउड बैकअप हटाया गया: {{title}}",
"Failed to delete cloud backup of the book": "पुस्तक का क्लाउड बैकअप हटाने में विफल",
"Are you sure to delete the cloud backup of the selected book?": "क्या आप सुनिश्चित हैं कि आप चयनित पुस्तक का क्लाउड बैकअप हटाना चाहते हैं?",
"What's New in Readest": "Readest में नया क्या है",
"Enter book title": "पुस्तक का शीर्षक दर्ज करें",
@@ -465,5 +464,12 @@
"Show Reading Progress": "पढ़ने की प्रगति दिखाएं",
"Reading Progress Style": "पढ़ने की प्रगति शैली",
"Page Number": "पृष्ठ संख्या",
"Percentage": "प्रतिशत"
"Percentage": "प्रतिशत",
"Deleted local copy of the book: {{title}}": "पुस्तक की स्थानीय प्रति हटाई गई: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "पुस्तक का क्लाउड बैकअप हटाने में विफल: {{title}}",
"Failed to delete local copy of the book: {{title}}": "पुस्तक की स्थानीय प्रति हटाने में विफल: {{title}}",
"Are you sure to delete the local copy of the selected book?": "क्या आप सुनिश्चित हैं कि आप चयनित पुस्तक की स्थानीय प्रति हटाना चाहते हैं?",
"Remove from Cloud & Device": "क्लाउड और डिवाइस से हटाएँ",
"Remove from Cloud Only": "केवल क्लाउड से हटाएँ",
"Remove from Device Only": "केवल डिवाइस से हटाएँ"
}
@@ -405,7 +405,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Simpan dan akses koleksi bacaan lengkap dengan aman menggunakan penyimpanan cloud 5 GB.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Simpan dan akses koleksi bacaan lengkap dengan aman menggunakan penyimpanan cloud 20 GB.",
"Deleted cloud backup of the book: {{title}}": "Cadangan cloud buku dihapus: {{title}}",
"Failed to delete cloud backup of the book": "Cadangan cloud buku gagal dihapus",
"Are you sure to delete the cloud backup of the selected book?": "Apakah Anda yakin ingin menghapus cadangan cloud dari buku yang dipilih?",
"What's New in Readest": "Yang Baru di Readest",
"Enter book title": "Masukkan judul buku",
@@ -461,5 +460,13 @@
"Show Reading Progress": "Perlihatkan Progres Membaca",
"Reading Progress Style": "Gaya Progres Membaca",
"Page Number": "Nomor Halaman",
"Percentage": "Persentase"
"Percentage": "Persentase",
"Deleted local copy of the book: {{title}}": "Salinan lokal buku dihapus: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Gagal menghapus cadangan cloud buku: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Gagal menghapus salinan lokal buku: {{title}}",
"Are you sure to delete the local copy of the selected book?": "Apakah Anda yakin ingin menghapus salinan lokal buku yang dipilih?",
"Remove from Cloud & Device": "Hapus dari Cloud & Perangkat",
"Remove from Cloud Only": "Hapus dari Cloud Saja",
"Remove from Device Only": "Hapus dari Perangkat Saja"
}
@@ -413,7 +413,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Archivia e accedi in sicurezza alla tua intera collezione di lettura con fino a 5 GB di storage cloud.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Archivia e accedi in sicurezza alla tua intera collezione di lettura con fino a 20 GB di storage cloud.",
"Deleted cloud backup of the book: {{title}}": "Backup cloud del libro eliminato: {{title}}",
"Failed to delete cloud backup of the book": "Impossibile eliminare il backup cloud del libro",
"Are you sure to delete the cloud backup of the selected book?": "Sei sicuro di voler eliminare il backup cloud del libro selezionato?",
"What's New in Readest": "Novità in Readest",
"Enter book title": "Inserisci il titolo del libro",
@@ -469,5 +468,12 @@
"Show Reading Progress": "Mostra Progresso Lettura",
"Reading Progress Style": "Stile di Progresso Lettura",
"Page Number": "Numero di Pagina",
"Percentage": "Percentuale"
"Percentage": "Percentuale",
"Deleted local copy of the book: {{title}}": "Copie locale del libro eliminata: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Impossibile eliminare il backup cloud del libro: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Impossibile eliminare la copia locale del libro: {{title}}",
"Are you sure to delete the local copy of the selected book?": "Sei sicuro di voler eliminare la copia locale del libro selezionato?",
"Remove from Cloud & Device": "Rimuovi da Cloud & Dispositivo",
"Remove from Cloud Only": "Rimuovi solo da Cloud",
"Remove from Device Only": "Rimuovi solo da Dispositivo"
}
@@ -405,7 +405,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "最大5GBの安全なクラウドストレージで読書コレクション全体を保存・アクセス。",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "最大20GBの安全なクラウドストレージで読書コレクション全体を保存・アクセス。",
"Deleted cloud backup of the book: {{title}}": "書籍のクラウドバックアップを削除しました:{{title}}",
"Failed to delete cloud backup of the book": "書籍のクラウドバックアップを削除できませんでした",
"Are you sure to delete the cloud backup of the selected book?": "選択した書籍のクラウドバックアップを削除してもよろしいですか?",
"What's New in Readest": "Readestの新機能",
"Enter book title": "本のタイトルを入力",
@@ -461,5 +460,12 @@
"Show Reading Progress": "読書進捗を表示",
"Reading Progress Style": "読書進捗スタイル",
"Page Number": "ページ番号",
"Percentage": "パーセンテージ"
"Percentage": "パーセンテージ",
"Deleted local copy of the book: {{title}}": "書籍のローカルコピーを削除しました:{{title}}",
"Failed to delete cloud backup of the book: {{title}}": "書籍のクラウドバックアップの削除に失敗しました:{{title}}",
"Failed to delete local copy of the book: {{title}}": "書籍のローカルコピーの削除に失敗しました:{{title}}",
"Are you sure to delete the local copy of the selected book?": "選択した書籍のローカルコピーを削除してもよろしいですか?",
"Remove from Cloud & Device": "クラウドとデバイスから削除",
"Remove from Cloud Only": "クラウドからのみ削除",
"Remove from Device Only": "デバイスからのみ削除"
}
@@ -405,7 +405,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "최대 5GB의 안전한 클라우드 저장소로 전체 독서 컬렉션을 저장하고 액세스하세요.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "최대 20GB의 안전한 클라우드 저장소로 전체 독서 컬렉션을 저장하고 액세스하세요.",
"Deleted cloud backup of the book: {{title}}": "책의 클라우드 백업이 삭제됨: {{title}}",
"Failed to delete cloud backup of the book": "책의 클라우드 백업을 삭제하지 못했습니다.",
"Are you sure to delete the cloud backup of the selected book?": "선택한 책의 클라우드 백업을 삭제하시겠습니까?",
"What's New in Readest": "Readest의 새로운 기능",
"Enter book title": "도서 제목 입력",
@@ -461,5 +460,12 @@
"Show Reading Progress": "읽기 진행 상황 표시",
"Reading Progress Style": "읽기 진행 상황 스타일",
"Page Number": "페이지 번호",
"Percentage": "백분율"
"Percentage": "백분율",
"Deleted local copy of the book: {{title}}": "책의 로컬 사본이 삭제됨: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "책의 클라우드 백업 삭제에 실패했습니다: {{title}}",
"Failed to delete local copy of the book: {{title}}": "책의 로컬 사본 삭제에 실패했습니다: {{title}}",
"Are you sure to delete the local copy of the selected book?": "선택한 책의 로컬 사본을 삭제하시겠습니까?",
"Remove from Cloud & Device": "클라우드 및 장치에서 제거",
"Remove from Cloud Only": "클라우드에서만 제거",
"Remove from Device Only": "장치에서만 제거"
}
@@ -409,7 +409,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Sla je hele leesverzameling veilig op en benader deze met tot 5 GB cloudopslag.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Sla je hele leesverzameling veilig op en benader deze met tot 20 GB cloudopslag.",
"Deleted cloud backup of the book: {{title}}": "Verwijderde cloudback-up van het boek: {{title}}",
"Failed to delete cloud backup of the book": "Verwijderen van cloudback-up van het boek is mislukt.",
"Are you sure to delete the cloud backup of the selected book?": "Weet je zeker dat je de cloudback-up van het geselecteerde boek wilt verwijderen?",
"What's New in Readest": "Wat is er nieuw in Readest",
"Enter book title": "Voer boektitel in",
@@ -465,5 +464,12 @@
"Show Reading Progress": "Leesvoortgang weergeven",
"Reading Progress Style": "Stijl van leesvoortgang",
"Page Number": "Pagina nummer",
"Percentage": "Percentage"
"Percentage": "Percentage",
"Deleted local copy of the book: {{title}}": "Verwijderde lokale kopie van het boek: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Verwijderen van cloudback-up van het boek is mislukt: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Verwijderen van lokale kopie van het boek is mislukt: {{title}}",
"Are you sure to delete the local copy of the selected book?": "Weet je zeker dat je de lokale kopie van het geselecteerde boek wilt verwijderen?",
"Remove from Cloud & Device": "Verwijder uit Cloud & Apparaat",
"Remove from Cloud Only": "Verwijder alleen uit Cloud",
"Remove from Device Only": "Verwijder alleen uit Apparaat"
}
@@ -417,7 +417,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Bezpiecznie przechowuj i uzyskuj dostęp do całej kolekcji czytelniczej z do 5 GB pamięci w chmurze.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Bezpiecznie przechowuj i uzyskuj dostęp do całej kolekcji czytelniczej z do 20 GB pamięci w chmurze.",
"Deleted cloud backup of the book: {{title}}": "Usunięto kopię zapasową książki w chmurze: {{title}}",
"Failed to delete cloud backup of the book": "Nie udało się usunąć kopii zapasowej książki w chmurze.",
"Are you sure to delete the cloud backup of the selected book?": "Czy na pewno chcesz usunąć kopię zapasową chmury wybranej książki?",
"What's New in Readest": "Co nowego w Readest",
"Enter book title": "Wprowadź tytuł książki",
@@ -473,5 +472,12 @@
"Show Reading Progress": "Pokazuj postęp czytania",
"Reading Progress Style": "Styl postępu czytania",
"Page Number": "Numer strony",
"Percentage": "Procent"
"Percentage": "Procent",
"Deleted local copy of the book: {{title}}": "Usunięto lokalną kopię książki: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Nie udało się usunąć kopii zapasowej w chmurze książki: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Nie udało się usunąć lokalnej kopii książki: {{title}}",
"Are you sure to delete the local copy of the selected book?": "Czy na pewno chcesz usunąć lokalną kopię wybranej książki?",
"Remove from Cloud & Device": "Usuń z chmury i urządzenia",
"Remove from Cloud Only": "Usuń tylko z chmury",
"Remove from Device Only": "Usuń tylko z urządzenia"
}
@@ -413,7 +413,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Armazene e acesse com segurança sua coleção completa de leitura com até 5 GB de armazenamento na nuvem.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Armazene e acesse com segurança sua coleção completa de leitura com até 20 GB de armazenamento na nuvem.",
"Deleted cloud backup of the book: {{title}}": "Backup na nuvem do livro excluído: {{title}}",
"Failed to delete cloud backup of the book": "Falha ao excluir o backup na nuvem do livro.",
"Are you sure to delete the cloud backup of the selected book?": "Tem certeza de que deseja excluir o backup na nuvem do livro selecionado?",
"What's New in Readest": "Novidades no Readest",
"Enter book title": "Digite o título do livro",
@@ -469,5 +468,12 @@
"Show Reading Progress": "Mostrar Progresso de Leitura",
"Reading Progress Style": "Estilo de Progresso de Leitura",
"Page Number": "Número da Página",
"Percentage": "Porcentagem"
"Percentage": "Porcentagem",
"Deleted local copy of the book: {{title}}": " cópia local do livro excluída: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Falha ao excluir backup na nuvem do livro: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Falha ao excluir cópia local do livro: {{title}}",
"Are you sure to delete the local copy of the selected book?": "Tem certeza de que deseja excluir a cópia local do livro selecionado?",
"Remove from Cloud & Device": "Remover da Nuvem & Dispositivo",
"Remove from Cloud Only": "Remover apenas da Nuvem",
"Remove from Device Only": "Remover apenas do Dispositivo"
}
@@ -417,7 +417,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Безопасно храните и получайте доступ ко всей коллекции чтения с до 5 ГБ облачного хранилища.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Безопасно храните и получайте доступ ко всей коллекции чтения с до 20 ГБ облачного хранилища.",
"Deleted cloud backup of the book: {{title}}": "Удалено облачное резервное копирование книги: {{title}}",
"Failed to delete cloud backup of the book": "Не удалось удалить облачное резервное копирование книги.",
"Are you sure to delete the cloud backup of the selected book?": "Вы уверены, что хотите удалить облачное резервное копирование выбранной книги?",
"What's New in Readest": "Что нового в Readest",
"Enter book title": "Введите название книги",
@@ -473,5 +472,12 @@
"Show Reading Progress": "Показать прогресс чтения",
"Reading Progress Style": "Стиль прогресса чтения",
"Page Number": "Номер страницы",
"Percentage": "Процент"
"Percentage": "Процент",
"Deleted local copy of the book: {{title}}": "Удалена локальная копия книги: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Не удалось удалить резервную копию книги в облаке: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Не удалось удалить локальную копию книги: {{title}}",
"Are you sure to delete the local copy of the selected book?": "Вы уверены, что хотите удалить локальную копию выбранной книги?",
"Remove from Cloud & Device": "Удалить из облака и устройства",
"Remove from Cloud Only": "Удалить только из облака",
"Remove from Device Only": "Удалить только с устройства"
}
@@ -114,7 +114,6 @@
"Book deleted: {{title}}": "ลบหนังสือแล้ว: {{title}}",
"Failed to delete book: {{title}}": "ไม่สามารถลบหนังสือ: {{title}}",
"Deleted cloud backup of the book: {{title}}": "ลบสำรองบนคลาวด์แล้ว: {{title}}",
"Failed to delete cloud backup of the book": "ไม่สามารถลบสำรองบนคลาวด์",
"Welcome to your library. You can import your books here and read them anytime.": "ยินดีต้อนรับสู่คลังหนังสือ คุณสามารถนำเข้าหนังสือและอ่านได้ตลอดเวลา",
"Copied to notebook": "คัดลอกไปยังสมุดบันทึก",
"No annotations to export": "ไม่มีบันทึกให้ส่งออก",
@@ -461,5 +460,12 @@
"Show Reading Progress": "แสดงความคืบหน้าในการอ่าน",
"Reading Progress Style": "สไตล์ความก้าวหน้าในการอ่าน",
"Page Number": "หมายเลขหน้า",
"Percentage": "เปอร์เซ็นต์"
"Percentage": "เปอร์เซ็นต์",
"Deleted local copy of the book: {{title}}": "ลบสำเนาในเครื่องแล้ว: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "ไม่สามารถลบสำเนาสำรองในคลาวด์ของหนังสือ: {{title}}",
"Failed to delete local copy of the book: {{title}}": "ไม่สามารถลบสำเนาในเครื่องของหนังสือ: {{title}}",
"Are you sure to delete the local copy of the selected book?": "คุณแน่ใจหรือไม่ว่าต้องการลบสำเนาในเครื่องของหนังสือที่เลือก?",
"Remove from Cloud & Device": "ลบจากคลาวด์และอุปกรณ์",
"Remove from Cloud Only": "ลบจากคลาวด์เท่านั้น",
"Remove from Device Only": "ลบจากอุปกรณ์เท่านั้น"
}
@@ -409,7 +409,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Tüm okuma koleksiyonunuzu 5 GB'a kadar güvenli bulut depolamayla saklayın ve erişin.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Tüm okuma koleksiyonunuzu 20 GB'a kadar güvenli bulut depolamayla saklayın ve erişin.",
"Deleted cloud backup of the book: {{title}}": "Kitabın bulut yedeği silindi: {{title}}",
"Failed to delete cloud backup of the book": "Kitabın bulut yedeğini silme işlemi başarısız oldu.",
"Are you sure to delete the cloud backup of the selected book?": "Seçilen kitabın bulut yedeğini silmek istediğinize emin misiniz?",
"What's New in Readest": "Readest'te Neler Yeni",
"Enter book title": "Kitap başlığını girin",
@@ -465,5 +464,12 @@
"Show Reading Progress": "Okuma İlerlemesini Göster",
"Reading Progress Style": "Okuma İlerlemesi Stili",
"Page Number": "Sayfa Numarası",
"Percentage": "Yüzde"
"Percentage": "Yüzde",
"Deleted local copy of the book: {{title}}": "Kitabın yerel kopyası silindi: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Kitabın bulut yedeğini silme başarısız oldu: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Kitabın yerel kopyasını silme başarısız oldu: {{title}}",
"Are you sure to delete the local copy of the selected book?": "Seçilen kitabın yerel kopyasını silmek istediğinize emin misiniz?",
"Remove from Cloud & Device": "Buluttan ve Cihazdan Kaldır",
"Remove from Cloud Only": "Sadece Buluttan Kaldır",
"Remove from Device Only": "Sadece Cihazdan Kaldır"
}
@@ -417,7 +417,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Безпечно зберігайте та отримуйте доступ до всієї колекції читання з до 5 ГБ хмарного сховища.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Безпечно зберігайте та отримуйте доступ до всієї колекції читання з до 20 ГБ хмарного сховища.",
"Deleted cloud backup of the book: {{title}}": "Видалено хмарну резервну копію книги: {{title}}",
"Failed to delete cloud backup of the book": "Не вдалося видалити хмарну резервну копію.",
"Are you sure to delete the cloud backup of the selected book?": "Ви впевнені, що хочете видалити хмарну резервну копію вибраної книги?",
"What's New in Readest": "Що нового в Readest",
"Enter book title": "Введіть назву книги",
@@ -473,5 +472,12 @@
"Show Reading Progress": "Показати прогрес читання",
"Reading Progress Style": "Стиль прогресу читання",
"Page Number": "Номер сторінки",
"Percentage": "Процент"
"Percentage": "Процент",
"Deleted local copy of the book: {{title}}": "Видалено локальну копію книги: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Не вдалося видалити резервну копію книги в хмарі: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Не вдалося видалити локальну копію книги: {{title}}",
"Are you sure to delete the local copy of the selected book?": "Ви впевнені, що хочете видалити локальну копію вибраної книги?",
"Remove from Cloud & Device": "Видалити з хмари та пристрою",
"Remove from Cloud Only": "Видалити тільки з хмари",
"Remove from Device Only": "Видалити тільки з пристрою"
}
@@ -405,7 +405,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "Lưu trữ và truy cập an toàn toàn bộ bộ sưu tập đọc với tới 5 GB lưu trữ đám mây.",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "Lưu trữ và truy cập an toàn toàn bộ bộ sưu tập đọc với tới 20 GB lưu trữ đám mây.",
"Deleted cloud backup of the book: {{title}}": "Đã xóa bản sao lưu đám mây của sách: {{title}}",
"Failed to delete cloud backup of the book": "Không thể xóa bản sao lưu đám mây của sách.",
"Are you sure to delete the cloud backup of the selected book?": "Bạn có chắc chắn muốn xóa bản sao lưu đám mây của sách đã chọn không?",
"What's New in Readest": "Những gì mới trong Readest",
"Enter book title": "Nhập tiêu đề sách",
@@ -461,5 +460,12 @@
"Show Reading Progress": "Hiển thị tiến độ đọc",
"Reading Progress Style": "Phong cách tiến độ đọc",
"Page Number": "Số trang",
"Percentage": "Phần trăm"
"Percentage": "Phần trăm",
"Deleted local copy of the book: {{title}}": "Đã xóa bản sao cục bộ của sách: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "Không thể xóa bản sao lưu đám mây của sách: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Không thể xóa bản sao cục bộ của sách: {{title}}",
"Are you sure to delete the local copy of the selected book?": "Bạn có chắc chắn muốn xóa bản sao cục bộ của cuốn sách đã chọn không?",
"Remove from Cloud & Device": "Xóa khỏi Đám mây & Thiết bị",
"Remove from Cloud Only": "Xóa chỉ khỏi Đám mây",
"Remove from Device Only": "Xóa chỉ khỏi Thiết bị"
}
@@ -405,7 +405,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "使用多达 5GB 的安全云存储保存和访问您的整个阅读收藏。",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "使用多达 20GB 的安全云存储保存和访问您的整个阅读收藏。",
"Deleted cloud backup of the book: {{title}}": "已删除书籍云备份:{{title}}",
"Failed to delete cloud backup of the book": "无法删除书籍云备份。",
"Are you sure to delete the cloud backup of the selected book?": "您确定要删除所选书籍的云备份吗?",
"What's New in Readest": "Readest 更新功能",
"Enter book title": "输入书名",
@@ -461,5 +460,12 @@
"Show Reading Progress": "显示阅读进度",
"Reading Progress Style": "阅读进度样式",
"Page Number": "页码",
"Percentage": "百分比"
"Percentage": "百分比",
"Deleted local copy of the book: {{title}}": "已删除书籍本地副本:{{title}}",
"Failed to delete cloud backup of the book: {{title}}": "未能删除书籍云备份:{{title}}",
"Failed to delete local copy of the book: {{title}}": "未能删除书籍本地副本:{{title}}",
"Are you sure to delete the local copy of the selected book?": "您确定要删除所选书籍的本地副本吗?",
"Remove from Cloud & Device": "从云端和设备中移除",
"Remove from Cloud Only": "仅从云端移除",
"Remove from Device Only": "仅从设备中移除"
}
@@ -405,7 +405,6 @@
"Securely store and access your entire reading collection with up to 5 GB of cloud storage.": "使用多達 5GB 的安全雲端儲存保存和存取您的整個閱讀收藏。",
"Securely store and access your entire reading collection with up to 20 GB of cloud storage.": "使用多達 20GB 的安全雲端儲存保存和存取您的整個閱讀收藏。",
"Deleted cloud backup of the book: {{title}}": "已刪除書籍的雲端備份:{{title}}",
"Failed to delete cloud backup of the book": "無法刪除書籍的雲端備份。",
"Are you sure to delete the cloud backup of the selected book?": "您確定要刪除所選書籍的雲端備份嗎?",
"What's New in Readest": "Readest 更新功能",
"Enter book title": "輸入書名",
@@ -461,5 +460,12 @@
"Show Reading Progress": "顯示閱讀進度",
"Reading Progress Style": "閱讀進度樣式",
"Page Number": "頁碼",
"Percentage": "百分比"
"Percentage": "百分比",
"Deleted local copy of the book: {{title}}": "已刪除書籍的本地副本:{{title}}",
"Failed to delete cloud backup of the book: {{title}}": "未能刪除書籍的雲端備份:{{title}}",
"Failed to delete local copy of the book: {{title}}": "未能刪除書籍的本地副本:{{title}}",
"Are you sure to delete the local copy of the selected book?": "您確定要刪除所選書籍的本地副本嗎?",
"Remove from Cloud & Device": "從雲端和設備中移除",
"Remove from Cloud Only": "僅從雲端移除",
"Remove from Device Only": "僅從設備中移除"
}
+35 -51
View File
@@ -8,7 +8,7 @@ import { OverlayScrollbarsComponent, OverlayScrollbarsComponentRef } from 'overl
import 'overlayscrollbars/overlayscrollbars.css';
import { Book } from '@/types/book';
import { AppService } from '@/types/system';
import { AppService, DeleteAction } from '@/types/system';
import { navigateToLogin, navigateToReader } from '@/utils/nav';
import {
formatAuthors,
@@ -543,53 +543,36 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP
[appService],
);
const handleBookDelete = async (book: Book) => {
try {
await appService?.deleteBook(book, !!book.uploadedAt, true);
await updateBook(envConfig, book);
pushLibrary();
eventDispatcher.dispatch('toast', {
type: 'info',
timeout: 2000,
message: _('Book deleted: {{title}}', {
title: book.title,
}),
});
return true;
} catch {
eventDispatcher.dispatch('toast', {
message: _('Failed to delete book: {{title}}', {
title: book.title,
}),
type: 'error',
});
return false;
}
};
const handleBookDeleteCloudBackup = async (book: Book) => {
try {
await appService?.deleteBook(book, !!book.uploadedAt, false);
await updateBook(envConfig, book);
pushLibrary();
eventDispatcher.dispatch('toast', {
type: 'info',
timeout: 2000,
message: _('Deleted cloud backup of the book: {{title}}', {
title: book.title,
}),
});
return true;
} catch (e) {
console.error(e);
eventDispatcher.dispatch('toast', {
type: 'error',
message: _('Failed to delete cloud backup of the book', {
title: book.title,
}),
});
return false;
}
const handleBookDelete = (deleteAction: DeleteAction) => {
return async (book: Book) => {
const deletionMessages = {
both: _('Book deleted: {{title}}', { title: book.title }),
cloud: _('Deleted cloud backup of the book: {{title}}', { title: book.title }),
local: _('Deleted local copy of the book: {{title}}', { title: book.title }),
};
const deletionFailMessages = {
both: _('Failed to delete book: {{title}}', { title: book.title }),
cloud: _('Failed to delete cloud backup of the book: {{title}}', { title: book.title }),
local: _('Failed to delete local copy of the book: {{title}}', { title: book.title }),
};
try {
await appService?.deleteBook(book, deleteAction);
await updateBook(envConfig, book);
pushLibrary();
eventDispatcher.dispatch('toast', {
type: 'info',
timeout: 2000,
message: deletionMessages[deleteAction],
});
return true;
} catch {
eventDispatcher.dispatch('toast', {
message: deletionFailMessages[deleteAction],
type: 'error',
});
return false;
}
};
};
const handleUpdateMetadata = async (book: Book, metadata: BookMetadata) => {
@@ -731,7 +714,7 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP
handleImportBooks={handleImportBooks}
handleBookUpload={handleBookUpload}
handleBookDownload={handleBookDownload}
handleBookDelete={handleBookDelete}
handleBookDelete={handleBookDelete('both')}
handleSetSelectMode={handleSetSelectMode}
handleShowDetailsBook={handleShowDetailsBook}
booksTransferProgress={booksTransferProgress}
@@ -763,8 +746,9 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP
onClose={() => setShowDetailsBook(null)}
handleBookUpload={handleBookUpload}
handleBookDownload={handleBookDownload}
handleBookDelete={handleBookDelete}
handleBookDeleteCloudBackup={handleBookDeleteCloudBackup}
handleBookDelete={handleBookDelete('both')}
handleBookDeleteCloudBackup={handleBookDelete('cloud')}
handleBookDeleteLocalCopy={handleBookDelete('local')}
handleBookMetadataUpdate={handleUpdateMetadata}
/>
)}
+48 -3
View File
@@ -1,15 +1,54 @@
import clsx from 'clsx';
import React, { useState, isValidElement, ReactElement } from 'react';
import React, { useState, isValidElement, ReactElement, ReactNode } from 'react';
import MenuItem from './MenuItem';
interface DropdownProps {
className?: string;
menuClassName?: string;
buttonClassName?: string;
toggleButton: React.ReactNode;
children: ReactElement<{ setIsDropdownOpen: (isOpen: boolean) => void; menuClassName?: string }>;
children: ReactElement<{
setIsDropdownOpen: (isOpen: boolean) => void;
menuClassName?: string;
children: ReactNode;
}>;
onToggle?: (isOpen: boolean) => void;
}
const enhanceMenuItems = (
children: ReactNode,
setIsDropdownOpen: (isOpen: boolean) => void,
): ReactNode => {
const processNode = (node: ReactNode): ReactNode => {
if (!isValidElement(node)) {
return node;
}
const element = node as ReactElement;
const isMenuItem =
element.type === MenuItem ||
(typeof element.type === 'function' && element.type.name === 'MenuItem');
const clonedElement = isMenuItem
? React.cloneElement(element, {
setIsDropdownOpen,
...element.props,
})
: element;
if (clonedElement.props?.children) {
return React.cloneElement(clonedElement, {
...clonedElement.props,
children: React.Children.map(clonedElement.props.children, processNode),
});
}
return clonedElement;
};
return React.Children.map(children, processNode);
};
const Dropdown: React.FC<DropdownProps> = ({
className,
menuClassName,
@@ -32,7 +71,13 @@ const Dropdown: React.FC<DropdownProps> = ({
};
const childrenWithToggle = isValidElement(children)
? React.cloneElement(children, { setIsDropdownOpen, menuClassName })
? React.cloneElement(children, {
...(typeof children.type !== 'string' && {
setIsDropdownOpen,
menuClassName,
}),
children: enhanceMenuItems(children.props?.children, setIsDropdownOpen),
})
: children;
return (
+11 -1
View File
@@ -12,9 +12,11 @@ interface MenuItemProps {
shortcut?: string;
disabled?: boolean;
noIcon?: boolean;
transient?: boolean; // For transient items the dropdown will close on click
Icon?: React.ReactNode | IconType;
children?: React.ReactNode;
onClick?: () => void;
setIsDropdownOpen?: (isOpen: boolean) => void;
}
const MenuItem: React.FC<MenuItemProps> = ({
@@ -26,9 +28,11 @@ const MenuItem: React.FC<MenuItemProps> = ({
shortcut,
disabled,
noIcon = false,
transient = false,
Icon,
children,
onClick,
setIsDropdownOpen,
}) => {
const iconSize = useResponsiveSize(16);
const menuButton = (
@@ -38,8 +42,14 @@ const MenuItem: React.FC<MenuItemProps> = ({
disabled && 'btn-disabled text-gray-400',
buttonClass,
)}
aria-label={label}
data-tip={tooltip ? tooltip : ''}
onClick={onClick}
onClick={() => {
onClick?.();
if (transient) {
setIsDropdownOpen?.(false);
}
}}
disabled={disabled}
>
<div className='flex w-full items-center justify-between'>
@@ -7,6 +7,7 @@ import { useEnv } from '@/context/EnvContext';
import { useSettingsStore } from '@/store/settingsStore';
import { useTranslation } from '@/hooks/useTranslation';
import { useMetadataEdit } from './useMetadataEdit';
import { DeleteAction } from '@/types/system';
import Alert from '@/components/Alert';
import Dialog from '@/components/Dialog';
import Spinner from '@/components/Spinner';
@@ -22,9 +23,16 @@ interface BookDetailModalProps {
handleBookUpload?: (book: Book) => void;
handleBookDelete?: (book: Book) => void;
handleBookDeleteCloudBackup?: (book: Book) => void;
handleBookDeleteLocalCopy?: (book: Book) => void;
handleBookMetadataUpdate?: (book: Book, updatedMetadata: BookMetadata) => void;
}
interface DeleteConfig {
title: string;
message: string;
handler?: (book: Book) => void;
}
const BookDetailModal: React.FC<BookDetailModalProps> = ({
book,
isOpen,
@@ -33,12 +41,12 @@ const BookDetailModal: React.FC<BookDetailModalProps> = ({
handleBookUpload,
handleBookDelete,
handleBookDeleteCloudBackup,
handleBookDeleteLocalCopy,
handleBookMetadataUpdate,
}) => {
const _ = useTranslation();
const [loading, setLoading] = useState(false);
const [showDeleteAlert, setShowDeleteAlert] = useState(false);
const [showDeleteCloudBackupAlert, setShowDeleteCloudBackupAlert] = useState(false);
const [activeDeleteAction, setActiveDeleteAction] = useState<DeleteAction | null>(null);
const [editMode, setEditMode] = useState(false);
const [bookMeta, setBookMeta] = useState<BookMetadata | null>(null);
const [fileSize, setFileSize] = useState<number | null>(null);
@@ -64,6 +72,24 @@ const BookDetailModal: React.FC<BookDetailModalProps> = ({
resetToOriginal,
} = useMetadataEdit(bookMeta);
const deleteConfigs: Record<DeleteAction, DeleteConfig> = {
both: {
title: _('Confirm Deletion'),
message: _('Are you sure to delete the selected book?'),
handler: handleBookDelete,
},
cloud: {
title: _('Confirm Deletion'),
message: _('Are you sure to delete the cloud backup of the selected book?'),
handler: handleBookDeleteCloudBackup,
},
local: {
title: _('Confirm Deletion'),
message: _('Are you sure to delete the local copy of the selected book?'),
handler: handleBookDeleteLocalCopy,
},
};
useEffect(() => {
const loadingTimeout = setTimeout(() => setLoading(true), 300);
const fetchBookDetails = async () => {
@@ -85,6 +111,7 @@ const BookDetailModal: React.FC<BookDetailModalProps> = ({
const handleClose = () => {
setBookMeta(null);
setEditMode(false);
setActiveDeleteAction(null);
onClose();
};
@@ -105,30 +132,29 @@ const BookDetailModal: React.FC<BookDetailModalProps> = ({
}
};
const handleDelete = () => {
setShowDeleteAlert(true);
const handleDeleteAction = (action: DeleteAction) => {
setActiveDeleteAction(action);
};
const handleDeleteCloudBackup = () => {
setShowDeleteCloudBackupAlert(true);
};
const confirmDeleteAction = async () => {
if (!activeDeleteAction) return;
const confirmDelete = async () => {
const config = deleteConfigs[activeDeleteAction];
handleClose();
setShowDeleteAlert(false);
if (handleBookDelete) {
handleBookDelete(book);
if (config.handler) {
config.handler(book);
}
};
const confirmDeleteCloudBackup = async () => {
handleClose();
setShowDeleteCloudBackupAlert(false);
if (handleBookDeleteCloudBackup) {
handleBookDeleteCloudBackup(book);
}
const cancelDeleteAction = () => {
setActiveDeleteAction(null);
};
const handleDelete = () => handleDeleteAction('both');
const handleDeleteCloudBackup = () => handleDeleteAction('cloud');
const handleDeleteLocalCopy = () => handleDeleteAction('local');
const handleRedownload = async () => {
handleClose();
if (handleBookDownload) {
@@ -143,6 +169,8 @@ const BookDetailModal: React.FC<BookDetailModalProps> = ({
}
};
const currentDeleteConfig = activeDeleteAction ? deleteConfigs[activeDeleteAction] : null;
if (!bookMeta)
return (
loading && (
@@ -194,6 +222,7 @@ const BookDetailModal: React.FC<BookDetailModalProps> = ({
onDeleteCloudBackup={
handleBookDeleteCloudBackup ? handleDeleteCloudBackup : undefined
}
onDeleteLocalCopy={handleBookDeleteLocalCopy ? handleDeleteLocalCopy : undefined}
onDownload={handleBookDownload ? handleRedownload : undefined}
onUpload={handleBookUpload ? handleReupload : undefined}
/>
@@ -209,8 +238,7 @@ const BookDetailModal: React.FC<BookDetailModalProps> = ({
onClose={handleCloseSourceSelection}
/>
{/* Delete Alerts */}
{showDeleteAlert && (
{activeDeleteAction && currentDeleteConfig && (
<div
className={clsx(
'fixed bottom-0 left-0 right-0 z-50 flex justify-center',
@@ -218,25 +246,10 @@ const BookDetailModal: React.FC<BookDetailModalProps> = ({
)}
>
<Alert
title={_('Confirm Deletion')}
message={_('Are you sure to delete the selected book?')}
onCancel={() => setShowDeleteAlert(false)}
onConfirm={confirmDelete}
/>
</div>
)}
{showDeleteCloudBackupAlert && (
<div
className={clsx(
'fixed bottom-0 left-0 right-0 z-50 flex justify-center',
'pb-[calc(env(safe-area-inset-bottom)+16px)]',
)}
>
<Alert
title={_('Confirm Deletion')}
message={_('Are you sure to delete the cloud backup of the selected book?')}
onCancel={() => setShowDeleteCloudBackupAlert(false)}
onConfirm={confirmDeleteCloudBackup}
title={currentDeleteConfig.title}
message={currentDeleteConfig.message}
onCancel={cancelDeleteAction}
onConfirm={confirmDeleteAction}
/>
</div>
)}
@@ -1,9 +1,9 @@
import clsx from 'clsx';
import React from 'react';
import {
MdOutlineDelete,
MdOutlineCloudDownload,
MdOutlineCloudUpload,
MdOutlineCloudOff,
MdOutlineDelete,
MdOutlineEdit,
} from 'react-icons/md';
@@ -19,6 +19,8 @@ import {
formatTitle,
} from '@/utils/book';
import BookCover from '@/components/BookCover';
import Dropdown from '../Dropdown';
import MenuItem from '../MenuItem';
interface BookDetailViewProps {
book: Book;
@@ -27,6 +29,7 @@ interface BookDetailViewProps {
onEdit?: () => void;
onDelete?: () => void;
onDeleteCloudBackup?: () => void;
onDeleteLocalCopy?: () => void;
onDownload?: () => void;
onUpload?: () => void;
}
@@ -38,6 +41,7 @@ const BookDetailView: React.FC<BookDetailViewProps> = ({
onEdit,
onDelete,
onDeleteCloudBackup,
onDeleteLocalCopy,
onDownload,
onUpload,
}) => {
@@ -65,14 +69,40 @@ const BookDetailView: React.FC<BookDetailViewProps> = ({
</button>
)}
{onDelete && (
<button onClick={onDelete}>
<MdOutlineDelete className='fill-red-500' />
</button>
)}
{book.uploadedAt && onDeleteCloudBackup && (
<button onClick={onDeleteCloudBackup}>
<MdOutlineCloudOff className='fill-red-500' />
</button>
<Dropdown
className='dropdown-bottom flex justify-center'
buttonClassName='btn btn-ghost h-8 min-h-8 w-8 p-0'
toggleButton={<MdOutlineDelete className='fill-red-500' />}
>
<div
tabIndex={0}
className={clsx(
'delete-menu dropdown-content dropdown-center no-triangle',
'border-base-200 z-20 mt-1 max-w-[90vw] shadow-2xl',
)}
>
<MenuItem
noIcon
transient
label={_('Remove from Cloud & Device')}
onClick={onDelete}
/>
<MenuItem
noIcon
transient
label={_('Remove from Cloud Only')}
onClick={onDeleteCloudBackup}
disabled={!book.uploadedAt}
/>
<MenuItem
noIcon
transient
label={_('Remove from Device Only')}
onClick={onDeleteLocalCopy}
disabled={!book.downloadedAt}
/>
</div>
</Dropdown>
)}
{book.uploadedAt && onDownload && (
<button onClick={onDownload}>
+16 -13
View File
@@ -1,7 +1,7 @@
import { AppPlatform, AppService, OsPlatform } from '@/types/system';
import { SystemSettings } from '@/types/settings';
import { FileSystem, BaseDir } from '@/types/system';
import { FileSystem, BaseDir, DeleteAction } from '@/types/system';
import { Book, BookConfig, BookContent, BookFormat, ViewSettings } from '@/types/book';
import {
getDir,
@@ -273,16 +273,27 @@ export abstract class BaseAppService implements AppService {
}
}
async deleteBook(book: Book, includingUploaded = false, includingLocal = true): Promise<void> {
if (includingLocal) {
const localDeleteFps = [getLocalBookFilename(book), getCoverFilename(book)];
async deleteBook(book: Book, deleteAction: DeleteAction): Promise<void> {
console.log('Deleting book with action:', deleteAction, book.title);
if (deleteAction === 'local' || deleteAction === 'both') {
const localDeleteFps =
deleteAction === 'local'
? [getLocalBookFilename(book)]
: [getLocalBookFilename(book), getCoverFilename(book)];
for (const fp of localDeleteFps) {
if (await this.fs.exists(fp, 'Books')) {
await this.fs.removeFile(fp, 'Books');
}
}
if (deleteAction === 'local') {
book.downloadedAt = null;
} else {
book.deletedAt = Date.now();
book.downloadedAt = null;
book.coverDownloadedAt = null;
}
}
if (includingUploaded) {
if (deleteAction === 'cloud' || deleteAction === 'both') {
const fps = [getRemoteBookFilename(book), getCoverFilename(book)];
for (const fp of fps) {
console.log('Deleting uploaded file:', fp);
@@ -293,14 +304,6 @@ export abstract class BaseAppService implements AppService {
console.log('Failed to delete uploaded file:', error);
}
}
}
if (includingLocal) {
book.deletedAt = Date.now();
book.downloadedAt = null;
book.coverDownloadedAt = null;
}
if (includingUploaded) {
book.uploadedAt = null;
}
}
+2 -1
View File
@@ -6,6 +6,7 @@ import { ProgressHandler } from '@/utils/transfer';
export type AppPlatform = 'web' | 'tauri';
export type OsPlatform = 'android' | 'ios' | 'macos' | 'windows' | 'linux' | 'unknown';
export type BaseDir = 'Books' | 'Settings' | 'Data' | 'Log' | 'Cache' | 'None';
export type DeleteAction = 'cloud' | 'local' | 'both';
export interface FileSystem {
getURL(path: string): string;
@@ -57,7 +58,7 @@ export interface AppService {
overwrite?: boolean,
transient?: boolean,
): Promise<Book | null>;
deleteBook(book: Book, includingUploaded?: boolean, includingLocal?: boolean): Promise<void>;
deleteBook(book: Book, deleteAction: DeleteAction): Promise<void>;
uploadBook(book: Book, onProgress?: ProgressHandler): Promise<void>;
downloadBook(
book: Book,