From 110b4b37cddc6f3302555f0a31ec786af15ad2f6 Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Sun, 11 May 2025 00:18:15 +0800 Subject: [PATCH] ui: various UI fixes and enhancements on mobile platforms (#1113) --- .../public/locales/ar/translation.json | 4 +- .../public/locales/de/translation.json | 6 +- .../public/locales/el/translation.json | 12 ++- .../public/locales/es/translation.json | 4 +- .../public/locales/fr/translation.json | 4 +- .../public/locales/hi/translation.json | 4 +- .../public/locales/id/translation.json | 4 +- .../public/locales/it/translation.json | 4 +- .../public/locales/ja/translation.json | 4 +- .../public/locales/ko/translation.json | 4 +- .../public/locales/pl/translation.json | 4 +- .../public/locales/pt/translation.json | 4 +- .../public/locales/ru/translation.json | 4 +- .../public/locales/tr/translation.json | 4 +- .../public/locales/uk/translation.json | 4 +- .../public/locales/vi/translation.json | 4 +- .../public/locales/zh-CN/translation.json | 4 +- .../public/locales/zh-TW/translation.json | 4 +- apps/readest-app/src/app/auth/page.tsx | 6 +- .../src/app/library/components/BookItem.tsx | 28 +++--- .../src/app/library/components/Bookshelf.tsx | 44 ++++++--- .../src/app/library/components/ImportMenu.tsx | 8 +- .../app/library/components/LibraryHeader.tsx | 97 +++++++++++-------- .../app/library/components/SettingsMenu.tsx | 6 +- .../src/app/reader/components/Reader.tsx | 2 +- .../app/reader/components/SettingsToggler.tsx | 3 + .../components/settings/SettingsDialog.tsx | 69 +++++++++++-- .../src/components/AboutWindow.tsx | 15 ++- apps/readest-app/src/components/Dialog.tsx | 27 +++--- apps/readest-app/src/hooks/useTheme.ts | 2 +- 30 files changed, 264 insertions(+), 125 deletions(-) diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 15d2055f..10c7a2cd 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -305,5 +305,7 @@ "Landscape": "الأفقي", "Open Last Book on Start": "فتح آخر كتاب عند البدء", "Checking for updates...": "جارٍ التحقق من التحديثات...", - "Error checking for updates": "خطأ في التحقق من التحديثات" + "Error checking for updates": "خطأ في التحقق من التحديثات", + "Details": "التفاصيل", + "Cancel Selection": "إلغاء التحديد" } diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index ebe71fb4..49fa574b 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -134,7 +134,7 @@ "Book downloaded: {{title}}": "Buch heruntergeladen: {{title}}", "Failed to download book: {{title}}": "Fehler beim Herunterladen des Buches: {{title}}", "Upload Book": "Buch hochladen", - "Auto Upload Books to Cloud": "Bücher automatisch in die Cloud hochladen", + "Auto Upload Books to Cloud": "Bücher automatisch hochladen", "{{percentage}}% of Cloud Storage Used.": "{{percentage}}% des Cloud-Speichers verwendet.", "Storage": "Speicher", "Book deleted: {{title}}": "Buch gelöscht: {{title}}", @@ -305,5 +305,7 @@ "Landscape": "Querformat", "Open Last Book on Start": "Letztes Buch beim Start öffnen", "Checking for updates...": "Auf Updates prüfen...", - "Error checking for updates": "Fehler beim Überprüfen auf Updates" + "Error checking for updates": "Fehler beim Überprüfen auf Updates", + "Details": "Details", + "Cancel Selection": "Auswahl abbrechen" } diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index 90aeeb9a..601c259a 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -134,12 +134,12 @@ "Book downloaded: {{title}}": "Το βιβλίο με τίτλο {{title}} κατέβηκε", "Failed to download book: {{title}}": "Αποτυχία λήψης βιβλίου: {{title}}", "Upload Book": "Ανέβασμα βιβλίου", - "Auto Upload Books to Cloud": "Αυτόματο ανέβασμα βιβλίων στο cloud", + "Auto Upload Books to Cloud": "Αυτόματη αποθήκευση στο cloud", "{{percentage}}% of Cloud Storage Used.": "{{percentage}}% της αποθήκευσης στο cloud χρησιμοποιήθηκε.", "Storage": "Αποθήκευση", "Book deleted: {{title}}": "Το βιβλίο με τίτλο {{title}} διαγράφηκε", "Failed to delete book: {{title}}": "Αποτυχία διαγραφής βιβλίου: {{title}}", - "Check Updates on Start": "Έλεγχος ενημερώσεων κατά την εκκίνηση", + "Check Updates on Start": "Αυτόματος έλεγχος ενημερώσεων", "Insufficient storage quota": "Ανεπαρκές όριο αποθήκευσης", "Font Weight": "Βάρος γραμματοσειράς", "Line Spacing": "Διάκενο γραμμών", @@ -296,14 +296,16 @@ "Grid": "Πλέγμα", "(from 'As You Like It', Act II)": "('Όπως σας αρέσει', Πράξη II)", "Link Color": "Χρώμα συνδέσμου", - "Volume Keys for Page Flip": "Πλήκτρα έντασης για ανατροπή σελίδας", + "Volume Keys for Page Flip": "Ανατροπή με πλήκτρα έντασης", "Clicks for Page Flip": "Κλικ για ανατροπή σελίδας", "Swap Clicks Area": "Ανταλλαγή περιοχής κλικ", "Screen": "Οθόνη", "Orientation": "Προσανατολισμός", "Portrait": "Πορτραίτο", "Landscape": "Τοπίο", - "Open Last Book on Start": "Άνοιγμα τελευταίου βιβλίου κατά την εκκίνηση", + "Open Last Book on Start": "Άνοιγμα τελευταίου βιβλίου", "Checking for updates...": "Έλεγχος για ενημερώσεις...", - "Error checking for updates": "Σφάλμα κατά τον έλεγχο για ενημερώσεις" + "Error checking for updates": "Σφάλμα κατά τον έλεγχο για ενημερώσεις", + "Details": "Πληρ.", + "Cancel Selection": "Ακύρωση επιλογής" } diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index a1c42be4..ce1d8a01 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -305,5 +305,7 @@ "Landscape": "Horizontal", "Open Last Book on Start": "Abrir último libro al iniciar", "Checking for updates...": "Comprobando actualizaciones...", - "Error checking for updates": "Error al comprobar actualizaciones" + "Error checking for updates": "Error al comprobar actualizaciones", + "Details": "Detalles", + "Cancel Selection": "Cancelar selección" } diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index e2cd3d74..f92ffced 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -305,5 +305,7 @@ "Landscape": "Paysage", "Open Last Book on Start": "Ouvrir le dernier livre au démarrage", "Checking for updates...": "Vérification des mises à jour...", - "Error checking for updates": "Erreur lors de la vérification des mises à jour" + "Error checking for updates": "Erreur lors de la vérification des mises à jour", + "Details": "Détails", + "Cancel Selection": "Annuler la sélection" } diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index 9800e6d9..3819017a 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -305,5 +305,7 @@ "Landscape": "लैंडस्केप", "Open Last Book on Start": "शुरू में अंतिम पुस्तक खोलें", "Checking for updates...": "अपडेट की जांच कर रहा है...", - "Error checking for updates": "अपडेट की जांच करते समय त्रुटि" + "Error checking for updates": "अपडेट की जांच करते समय त्रुटि", + "Details": "विवरण", + "Cancel Selection": "चयन रद्द करें" } diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index e1265f2f..3b8b7d14 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -305,5 +305,7 @@ "Landscape": "Lanskap", "Open Last Book on Start": "Buka Buku Terakhir saat Memulai", "Checking for updates...": "Memeriksa pembaruan...", - "Error checking for updates": "Kesalahan saat memeriksa pembaruan" + "Error checking for updates": "Kesalahan saat memeriksa pembaruan", + "Details": "Detail", + "Cancel Selection": "Batalkan Pilihan" } diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index 1312f842..fb7c9a73 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -305,5 +305,7 @@ "Landscape": "Paesaggio", "Open Last Book on Start": "Apri ultimo libro all'avvio", "Checking for updates...": "Controllo aggiornamenti...", - "Error checking for updates": "Errore durante il controllo degli aggiornamenti" + "Error checking for updates": "Errore durante il controllo degli aggiornamenti", + "Details": "Dettagli", + "Cancel Selection": "Annulla selezione" } diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index d776f9e4..a9d0977b 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -305,5 +305,7 @@ "Landscape": "横", "Open Last Book on Start": "開始時に最後の書籍を開く", "Checking for updates...": "更新を確認中...", - "Error checking for updates": "更新の確認中にエラーが発生しました" + "Error checking for updates": "更新の確認中にエラーが発生しました", + "Details": "詳細", + "Cancel Selection": "選択をキャンセル" } diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index 4df5284c..0204632c 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -305,5 +305,7 @@ "Landscape": "가로", "Open Last Book on Start": "시작 시 마지막 책 열기", "Checking for updates...": "업데이트 확인 중...", - "Error checking for updates": "업데이트 확인 중 오류 발생" + "Error checking for updates": "업데이트 확인 중 오류 발생", + "Details": "세부정보", + "Cancel Selection": "선택 취소" } diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index bd6adc27..d4ff10e7 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -305,5 +305,7 @@ "Landscape": "Krajobraz", "Open Last Book on Start": "Otwórz ostatnią książkę przy starcie", "Checking for updates...": "Sprawdzanie aktualizacji...", - "Error checking for updates": "Błąd podczas sprawdzania aktualizacji" + "Error checking for updates": "Błąd podczas sprawdzania aktualizacji", + "Details": "Szczegóły", + "Cancel Selection": "Anuluj zaznaczenie" } diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index bfde8c47..1610a1c5 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -305,5 +305,7 @@ "Landscape": "Paisagem", "Open Last Book on Start": "Abrir o Último Livro ao Iniciar", "Checking for updates...": "Verificando atualizações...", - "Error checking for updates": "Erro ao verificar atualizações" + "Error checking for updates": "Erro ao verificar atualizações", + "Details": "Detalhes", + "Cancel Selection": "Cancelar Seleção" } diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index 4a1dec9c..ce256759 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -305,5 +305,7 @@ "Landscape": "Ландшафт", "Open Last Book on Start": "Открыть последнюю книгу при запуске", "Checking for updates...": "Проверка обновлений...", - "Error checking for updates": "Ошибка при проверке обновлений" + "Error checking for updates": "Ошибка при проверке обновлений", + "Details": "Инфо", + "Cancel Selection": "Отменить выбор" } diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index f87ba5bf..99a7caa5 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -305,5 +305,7 @@ "Landscape": "Yatay", "Open Last Book on Start": "Açılışta Son Kitabı Aç", "Checking for updates...": "Yenilikler kontrol ediliyor...", - "Error checking for updates": "Güncellemeleri kontrol ederken hata oluştu" + "Error checking for updates": "Güncellemeleri kontrol ederken hata oluştu", + "Details": "Detaylar", + "Cancel Selection": "Işaretlemeyi İptal Et" } diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index 4e630079..321b8d04 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -305,5 +305,7 @@ "Landscape": "Ландшафт", "Open Last Book on Start": "Відкрити останню книгу при запуску", "Checking for updates...": "Перевірка наявності оновлень...", - "Error checking for updates": "Помилка перевірки наявності оновлень" + "Error checking for updates": "Помилка перевірки наявності оновлень", + "Details": "Деталі", + "Cancel Selection": "Скасувати вибір" } diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index 37bdf734..bda61374 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -305,5 +305,7 @@ "Landscape": "Phong cảnh", "Open Last Book on Start": "Mở sách cuối cùng khi khởi động", "Checking for updates...": "Đang kiểm tra cập nhật...", - "Error checking for updates": "Lỗi khi kiểm tra cập nhật" + "Error checking for updates": "Lỗi khi kiểm tra cập nhật", + "Details": "Chi tiết", + "Cancel Selection": "Hủy chọn" } diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index c155777d..de369280 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -305,5 +305,7 @@ "Landscape": "横屏", "Open Last Book on Start": "启动时打开上次阅读的书籍", "Checking for updates...": "检查更新中...", - "Error checking for updates": "检查更新时出错" + "Error checking for updates": "检查更新时出错", + "Details": "详情", + "Cancel Selection": "取消选择" } diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index 292fed1e..f709e393 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -305,5 +305,7 @@ "Landscape": "橫屏", "Open Last Book on Start": "啟動時打開上次閱讀的書籍", "Checking for updates...": "檢查更新中...", - "Error checking for updates": "檢查更新時出錯" + "Error checking for updates": "檢查更新時出錯", + "Details": "詳情", + "Cancel Selection": "取消選擇" } diff --git a/apps/readest-app/src/app/auth/page.tsx b/apps/readest-app/src/app/auth/page.tsx index cc6db434..3f8f030a 100644 --- a/apps/readest-app/src/app/auth/page.tsx +++ b/apps/readest-app/src/app/auth/page.tsx @@ -78,8 +78,8 @@ export default function AuthPage() { useTheme({ systemUIVisible: false }); const getTauriRedirectTo = (isOAuth: boolean) => { - if (process.env.NODE_ENV === 'production' || appService?.isMobile || USE_APPLE_SIGN_IN) { - if (appService?.isMobile) { + if (process.env.NODE_ENV === 'production' || appService?.isMobileApp || USE_APPLE_SIGN_IN) { + if (appService?.isMobileApp) { return isOAuth ? DEEPLINK_CALLBACK : WEB_AUTH_CALLBACK; } return DEEPLINK_CALLBACK; @@ -172,7 +172,7 @@ export default function AuthPage() { const startTauriOAuth = async () => { try { - if (process.env.NODE_ENV === 'production' || appService?.isMobile || USE_APPLE_SIGN_IN) { + if (process.env.NODE_ENV === 'production' || appService?.isMobileApp || USE_APPLE_SIGN_IN) { const { getCurrentWindow } = await import('@tauri-apps/api/window'); const currentWindow = getCurrentWindow(); currentWindow.listen('single-instance', ({ event, payload }) => { diff --git a/apps/readest-app/src/app/library/components/BookItem.tsx b/apps/readest-app/src/app/library/components/BookItem.tsx index 239916cf..6915f85e 100644 --- a/apps/readest-app/src/app/library/components/BookItem.tsx +++ b/apps/readest-app/src/app/library/components/BookItem.tsx @@ -100,7 +100,7 @@ const BookItem: React.FC = ({ {transferProgress !== null ? ( transferProgress === 100 ? null : (
= ({ ) ) : ( )} - + {!appService?.isMobile && ( + + )}
diff --git a/apps/readest-app/src/app/library/components/Bookshelf.tsx b/apps/readest-app/src/app/library/components/Bookshelf.tsx index 2e87d164..88d713dd 100644 --- a/apps/readest-app/src/app/library/components/Bookshelf.tsx +++ b/apps/readest-app/src/app/library/components/Bookshelf.tsx @@ -2,7 +2,7 @@ import clsx from 'clsx'; import * as React from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { useEffect, useRef, useState } from 'react'; -import { MdDelete, MdOpenInNew, MdOutlineCancel } from 'react-icons/md'; +import { MdDelete, MdOpenInNew, MdOutlineCancel, MdInfoOutline } from 'react-icons/md'; import { LuFolderPlus } from 'react-icons/lu'; import { PiPlus } from 'react-icons/pi'; import { Book, BooksGroup } from '@/types/book'; @@ -162,6 +162,13 @@ const Bookshelf: React.FC = ({ navigateToReader(router, selectedBooks); }; + const openBookDetails = () => { + const book = libraryBooks.find((book) => book.hash === selectedBooks[0]); + if (book) { + handleShowDetailsBook(book); + } + }; + const confirmDelete = async () => { selectedBooks.forEach((id) => { for (const book of libraryBooks.filter((book) => book.hash === id || book.groupId === id)) { @@ -290,14 +297,14 @@ const Bookshelf: React.FC = ({
+ - + {!appService?.isMobile && ( + + )}
)} diff --git a/apps/readest-app/src/app/library/components/ImportMenu.tsx b/apps/readest-app/src/app/library/components/ImportMenu.tsx index ca5e2d90..c1638bec 100644 --- a/apps/readest-app/src/app/library/components/ImportMenu.tsx +++ b/apps/readest-app/src/app/library/components/ImportMenu.tsx @@ -1,3 +1,5 @@ +import clsx from 'clsx'; +import { useEnv } from '@/context/EnvContext'; import { useTranslation } from '@/hooks/useTranslation'; import MenuItem from '@/components/MenuItem'; @@ -8,6 +10,7 @@ interface ImportMenuProps { const ImportMenu: React.FC = ({ setIsDropdownOpen, onImportBooks }) => { const _ = useTranslation(); + const { appService } = useEnv(); const handleImportBooks = () => { onImportBooks(); @@ -17,7 +20,10 @@ const ImportMenu: React.FC = ({ setIsDropdownOpen, onImportBook return (
diff --git a/apps/readest-app/src/app/library/components/LibraryHeader.tsx b/apps/readest-app/src/app/library/components/LibraryHeader.tsx index f19f5f8b..70a1d3d7 100644 --- a/apps/readest-app/src/app/library/components/LibraryHeader.tsx +++ b/apps/readest-app/src/app/library/components/LibraryHeader.tsx @@ -142,7 +142,7 @@ const LibraryHeader: React.FC = ({ setSearchQuery(''); throttledUpdateQueryParam(''); }} - className='text-gray-400 hover:text-gray-600' + className='pe-1 text-gray-400 hover:text-gray-600' aria-label={_('Clear Search')} > @@ -150,7 +150,10 @@ const LibraryHeader: React.FC = ({ )} @@ -160,47 +163,61 @@ const LibraryHeader: React.FC = ({ > - +
+ +
+ + )} -
- } - > - - - } - > - - - {appService?.hasWindowBar && ( - - )} -
+ {appService?.isMobile && isSelectMode ? ( +
+ +
+ ) : ( +
+ } + > + + + } + > + + + {appService?.hasWindowBar && ( + + )} +
+ )} ); diff --git a/apps/readest-app/src/app/library/components/SettingsMenu.tsx b/apps/readest-app/src/app/library/components/SettingsMenu.tsx index 852a71e7..f5fd5474 100644 --- a/apps/readest-app/src/app/library/components/SettingsMenu.tsx +++ b/apps/readest-app/src/app/library/components/SettingsMenu.tsx @@ -1,3 +1,4 @@ +import clsx from 'clsx'; import React, { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { PiUserCircle } from 'react-icons/pi'; @@ -142,7 +143,10 @@ const SettingsMenu: React.FC = ({ setIsDropdownOpen }) => { return (
{user ? ( = ({ ids }) => { }, []); useEffect(() => { - if (!appService?.isMobile) return; + if (!appService?.isMobileApp) return; const systemUIVisible = !!hoveredBookKey; setSystemUIVisibility({ visible: systemUIVisible, darkMode: isDarkMode }); if (systemUIVisible) { diff --git a/apps/readest-app/src/app/reader/components/SettingsToggler.tsx b/apps/readest-app/src/app/reader/components/SettingsToggler.tsx index b8172c3b..5902ebd6 100644 --- a/apps/readest-app/src/app/reader/components/SettingsToggler.tsx +++ b/apps/readest-app/src/app/reader/components/SettingsToggler.tsx @@ -1,14 +1,17 @@ import React from 'react'; import { RiFontSize } from 'react-icons/ri'; +import { useReaderStore } from '@/store/readerStore'; import { useTranslation } from '@/hooks/useTranslation'; import { useSettingsStore } from '@/store/settingsStore'; import Button from '@/components/Button'; const SettingsToggler = () => { const _ = useTranslation(); + const { setHoveredBookKey } = useReaderStore(); const { isFontLayoutSettingsDialogOpen, setFontLayoutSettingsDialogOpen } = useSettingsStore(); const handleToggleSettings = () => { + setHoveredBookKey(''); setFontLayoutSettingsDialogOpen(!isFontLayoutSettingsDialogOpen); }; return ( diff --git a/apps/readest-app/src/app/reader/components/settings/SettingsDialog.tsx b/apps/readest-app/src/app/reader/components/settings/SettingsDialog.tsx index efed82e7..0090fff9 100644 --- a/apps/readest-app/src/app/reader/components/settings/SettingsDialog.tsx +++ b/apps/readest-app/src/app/reader/components/settings/SettingsDialog.tsx @@ -1,6 +1,7 @@ import clsx from 'clsx'; -import React, { useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { BookConfig } from '@/types/book'; +import { useEnv } from '@/context/EnvContext'; import { useSettingsStore } from '@/store/settingsStore'; import { useTranslation } from '@/hooks/useTranslation'; import { RiFontSize } from 'react-icons/ri'; @@ -28,7 +29,10 @@ type TabConfig = { const SettingsDialog: React.FC<{ bookKey: string; config: BookConfig }> = ({ bookKey }) => { const _ = useTranslation(); + const { appService } = useEnv(); const [isRtl] = useState(() => getDirFromUILanguage() === 'rtl'); + const tabsRef = useRef(null); + const [showTabLabels, setShowTabLabels] = useState(false); const [activePanel, setActivePanel] = useState( (localStorage.getItem('lastConfigPanel') || 'Font') as SettingsPanelType, ); @@ -66,14 +70,56 @@ const SettingsDialog: React.FC<{ bookKey: string; config: BookConfig }> = ({ boo setFontLayoutSettingsDialogOpen(false); }; + useEffect(() => { + const container = tabsRef.current; + if (!container) return; + + const checkButtonWidths = () => { + const threshold = (container.clientWidth - 64) * 0.3; + const hideLabel = Array.from(container.querySelectorAll('button')).some((button) => { + const labelSpan = button.querySelector('span'); + const labelText = labelSpan?.textContent || ''; + const clone = button.cloneNode(true) as HTMLButtonElement; + clone.style.position = 'absolute'; + clone.style.visibility = 'hidden'; + clone.style.width = 'auto'; + const cloneSpan = clone.querySelector('span'); + if (cloneSpan) { + cloneSpan.classList.remove('hidden'); + cloneSpan.textContent = labelText; + } + document.body.appendChild(clone); + const fullWidth = clone.scrollWidth; + document.body.removeChild(clone); + return fullWidth > threshold; + }); + setShowTabLabels(!hideLabel); + }; + + checkButtonWidths(); + + const resizeObserver = new ResizeObserver(checkButtonWidths); + resizeObserver.observe(container); + const mutationObserver = new MutationObserver(checkButtonWidths); + mutationObserver.observe(container, { + subtree: true, + characterData: true, + }); + + return () => { + resizeObserver.disconnect(); + mutationObserver.disconnect(); + }; + }, []); + return ( <> -
+
{tabConfig.map(({ tab, icon: Icon, label }) => ( ))}
} >