forked from akai/readest
This commit is contained in:
@@ -690,5 +690,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "فشل في الحفظ التلقائي لغلاف الكتاب لشاشة القفل: {{error}}",
|
||||
"Download from Cloud": "تحميل من السحابة",
|
||||
"Upload to Cloud": "رفع إلى السحابة",
|
||||
"Clear Custom Fonts": "مسح الخطوط المخصصة"
|
||||
"Clear Custom Fonts": "مسح الخطوط المخصصة",
|
||||
"Columns": "الأعمدة"
|
||||
}
|
||||
|
||||
@@ -674,5 +674,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "লক স্ক্রিনের জন্য বইয়ের মলাট স্বয়ংক্রিয়ভাবে সংরক্ষণ করতে ব্যর্থ: {{error}}",
|
||||
"Download from Cloud": "ক্লাউড থেকে ডাউনলোড করুন",
|
||||
"Upload to Cloud": "ক্লাউডে আপলোড করুন",
|
||||
"Clear Custom Fonts": "কাস্টম ফন্টস মুছুন"
|
||||
"Clear Custom Fonts": "কাস্টম ফন্টস মুছুন",
|
||||
"Columns": "কলামস"
|
||||
}
|
||||
|
||||
@@ -670,5 +670,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "སྒྲོམ་སྒོར་དེབ་གནས་བཅས་པའི་སྤྱོད་བྱས་མ་ཐུབ།: {{error}}",
|
||||
"Download from Cloud": "སྤྲིན་ནས་ཕབ་སྟེ་འབེབས་",
|
||||
"Upload to Cloud": "སྤྲིན་ལ་ཡར་སྤེལ་",
|
||||
"Clear Custom Fonts": "རང་བཞིན་ཡིག་གཟུགས་སུབ་པ།"
|
||||
"Clear Custom Fonts": "རང་བཞིན་ཡིག་གཟུགས་སུབ་པ།",
|
||||
"Columns": "མཚན་ཉིད།"
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
"No supported files found. Supported formats: {{formats}}": "Keine unterstützten Dateien gefunden. Unterstützte Formate: {{formats}}",
|
||||
"Drop to Import Books": "Zum Importieren von Büchern ablegen",
|
||||
"Custom": "Eigen",
|
||||
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Die ganze Welt ist eine Bühne,\nUnd alle Männer und Frauen sind bloß Spieler;\nSie haben ihre Abgänge und ihre Auftritte,\nUnd ein Mann spielt in seinem Leben viele Rollen,\nSeine Taten sind sieben Zeitalter.\n\n— William Shakespeare",
|
||||
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Die ganze Welt ist eine Bühne,\nUnd alle Männer und Frauen sind bloß Spieler;\nSie haben ihre Abgänge und ihre Auftritte,\nUnd ein Mann spielt in seinem Leben viele Rollen,\nSeine Taten sind sieben Zeitalter.\n\n— William Shakespeare",
|
||||
"Custom Theme": "Benutzerdefiniertes Thema",
|
||||
"Theme Name": "Themenname",
|
||||
"Text Color": "Textfarbe",
|
||||
@@ -674,5 +674,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Automatisches Speichern des Buchcovers für den Sperrbildschirm fehlgeschlagen: {{error}}",
|
||||
"Download from Cloud": "Aus der Cloud herunterladen",
|
||||
"Upload to Cloud": "In die Cloud hochladen",
|
||||
"Clear Custom Fonts": "Benutzerdefinierte Schriftarten löschen"
|
||||
"Clear Custom Fonts": "Benutzerdefinierte Schriftarten löschen",
|
||||
"Columns": "Spalten"
|
||||
}
|
||||
|
||||
@@ -674,5 +674,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Αποτυχία αυτόματης αποθήκευσης εξωφύλλου βιβλίου για την οθόνη κλειδώματος: {{error}}",
|
||||
"Download from Cloud": "Λήψη από το Cloud",
|
||||
"Upload to Cloud": "Ανέβασμα στο Cloud",
|
||||
"Clear Custom Fonts": "Καθαρισμός προσαρμοσμένων γραμματοσειρών"
|
||||
"Clear Custom Fonts": "Καθαρισμός προσαρμοσμένων γραμματοσειρών",
|
||||
"Columns": "Στήλες"
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
"No supported files found. Supported formats: {{formats}}": "No se encontraron archivos compatibles. Formatos compatibles: {{formats}}",
|
||||
"Drop to Import Books": "Soltar para importar libros",
|
||||
"Custom": "Personalizado",
|
||||
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Todo el mundo es un escenario,\nY todos los hombres y mujeres son meros actores;\nTienen sus salidas y sus entradas,\nY un hombre en su tiempo interpreta muchos papeles,\nSus actos son siete edades.\n\n— William Shakespeare",
|
||||
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Todo el mundo es un escenario,\nY todos los hombres y mujeres son meros actores;\nTienen sus salidas y sus entradas,\nY un hombre en su tiempo interpreta muchos papeles,\nSus actos son siete edades.\n\n— William Shakespeare",
|
||||
"Custom Theme": "Tema personalizado",
|
||||
"Theme Name": "Nombre del tema",
|
||||
"Text Color": "Color del texto",
|
||||
@@ -678,5 +678,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Error al guardar automáticamente la portada del libro para la pantalla de bloqueo: {{error}}",
|
||||
"Download from Cloud": "Descargar desde la nube",
|
||||
"Upload to Cloud": "Subir a la nube",
|
||||
"Clear Custom Fonts": "Limpiar fuentes personalizadas"
|
||||
"Clear Custom Fonts": "Limpiar fuentes personalizadas",
|
||||
"Columns": "Columnas"
|
||||
}
|
||||
|
||||
@@ -674,5 +674,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "ذخیرهی خودکار جلد کتاب برای صفحهی قفل ناموفق بود: {{error}}",
|
||||
"Download from Cloud": "دانلود از فضای ابری",
|
||||
"Upload to Cloud": "آپلود به فضای ابری",
|
||||
"Clear Custom Fonts": "پاککردن فونتهای سفارشی"
|
||||
"Clear Custom Fonts": "پاککردن فونتهای سفارشی",
|
||||
"Columns": "ستونها"
|
||||
}
|
||||
|
||||
@@ -678,5 +678,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Échec de l'enregistrement automatique de la couverture du livre pour l'écran de verrouillage : {{error}}",
|
||||
"Download from Cloud": "Télécharger depuis le Cloud",
|
||||
"Upload to Cloud": "Téléverser vers le Cloud",
|
||||
"Clear Custom Fonts": "Effacer les Polices Personnalisées"
|
||||
"Clear Custom Fonts": "Effacer les Polices Personnalisées",
|
||||
"Columns": "Colonnes"
|
||||
}
|
||||
|
||||
@@ -674,5 +674,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "लॉक स्क्रीन के लिए पुस्तक कवर स्वचालित रूप से सहेजने में विफल: {{error}}",
|
||||
"Download from Cloud": "क्लाउड से डाउनलोड करें",
|
||||
"Upload to Cloud": "क्लाउड पर अपलोड करें",
|
||||
"Clear Custom Fonts": "कस्टम फ़ॉन्ट साफ़ करें"
|
||||
"Clear Custom Fonts": "कस्टम फ़ॉन्ट साफ़ करें",
|
||||
"Columns": "कॉलम"
|
||||
}
|
||||
|
||||
@@ -670,5 +670,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Gagal menyimpan otomatis sampul buku untuk layar kunci: {{error}}",
|
||||
"Download from Cloud": "Unduh dari Cloud",
|
||||
"Upload to Cloud": "Unggah ke Cloud",
|
||||
"Clear Custom Fonts": "Bersihkan Font Kustom"
|
||||
"Clear Custom Fonts": "Bersihkan Font Kustom",
|
||||
"Columns": "Kolom"
|
||||
}
|
||||
|
||||
@@ -678,5 +678,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Impossibile salvare automaticamente la copertina del libro per la schermata di blocco: {{error}}",
|
||||
"Download from Cloud": "Scarica dal Cloud",
|
||||
"Upload to Cloud": "Carica sul Cloud",
|
||||
"Clear Custom Fonts": "Pulisci Font Personalizzati"
|
||||
"Clear Custom Fonts": "Pulisci Font Personalizzati",
|
||||
"Columns": "Colonne"
|
||||
}
|
||||
|
||||
@@ -670,5 +670,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "ロック画面の本のカバーの自動保存に失敗しました:{{error}}",
|
||||
"Download from Cloud": "クラウドからダウンロード",
|
||||
"Upload to Cloud": "クラウドにアップロード",
|
||||
"Clear Custom Fonts": "カスタムフォントをクリア"
|
||||
"Clear Custom Fonts": "カスタムフォントをクリア",
|
||||
"Columns": "列"
|
||||
}
|
||||
|
||||
@@ -670,5 +670,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "잠금 화면용 책 표지 자동 저장 실패: {{error}}",
|
||||
"Download from Cloud": "클라우드에서 다운로드",
|
||||
"Upload to Cloud": "클라우드에 업로드",
|
||||
"Clear Custom Fonts": "사용자 정의 글꼴 지우기"
|
||||
"Clear Custom Fonts": "사용자 정의 글꼴 지우기",
|
||||
"Columns": "열"
|
||||
}
|
||||
|
||||
@@ -670,5 +670,6 @@
|
||||
"Sunset": "Matahari Terbenam",
|
||||
"Reveal in Finder": "Tunjukkan dalam Finder",
|
||||
"Reveal in File Explorer": "Tunjukkan dalam File Explorer",
|
||||
"Reveal in Folder": "Tunjukkan dalam Folder"
|
||||
"Reveal in Folder": "Tunjukkan dalam Folder",
|
||||
"Columns": "Lajur"
|
||||
}
|
||||
|
||||
@@ -674,5 +674,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Automatisch opslaan van boekomslag voor vergrendelscherm mislukt: {{error}}",
|
||||
"Download from Cloud": "Downloaden van Cloud",
|
||||
"Upload to Cloud": "Uploaden naar Cloud",
|
||||
"Clear Custom Fonts": "Aangepaste Lettertypen Wissen"
|
||||
"Clear Custom Fonts": "Aangepaste Lettertypen Wissen",
|
||||
"Columns": "Kolommen"
|
||||
}
|
||||
|
||||
@@ -682,5 +682,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Nie udało się automatycznie zapisać okładki książki dla ekranu blokady: {{error}}",
|
||||
"Download from Cloud": "Pobierz z chmury",
|
||||
"Upload to Cloud": "Prześlij do chmury",
|
||||
"Clear Custom Fonts": "Wyczyść niestandardowe czcionki"
|
||||
"Clear Custom Fonts": "Wyczyść niestandardowe czcionki",
|
||||
"Columns": "Kolumny"
|
||||
}
|
||||
|
||||
@@ -678,5 +678,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Falha ao salvar automaticamente a capa do livro para a tela de bloqueio: {{error}}",
|
||||
"Download from Cloud": "Baixar da Nuvem",
|
||||
"Upload to Cloud": "Enviar para a Nuvem",
|
||||
"Clear Custom Fonts": "Limpar Fontes Personalizadas"
|
||||
"Clear Custom Fonts": "Limpar Fontes Personalizadas",
|
||||
"Columns": "Colunas"
|
||||
}
|
||||
|
||||
@@ -682,5 +682,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Не удалось автоматически сохранить обложку книги для экрана блокировки: {{error}}",
|
||||
"Download from Cloud": "Скачать из облака",
|
||||
"Upload to Cloud": "Загрузить в облако",
|
||||
"Clear Custom Fonts": "Очистить пользовательские шрифты"
|
||||
"Clear Custom Fonts": "Очистить пользовательские шрифты",
|
||||
"Columns": "Колонки"
|
||||
}
|
||||
|
||||
@@ -674,5 +674,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "අගුළු තිරය සඳහා පොත් ආවරණය ස්වයංක්රීයව සුරකිීමට අසමත් විය: {{error}}",
|
||||
"Download from Cloud": "කලාඬයෙන් බාගත කරන්න",
|
||||
"Upload to Cloud": "කලාඬයට උඩුගත කරන්න",
|
||||
"Clear Custom Fonts": "අභිරුචි අකුරු පැහැදිලි කරන්න"
|
||||
"Clear Custom Fonts": "අභිරුචි අකුරු පැහැදිලි කරන්න",
|
||||
"Columns": "තීරු"
|
||||
}
|
||||
|
||||
@@ -674,5 +674,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Kunde inte autospara bokomslag för låsskärm: {{error}}",
|
||||
"Download from Cloud": "Ladda ner från molnet",
|
||||
"Upload to Cloud": "Ladda upp till molnet",
|
||||
"Clear Custom Fonts": "Rensa anpassade typsnitt"
|
||||
"Clear Custom Fonts": "Rensa anpassade typsnitt",
|
||||
"Columns": "Kolumner"
|
||||
}
|
||||
|
||||
@@ -674,5 +674,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "பூட்டு திரைக்கான புத்தகக் கோப்பை தானாகச் சேமிக்க முடியவில்லை: {{error}}",
|
||||
"Download from Cloud": "மேகத்திலிருந்து பதிவிறக்கு செய்யவும்",
|
||||
"Upload to Cloud": "மேகத்திற்கு பதிவேற்றவும்",
|
||||
"Clear Custom Fonts": "தனிப்பயன் எழுத்துருக்களை அழிக்கவும்"
|
||||
"Clear Custom Fonts": "தனிப்பயன் எழுத்துருக்களை அழிக்கவும்",
|
||||
"Columns": "நெடுவரிசைகள்"
|
||||
}
|
||||
|
||||
@@ -670,5 +670,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "ไม่สามารถบันทึกปกหนังสือสำหรับหน้าจอล็อกโดยอัตโนมัติ: {{error}}",
|
||||
"Download from Cloud": "ดาวน์โหลดจากคลาวด์",
|
||||
"Upload to Cloud": "อัปโหลดไปยังคลาวด์",
|
||||
"Clear Custom Fonts": "ล้างฟอนต์กำหนดเอง"
|
||||
"Clear Custom Fonts": "ล้างฟอนต์กำหนดเอง",
|
||||
"Columns": "คอลัมน์"
|
||||
}
|
||||
|
||||
@@ -674,5 +674,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Kitap kapağı kilit ekranı için otomatik kaydedilemedi: {{error}}",
|
||||
"Download from Cloud": "Buluttan İndir",
|
||||
"Upload to Cloud": "Buluta Yükle",
|
||||
"Clear Custom Fonts": "Özel Yazı Tiplerini Temizle"
|
||||
"Clear Custom Fonts": "Özel Yazı Tiplerini Temizle",
|
||||
"Columns": "Sütunlar"
|
||||
}
|
||||
|
||||
@@ -682,5 +682,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Не вдалося автоматично зберегти обкладинку книги для екрана блокування: {{error}}",
|
||||
"Download from Cloud": "Завантажити з хмари",
|
||||
"Upload to Cloud": "Завантажити в хмару",
|
||||
"Clear Custom Fonts": "Очистити користувацькі шрифти"
|
||||
"Clear Custom Fonts": "Очистити користувацькі шрифти",
|
||||
"Columns": "Стовпці"
|
||||
}
|
||||
|
||||
@@ -670,5 +670,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "Không thể tự động lưu bìa sách cho màn hình khóa: {{error}}",
|
||||
"Download from Cloud": "Tải xuống từ đám mây",
|
||||
"Upload to Cloud": "Tải lên đám mây",
|
||||
"Clear Custom Fonts": "Xóa phông chữ tùy chỉnh"
|
||||
"Clear Custom Fonts": "Xóa phông chữ tùy chỉnh",
|
||||
"Columns": "Cột"
|
||||
}
|
||||
|
||||
@@ -670,5 +670,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "自动保存锁屏书籍封面失败:{{error}}",
|
||||
"Download from Cloud": "从云端下载",
|
||||
"Upload to Cloud": "上传到云端",
|
||||
"Clear Custom Fonts": "清除自定义字体"
|
||||
"Clear Custom Fonts": "清除自定义字体",
|
||||
"Columns": "列数"
|
||||
}
|
||||
|
||||
@@ -670,5 +670,6 @@
|
||||
"Failed to auto-save book cover for lock screen: {{error}}": "自動保存鎖定螢幕書籍封面失敗:{{error}}",
|
||||
"Download from Cloud": "從雲端下載",
|
||||
"Upload to Cloud": "上傳到雲端",
|
||||
"Clear Custom Fonts": "清除自訂字型"
|
||||
"Clear Custom Fonts": "清除自訂字型",
|
||||
"Columns": "欄數"
|
||||
}
|
||||
|
||||
@@ -322,6 +322,12 @@ const Bookshelf: React.FC<BookshelfProps> = ({
|
||||
viewMode === 'grid' && 'sm:grid-cols-4 md:grid-cols-6 xl:grid-cols-8 2xl:grid-cols-12',
|
||||
viewMode === 'list' && 'flex flex-col',
|
||||
)}
|
||||
style={{
|
||||
gridTemplateColumns:
|
||||
viewMode === 'grid' && !settings.libraryAutoColumns
|
||||
? `repeat(${settings.libraryColumns}, minmax(0, 1fr))`
|
||||
: undefined,
|
||||
}}
|
||||
role='main'
|
||||
aria-label={_('Bookshelf')}
|
||||
>
|
||||
|
||||
@@ -105,6 +105,8 @@ const LibraryHeader: React.FC<LibraryHeaderProps> = ({
|
||||
|
||||
if (!insets) return null;
|
||||
|
||||
const isMobile = appService?.isMobile || window.innerWidth <= 640;
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={headerRef}
|
||||
@@ -138,12 +140,12 @@ const LibraryHeader: React.FC<LibraryHeaderProps> = ({
|
||||
onChange={handleSearchChange}
|
||||
spellCheck='false'
|
||||
className={clsx(
|
||||
'input rounded-badge h-9 w-full pl-10 pr-10 sm:h-7',
|
||||
'input rounded-badge h-9 w-full pl-10 pr-[30%] sm:h-7',
|
||||
viewSettings?.isEink
|
||||
? 'border-1 border-base-content focus:border-base-content'
|
||||
: 'bg-base-300/45 border-none',
|
||||
'font-sans text-sm font-light',
|
||||
'placeholder:text-base-content/50',
|
||||
'placeholder:text-base-content/50 truncate',
|
||||
'focus:outline-none focus:ring-0',
|
||||
)}
|
||||
/>
|
||||
@@ -167,14 +169,14 @@ const LibraryHeader: React.FC<LibraryHeaderProps> = ({
|
||||
label={_('Import Books')}
|
||||
className={clsx(
|
||||
'exclude-title-bar-mousedown dropdown-bottom flex h-6 cursor-pointer justify-center',
|
||||
appService?.isMobile ? 'dropdown-end' : 'dropdown-center',
|
||||
isMobile ? 'dropdown-end' : 'dropdown-center',
|
||||
)}
|
||||
buttonClassName='p-0 h-6 min-h-6 w-6 flex items-center justify-center'
|
||||
toggleButton={<PiPlus role='none' className='m-0.5 h-5 w-5' />}
|
||||
>
|
||||
<ImportMenu onImportBooks={onImportBooks} />
|
||||
</Dropdown>
|
||||
{appService?.isMobile ? null : (
|
||||
{isMobile ? null : (
|
||||
<button
|
||||
onClick={onToggleSelectMode}
|
||||
aria-label={_('Select Books')}
|
||||
|
||||
@@ -3,9 +3,11 @@ import { useRouter, useSearchParams } from 'next/navigation';
|
||||
import { useEnv } from '@/context/EnvContext';
|
||||
import { useSettingsStore } from '@/store/settingsStore';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
|
||||
import { LibraryCoverFitType, LibrarySortByType, LibraryViewModeType } from '@/types/settings';
|
||||
import { saveSysSettings } from '@/helpers/settings';
|
||||
import { navigateToLibrary } from '@/utils/nav';
|
||||
import NumberInput from '@/components/settings/NumberInput';
|
||||
import MenuItem from '@/components/MenuItem';
|
||||
import Menu from '@/components/Menu';
|
||||
|
||||
@@ -16,6 +18,7 @@ interface ViewMenuProps {
|
||||
const ViewMenu: React.FC<ViewMenuProps> = ({ setIsDropdownOpen }) => {
|
||||
const _ = useTranslation();
|
||||
const router = useRouter();
|
||||
const iconSize = useResponsiveSize(16);
|
||||
const searchParams = useSearchParams();
|
||||
const { envConfig } = useEnv();
|
||||
const { settings } = useSettingsStore();
|
||||
@@ -24,6 +27,8 @@ const ViewMenu: React.FC<ViewMenuProps> = ({ setIsDropdownOpen }) => {
|
||||
const sortBy = settings.librarySortBy;
|
||||
const isAscending = settings.librarySortAscending;
|
||||
const coverFit = settings.libraryCoverFit;
|
||||
const autoColumns = settings.libraryAutoColumns;
|
||||
const columns = settings.libraryColumns;
|
||||
|
||||
const viewOptions = [
|
||||
{ label: _('List'), value: 'list' },
|
||||
@@ -66,6 +71,16 @@ const ViewMenu: React.FC<ViewMenuProps> = ({ setIsDropdownOpen }) => {
|
||||
navigateToLibrary(router, `${params.toString()}`);
|
||||
};
|
||||
|
||||
const handleToggleAutoColumns = () => {
|
||||
const newValue = !settings.libraryAutoColumns;
|
||||
saveSysSettings(envConfig, 'libraryAutoColumns', newValue);
|
||||
};
|
||||
|
||||
const handleSetColumns = (value: number) => {
|
||||
saveSysSettings(envConfig, 'libraryColumns', value);
|
||||
saveSysSettings(envConfig, 'libraryAutoColumns', false);
|
||||
};
|
||||
|
||||
const handleSetSortBy = (value: LibrarySortByType) => {
|
||||
saveSysSettings(envConfig, 'librarySortBy', value);
|
||||
setIsDropdownOpen?.(false);
|
||||
@@ -99,6 +114,28 @@ const ViewMenu: React.FC<ViewMenuProps> = ({ setIsDropdownOpen }) => {
|
||||
/>
|
||||
))}
|
||||
<hr aria-hidden='true' className='border-base-200 my-1' />
|
||||
<MenuItem label={_('Columns')} buttonClass='h-8' labelClass='text-sm sm:text-xs' disabled />
|
||||
<MenuItem
|
||||
label={_('Auto')}
|
||||
buttonClass='h-10'
|
||||
toggled={autoColumns}
|
||||
disabled={viewMode === 'list'}
|
||||
siblings={
|
||||
<NumberInput
|
||||
className='!h-10 !p-0 !pe-1 !ps-0'
|
||||
iconSize={iconSize}
|
||||
inputClassName={autoColumns ? 'opacity-50 !p-0 !w-6' : 'p-0 !w-6'}
|
||||
label={''}
|
||||
value={columns}
|
||||
disabled={viewMode === 'list'}
|
||||
onChange={handleSetColumns}
|
||||
min={window.innerWidth < 640 ? 1 : window.innerWidth < 1024 ? 2 : 3}
|
||||
max={window.innerWidth < 640 ? 4 : window.innerWidth < 1024 ? 6 : 12}
|
||||
/>
|
||||
}
|
||||
onClick={() => handleToggleAutoColumns()}
|
||||
/>
|
||||
<hr aria-hidden='true' className='border-base-200 my-1' />
|
||||
<MenuItem
|
||||
label={_('Book Covers')}
|
||||
buttonClass='h-8'
|
||||
|
||||
@@ -89,6 +89,9 @@ const Dropdown: React.FC<DropdownProps> = ({
|
||||
};
|
||||
|
||||
const handleBlur = (e: React.FocusEvent) => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
return;
|
||||
}
|
||||
if (!containerRef.current) return;
|
||||
if (!containerRef.current.contains(e.relatedTarget as Node)) {
|
||||
setIsFocused(false);
|
||||
|
||||
@@ -19,6 +19,7 @@ interface MenuItemProps {
|
||||
Icon?: React.ReactNode | IconType;
|
||||
iconClassName?: string;
|
||||
children?: React.ReactNode;
|
||||
siblings?: React.ReactNode;
|
||||
onClick?: () => void;
|
||||
setIsDropdownOpen?: (isOpen: boolean) => void;
|
||||
}
|
||||
@@ -37,6 +38,7 @@ const MenuItem: React.FC<MenuItemProps> = ({
|
||||
Icon,
|
||||
iconClassName,
|
||||
children,
|
||||
siblings,
|
||||
onClick,
|
||||
setIsDropdownOpen,
|
||||
}) => {
|
||||
@@ -123,22 +125,27 @@ const MenuItem: React.FC<MenuItemProps> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
role={disabled ? 'none' : 'menuitem'}
|
||||
aria-label={toggled !== undefined ? `${label} - ${toggled ? _('ON') : _('OFF')}` : undefined}
|
||||
aria-live={toggled === undefined ? 'polite' : 'off'}
|
||||
tabIndex={disabled ? -1 : 0}
|
||||
className={clsx(
|
||||
'hover:bg-base-300 text-base-content flex w-full flex-col items-center justify-center rounded-md p-1 py-[10px]',
|
||||
disabled && 'btn-disabled text-gray-400',
|
||||
buttonClass,
|
||||
)}
|
||||
title={tooltip ? tooltip : ''}
|
||||
onClick={handleClick}
|
||||
disabled={disabled}
|
||||
>
|
||||
{buttonContent}
|
||||
</button>
|
||||
<div className='flex'>
|
||||
<button
|
||||
role={disabled ? 'none' : 'menuitem'}
|
||||
aria-label={
|
||||
toggled !== undefined ? `${label} - ${toggled ? _('ON') : _('OFF')}` : undefined
|
||||
}
|
||||
aria-live={toggled === undefined ? 'polite' : 'off'}
|
||||
tabIndex={disabled ? -1 : 0}
|
||||
className={clsx(
|
||||
'hover:bg-base-300 text-base-content flex w-full flex-col items-center justify-center rounded-md p-1 py-[10px]',
|
||||
disabled && 'btn-disabled text-gray-400',
|
||||
buttonClass,
|
||||
)}
|
||||
title={tooltip ? tooltip : ''}
|
||||
onClick={handleClick}
|
||||
disabled={disabled}
|
||||
>
|
||||
{buttonContent}
|
||||
</button>
|
||||
{siblings}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ import { useTranslation } from '@/hooks/useTranslation';
|
||||
|
||||
interface NumberInputProps {
|
||||
className?: string;
|
||||
inputClassName?: string;
|
||||
label: string;
|
||||
iconSize?: number;
|
||||
value: number;
|
||||
min: number;
|
||||
max: number;
|
||||
@@ -16,7 +18,9 @@ interface NumberInputProps {
|
||||
|
||||
const NumberInput: React.FC<NumberInputProps> = ({
|
||||
className,
|
||||
inputClassName,
|
||||
label,
|
||||
iconSize,
|
||||
value,
|
||||
onChange,
|
||||
min,
|
||||
@@ -70,6 +74,7 @@ const NumberInput: React.FC<NumberInputProps> = ({
|
||||
return (
|
||||
<div className={clsx('config-item', className)}>
|
||||
<span className='text-base-content line-clamp-2'>{label}</span>
|
||||
{iconSize && <span style={{ minWidth: `${iconSize}px` }} />}
|
||||
<div className='text-base-content flex items-center gap-2'>
|
||||
<input
|
||||
type='text'
|
||||
@@ -79,14 +84,15 @@ const NumberInput: React.FC<NumberInputProps> = ({
|
||||
onChange={handleChange}
|
||||
onBlur={handleOnBlur}
|
||||
className={clsx(
|
||||
'input input-ghost settings-content text-base-content w-16 max-w-xs rounded border-0 bg-transparent py-1 pe-3 ps-1 text-right !outline-none',
|
||||
'input input-ghost settings-content text-base-content w-16 max-w-xs rounded border-0 bg-transparent pe-3 !outline-none',
|
||||
label && 'py-1 ps-1 text-right',
|
||||
disabled && 'input-disabled cursor-not-allowed disabled:bg-transparent',
|
||||
inputClassName,
|
||||
)}
|
||||
onFocus={(e) => e.target.select()}
|
||||
/>
|
||||
<button
|
||||
tabIndex={disabled ? -1 : 0}
|
||||
disabled={value <= min || disabled}
|
||||
aria-label={_('Decrease')}
|
||||
onClick={decrement}
|
||||
className={`btn btn-circle btn-sm ${value <= min || disabled ? 'btn-disabled !bg-opacity-5' : ''}`}
|
||||
@@ -95,7 +101,6 @@ const NumberInput: React.FC<NumberInputProps> = ({
|
||||
</button>
|
||||
<button
|
||||
tabIndex={disabled ? -1 : 0}
|
||||
disabled={value >= max || disabled}
|
||||
aria-label={_('Increase')}
|
||||
onClick={increment}
|
||||
className={`btn btn-circle btn-sm ${value >= max || disabled ? 'btn-disabled !bg-opacity-5' : ''}`}
|
||||
|
||||
@@ -53,6 +53,7 @@ import {
|
||||
DEFAULT_TRANSLATOR_CONFIG,
|
||||
DEFAULT_FIXED_LAYOUT_VIEW_SETTINGS,
|
||||
SETTINGS_FILENAME,
|
||||
DEFAULT_MOBILE_SYSTEM_SETTINGS,
|
||||
} from './constants';
|
||||
import { fetch as tauriFetch } from '@tauri-apps/plugin-http';
|
||||
import { getOSPlatform, getTargetLang, isCJKEnv, isContentURI, isValidURL } from '@/utils/misc';
|
||||
@@ -195,6 +196,7 @@ export abstract class BaseAppService implements AppService {
|
||||
async loadSettings(): Promise<SystemSettings> {
|
||||
const defaultSettings: SystemSettings = {
|
||||
...DEFAULT_SYSTEM_SETTINGS,
|
||||
...(this.isMobile ? DEFAULT_MOBILE_SYSTEM_SETTINGS : {}),
|
||||
version: SYSTEM_SETTINGS_VERSION,
|
||||
localBooksDir: await this.fs.getPrefix('Books'),
|
||||
koreaderSyncDeviceId: uuidv4(),
|
||||
@@ -215,8 +217,16 @@ export abstract class BaseAppService implements AppService {
|
||||
if (this.isAppDataSandbox || version < SYSTEM_SETTINGS_VERSION) {
|
||||
settings.version = SYSTEM_SETTINGS_VERSION;
|
||||
}
|
||||
settings = { ...DEFAULT_SYSTEM_SETTINGS, ...settings };
|
||||
settings.globalReadSettings = { ...DEFAULT_READSETTINGS, ...settings.globalReadSettings };
|
||||
settings = {
|
||||
...DEFAULT_SYSTEM_SETTINGS,
|
||||
...(this.isMobile ? DEFAULT_MOBILE_SYSTEM_SETTINGS : {}),
|
||||
...settings,
|
||||
};
|
||||
settings.globalReadSettings = {
|
||||
...DEFAULT_READSETTINGS,
|
||||
...(this.isMobile ? DEFAULT_MOBILE_READSETTINGS : {}),
|
||||
...settings.globalReadSettings,
|
||||
};
|
||||
settings.globalViewSettings = {
|
||||
...this.getDefaultViewSettings(),
|
||||
...settings.globalViewSettings,
|
||||
|
||||
@@ -72,6 +72,8 @@ export const DEFAULT_SYSTEM_SETTINGS: Partial<SystemSettings> = {
|
||||
librarySortBy: 'updated',
|
||||
librarySortAscending: false,
|
||||
libraryCoverFit: 'crop',
|
||||
libraryAutoColumns: true,
|
||||
libraryColumns: 6,
|
||||
|
||||
kosync: DEFAULT_KOSYNC_SETTINGS,
|
||||
|
||||
@@ -80,6 +82,10 @@ export const DEFAULT_SYSTEM_SETTINGS: Partial<SystemSettings> = {
|
||||
lastSyncedAtNotes: 0,
|
||||
};
|
||||
|
||||
export const DEFAULT_MOBILE_SYSTEM_SETTINGS: Partial<SystemSettings> = {
|
||||
libraryColumns: 3,
|
||||
};
|
||||
|
||||
export const HIGHLIGHT_COLOR_HEX: Record<HighlightColor, string> = {
|
||||
red: '#f87171', // red-400
|
||||
yellow: '#facc15', // yellow-400
|
||||
|
||||
@@ -63,6 +63,8 @@ export interface SystemSettings {
|
||||
librarySortBy: LibrarySortByType;
|
||||
librarySortAscending: boolean;
|
||||
libraryCoverFit: LibraryCoverFitType;
|
||||
libraryAutoColumns: boolean;
|
||||
libraryColumns: number;
|
||||
customFonts: CustomFont[];
|
||||
customTextures: CustomTexture[];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user