import clsx from 'clsx'; import React, { useEffect, useState } from 'react'; import { ANDROID_FONTS, IOS_FONTS, LINUX_FONTS, MACOS_FONTS, MONOSPACE_FONTS, SANS_SERIF_FONTS, SERIF_FONTS, WINDOWS_FONTS, } from '@/services/constants'; import { useReaderStore } from '@/store/readerStore'; import { useTranslation } from '@/hooks/useTranslation'; import { useEnv } from '@/context/EnvContext'; import { getOSPlatform } from '@/utils/misc'; import { getSysFontsList } from '@/utils/font'; import { isTauriAppPlatform } from '@/services/environment'; import { saveViewSettings } from '../../utils/viewSettingsHelper'; import NumberInput from './NumberInput'; import FontDropdown from './FontDropDown'; interface FontFaceProps { className?: string; family: string; label: string; options: string[]; moreOptions?: string[]; selected: string; onSelect: (option: string) => void; } const handleFontFaceFont = (option: string, family: string) => { return `'${option}', ${family}`; }; const FontFace = ({ className, family, label, options, moreOptions, selected, onSelect, }: FontFaceProps) => { const _ = useTranslation(); return (
{label} ({ option, label: _(option) }))} moreOptions={moreOptions?.map((option) => ({ option, label: option })) ?? []} selected={selected} onSelect={onSelect} onGetFontFamily={handleFontFaceFont} />
); }; const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => { const _ = useTranslation(); const { envConfig, appService } = useEnv(); const { getViewSettings } = useReaderStore(); const viewSettings = getViewSettings(bookKey)!; const fontFamilyOptions = [ { option: 'Serif', label: _('Serif Font'), }, { option: 'Sans-serif', label: _('Sans-Serif Font'), }, ]; const osPlatform = getOSPlatform(); let defaultSysFonts: string[] = []; switch (osPlatform) { case 'macos': defaultSysFonts = MACOS_FONTS; break; case 'windows': defaultSysFonts = WINDOWS_FONTS; break; case 'linux': defaultSysFonts = LINUX_FONTS; break; case 'ios': defaultSysFonts = IOS_FONTS; break; case 'android': defaultSysFonts = ANDROID_FONTS; break; default: break; } const [sysFonts, setSysFonts] = useState(defaultSysFonts); const [defaultFontSize, setDefaultFontSize] = useState(viewSettings.defaultFontSize!); const [minFontSize, setMinFontSize] = useState(viewSettings.minimumFontSize!); const [overrideFont, setOverrideFont] = useState(viewSettings.overrideFont!); const [defaultFont, setDefaultFont] = useState(viewSettings.defaultFont!); const [serifFont, setSerifFont] = useState(viewSettings.serifFont!); const [sansSerifFont, setSansSerifFont] = useState(viewSettings.sansSerifFont!); const [monospaceFont, setMonospaceFont] = useState(viewSettings.monospaceFont!); const [fontWeight, setFontWeight] = useState(viewSettings.fontWeight!); useEffect(() => { if (isTauriAppPlatform() && appService?.hasSysFontsList) { getSysFontsList().then((fonts) => { setSysFonts(fonts); }); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { saveViewSettings(envConfig, bookKey, 'defaultFont', defaultFont); // eslint-disable-next-line react-hooks/exhaustive-deps }, [defaultFont]); useEffect(() => { saveViewSettings(envConfig, bookKey, 'defaultFontSize', defaultFontSize); // eslint-disable-next-line react-hooks/exhaustive-deps }, [defaultFontSize]); useEffect(() => { saveViewSettings(envConfig, bookKey, 'minimumFontSize', minFontSize); // eslint-disable-next-line react-hooks/exhaustive-deps }, [minFontSize]); useEffect(() => { saveViewSettings(envConfig, bookKey, 'fontWeight', fontWeight); // eslint-disable-next-line react-hooks/exhaustive-deps }, [fontWeight]); useEffect(() => { saveViewSettings(envConfig, bookKey, 'serifFont', serifFont); // eslint-disable-next-line react-hooks/exhaustive-deps }, [serifFont]); useEffect(() => { saveViewSettings(envConfig, bookKey, 'sansSerifFont', sansSerifFont); // eslint-disable-next-line react-hooks/exhaustive-deps }, [sansSerifFont]); useEffect(() => { saveViewSettings(envConfig, bookKey, 'monospaceFont', monospaceFont); // eslint-disable-next-line react-hooks/exhaustive-deps }, [monospaceFont]); useEffect(() => { saveViewSettings(envConfig, bookKey, 'overrideFont', overrideFont); // eslint-disable-next-line react-hooks/exhaustive-deps }, [overrideFont]); const handleFontFamilyFont = (option: string) => { switch (option) { case 'Serif': return `'${serifFont}', serif`; case 'Sans-serif': return `'${sansSerifFont}', sans-serif`; case 'Monospace': return `'${monospaceFont}', monospace`; default: return ''; } }; return (

{_('Font Size')}

{_('Font Weight')}

{_('Font Family')}

{_('Default Font')}
{_('Override Book Font')} setOverrideFont(!overrideFont)} />

{_('Font Face')}

); }; export default FontPanel;