forked from akai/readest
fix: resolve endless loading indicator (#2502)
This commit is contained in:
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "الوضع التلقائي",
|
||||
"Behavior": "السلوك",
|
||||
"Book": "الكتاب",
|
||||
"Book Cover": "غلاف الكتاب",
|
||||
"Bookmark": "علامة مرجعية",
|
||||
"Cancel": "إلغاء",
|
||||
"Chapter": "الفصل",
|
||||
@@ -672,5 +671,6 @@
|
||||
"Update email": "تحديث البريد الإلكتروني",
|
||||
"Current email": "البريد الإلكتروني الحالي",
|
||||
"Update Email": "تحديث البريد الإلكتروني",
|
||||
"All": "الكل"
|
||||
"All": "الكل",
|
||||
"Unable to open book": "غير قادر على فتح الكتاب"
|
||||
}
|
||||
|
||||
@@ -302,7 +302,6 @@
|
||||
"Link Color": "লিঙ্ক রঙ",
|
||||
"Preview": "প্রিভিউ",
|
||||
"Font & Layout": "ফন্ট ও লেআউট",
|
||||
"Book Cover": "বইয়ের মলাট",
|
||||
"More Info": "আরো তথ্য",
|
||||
"Parallel Read": "সমান্তরাল পড়া",
|
||||
"Disable": "নিষ্ক্রিয়",
|
||||
@@ -656,5 +655,6 @@
|
||||
"Update email": "ইমেল আপডেট করুন",
|
||||
"Current email": "বর্তমান ইমেল",
|
||||
"Update Email": "ইমেল আপডেট করুন",
|
||||
"All": "সব"
|
||||
"All": "সব",
|
||||
"Unable to open book": "বই খুলতে অক্ষম"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "རང་འགུལ་བརྗོད་བྱ།",
|
||||
"Behavior": "བྱ་སྤྱོད།",
|
||||
"Book": "དཔེ་དེབ།",
|
||||
"Book Cover": "དཔེ་དེབ་ཀྱི་སྟོང་ངོས།",
|
||||
"Bookmark": "དཔེ་རྟགས།",
|
||||
"Cancel": "འདོར་བ།",
|
||||
"Chapter": "ལེའུ།",
|
||||
@@ -652,5 +651,6 @@
|
||||
"Update email": "ཡིག་འཕྲིན་གསར་བསྒྱུར།",
|
||||
"Current email": "མིག་སྔའི་ཡིག་འཕྲིན།",
|
||||
"Update Email": "ཡིག་འཕྲིན་གསར་བསྒྱུར།",
|
||||
"All": "ཆེན་མོ།"
|
||||
"All": "ཆེན་མོ།",
|
||||
"Unable to open book": "དེབ་ཀྱི་སྤྱོད་བྱས་མ་ཐུབ།"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "Automatischer Modus",
|
||||
"Behavior": "Verhalten",
|
||||
"Book": "Buch",
|
||||
"Book Cover": "Buchcover",
|
||||
"Bookmark": "Lesezeichen",
|
||||
"Cancel": "Abbrechen",
|
||||
"Chapter": "Kapitel",
|
||||
@@ -656,5 +655,6 @@
|
||||
"Update email": "E-Mail aktualisieren",
|
||||
"Current email": "Aktuelle E-Mail",
|
||||
"Update Email": "E-Mail aktualisieren",
|
||||
"All": "Alle"
|
||||
"All": "Alle",
|
||||
"Unable to open book": "Buch kann nicht geöffnet werden"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "Αυτόματη λειτουργία",
|
||||
"Behavior": "Συμπεριφορά",
|
||||
"Book": "Βιβλίο",
|
||||
"Book Cover": "Εξώφυλλο βιβλίου",
|
||||
"Bookmark": "Σελιδοδείκτης",
|
||||
"Cancel": "Ακύρωση",
|
||||
"Chapter": "Κεφάλαιο",
|
||||
@@ -656,5 +655,6 @@
|
||||
"Update email": "Ενημέρωση email",
|
||||
"Current email": "Τρέχον email",
|
||||
"Update Email": "Ενημέρωση email",
|
||||
"All": "Όλα"
|
||||
"All": "Όλα",
|
||||
"Unable to open book": "Αδύνατη η άνοιγμα του βιβλίου"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "Modo automático",
|
||||
"Behavior": "Comportamiento",
|
||||
"Book": "Libro",
|
||||
"Book Cover": "Portada del libro",
|
||||
"Bookmark": "Marcador",
|
||||
"Cancel": "Cancelar",
|
||||
"Chapter": "Capítulo",
|
||||
@@ -660,5 +659,6 @@
|
||||
"Update email": "Actualizar correo electrónico",
|
||||
"Current email": "Correo electrónico actual",
|
||||
"Update Email": "Actualizar correo electrónico",
|
||||
"All": "Todos"
|
||||
"All": "Todos",
|
||||
"Unable to open book": "No se puede abrir el libro"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "حالت خودکار",
|
||||
"Behavior": "رفتار",
|
||||
"Book": "کتاب",
|
||||
"Book Cover": "جلد کتاب",
|
||||
"Bookmark": "نشانک",
|
||||
"Cancel": "لغو",
|
||||
"Chapter": "فصل",
|
||||
@@ -656,5 +655,6 @@
|
||||
"Update email": "بهروزرسانی ایمیل",
|
||||
"Current email": "ایمیل فعلی",
|
||||
"Update Email": "بهروزرسانی ایمیل",
|
||||
"All": "همه"
|
||||
"All": "همه",
|
||||
"Unable to open book": "قادر به باز کردن کتاب نیست"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "Mode automatique",
|
||||
"Behavior": "Comportement",
|
||||
"Book": "Livre",
|
||||
"Book Cover": "Couverture du livre",
|
||||
"Bookmark": "Signet",
|
||||
"Cancel": "Annuler",
|
||||
"Chapter": "Chapitre",
|
||||
@@ -660,5 +659,6 @@
|
||||
"Update email": "Mettre à jour l’e-mail",
|
||||
"Current email": "E-mail actuel",
|
||||
"Update Email": "Mettre à jour l’e-mail",
|
||||
"All": "Tous"
|
||||
"All": "Tous",
|
||||
"Unable to open book": "Impossible d'ouvrir le livre"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "स्वचालित मोड",
|
||||
"Behavior": "व्यवहार",
|
||||
"Book": "पुस्तक",
|
||||
"Book Cover": "पुस्तक का कवर",
|
||||
"Bookmark": "बुकमार्क",
|
||||
"Cancel": "रद्द करें",
|
||||
"Chapter": "अध्याय",
|
||||
@@ -656,5 +655,6 @@
|
||||
"Update email": "ईमेल अपडेट करें",
|
||||
"Current email": "वर्तमान ईमेल",
|
||||
"Update Email": "ईमेल अपडेट करें",
|
||||
"All": "सभी"
|
||||
"All": "सभी",
|
||||
"Unable to open book": "पुस्तक खोलने में असमर्थ"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "Mode Otomatis",
|
||||
"Behavior": "Perilaku",
|
||||
"Book": "Buku",
|
||||
"Book Cover": "Sampul Buku",
|
||||
"Bookmark": "Penanda",
|
||||
"Cancel": "Batal",
|
||||
"Chapter": "Bab",
|
||||
@@ -652,5 +651,6 @@
|
||||
"Update email": "Perbarui email",
|
||||
"Current email": "Email saat ini",
|
||||
"Update Email": "Perbarui email",
|
||||
"All": "Semua"
|
||||
"All": "Semua",
|
||||
"Unable to open book": "Tidak dapat membuka buku"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "Modalità automatica",
|
||||
"Behavior": "Comportamento",
|
||||
"Book": "Libro",
|
||||
"Book Cover": "Copertina",
|
||||
"Bookmark": "Segnalibro",
|
||||
"Cancel": "Annulla",
|
||||
"Chapter": "Capitolo",
|
||||
@@ -660,5 +659,6 @@
|
||||
"Update email": "Aggiorna email",
|
||||
"Current email": "Email attuale",
|
||||
"Update Email": "Aggiorna email",
|
||||
"All": "Tutti"
|
||||
"All": "Tutti",
|
||||
"Unable to open book": "Impossibile aprire il libro"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "自動モード",
|
||||
"Behavior": "動作",
|
||||
"Book": "書籍",
|
||||
"Book Cover": "表紙",
|
||||
"Bookmark": "ブックマーク",
|
||||
"Cancel": "キャンセル",
|
||||
"Chapter": "章",
|
||||
@@ -652,5 +651,6 @@
|
||||
"Update email": "メールを更新",
|
||||
"Current email": "現在のメールアドレス",
|
||||
"Update Email": "メールを更新",
|
||||
"All": "すべて"
|
||||
"All": "すべて",
|
||||
"Unable to open book": "本を開くことができません"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "자동 모드",
|
||||
"Behavior": "동작",
|
||||
"Book": "책",
|
||||
"Book Cover": "책 표지",
|
||||
"Bookmark": "북마크",
|
||||
"Cancel": "취소",
|
||||
"Chapter": "챕터",
|
||||
@@ -652,5 +651,6 @@
|
||||
"Update email": "이메일 업데이트",
|
||||
"Current email": "현재 이메일",
|
||||
"Update Email": "이메일 업데이트",
|
||||
"All": "전체"
|
||||
"All": "전체",
|
||||
"Unable to open book": "책을 열 수 없습니다"
|
||||
}
|
||||
|
||||
@@ -196,7 +196,6 @@
|
||||
"Link Color": "Linkkleur",
|
||||
"Preview": "Voorbeeld",
|
||||
"Font & Layout": "Lettertype & opmaak",
|
||||
"Book Cover": "Boekomslag",
|
||||
"More Info": "Meer informatie",
|
||||
"Parallel Read": "Parallel lezen",
|
||||
"Export Annotations": "Annotaties exporteren",
|
||||
@@ -656,5 +655,6 @@
|
||||
"Update email": "E-mail bijwerken",
|
||||
"Current email": "Huidig e-mailadres",
|
||||
"Update Email": "E-mail bijwerken",
|
||||
"All": "Alles"
|
||||
"All": "Alles",
|
||||
"Unable to open book": "Kan boek niet openen"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "Tryb automatyczny",
|
||||
"Behavior": "Zachowanie",
|
||||
"Book": "Książka",
|
||||
"Book Cover": "Okładka książki",
|
||||
"Bookmark": "Zakładka",
|
||||
"Cancel": "Anuluj",
|
||||
"Chapter": "Rozdział",
|
||||
@@ -664,5 +663,6 @@
|
||||
"Update email": "Zaktualizuj e-mail",
|
||||
"Current email": "Obecny e-mail",
|
||||
"Update Email": "Zaktualizuj e-mail",
|
||||
"All": "Wszystkie"
|
||||
"All": "Wszystkie",
|
||||
"Unable to open book": "Nie można otworzyć książki"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "Modo Automático",
|
||||
"Behavior": "Comportamento",
|
||||
"Book": "Livro",
|
||||
"Book Cover": "Capa do Livro",
|
||||
"Bookmark": "Marcador",
|
||||
"Cancel": "Cancelar",
|
||||
"Chapter": "Capítulo",
|
||||
@@ -660,5 +659,6 @@
|
||||
"Update email": "Atualizar e-mail",
|
||||
"Current email": "E-mail atual",
|
||||
"Update Email": "Atualizar e-mail",
|
||||
"All": "Todos"
|
||||
"All": "Todos",
|
||||
"Unable to open book": "Não foi possível abrir o livro"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "Автоматический режим",
|
||||
"Behavior": "Поведение",
|
||||
"Book": "Книга",
|
||||
"Book Cover": "Обложка книги",
|
||||
"Bookmark": "Закладка",
|
||||
"Cancel": "Отмена",
|
||||
"Chapter": "Глава",
|
||||
@@ -664,5 +663,6 @@
|
||||
"Update email": "Обновить электронную почту",
|
||||
"Current email": "Текущий адрес электронной почты",
|
||||
"Update Email": "Обновить электронную почту",
|
||||
"All": "Все"
|
||||
"All": "Все",
|
||||
"Unable to open book": "Не удалось открыть книгу"
|
||||
}
|
||||
|
||||
@@ -302,7 +302,6 @@
|
||||
"Link Color": "සබැඳි වර්ණය",
|
||||
"Preview": "පෙර දසුන",
|
||||
"Font & Layout": "අකුරු සහ පිරිසැලසුම",
|
||||
"Book Cover": "පොත් ආවරණය",
|
||||
"More Info": "තවත් තොරතුරු",
|
||||
"Parallel Read": "සමාන්තර කියවීම",
|
||||
"Disable": "අබල කරන්න",
|
||||
@@ -656,5 +655,6 @@
|
||||
"Update email": "විද්යුත් තැපැල් යාවත්කාලීන කරන්න",
|
||||
"Current email": "වත්මන් විද්යුත් තැපැල්",
|
||||
"Update Email": "විද්යුත් තැපැල් යාවත්කාලීන කරන්න",
|
||||
"All": "සියල්ල"
|
||||
"All": "සියල්ල",
|
||||
"Unable to open book": "පොත විවෘත කිරීමට නොහැක"
|
||||
}
|
||||
|
||||
@@ -241,7 +241,6 @@
|
||||
"{{count}} pages left in chapter_other": "{{count}} sidor kvar i kapitlet",
|
||||
"On {{current}} of {{total}} page": "På {{current}} av {{total}} sidor",
|
||||
"Section Title": "Sektionstitel",
|
||||
"Book Cover": "Bokomslag",
|
||||
"More Info": "Mer info",
|
||||
"Parallel Read": "Parallell läsning",
|
||||
"Disable": "Inaktivera",
|
||||
@@ -656,5 +655,6 @@
|
||||
"Update email": "Uppdatera e-post",
|
||||
"Current email": "Nuvarande e-post",
|
||||
"Update Email": "Uppdatera e-post",
|
||||
"All": "Alla"
|
||||
"All": "Alla",
|
||||
"Unable to open book": "Kunde inte öppna bok"
|
||||
}
|
||||
|
||||
@@ -302,7 +302,6 @@
|
||||
"Link Color": "இணைப்பு நிறம்",
|
||||
"Preview": "முன்னோட்டம்",
|
||||
"Font & Layout": "எழுத்துரு மற்றும் அமைப்பு",
|
||||
"Book Cover": "புத்தக அட்டை",
|
||||
"More Info": "மேலும் தகவல்",
|
||||
"Parallel Read": "இணை வாசிப்பு",
|
||||
"Disable": "முடக்கவும்",
|
||||
@@ -656,5 +655,6 @@
|
||||
"Update email": "மின்னஞ்சல் புதுப்பிக்கவும்",
|
||||
"Current email": "தற்போதைய மின்னஞ்சல்",
|
||||
"Update Email": "மின்னஞ்சல் புதுப்பிக்கவும்",
|
||||
"All": "அனைத்து"
|
||||
"All": "அனைத்து",
|
||||
"Unable to open book": "புத்தகத்தைத் திறக்க முடியவில்லை"
|
||||
}
|
||||
|
||||
@@ -255,7 +255,6 @@
|
||||
"Link Color": "สีลิงก์",
|
||||
"Preview": "ดูตัวอย่าง",
|
||||
"Font & Layout": "ฟอนต์และเลย์เอาต์",
|
||||
"Book Cover": "ปกหนังสือ",
|
||||
"More Info": "ข้อมูลเพิ่มเติม",
|
||||
"Parallel Read": "อ่านคู่ขนาน",
|
||||
"Disable": "ปิด",
|
||||
@@ -652,5 +651,6 @@
|
||||
"Update email": "อัปเดตอีเมล",
|
||||
"Current email": "อีเมลปัจจุบัน",
|
||||
"Update Email": "อัปเดตอีเมล",
|
||||
"All": "ทั้งหมด"
|
||||
"All": "ทั้งหมด",
|
||||
"Unable to open book": "ไม่สามารถเปิดหนังสือได้"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "Otomatik Mod",
|
||||
"Behavior": "Davranış",
|
||||
"Book": "Kitap",
|
||||
"Book Cover": "Kitap Kapağı",
|
||||
"Bookmark": "Yer İmi",
|
||||
"Cancel": "İptal",
|
||||
"Chapter": "Bölüm",
|
||||
@@ -656,5 +655,6 @@
|
||||
"Update email": "E-postayı güncelle",
|
||||
"Current email": "Mevcut e-posta",
|
||||
"Update Email": "E-postayı güncelle",
|
||||
"All": "Tümü"
|
||||
"All": "Tümü",
|
||||
"Unable to open book": "Kitap açılamıyor"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "Автоматичний режим",
|
||||
"Behavior": "Поведінка",
|
||||
"Book": "Книга",
|
||||
"Book Cover": "Обкладинка книги",
|
||||
"Bookmark": "Закладка",
|
||||
"Cancel": "Скасувати",
|
||||
"Chapter": "Розділ",
|
||||
@@ -664,5 +663,6 @@
|
||||
"Update email": "Оновити електронну пошту",
|
||||
"Current email": "Поточна електронна пошта",
|
||||
"Update Email": "Оновити електронну пошту",
|
||||
"All": "Всі"
|
||||
"All": "Всі",
|
||||
"Unable to open book": "Не вдалося відкрити книгу"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "Chế độ tự động",
|
||||
"Behavior": "Hành vi",
|
||||
"Book": "Sách",
|
||||
"Book Cover": "Bìa sách",
|
||||
"Bookmark": "Đánh dấu",
|
||||
"Cancel": "Hủy",
|
||||
"Chapter": "Chương",
|
||||
@@ -652,5 +651,6 @@
|
||||
"Update email": "Cập nhật email",
|
||||
"Current email": "Email hiện tại",
|
||||
"Update Email": "Cập nhật email",
|
||||
"All": "Tất cả"
|
||||
"All": "Tất cả",
|
||||
"Unable to open book": "Không thể mở sách"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "自动主题",
|
||||
"Behavior": "行为",
|
||||
"Book": "书籍",
|
||||
"Book Cover": "书籍封面",
|
||||
"Bookmark": "书签",
|
||||
"Cancel": "取消",
|
||||
"Chapter": "章节",
|
||||
@@ -652,5 +651,6 @@
|
||||
"Update email": "更新邮箱",
|
||||
"Current email": "当前邮箱",
|
||||
"Update Email": "更新邮箱",
|
||||
"All": "全部"
|
||||
"All": "全部",
|
||||
"Unable to open book": "无法打开书籍"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"Auto Mode": "自動主題",
|
||||
"Behavior": "行為",
|
||||
"Book": "書籍",
|
||||
"Book Cover": "書籍封面",
|
||||
"Bookmark": "書籤",
|
||||
"Cancel": "取消",
|
||||
"Chapter": "章節",
|
||||
@@ -652,5 +651,6 @@
|
||||
"Update email": "更新電子郵件",
|
||||
"Current email": "當前電子郵件",
|
||||
"Update Email": "更新電子郵件",
|
||||
"All": "全部"
|
||||
"All": "全部",
|
||||
"Unable to open book": "無法打開書籍"
|
||||
}
|
||||
|
||||
@@ -129,22 +129,22 @@ export const useBooksSync = () => {
|
||||
if (newBooks.length > 0) {
|
||||
setIsSyncing(true);
|
||||
}
|
||||
|
||||
const batchSize = 10;
|
||||
for (let i = 0; i < newBooks.length; i += batchSize) {
|
||||
const batch = newBooks.slice(i, i + batchSize);
|
||||
await appService?.downloadBookCovers(batch);
|
||||
await Promise.all(batch.map(processNewBook));
|
||||
const progress = Math.min((i + batchSize) / newBooks.length, 1);
|
||||
setLibrary([...updatedLibrary]);
|
||||
setSyncProgress(progress);
|
||||
}
|
||||
|
||||
setLibrary(updatedLibrary);
|
||||
appService?.saveLibraryBooks(updatedLibrary);
|
||||
|
||||
if (newBooks.length > 0) {
|
||||
setIsSyncing(false);
|
||||
try {
|
||||
const batchSize = 10;
|
||||
for (let i = 0; i < newBooks.length; i += batchSize) {
|
||||
const batch = newBooks.slice(i, i + batchSize);
|
||||
await appService?.downloadBookCovers(batch);
|
||||
await Promise.all(batch.map(processNewBook));
|
||||
const progress = Math.min((i + batchSize) / newBooks.length, 1);
|
||||
setLibrary([...updatedLibrary]);
|
||||
setSyncProgress(progress);
|
||||
}
|
||||
setLibrary(updatedLibrary);
|
||||
appService?.saveLibraryBooks(updatedLibrary);
|
||||
} finally {
|
||||
if (newBooks.length > 0) {
|
||||
setIsSyncing(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { useSettingsStore } from '@/store/settingsStore';
|
||||
import { useBookDataStore } from '@/store/bookDataStore';
|
||||
import { useReaderStore } from '@/store/readerStore';
|
||||
import { useSidebarStore } from '@/store/sidebarStore';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { SystemSettings } from '@/types/settings';
|
||||
import { parseOpenWithFiles } from '@/helpers/openWith';
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window';
|
||||
@@ -30,6 +31,7 @@ import Notebook from './notebook/Notebook';
|
||||
import BooksGrid from './BooksGrid';
|
||||
|
||||
const ReaderContent: React.FC<{ ids?: string; settings: SystemSettings }> = ({ ids, settings }) => {
|
||||
const _ = useTranslation();
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const { envConfig, appService } = useEnv();
|
||||
@@ -42,6 +44,7 @@ const ReaderContent: React.FC<{ ids?: string; settings: SystemSettings }> = ({ i
|
||||
const [showDetailsBook, setShowDetailsBook] = useState<Book | null>(null);
|
||||
const isInitiating = useRef(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [errorLoading, setErrorLoading] = useState(false);
|
||||
|
||||
useBookShortcuts({ sideBarBookKey, bookKeys });
|
||||
|
||||
@@ -62,6 +65,13 @@ const ReaderContent: React.FC<{ ids?: string; settings: SystemSettings }> = ({ i
|
||||
if (!getViewState(key)) {
|
||||
initViewState(envConfig, id, key, isPrimary).catch((error) => {
|
||||
console.log('Error initializing book', key, error);
|
||||
setErrorLoading(true);
|
||||
eventDispatcher.dispatch('toast', {
|
||||
message: _('Unable to open book'),
|
||||
callback: () => navigateBackToLibrary(),
|
||||
timeout: 2000,
|
||||
type: 'error',
|
||||
});
|
||||
});
|
||||
if (index === 0) setSideBarBookKey(key);
|
||||
}
|
||||
@@ -188,7 +198,8 @@ const ReaderContent: React.FC<{ ids?: string; settings: SystemSettings }> = ({ i
|
||||
if (!bookData || !bookData.book || !bookData.bookDoc || !viewSettings) {
|
||||
setTimeout(() => setLoading(true), 200);
|
||||
return (
|
||||
loading && (
|
||||
loading &&
|
||||
!errorLoading && (
|
||||
<div className='hero hero-content h-[100vh]'>
|
||||
<Spinner loading={true} />
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,7 @@ export const Toast = () => {
|
||||
const [toastType, setToastType] = useState<ToastType>('info');
|
||||
const [toastTimeout, setToastTimeout] = useState(5000);
|
||||
const [messageClass, setMessageClass] = useState('');
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const toastDismissTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
|
||||
const toastClassMap = {
|
||||
@@ -22,26 +23,81 @@ export const Toast = () => {
|
||||
|
||||
const alertClassMap = {
|
||||
info: 'alert-primary border-base-300',
|
||||
success: 'alert-success border-0',
|
||||
warning: 'alert-warning border-0',
|
||||
error: 'alert-error border-0',
|
||||
success: 'alert-success border-0 bg-gradient-to-r from-green-500 to-emerald-500',
|
||||
warning: 'alert-warning border-0 bg-gradient-to-r from-amber-500 to-orange-500',
|
||||
error: 'alert-error border-0 bg-gradient-to-r from-red-500 to-rose-500',
|
||||
};
|
||||
|
||||
const iconMap = {
|
||||
info: (
|
||||
<svg className='h-5 w-5' fill='currentColor' viewBox='0 0 20 20'>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
d='M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z'
|
||||
clipRule='evenodd'
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
success: (
|
||||
<svg className='h-5 w-5' fill='currentColor' viewBox='0 0 20 20'>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
d='M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z'
|
||||
clipRule='evenodd'
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
warning: (
|
||||
<svg className='h-5 w-5' fill='currentColor' viewBox='0 0 20 20'>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
d='M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z'
|
||||
clipRule='evenodd'
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
error: (
|
||||
<svg className='h-5 w-5' fill='currentColor' viewBox='0 0 20 20'>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
d='M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z'
|
||||
clipRule='evenodd'
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (toastDismissTimeout.current) clearTimeout(toastDismissTimeout.current);
|
||||
const timeout = setTimeout(() => setToastMessage(''), toastTimeout);
|
||||
toastDismissTimeout.current = timeout;
|
||||
if (toastMessage) {
|
||||
setTimeout(() => {
|
||||
setIsVisible(true);
|
||||
}, 0);
|
||||
}
|
||||
}, [toastMessage]);
|
||||
|
||||
return () => {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
};
|
||||
useEffect(() => {
|
||||
if (toastDismissTimeout.current) clearTimeout(toastDismissTimeout.current);
|
||||
if (toastMessage) {
|
||||
const timeout = setTimeout(() => {
|
||||
setIsVisible(false);
|
||||
setTimeout(() => setToastMessage(''), 300);
|
||||
}, toastTimeout);
|
||||
toastDismissTimeout.current = timeout;
|
||||
return () => {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
};
|
||||
}
|
||||
return;
|
||||
}, [toastMessage, toastTimeout]);
|
||||
|
||||
const handleShowToast = async (event: CustomEvent) => {
|
||||
const { message, type = 'info', timeout, className = '' } = event.detail;
|
||||
const { message, type = 'info', timeout, className = '', callback = null } = event.detail;
|
||||
setToastMessage(message);
|
||||
setToastType(type);
|
||||
if (timeout) setToastTimeout(timeout);
|
||||
if (callback && typeof callback === 'function') {
|
||||
setTimeout(() => callback(), timeout || 5000);
|
||||
}
|
||||
setMessageClass(className);
|
||||
};
|
||||
|
||||
@@ -52,12 +108,19 @@ export const Toast = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleDismiss = () => {
|
||||
setIsVisible(false);
|
||||
setTimeout(() => setToastMessage(''), 300);
|
||||
if (toastDismissTimeout.current) clearTimeout(toastDismissTimeout.current);
|
||||
};
|
||||
|
||||
return (
|
||||
toastMessage && (
|
||||
<div
|
||||
className={clsx(
|
||||
'toast toast-center toast-middle z-50 w-auto max-w-screen-sm',
|
||||
'toast z-50 w-auto max-w-screen-sm transition-all duration-300',
|
||||
toastClassMap[toastType],
|
||||
isVisible ? 'scale-100 opacity-100' : 'scale-95 opacity-0',
|
||||
)}
|
||||
style={{
|
||||
top: toastClassMap[toastType].includes('toast-top')
|
||||
@@ -65,11 +128,22 @@ export const Toast = () => {
|
||||
: undefined,
|
||||
}}
|
||||
>
|
||||
<div className={clsx('alert flex items-center justify-center', alertClassMap[toastType])}>
|
||||
<div
|
||||
className={clsx(
|
||||
'alert flex items-center gap-3 shadow-2xl backdrop-blur-sm',
|
||||
'min-h-0 rounded-2xl px-5 py-4',
|
||||
alertClassMap[toastType],
|
||||
toastType !== 'info' && 'text-white',
|
||||
)}
|
||||
>
|
||||
{/* Icon */}
|
||||
<div className='flex-shrink-0'>{iconMap[toastType]}</div>
|
||||
|
||||
{/* Message */}
|
||||
<span
|
||||
className={clsx(
|
||||
'max-h-[50vh] min-w-32 overflow-y-auto',
|
||||
'text-center font-sans text-base font-normal sm:text-sm',
|
||||
'max-h-[50vh] flex-1 overflow-y-auto',
|
||||
'font-sans text-base font-medium leading-snug sm:text-sm',
|
||||
toastType === 'info'
|
||||
? 'max-w-[80vw] overflow-x-hidden'
|
||||
: 'min-w-[60vw] max-w-[80vw] whitespace-normal break-words sm:min-w-40 sm:max-w-80',
|
||||
@@ -79,10 +153,28 @@ export const Toast = () => {
|
||||
{toastMessage.split('\n').map((line, idx) => (
|
||||
<React.Fragment key={idx}>
|
||||
{line || <> </>}
|
||||
<br />
|
||||
{idx < toastMessage.split('\n').length - 1 && <br />}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</span>
|
||||
|
||||
{/* Close button */}
|
||||
<button
|
||||
onClick={handleDismiss}
|
||||
className={clsx(
|
||||
'flex-shrink-0 rounded-lg p-1 transition-colors',
|
||||
toastType === 'info' ? 'hover:bg-base-300' : 'hover:bg-white/20 active:bg-white/30',
|
||||
)}
|
||||
aria-label='Dismiss'
|
||||
>
|
||||
<svg className='h-4 w-4' fill='currentColor' viewBox='0 0 20 20'>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
d='M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z'
|
||||
clipRule='evenodd'
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -231,6 +231,7 @@ export const useReaderStore = create<ReaderStore>((set, get) => ({
|
||||
},
|
||||
},
|
||||
}));
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
getViewSettings: (key: string) => get().viewStates[key]?.viewSettings || null,
|
||||
|
||||
Reference in New Issue
Block a user