From dbee0548386fca2315dd36e62dafe67e24b50c86 Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Fri, 22 Aug 2025 18:17:57 +0800 Subject: [PATCH] feat: apply custom fonts directly in custom font panel (#1870) --- .../public/locales/ar/translation.json | 3 +- .../public/locales/bo/translation.json | 3 +- .../public/locales/de/translation.json | 3 +- .../public/locales/el/translation.json | 3 +- .../public/locales/es/translation.json | 3 +- .../public/locales/fr/translation.json | 3 +- .../public/locales/hi/translation.json | 3 +- .../public/locales/id/translation.json | 3 +- .../public/locales/it/translation.json | 3 +- .../public/locales/ja/translation.json | 3 +- .../public/locales/ko/translation.json | 3 +- .../public/locales/nl/translation.json | 3 +- .../public/locales/pl/translation.json | 3 +- .../public/locales/pt/translation.json | 3 +- .../public/locales/ru/translation.json | 3 +- .../public/locales/th/translation.json | 3 +- .../public/locales/tr/translation.json | 3 +- .../public/locales/uk/translation.json | 3 +- .../public/locales/vi/translation.json | 3 +- .../public/locales/zh-CN/translation.json | 3 +- .../public/locales/zh-TW/translation.json | 3 +- .../components/annotator/TranslatorPopup.tsx | 9 ++-- .../components/settings/CustomFonts.tsx | 49 ++++++++++++++++--- .../reader/components/settings/FontPanel.tsx | 10 +++- .../components/settings/SettingsDialog.tsx | 5 +- 25 files changed, 102 insertions(+), 34 deletions(-) diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 9faea47f..53f3b67f 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -532,5 +532,6 @@ "Select Image": "حدد صورة", "Select Video": "حدد فيديو", "Select Audio": "حدد صوت", - "Select Fonts": "حدد الخطوط" + "Select Fonts": "حدد الخطوط", + "Supported font formats: .ttf, .odf, .woff, .woff2": "تنسيقات الخط المدعومة: .ttf، .odf، .woff، .woff2" } diff --git a/apps/readest-app/public/locales/bo/translation.json b/apps/readest-app/public/locales/bo/translation.json index e4a85d7a..695e7d39 100644 --- a/apps/readest-app/public/locales/bo/translation.json +++ b/apps/readest-app/public/locales/bo/translation.json @@ -512,5 +512,6 @@ "Select Image": "རི་མོ་འདེམས་པ།", "Select Video": "བརྙན་ཟློས་འདེམས་པ།", "Select Audio": "སྒྲ་ཟློས་འདེམས་པ།", - "Select Fonts": "ཡིག་གཟུགས་འདེམས་པ།" + "Select Fonts": "ཡིག་གཟུགས་འདེམས་པ།", + "Supported font formats: .ttf, .odf, .woff, .woff2": "ཡིག་གཟུགས་འདེམས་པ་བྱས་ནས་བསྐྱར་བརྗེ་བ། ཡིག་གཟུགས་ཀྱི་སྒྲ་སྐད། .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index 8560a709..edffbaff 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -516,5 +516,6 @@ "Select Image": "Bild auswählen", "Select Video": "Video auswählen", "Select Audio": "Audio auswählen", - "Select Fonts": "Schriftarten auswählen" + "Select Fonts": "Schriftarten auswählen", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Unterstützte Schriftartenformate: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index 0fb16ad8..c3ef0b08 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -516,5 +516,6 @@ "Select Image": "Επιλογή Εικόνας", "Select Video": "Επιλογή Βίντεο", "Select Audio": "Επιλογή Ήχου", - "Select Fonts": "Επιλογή Γραμματοσειρών" + "Select Fonts": "Επιλογή Γραμματοσειρών", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Υποστηριζόμενες μορφές γραμματοσειρών: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index 6a1e287d..5bdcf131 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -520,5 +520,6 @@ "Select Image": "Seleccionar Imagen", "Select Video": "Seleccionar Video", "Select Audio": "Seleccionar Audio", - "Select Fonts": "Seleccionar Fuentes" + "Select Fonts": "Seleccionar Fuentes", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Formatos de fuente compatibles: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index b2022260..ebabdfae 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -520,5 +520,6 @@ "Select Image": "Sélectionner une Image", "Select Video": "Sélectionner une Vidéo", "Select Audio": "Sélectionner un Audio", - "Select Fonts": "Sélectionner des Polices" + "Select Fonts": "Sélectionner des Polices", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Formats de police pris en charge : .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index 495d9577..ca1840cb 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -516,5 +516,6 @@ "Select Image": "छवि चुनें", "Select Video": "वीडियो चुनें", "Select Audio": "ऑडियो चुनें", - "Select Fonts": "फ़ॉन्ट चुनें" + "Select Fonts": "फ़ॉन्ट चुनें", + "Supported font formats: .ttf, .odf, .woff, .woff2": "समर्थित फ़ॉन्ट प्रारूप: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index 40698755..9b23fd6a 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -512,5 +512,6 @@ "Select Image": "Pilih Gambar", "Select Video": "Pilih Video", "Select Audio": "Pilih Audio", - "Select Fonts": "Pilih Font" + "Select Fonts": "Pilih Font", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Format font yang didukung: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index f11a7de8..5945528b 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -520,5 +520,6 @@ "Select Image": "Seleziona Immagine", "Select Video": "Seleziona Video", "Select Audio": "Seleziona Audio", - "Select Fonts": "Seleziona Font" + "Select Fonts": "Seleziona Font", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Formati di font supportati: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index d17665b0..14fc1dc8 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -512,5 +512,6 @@ "Select Image": "画像を選択", "Select Video": "動画を選択", "Select Audio": "音声を選択", - "Select Fonts": "フォントを選択" + "Select Fonts": "フォントを選択", + "Supported font formats: .ttf, .odf, .woff, .woff2": "サポートされているフォント形式:.ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index ec25ea41..57f1c5a2 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -512,5 +512,6 @@ "Select Image": "이미지 선택", "Select Video": "동영상 선택", "Select Audio": "오디오 선택", - "Select Fonts": "글꼴 선택" + "Select Fonts": "글꼴 선택", + "Supported font formats: .ttf, .odf, .woff, .woff2": "지원되는 글꼴 형식: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/nl/translation.json b/apps/readest-app/public/locales/nl/translation.json index 367c0788..9f2a6a06 100644 --- a/apps/readest-app/public/locales/nl/translation.json +++ b/apps/readest-app/public/locales/nl/translation.json @@ -516,5 +516,6 @@ "Select Image": "Afbeelding Selecteren", "Select Video": "Video Selecteren", "Select Audio": "Audio Selecteren", - "Select Fonts": "Lettertypen Selecteren" + "Select Fonts": "Lettertypen Selecteren", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Ondersteunde lettertypeformaten: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index d8e5fb3d..484428e5 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -524,5 +524,6 @@ "Select Image": "Wybierz Obraz", "Select Video": "Wybierz Wideo", "Select Audio": "Wybierz Audio", - "Select Fonts": "Wybierz Czcionki" + "Select Fonts": "Wybierz Czcionki", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Obsługiwane formaty czcionek: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index 1476ef4c..f9ed978b 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -520,5 +520,6 @@ "Select Image": "Selecionar Imagem", "Select Video": "Selecionar Vídeo", "Select Audio": "Selecionar Áudio", - "Select Fonts": "Selecionar Fontes" + "Select Fonts": "Selecionar Fontes", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Formatos de fonte suportados: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index f7dd02c2..618cffb6 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -524,5 +524,6 @@ "Select Image": "Выбрать Изображение", "Select Video": "Выбрать Видео", "Select Audio": "Выбрать Аудио", - "Select Fonts": "Выбрать Шрифты" + "Select Fonts": "Выбрать Шрифты", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Поддерживаемые форматы шрифтов: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/th/translation.json b/apps/readest-app/public/locales/th/translation.json index 4e9703c4..55fd65e1 100644 --- a/apps/readest-app/public/locales/th/translation.json +++ b/apps/readest-app/public/locales/th/translation.json @@ -512,5 +512,6 @@ "Select Image": "เลือกรูปภาพ", "Select Video": "เลือกวิดีโอ", "Select Audio": "เลือกเสียง", - "Select Fonts": "เลือกฟอนต์" + "Select Fonts": "เลือกฟอนต์", + "Supported font formats: .ttf, .odf, .woff, .woff2": "รูปแบบฟอนต์ที่รองรับ: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index c57094ef..65f22643 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -516,5 +516,6 @@ "Select Image": "Resim Seç", "Select Video": "Video Seç", "Select Audio": "Ses Seç", - "Select Fonts": "Yazı Tiplerini Seç" + "Select Fonts": "Yazı Tiplerini Seç", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Desteklenen yazı tipi formatları: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index 5a093d5f..94cc3c1e 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -524,5 +524,6 @@ "Select Image": "Вибрати Зображення", "Select Video": "Вибрати Відео", "Select Audio": "Вибрати Аудіо", - "Select Fonts": "Вибрати Шрифти" + "Select Fonts": "Вибрати Шрифти", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Підтримувані формати шрифтів: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index 41071de3..70cbe64a 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -512,5 +512,6 @@ "Select Image": "Chọn Hình Ảnh", "Select Video": "Chọn Video", "Select Audio": "Chọn Âm Thanh", - "Select Fonts": "Chọn Phông Chữ" + "Select Fonts": "Chọn Phông Chữ", + "Supported font formats: .ttf, .odf, .woff, .woff2": "Định dạng phông chữ được hỗ trợ: .ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index 982cb532..e086f24e 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -512,5 +512,6 @@ "Select Image": "选择图片", "Select Video": "选择视频", "Select Audio": "选择音频", - "Select Fonts": "选择字体" + "Select Fonts": "选择字体", + "Supported font formats: .ttf, .odf, .woff, .woff2": "支持的字体格式:.ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index a765d400..520ba4d7 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -512,5 +512,6 @@ "Select Image": "選擇圖片", "Select Video": "選擇影片", "Select Audio": "選擇音訊", - "Select Fonts": "選擇字型" + "Select Fonts": "選擇字型", + "Supported font formats: .ttf, .odf, .woff, .woff2": "支援的字型格式:.ttf, .odf, .woff, .woff2" } diff --git a/apps/readest-app/src/app/reader/components/annotator/TranslatorPopup.tsx b/apps/readest-app/src/app/reader/components/annotator/TranslatorPopup.tsx index 3e8960e0..6e65a9fa 100644 --- a/apps/readest-app/src/app/reader/components/annotator/TranslatorPopup.tsx +++ b/apps/readest-app/src/app/reader/components/annotator/TranslatorPopup.tsx @@ -176,9 +176,12 @@ const TranslatorPopup: React.FC = ({ className='bg-gray-600 text-white/75' value={targetLang} onChange={handleTargetLangChange} - options={Object.entries(translatorLangs) - .sort((a, b) => a[1].localeCompare(b[1])) - .map(([code, name]) => ({ value: code, label: name }))} + options={[ + { value: '', label: _('System Language') }, + ...Object.entries(translatorLangs) + .sort((a, b) => a[1].localeCompare(b[1])) + .map(([code, name]) => ({ value: code, label: name })), + ]} /> {loading ? ( diff --git a/apps/readest-app/src/app/reader/components/settings/CustomFonts.tsx b/apps/readest-app/src/app/reader/components/settings/CustomFonts.tsx index a2d0de8d..0492f868 100644 --- a/apps/readest-app/src/app/reader/components/settings/CustomFonts.tsx +++ b/apps/readest-app/src/app/reader/components/settings/CustomFonts.tsx @@ -1,19 +1,23 @@ +import clsx from 'clsx'; import React, { useState } from 'react'; import { MdAdd, MdDelete } from 'react-icons/md'; import { IoMdCloseCircleOutline } from 'react-icons/io'; import { useEnv } from '@/context/EnvContext'; +import { useReaderStore } from '@/store/readerStore'; import { useTranslation } from '@/hooks/useTranslation'; import { useCustomFontStore } from '@/store/customFontStore'; import { FILE_SELECTION_PRESETS, useFileSelector } from '@/hooks/useFileSelector'; import { mountCustomFont } from '@/styles/fonts'; import { parseFontFamily } from '@/utils/font'; import { getFilename } from '@/utils/path'; +import { saveViewSettings } from '../../utils/viewSettingsHelper'; interface CustomFontsProps { + bookKey: string; onBack: () => void; } -const CustomFonts: React.FC = ({ onBack }) => { +const CustomFonts: React.FC = ({ bookKey, onBack }) => { const _ = useTranslation(); const { appService, envConfig } = useEnv(); const { @@ -24,10 +28,18 @@ const CustomFonts: React.FC = ({ onBack }) => { getAvailableFonts, saveCustomFonts, } = useCustomFontStore(); + const { getViewSettings } = useReaderStore(); + const viewSettings = getViewSettings(bookKey)!; const [isDeleteMode, setIsDeleteMode] = useState(false); const { selectFiles } = useFileSelector(appService, _); + const currentDefaultFont = + viewSettings.defaultFont.toLowerCase() === 'serif' ? 'serif' : 'sans-serif'; + + const currentFontFamily = + currentDefaultFont === 'serif' ? viewSettings.serifFont : viewSettings.sansSerifFont; + const handleImportFont = () => { selectFiles({ ...FILE_SELECTION_PRESETS.fonts, multiple: true }).then(async (result) => { if (result.error || result.files.length === 0) return; @@ -76,6 +88,17 @@ const CustomFonts: React.FC = ({ onBack }) => { } }; + const handleSelectFont = (fontId: string) => { + const font = customFonts.find((f) => f.id === fontId); + if (font) { + if (currentDefaultFont === 'serif') { + saveViewSettings(envConfig, bookKey, 'serifFont', font.name); + } else { + saveViewSettings(envConfig, bookKey, 'sansSerifFont', font.name); + } + } + }; + const toggleDeleteMode = () => { setIsDeleteMode(!isDeleteMode); }; @@ -87,12 +110,14 @@ const CustomFonts: React.FC = ({ onBack }) => { return (
-
+
{availableFonts.length > 0 && ( @@ -131,11 +156,20 @@ const CustomFonts: React.FC = ({ onBack }) => {
{availableFonts.map((font) => ( -
+
handleSelectFont(font.id)} + >
= ({ onBack }) => {
{_('Tips')}:
-
    +
      +
    • {_('Supported font formats: .ttf, .odf, .woff, .woff2')}
    • {_('Custom fonts can be selected from the Font Face menu')}
diff --git a/apps/readest-app/src/app/reader/components/settings/FontPanel.tsx b/apps/readest-app/src/app/reader/components/settings/FontPanel.tsx index 352c0d63..641525b0 100644 --- a/apps/readest-app/src/app/reader/components/settings/FontPanel.tsx +++ b/apps/readest-app/src/app/reader/components/settings/FontPanel.tsx @@ -22,6 +22,7 @@ import { useReaderStore } from '@/store/readerStore'; import { useTranslation } from '@/hooks/useTranslation'; import { useSettingsStore } from '@/store/settingsStore'; import { useCustomFontStore } from '@/store/customFontStore'; +import { useResponsiveSize } from '@/hooks/useResponsiveSize'; import { getOSPlatform, isCJKEnv } from '@/utils/misc'; import { getSysFontsList } from '@/utils/bridge'; import { isCJKStr } from '@/utils/lang'; @@ -32,7 +33,6 @@ import { SettingsPanelPanelProp } from './SettingsDialog'; import NumberInput from './NumberInput'; import FontDropdown from './FontDropDown'; import CustomFonts from './CustomFonts'; -import { useResponsiveSize } from '@/hooks/useResponsiveSize'; const genCJKFontsList = (sysFonts: string[]) => { return Array.from(new Set([...sysFonts, ...CJK_SERIF_FONTS, ...CJK_SANS_SERIF_FONTS])) @@ -185,6 +185,12 @@ const FontPanel: React.FC = ({ bookKey, onRegisterReset setCustomFonts(getFontFamilies()); }, [allCustomFonts, getFontFamilies]); + useEffect(() => { + setSerifFont(viewSettings.serifFont); + setSansSerifFont(viewSettings.sansSerifFont); + setMonospaceFont(viewSettings.monospaceFont); + }, [viewSettings.serifFont, viewSettings.sansSerifFont, viewSettings.monospaceFont]); + useEffect(() => { if (isTauriAppPlatform()) { getSysFontsList().then((res) => { @@ -273,7 +279,7 @@ const FontPanel: React.FC = ({ bookKey, onRegisterReset if (fontPanelView === 'custom-fonts') { 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 b237d5ec..887257d1 100644 --- a/apps/readest-app/src/app/reader/components/settings/SettingsDialog.tsx +++ b/apps/readest-app/src/app/reader/components/settings/SettingsDialog.tsx @@ -40,7 +40,7 @@ const SettingsDialog: React.FC<{ bookKey: string; config: BookConfig }> = ({ boo const [isRtl] = useState(() => getDirFromUILanguage() === 'rtl'); const tabsRef = useRef(null); const [showAllTabLabels, setShowAllTabLabels] = useState(false); - const { setFontLayoutSettingsDialogOpen } = useSettingsStore(); + const { setFontPanelView, setFontLayoutSettingsDialogOpen } = useSettingsStore(); const tabConfig = [ { @@ -85,6 +85,7 @@ const SettingsDialog: React.FC<{ bookKey: string; config: BookConfig }> = ({ boo const handleSetActivePanel = (tab: SettingsPanelType) => { setActivePanel(tab); + setFontPanelView('main-fonts'); localStorage.setItem('lastConfigPanel', tab); }; @@ -115,6 +116,8 @@ const SettingsDialog: React.FC<{ bookKey: string; config: BookConfig }> = ({ boo }; useEffect(() => { + setFontPanelView('main-fonts'); + const container = tabsRef.current; if (!container) return;