feat(library): separate background texture for library and reader (#4754)
* feat(library): separate background texture for library and reader (#4743) The library and reader shared a single background texture, so a reader backdrop with borders or other reading-oriented decoration looked wrong on the bookshelf. Let users set them independently. - Add device-local libraryBackground{TextureId,Opacity,Size} to SystemSettings. Each field falls back to the reader/global value when unset (getLibraryViewSettings), so an existing bookshelf looks unchanged until the user picks a library texture, then decouples per-field. No migration needed; the selection stays per-device like the reader's, while imported images keep syncing via the texture kind. - Make the Color panel's Background Image picker context-aware: opened from the library it edits the library texture, opened while reading it edits the reader texture. A sublabel states which page it applies to. - Apply the library texture at boot and on every library mount, so returning from a textured book restores the bookshelf background. - useBackgroundTexture now unmounts on 'none' instead of early-returning, since library and reader share one style element: switching a page to None must clear a texture the other page mounted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * i18n: translate library/reader background texture labels (#4743) Add translations for the two new context sublabels ("Applies to the Library" / "Applies to the Reader") across all 33 locales, anchored to each locale's existing Library and reading terminology. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1920,5 +1920,7 @@
|
||||
"Purge & Delete": "مسح وحذف",
|
||||
"Purge all reading data": "مسح جميع بيانات القراءة",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "يؤدي هذا إلى مسح تقدم القراءة والملاحظات والإشارات المرجعية نهائيًا. لا يمكن التراجع عن هذا الإجراء.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "يمسح أيضًا تقدم القراءة والملاحظات والإشارات المرجعية."
|
||||
"Also erase reading progress, notes, and bookmarks.": "يمسح أيضًا تقدم القراءة والملاحظات والإشارات المرجعية.",
|
||||
"Applies to the Library": "يُطبَّق على المكتبة",
|
||||
"Applies to the Reader": "يُطبَّق على واجهة القراءة"
|
||||
}
|
||||
|
||||
@@ -1788,5 +1788,7 @@
|
||||
"Purge & Delete": "পরিষ্কার করে মুছুন",
|
||||
"Purge all reading data": "সমস্ত পড়ার ডেটা পরিষ্কার করুন",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "এটি স্থায়ীভাবে পড়ার অগ্রগতি, নোট এবং বুকমার্ক মুছে ফেলে। এটি পূর্বাবস্থায় ফেরানো যাবে না।",
|
||||
"Also erase reading progress, notes, and bookmarks.": "পড়ার অগ্রগতি, নোট এবং বুকমার্কও মুছে ফেলে।"
|
||||
"Also erase reading progress, notes, and bookmarks.": "পড়ার অগ্রগতি, নোট এবং বুকমার্কও মুছে ফেলে।",
|
||||
"Applies to the Library": "লাইব্রেরিতে প্রযোজ্য",
|
||||
"Applies to the Reader": "রিডারে প্রযোজ্য"
|
||||
}
|
||||
|
||||
@@ -1755,5 +1755,7 @@
|
||||
"Purge & Delete": "གཙང་སེལ་བྱས་ནས་སུབ་པ།",
|
||||
"Purge all reading data": "ཀློག་པའི་གཞི་གྲངས་ཡོངས་གཙང་སེལ།",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "འདིས་ཀློག་པའི་ཡར་འཕེལ་དང་། ཟིན་བྲིས། དཔེ་རྟགས་བཅས་གཏན་དུ་སུབ་ངེས་ཡིན། ཕྱིར་ལྡོག་བྱེད་མི་ཐུབ།",
|
||||
"Also erase reading progress, notes, and bookmarks.": "ཀློག་པའི་ཡར་འཕེལ་དང་། ཟིན་བྲིས། དཔེ་རྟགས་བཅས་ཀྱང་སུབ་པ།"
|
||||
"Also erase reading progress, notes, and bookmarks.": "ཀློག་པའི་ཡར་འཕེལ་དང་། ཟིན་བྲིས། དཔེ་རྟགས་བཅས་ཀྱང་སུབ་པ།",
|
||||
"Applies to the Library": "དེབ་མཛོད་ལ་འཇུག་པ།",
|
||||
"Applies to the Reader": "ཀློག་ངོས་ལ་འཇུག་པ།"
|
||||
}
|
||||
|
||||
@@ -1788,5 +1788,7 @@
|
||||
"Purge & Delete": "Bereinigen und löschen",
|
||||
"Purge all reading data": "Alle Lesedaten bereinigen",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Dadurch werden Lesefortschritt, Notizen und Lesezeichen dauerhaft gelöscht. Dies kann nicht rückgängig gemacht werden.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Löscht auch Lesefortschritt, Notizen und Lesezeichen."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Löscht auch Lesefortschritt, Notizen und Lesezeichen.",
|
||||
"Applies to the Library": "Gilt für die Bibliothek",
|
||||
"Applies to the Reader": "Gilt für die Leseansicht"
|
||||
}
|
||||
|
||||
@@ -1788,5 +1788,7 @@
|
||||
"Purge & Delete": "Εκκαθάριση & Διαγραφή",
|
||||
"Purge all reading data": "Εκκαθάριση όλων των δεδομένων ανάγνωσης",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Αυτό διαγράφει οριστικά την πρόοδο ανάγνωσης, τις σημειώσεις και τους σελιδοδείκτες. Δεν είναι δυνατή η αναίρεση.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Διαγράφει επίσης την πρόοδο ανάγνωσης, τις σημειώσεις και τους σελιδοδείκτες."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Διαγράφει επίσης την πρόοδο ανάγνωσης, τις σημειώσεις και τους σελιδοδείκτες.",
|
||||
"Applies to the Library": "Ισχύει για τη βιβλιοθήκη",
|
||||
"Applies to the Reader": "Ισχύει για την προβολή ανάγνωσης"
|
||||
}
|
||||
|
||||
@@ -1821,5 +1821,7 @@
|
||||
"Purge & Delete": "Purgar y eliminar",
|
||||
"Purge all reading data": "Purgar todos los datos de lectura",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Esto borra permanentemente el progreso de lectura, las notas y los marcadores. Esta acción no se puede deshacer.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "También borra el progreso de lectura, las notas y los marcadores."
|
||||
"Also erase reading progress, notes, and bookmarks.": "También borra el progreso de lectura, las notas y los marcadores.",
|
||||
"Applies to the Library": "Se aplica a la biblioteca",
|
||||
"Applies to the Reader": "Se aplica al lector"
|
||||
}
|
||||
|
||||
@@ -1788,5 +1788,7 @@
|
||||
"Purge & Delete": "پاکسازی و حذف",
|
||||
"Purge all reading data": "پاکسازی همه دادههای مطالعه",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "این کار وضعیت مطالعه، یادداشتها و نشانکها را برای همیشه پاک میکند. این عمل قابل بازگشت نیست.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "همچنین وضعیت مطالعه، یادداشتها و نشانکها را پاک میکند."
|
||||
"Also erase reading progress, notes, and bookmarks.": "همچنین وضعیت مطالعه، یادداشتها و نشانکها را پاک میکند.",
|
||||
"Applies to the Library": "برای کتابخانه اعمال میشود",
|
||||
"Applies to the Reader": "برای صفحه مطالعه اعمال میشود"
|
||||
}
|
||||
|
||||
@@ -1821,5 +1821,7 @@
|
||||
"Purge & Delete": "Purger et supprimer",
|
||||
"Purge all reading data": "Purger toutes les données de lecture",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Cela efface définitivement la progression de lecture, les notes et les signets. Cette action est irréversible.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Efface aussi la progression de lecture, les notes et les signets."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Efface aussi la progression de lecture, les notes et les signets.",
|
||||
"Applies to the Library": "S’applique à la bibliothèque",
|
||||
"Applies to the Reader": "S’applique à la vue de lecture"
|
||||
}
|
||||
|
||||
@@ -1821,5 +1821,7 @@
|
||||
"Purge & Delete": "נקה ומחק",
|
||||
"Purge all reading data": "נקה את כל נתוני הקריאה",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "פעולה זו מוחקת לצמיתות את התקדמות הקריאה, ההערות והסימניות. לא ניתן לבטל פעולה זו.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "מוחק גם את התקדמות הקריאה, ההערות והסימניות."
|
||||
"Also erase reading progress, notes, and bookmarks.": "מוחק גם את התקדמות הקריאה, ההערות והסימניות.",
|
||||
"Applies to the Library": "חל על הספרייה",
|
||||
"Applies to the Reader": "חל על מצב הקריאה"
|
||||
}
|
||||
|
||||
@@ -1788,5 +1788,7 @@
|
||||
"Purge & Delete": "साफ़ करें और हटाएं",
|
||||
"Purge all reading data": "सभी पढ़ने का डेटा साफ़ करें",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "यह पढ़ने की प्रगति, नोट्स और बुकमार्क को स्थायी रूप से मिटा देता है। इसे पूर्ववत नहीं किया जा सकता।",
|
||||
"Also erase reading progress, notes, and bookmarks.": "पढ़ने की प्रगति, नोट्स और बुकमार्क भी मिटा देता है।"
|
||||
"Also erase reading progress, notes, and bookmarks.": "पढ़ने की प्रगति, नोट्स और बुकमार्क भी मिटा देता है।",
|
||||
"Applies to the Library": "लाइब्रेरी पर लागू होता है",
|
||||
"Applies to the Reader": "रीडर पर लागू होता है"
|
||||
}
|
||||
|
||||
@@ -1788,5 +1788,7 @@
|
||||
"Purge & Delete": "Tisztítás és törlés",
|
||||
"Purge all reading data": "Összes olvasási adat törlése",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Ez véglegesen törli az olvasási haladást, a jegyzeteket és a könyvjelzőket. A művelet nem vonható vissza.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Az olvasási haladást, jegyzeteket és könyvjelzőket is törli."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Az olvasási haladást, jegyzeteket és könyvjelzőket is törli.",
|
||||
"Applies to the Library": "A könyvtárra vonatkozik",
|
||||
"Applies to the Reader": "Az olvasónézetre vonatkozik"
|
||||
}
|
||||
|
||||
@@ -1755,5 +1755,7 @@
|
||||
"Purge & Delete": "Bersihkan & Hapus",
|
||||
"Purge all reading data": "Bersihkan semua data baca",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Ini menghapus permanen progres membaca, catatan, dan penanda. Tindakan ini tidak dapat dibatalkan.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Juga menghapus progres membaca, catatan, dan penanda."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Juga menghapus progres membaca, catatan, dan penanda.",
|
||||
"Applies to the Library": "Berlaku untuk Perpustakaan",
|
||||
"Applies to the Reader": "Berlaku untuk tampilan baca"
|
||||
}
|
||||
|
||||
@@ -1821,5 +1821,7 @@
|
||||
"Purge & Delete": "Svuota ed elimina",
|
||||
"Purge all reading data": "Elimina tutti i dati di lettura",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Questa operazione cancella definitivamente il progresso di lettura, le note e i segnalibri. Non può essere annullata.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Cancella anche il progresso di lettura, le note e i segnalibri."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Cancella anche il progresso di lettura, le note e i segnalibri.",
|
||||
"Applies to the Library": "Si applica alla libreria",
|
||||
"Applies to the Reader": "Si applica alla vista di lettura"
|
||||
}
|
||||
|
||||
@@ -1755,5 +1755,7 @@
|
||||
"Purge & Delete": "消去して削除",
|
||||
"Purge all reading data": "すべての読書データを消去",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "読書進捗、メモ、ブックマークが完全に消去されます。この操作は元に戻せません。",
|
||||
"Also erase reading progress, notes, and bookmarks.": "読書進捗、メモ、ブックマークも消去します。"
|
||||
"Also erase reading progress, notes, and bookmarks.": "読書進捗、メモ、ブックマークも消去します。",
|
||||
"Applies to the Library": "ライブラリに適用されます",
|
||||
"Applies to the Reader": "リーダーに適用されます"
|
||||
}
|
||||
|
||||
@@ -1755,5 +1755,7 @@
|
||||
"Purge & Delete": "데이터 지우고 삭제",
|
||||
"Purge all reading data": "모든 읽기 데이터 지우기",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "읽기 진행 상황, 메모, 북마크가 영구적으로 지워집니다. 이 작업은 되돌릴 수 없습니다.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "읽기 진행 상황, 메모, 북마크도 함께 지웁니다."
|
||||
"Also erase reading progress, notes, and bookmarks.": "읽기 진행 상황, 메모, 북마크도 함께 지웁니다.",
|
||||
"Applies to the Library": "라이브러리에 적용됩니다",
|
||||
"Applies to the Reader": "리더에 적용됩니다"
|
||||
}
|
||||
|
||||
@@ -1755,5 +1755,7 @@
|
||||
"Purge & Delete": "Bersihkan & Padam",
|
||||
"Purge all reading data": "Bersihkan semua data bacaan",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Ini memadam kemajuan membaca, nota dan penanda buku secara kekal. Tindakan ini tidak boleh dibatalkan.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Turut memadam kemajuan membaca, nota dan penanda buku."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Turut memadam kemajuan membaca, nota dan penanda buku.",
|
||||
"Applies to the Library": "Digunakan pada Perpustakaan",
|
||||
"Applies to the Reader": "Digunakan pada paparan bacaan"
|
||||
}
|
||||
|
||||
@@ -1788,5 +1788,7 @@
|
||||
"Purge & Delete": "Wissen en verwijderen",
|
||||
"Purge all reading data": "Alle leesgegevens wissen",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Hiermee worden leesvoortgang, notities en bladwijzers permanent gewist. Dit kan niet ongedaan worden gemaakt.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Wist ook leesvoortgang, notities en bladwijzers."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Wist ook leesvoortgang, notities en bladwijzers.",
|
||||
"Applies to the Library": "Geldt voor de bibliotheek",
|
||||
"Applies to the Reader": "Geldt voor de leesweergave"
|
||||
}
|
||||
|
||||
@@ -1854,5 +1854,7 @@
|
||||
"Purge & Delete": "Wyczyść i usuń",
|
||||
"Purge all reading data": "Wyczyść wszystkie dane czytania",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Spowoduje to trwałe usunięcie postępu czytania, notatek i zakładek. Tej operacji nie można cofnąć.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Usuwa również postęp czytania, notatki i zakładki."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Usuwa również postęp czytania, notatki i zakładki.",
|
||||
"Applies to the Library": "Dotyczy biblioteki",
|
||||
"Applies to the Reader": "Dotyczy widoku czytania"
|
||||
}
|
||||
|
||||
@@ -1821,5 +1821,7 @@
|
||||
"Purge & Delete": "Limpar e excluir",
|
||||
"Purge all reading data": "Limpar todos os dados de leitura",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Isso apaga permanentemente o progresso de leitura, as notas e os marcadores. Esta ação não pode ser desfeita.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Também apaga o progresso de leitura, as notas e os marcadores."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Também apaga o progresso de leitura, as notas e os marcadores.",
|
||||
"Applies to the Library": "Aplica-se à biblioteca",
|
||||
"Applies to the Reader": "Aplica-se à vista de leitura"
|
||||
}
|
||||
|
||||
@@ -1821,5 +1821,7 @@
|
||||
"Purge & Delete": "Limpar e excluir",
|
||||
"Purge all reading data": "Limpar todos os dados de leitura",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Isto apaga permanentemente o progresso de leitura, notas e marcadores. Esta ação não pode ser desfeita.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Também apaga o progresso de leitura, notas e marcadores."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Também apaga o progresso de leitura, notas e marcadores.",
|
||||
"Applies to the Library": "Aplica-se à biblioteca",
|
||||
"Applies to the Reader": "Aplica-se à vista de leitura"
|
||||
}
|
||||
|
||||
@@ -1821,5 +1821,7 @@
|
||||
"Purge & Delete": "Curăță și șterge",
|
||||
"Purge all reading data": "Curăță toate datele de citire",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Aceasta șterge definitiv progresul citirii, notele și marcajele. Această acțiune nu poate fi anulată.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Șterge de asemenea progresul citirii, notele și marcajele."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Șterge de asemenea progresul citirii, notele și marcajele.",
|
||||
"Applies to the Library": "Se aplică bibliotecii",
|
||||
"Applies to the Reader": "Se aplică vizualizării de lectură"
|
||||
}
|
||||
|
||||
@@ -1854,5 +1854,7 @@
|
||||
"Purge & Delete": "Очистить и удалить",
|
||||
"Purge all reading data": "Очистить все данные чтения",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Это безвозвратно удалит прогресс чтения, заметки и закладки. Это действие нельзя отменить.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Также удаляет прогресс чтения, заметки и закладки."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Также удаляет прогресс чтения, заметки и закладки.",
|
||||
"Applies to the Library": "Применяется к библиотеке",
|
||||
"Applies to the Reader": "Применяется к режиму чтения"
|
||||
}
|
||||
|
||||
@@ -1788,5 +1788,7 @@
|
||||
"Purge & Delete": "ඉවත් කර මකන්න",
|
||||
"Purge all reading data": "සියලු කියවීම් දත්ත ඉවත් කරන්න",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "මෙය කියවීමේ ප්රගතිය, සටහන් සහ පොත් සලකුණු ස්ථිරවම මකා දමයි. මෙය අහෝසි කළ නොහැක.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "කියවීමේ ප්රගතිය, සටහන් සහ පොත් සලකුණු ද මකා දමයි."
|
||||
"Also erase reading progress, notes, and bookmarks.": "කියවීමේ ප්රගතිය, සටහන් සහ පොත් සලකුණු ද මකා දමයි.",
|
||||
"Applies to the Library": "පුස්තකාලයට අදාළ වේ",
|
||||
"Applies to the Reader": "කියවීමේ දසුනට අදාළ වේ"
|
||||
}
|
||||
|
||||
@@ -1854,5 +1854,7 @@
|
||||
"Purge & Delete": "Počisti in izbriši",
|
||||
"Purge all reading data": "Počisti vse podatke o branju",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "To trajno izbriše napredek branja, opombe in zaznamke. Tega ni mogoče razveljaviti.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Izbriše tudi napredek branja, opombe in zaznamke."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Izbriše tudi napredek branja, opombe in zaznamke.",
|
||||
"Applies to the Library": "Velja za knjižnico",
|
||||
"Applies to the Reader": "Velja za bralni pogled"
|
||||
}
|
||||
|
||||
@@ -1788,5 +1788,7 @@
|
||||
"Purge & Delete": "Rensa och ta bort",
|
||||
"Purge all reading data": "Rensa alla läsdata",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Detta raderar permanent läsframsteg, anteckningar och bokmärken. Detta kan inte ångras.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Raderar även läsframsteg, anteckningar och bokmärken."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Raderar även läsframsteg, anteckningar och bokmärken.",
|
||||
"Applies to the Library": "Gäller biblioteket",
|
||||
"Applies to the Reader": "Gäller läsvyn"
|
||||
}
|
||||
|
||||
@@ -1788,5 +1788,7 @@
|
||||
"Purge & Delete": "அழித்து நீக்கு",
|
||||
"Purge all reading data": "அனைத்து வாசிப்புத் தரவையும் அழி",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "இது வாசிப்பு முன்னேற்றம், குறிப்புகள் மற்றும் புக்மார்க்குகளை நிரந்தரமாக அழிக்கும். இதை மீட்டெடுக்க முடியாது.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "வாசிப்பு முன்னேற்றம், குறிப்புகள் மற்றும் புக்மார்க்குகளையும் அழிக்கும்."
|
||||
"Also erase reading progress, notes, and bookmarks.": "வாசிப்பு முன்னேற்றம், குறிப்புகள் மற்றும் புக்மார்க்குகளையும் அழிக்கும்.",
|
||||
"Applies to the Library": "நூலகத்திற்குப் பொருந்தும்",
|
||||
"Applies to the Reader": "வாசிப்புப் பக்கத்திற்குப் பொருந்தும்"
|
||||
}
|
||||
|
||||
@@ -1755,5 +1755,7 @@
|
||||
"Purge & Delete": "ล้างและลบ",
|
||||
"Purge all reading data": "ล้างข้อมูลการอ่านทั้งหมด",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "การดำเนินการนี้จะลบความคืบหน้าในการอ่าน บันทึก และบุ๊กมาร์กอย่างถาวร ไม่สามารถเลิกทำได้",
|
||||
"Also erase reading progress, notes, and bookmarks.": "ลบความคืบหน้าในการอ่าน บันทึก และบุ๊กมาร์กด้วย"
|
||||
"Also erase reading progress, notes, and bookmarks.": "ลบความคืบหน้าในการอ่าน บันทึก และบุ๊กมาร์กด้วย",
|
||||
"Applies to the Library": "ใช้กับคลังหนังสือ",
|
||||
"Applies to the Reader": "ใช้กับมุมมองการอ่าน"
|
||||
}
|
||||
|
||||
@@ -1788,5 +1788,7 @@
|
||||
"Purge & Delete": "Temizle ve sil",
|
||||
"Purge all reading data": "Tüm okuma verilerini temizle",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Bu, okuma ilerlemesini, notları ve yer işaretlerini kalıcı olarak siler. Bu işlem geri alınamaz.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Okuma ilerlemesi, notlar ve yer işaretlerini de siler."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Okuma ilerlemesi, notlar ve yer işaretlerini de siler.",
|
||||
"Applies to the Library": "Kütüphaneye uygulanır",
|
||||
"Applies to the Reader": "Okuma görünümüne uygulanır"
|
||||
}
|
||||
|
||||
@@ -1854,5 +1854,7 @@
|
||||
"Purge & Delete": "Очистити та видалити",
|
||||
"Purge all reading data": "Очистити всі дані читання",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Це назавжди видалить проґрес читання, нотатки та закладки. Цю дію не можна скасувати.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Також видаляє проґрес читання, нотатки та закладки."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Також видаляє проґрес читання, нотатки та закладки.",
|
||||
"Applies to the Library": "Застосовується до бібліотеки",
|
||||
"Applies to the Reader": "Застосовується до режиму читання"
|
||||
}
|
||||
|
||||
@@ -1788,5 +1788,7 @@
|
||||
"Purge & Delete": "Tozalash va oʻchirish",
|
||||
"Purge all reading data": "Barcha oʻqish maʼlumotlarini tozalash",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Bu oʻqish jarayoni, eslatmalar va xatchoʻplarni butunlay oʻchiradi. Buni qaytarib boʻlmaydi.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Shuningdek, oʻqish jarayoni, eslatmalar va xatchoʻplarni ham oʻchiradi."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Shuningdek, oʻqish jarayoni, eslatmalar va xatchoʻplarni ham oʻchiradi.",
|
||||
"Applies to the Library": "Kutubxonaga qoʻllanadi",
|
||||
"Applies to the Reader": "Oʻqish koʻrinishiga qoʻllanadi"
|
||||
}
|
||||
|
||||
@@ -1755,5 +1755,7 @@
|
||||
"Purge & Delete": "Dọn sạch và xóa",
|
||||
"Purge all reading data": "Xóa toàn bộ dữ liệu đọc",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "Thao tác này xóa vĩnh viễn tiến độ đọc, ghi chú và dấu trang. Không thể hoàn tác.",
|
||||
"Also erase reading progress, notes, and bookmarks.": "Đồng thời xóa tiến độ đọc, ghi chú và dấu trang."
|
||||
"Also erase reading progress, notes, and bookmarks.": "Đồng thời xóa tiến độ đọc, ghi chú và dấu trang.",
|
||||
"Applies to the Library": "Áp dụng cho Thư viện",
|
||||
"Applies to the Reader": "Áp dụng cho trình đọc"
|
||||
}
|
||||
|
||||
@@ -1755,5 +1755,7 @@
|
||||
"Purge & Delete": "清除并删除",
|
||||
"Purge all reading data": "清除所有阅读数据",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "这将永久清除阅读进度、笔记和书签,且无法撤销。",
|
||||
"Also erase reading progress, notes, and bookmarks.": "同时清除阅读进度、笔记和书签。"
|
||||
"Also erase reading progress, notes, and bookmarks.": "同时清除阅读进度、笔记和书签。",
|
||||
"Applies to the Library": "应用于书库",
|
||||
"Applies to the Reader": "应用于阅读界面"
|
||||
}
|
||||
|
||||
@@ -1755,5 +1755,7 @@
|
||||
"Purge & Delete": "清除並刪除",
|
||||
"Purge all reading data": "清除所有閱讀資料",
|
||||
"This permanently erases reading progress, notes, and bookmarks. This cannot be undone.": "這將永久清除閱讀進度、筆記和書籤,且無法復原。",
|
||||
"Also erase reading progress, notes, and bookmarks.": "同時清除閱讀進度、筆記和書籤。"
|
||||
"Also erase reading progress, notes, and bookmarks.": "同時清除閱讀進度、筆記和書籤。",
|
||||
"Applies to the Library": "套用於書庫",
|
||||
"Applies to the Reader": "套用於閱讀介面"
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ vi.mock('@/utils/style', () => ({
|
||||
getStyles: vi.fn(() => ''),
|
||||
}));
|
||||
|
||||
import { saveViewSettings } from '@/helpers/settings';
|
||||
import { getLibraryViewSettings, saveViewSettings } from '@/helpers/settings';
|
||||
import { useSettingsStore } from '@/store/settingsStore';
|
||||
import type { EnvConfigType } from '@/services/environment';
|
||||
import type { SystemSettings } from '@/types/settings';
|
||||
@@ -55,6 +55,61 @@ beforeEach(() => {
|
||||
} as unknown as ReturnType<typeof useSettingsStore.getState>);
|
||||
});
|
||||
|
||||
describe('getLibraryViewSettings', () => {
|
||||
const makeTextureSettings = (overrides: Partial<SystemSettings> = {}): SystemSettings =>
|
||||
({
|
||||
globalViewSettings: {
|
||||
backgroundTextureId: 'paper',
|
||||
backgroundOpacity: 0.6,
|
||||
backgroundSize: 'cover',
|
||||
},
|
||||
...overrides,
|
||||
}) as unknown as SystemSettings;
|
||||
|
||||
test('inherits the reader/global texture when no library override is set', () => {
|
||||
const result = getLibraryViewSettings(makeTextureSettings());
|
||||
|
||||
expect(result.backgroundTextureId).toBe('paper');
|
||||
expect(result.backgroundOpacity).toBe(0.6);
|
||||
expect(result.backgroundSize).toBe('cover');
|
||||
});
|
||||
|
||||
test('uses the library overrides when they are set', () => {
|
||||
const result = getLibraryViewSettings(
|
||||
makeTextureSettings({
|
||||
libraryBackgroundTextureId: 'none',
|
||||
libraryBackgroundOpacity: 0.3,
|
||||
libraryBackgroundSize: 'contain',
|
||||
}),
|
||||
);
|
||||
|
||||
expect(result.backgroundTextureId).toBe('none');
|
||||
expect(result.backgroundOpacity).toBe(0.3);
|
||||
expect(result.backgroundSize).toBe('contain');
|
||||
});
|
||||
|
||||
test("tolerates the store's initial empty settings (no globalViewSettings yet)", () => {
|
||||
// useSettingsStore starts as `{} as SystemSettings`; the library page's
|
||||
// texture effect can resolve before appService.loadSettings() populates it.
|
||||
// It must yield a usable "no texture" result instead of throwing.
|
||||
const result = getLibraryViewSettings({} as SystemSettings);
|
||||
|
||||
expect(result.backgroundTextureId).toBe('none');
|
||||
});
|
||||
|
||||
test('resolves each field independently — an unset field still inherits', () => {
|
||||
// Only the texture id is decoupled; opacity/size were never touched and
|
||||
// must keep tracking the reader/global values.
|
||||
const result = getLibraryViewSettings(
|
||||
makeTextureSettings({ libraryBackgroundTextureId: 'sand' }),
|
||||
);
|
||||
|
||||
expect(result.backgroundTextureId).toBe('sand');
|
||||
expect(result.backgroundOpacity).toBe(0.6);
|
||||
expect(result.backgroundSize).toBe('cover');
|
||||
});
|
||||
});
|
||||
|
||||
describe('saveViewSettings', () => {
|
||||
test('global write swaps the settings reference so replicaSettingsSync subscribers fire', async () => {
|
||||
// Mirrors the gating subscriber installed by replicaSettingsSync.initSettingsSync.
|
||||
|
||||
@@ -107,4 +107,25 @@ describe('useBackgroundTexture', () => {
|
||||
|
||||
expect(useCustomTextureStore.getState().getTexture(SAVED_TEXTURE.id)).toBeUndefined();
|
||||
});
|
||||
|
||||
test('unmounts any mounted texture when textureId is "none"', async () => {
|
||||
// Library/reader share the single #background-texture style element. When a
|
||||
// page whose texture is "none" becomes active (e.g. returning to a
|
||||
// None-background library after reading a textured book), applying it must
|
||||
// actively clear the leftover texture, not silently leave it mounted.
|
||||
const { mountBackgroundTexture, unmountBackgroundTexture } = await import('@/styles/textures');
|
||||
vi.mocked(mountBackgroundTexture).mockClear();
|
||||
vi.mocked(unmountBackgroundTexture).mockClear();
|
||||
|
||||
const { result } = renderHook(() => useBackgroundTexture());
|
||||
result.current.applyBackgroundTexture(
|
||||
createMockEnvConfig(),
|
||||
makeViewSettings({ backgroundTextureId: 'none' }),
|
||||
);
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(unmountBackgroundTexture).toHaveBeenCalled();
|
||||
});
|
||||
expect(mountBackgroundTexture).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -41,6 +41,8 @@ import { useOPDSSubscriptions } from '@/hooks/useOPDSSubscriptions';
|
||||
import { useBookDataStore } from '@/store/bookDataStore';
|
||||
import { useTransferStore } from '@/store/transferStore';
|
||||
import { useScreenWakeLock } from '@/hooks/useScreenWakeLock';
|
||||
import { useBackgroundTexture } from '@/hooks/useBackgroundTexture';
|
||||
import { getLibraryViewSettings } from '@/helpers/settings';
|
||||
import { useAppUrlIngress } from '@/hooks/useAppUrlIngress';
|
||||
import { useOpenWithBooks } from '@/hooks/useOpenWithBooks';
|
||||
import { useOpenAnnotationLink } from '@/hooks/useOpenAnnotationLink';
|
||||
@@ -241,6 +243,25 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP
|
||||
useTheme({ systemUIVisible: true, appThemeColor: 'base-200' });
|
||||
useUICSS();
|
||||
|
||||
// Apply the library's own background texture (separate from the reader's,
|
||||
// issue #4743). Re-applies on mount so returning from a textured book
|
||||
// restores the library background, and whenever the library texture — or the
|
||||
// reader/global texture it inherits when unset — changes from the Color panel.
|
||||
const { applyBackgroundTexture } = useBackgroundTexture();
|
||||
useEffect(() => {
|
||||
applyBackgroundTexture(envConfig, getLibraryViewSettings(settings));
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [
|
||||
envConfig,
|
||||
applyBackgroundTexture,
|
||||
settings.libraryBackgroundTextureId,
|
||||
settings.libraryBackgroundOpacity,
|
||||
settings.libraryBackgroundSize,
|
||||
settings.globalViewSettings?.backgroundTextureId,
|
||||
settings.globalViewSettings?.backgroundOpacity,
|
||||
settings.globalViewSettings?.backgroundSize,
|
||||
]);
|
||||
|
||||
useAppUrlIngress();
|
||||
useOpenWithBooks();
|
||||
useOpenAnnotationLink();
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
setTelemetryDecision,
|
||||
TELEMETRY_OPT_OUT_KEY,
|
||||
} from '@/utils/telemetry';
|
||||
import { getLibraryViewSettings } from '@/helpers/settings';
|
||||
import { SETTINGS_FILENAME } from '@/services/constants';
|
||||
import type { AppService } from '@/types/system';
|
||||
import type { SystemSettings } from '@/types/settings';
|
||||
@@ -158,7 +159,10 @@ const Providers = ({ children }: { children: React.ReactNode }) => {
|
||||
if (settings.customTextures?.length) {
|
||||
useCustomTextureStore.getState().setTextures(settings.customTextures);
|
||||
}
|
||||
applyBackgroundTexture(envConfig, globalViewSettings);
|
||||
// The app boots onto the library, so apply the library background
|
||||
// (which inherits the reader/global texture until decoupled). The
|
||||
// reader re-applies its own texture when a book opens (issue #4743).
|
||||
applyBackgroundTexture(envConfig, getLibraryViewSettings(settings));
|
||||
if (globalViewSettings.isEink) {
|
||||
applyEinkMode(true);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import { useSettingsStore } from '@/store/settingsStore';
|
||||
import { useResetViewSettings } from '@/hooks/useResetSettings';
|
||||
import { useCustomTextureStore } from '@/store/customTextureStore';
|
||||
import { queueReplicaBinaryUpload } from '@/services/sync/replicaBinaryUpload';
|
||||
import { saveViewSettings } from '@/helpers/settings';
|
||||
import { saveSysSettings, saveViewSettings } from '@/helpers/settings';
|
||||
import { manageSyntaxHighlighting } from '@/utils/highlightjs';
|
||||
import { SettingsPanelPanelProp } from './SettingsDialog';
|
||||
import { useFileSelector } from '@/hooks/useFileSelector';
|
||||
@@ -42,6 +42,21 @@ const ColorPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterReset
|
||||
const { getView, getViewSettings } = useReaderStore();
|
||||
const viewSettings = getViewSettings(bookKey) || settings.globalViewSettings;
|
||||
|
||||
// The Background Image picker is context-aware (issue #4743): opened from the
|
||||
// library (no bookKey) it edits the library's own texture, which falls back
|
||||
// to the reader/global value per-field until decoupled; opened while reading
|
||||
// it edits the reader texture exactly as before.
|
||||
const isLibraryContext = !bookKey;
|
||||
const currentTextureId = isLibraryContext
|
||||
? (settings.libraryBackgroundTextureId ?? viewSettings.backgroundTextureId)
|
||||
: viewSettings.backgroundTextureId;
|
||||
const currentBackgroundOpacity = isLibraryContext
|
||||
? (settings.libraryBackgroundOpacity ?? viewSettings.backgroundOpacity)
|
||||
: viewSettings.backgroundOpacity;
|
||||
const currentBackgroundSize = isLibraryContext
|
||||
? (settings.libraryBackgroundSize ?? viewSettings.backgroundSize)
|
||||
: viewSettings.backgroundSize;
|
||||
|
||||
const [invertImgColorInDark, setInvertImgColorInDark] = useState(
|
||||
viewSettings.invertImgColorInDark,
|
||||
);
|
||||
@@ -51,9 +66,9 @@ const ColorPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterReset
|
||||
const [overrideColor, setOverrideColor] = useState(viewSettings.overrideColor);
|
||||
const [codeHighlighting, setcodeHighlighting] = useState(viewSettings.codeHighlighting);
|
||||
const [codeLanguage, setCodeLanguage] = useState(viewSettings.codeLanguage);
|
||||
const [selectedTextureId, setSelectedTextureId] = useState(viewSettings.backgroundTextureId);
|
||||
const [backgroundOpacity, setBackgroundOpacity] = useState(viewSettings.backgroundOpacity);
|
||||
const [backgroundSize, setBackgroundSize] = useState(viewSettings.backgroundSize);
|
||||
const [selectedTextureId, setSelectedTextureId] = useState(currentTextureId);
|
||||
const [backgroundOpacity, setBackgroundOpacity] = useState(currentBackgroundOpacity);
|
||||
const [backgroundSize, setBackgroundSize] = useState(currentBackgroundSize);
|
||||
const [highlightOpacity, setHighlightOpacity] = useState(viewSettings.highlightOpacity ?? 0.3);
|
||||
const [customHighlightColors, setCustomHighlightColors] = useState(
|
||||
settings.globalReadSettings.customHighlightColors,
|
||||
@@ -161,22 +176,34 @@ const ColorPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterReset
|
||||
}, [codeHighlighting, codeLanguage]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedTextureId === viewSettings.backgroundTextureId) return;
|
||||
saveViewSettings(envConfig, bookKey, 'backgroundTextureId', selectedTextureId);
|
||||
if (selectedTextureId === currentTextureId) return;
|
||||
if (isLibraryContext) {
|
||||
saveSysSettings(envConfig, 'libraryBackgroundTextureId', selectedTextureId);
|
||||
} else {
|
||||
saveViewSettings(envConfig, bookKey, 'backgroundTextureId', selectedTextureId);
|
||||
}
|
||||
applyBackgroundTexture();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedTextureId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (backgroundOpacity === viewSettings.backgroundOpacity) return;
|
||||
saveViewSettings(envConfig, bookKey, 'backgroundOpacity', backgroundOpacity);
|
||||
if (backgroundOpacity === currentBackgroundOpacity) return;
|
||||
if (isLibraryContext) {
|
||||
saveSysSettings(envConfig, 'libraryBackgroundOpacity', backgroundOpacity);
|
||||
} else {
|
||||
saveViewSettings(envConfig, bookKey, 'backgroundOpacity', backgroundOpacity);
|
||||
}
|
||||
applyBackgroundTexture();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [backgroundOpacity]);
|
||||
|
||||
useEffect(() => {
|
||||
if (backgroundSize === viewSettings.backgroundSize) return;
|
||||
saveViewSettings(envConfig, bookKey, 'backgroundSize', backgroundSize);
|
||||
if (backgroundSize === currentBackgroundSize) return;
|
||||
if (isLibraryContext) {
|
||||
saveSysSettings(envConfig, 'libraryBackgroundSize', backgroundSize);
|
||||
} else {
|
||||
saveViewSettings(envConfig, bookKey, 'backgroundSize', backgroundSize);
|
||||
}
|
||||
applyBackgroundTexture();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [backgroundSize]);
|
||||
@@ -364,6 +391,7 @@ const ColorPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterReset
|
||||
<BackgroundTextureSelector
|
||||
predefinedTextures={PREDEFINED_TEXTURES}
|
||||
customTextures={customTextures.filter((t) => !t.deletedAt)}
|
||||
scopeLabel={isLibraryContext ? _('Applies to the Library') : _('Applies to the Reader')}
|
||||
selectedTextureId={selectedTextureId}
|
||||
backgroundOpacity={backgroundOpacity}
|
||||
backgroundSize={backgroundSize}
|
||||
|
||||
@@ -15,6 +15,8 @@ interface Texture {
|
||||
interface BackgroundTextureSelectorProps {
|
||||
predefinedTextures: Texture[];
|
||||
customTextures: Texture[];
|
||||
/** Optional sublabel clarifying which page this texture applies to (#4743). */
|
||||
scopeLabel?: string;
|
||||
selectedTextureId: string;
|
||||
backgroundOpacity: number;
|
||||
backgroundSize: string;
|
||||
@@ -28,6 +30,7 @@ interface BackgroundTextureSelectorProps {
|
||||
const BackgroundTextureSelector: React.FC<BackgroundTextureSelectorProps> = ({
|
||||
predefinedTextures,
|
||||
customTextures,
|
||||
scopeLabel,
|
||||
selectedTextureId,
|
||||
backgroundOpacity,
|
||||
backgroundSize,
|
||||
@@ -44,7 +47,8 @@ const BackgroundTextureSelector: React.FC<BackgroundTextureSelectorProps> = ({
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SectionTitle className='mb-2'>{_('Background Image')}</SectionTitle>
|
||||
<SectionTitle className={scopeLabel ? 'mb-1' : 'mb-2'}>{_('Background Image')}</SectionTitle>
|
||||
{scopeLabel && <p className='text-base-content/60 mb-2 text-xs'>{scopeLabel}</p>}
|
||||
<div className='mb-4 grid grid-cols-2 gap-4'>
|
||||
{allTextures.map((texture) => (
|
||||
// The swatch is a div (not a <button>) so the inner Delete
|
||||
|
||||
@@ -6,6 +6,29 @@ import { useReaderStore } from '@/store/readerStore';
|
||||
import { useSettingsStore } from '@/store/settingsStore';
|
||||
import { getStyles } from '@/utils/style';
|
||||
|
||||
/**
|
||||
* Resolve the effective background texture for the library page (issue #4743).
|
||||
* The library texture is stored separately from the reader's, but each field
|
||||
* falls back to the reader/global value when unset — so the bookshelf inherits
|
||||
* the current look until the user explicitly picks a library texture, then
|
||||
* decouples per-field. Returns a `ViewSettings` so it can be handed straight to
|
||||
* `useBackgroundTexture().applyBackgroundTexture`.
|
||||
*/
|
||||
export const getLibraryViewSettings = (settings: SystemSettings): ViewSettings => {
|
||||
// globalViewSettings can be absent on the very first renders — the store
|
||||
// starts as `{} as SystemSettings` until appService.loadSettings() runs — so
|
||||
// every read is optional and falls back to a no-texture default.
|
||||
const globalViewSettings = settings.globalViewSettings;
|
||||
return {
|
||||
...globalViewSettings,
|
||||
backgroundTextureId:
|
||||
settings.libraryBackgroundTextureId ?? globalViewSettings?.backgroundTextureId ?? 'none',
|
||||
backgroundOpacity:
|
||||
settings.libraryBackgroundOpacity ?? globalViewSettings?.backgroundOpacity ?? 0.6,
|
||||
backgroundSize: settings.libraryBackgroundSize ?? globalViewSettings?.backgroundSize ?? 'cover',
|
||||
};
|
||||
};
|
||||
|
||||
export const saveViewSettings = async <K extends keyof ViewSettings>(
|
||||
envConfig: EnvConfigType,
|
||||
bookKey: string,
|
||||
|
||||
@@ -7,31 +7,40 @@ import { ViewSettings } from '@/types/book';
|
||||
export const useBackgroundTexture = () => {
|
||||
const applyBackgroundTexture = useCallback(
|
||||
(envConfig: EnvConfigType, viewSettings: ViewSettings) => {
|
||||
const textureId = viewSettings.backgroundTextureId;
|
||||
const textureOpacity = viewSettings.backgroundOpacity;
|
||||
const textureSize = viewSettings.backgroundSize;
|
||||
if (!textureId || textureId === 'none') return;
|
||||
const textureId = viewSettings.backgroundTextureId || 'none';
|
||||
|
||||
document.documentElement.style.setProperty('--bg-texture-opacity', `${textureOpacity}`);
|
||||
document.documentElement.style.setProperty('--bg-texture-size', textureSize);
|
||||
if (textureId !== 'none') {
|
||||
document.documentElement.style.setProperty(
|
||||
'--bg-texture-opacity',
|
||||
`${viewSettings.backgroundOpacity}`,
|
||||
);
|
||||
document.documentElement.style.setProperty(
|
||||
'--bg-texture-size',
|
||||
viewSettings.backgroundSize,
|
||||
);
|
||||
|
||||
const settings = useSettingsStore.getState().settings;
|
||||
const customTexture = settings.customTextures?.find((t) => t.id === textureId);
|
||||
const settings = useSettingsStore.getState().settings;
|
||||
const customTexture = settings.customTextures?.find((t) => t.id === textureId);
|
||||
|
||||
if (customTexture) {
|
||||
// Carry replica-sync metadata (contentId / bundleDir / byteSize)
|
||||
// through addTexture so the boot-time "ensure selected texture
|
||||
// is in the store" path doesn't drop them and silently un-
|
||||
// publish a remote-pulled record.
|
||||
useCustomTextureStore.getState().addTexture(customTexture.path, {
|
||||
name: customTexture.name,
|
||||
contentId: customTexture.contentId,
|
||||
bundleDir: customTexture.bundleDir,
|
||||
byteSize: customTexture.byteSize,
|
||||
animated: customTexture.animated,
|
||||
});
|
||||
if (customTexture) {
|
||||
// Carry replica-sync metadata (contentId / bundleDir / byteSize)
|
||||
// through addTexture so the boot-time "ensure selected texture
|
||||
// is in the store" path doesn't drop them and silently un-
|
||||
// publish a remote-pulled record.
|
||||
useCustomTextureStore.getState().addTexture(customTexture.path, {
|
||||
name: customTexture.name,
|
||||
contentId: customTexture.contentId,
|
||||
bundleDir: customTexture.bundleDir,
|
||||
byteSize: customTexture.byteSize,
|
||||
animated: customTexture.animated,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Always delegate to applyTexture: for a real texture it mounts/loads,
|
||||
// for 'none' it unmounts. The library and reader share one
|
||||
// #background-texture style element, so switching to a 'none' page must
|
||||
// actively clear a texture the other page mounted (issue #4743).
|
||||
useCustomTextureStore.getState().applyTexture(envConfig, textureId);
|
||||
},
|
||||
[],
|
||||
|
||||
@@ -324,6 +324,18 @@ export interface SystemSettings {
|
||||
libraryCoverFit: LibraryCoverFitType;
|
||||
libraryAutoColumns: boolean;
|
||||
libraryColumns: number;
|
||||
/**
|
||||
* Library page background texture, configured independently from the reader
|
||||
* background (issue #4743). When any of these is undefined the library
|
||||
* inherits the corresponding `globalViewSettings.background*` value, so an
|
||||
* existing user's bookshelf looks unchanged until they pick a library
|
||||
* texture. Device-local (the texture *selection* never syncs, matching the
|
||||
* reader's `backgroundTextureId`); only the imported image binaries sync via
|
||||
* the `texture` replica kind. Resolved by `getLibraryViewSettings`.
|
||||
*/
|
||||
libraryBackgroundTextureId?: string;
|
||||
libraryBackgroundOpacity?: number;
|
||||
libraryBackgroundSize?: string;
|
||||
customFonts: CustomFont[];
|
||||
customTextures: CustomTexture[];
|
||||
customDictionaries: ImportedDictionary[];
|
||||
|
||||
Reference in New Issue
Block a user