import React, { useEffect, useState } from 'react'; import { useSettingsStore } from '@/store/settingsStore'; import { useReaderStore } from '@/store/readerStore'; import { useTranslation } from '@/hooks/useTranslation'; import { getStyles } from '@/utils/style'; import { ONE_COLUMN_MAX_INLINE_SIZE } from '@/services/constants'; import NumberInput from './NumberInput'; import { useTheme } from '@/hooks/useTheme'; const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => { const _ = useTranslation(); const { settings, isFontLayoutSettingsGlobal, setSettings } = useSettingsStore(); const { getView, getViewSettings, setViewSettings } = useReaderStore(); const view = getView(bookKey); const viewSettings = getViewSettings(bookKey)!; const { themeCode } = useTheme(); const [lineHeight, setLineHeight] = useState(viewSettings.lineHeight!); const [fullJustification, setFullJustification] = useState(viewSettings.fullJustification!); const [hyphenation, setHyphenation] = useState(viewSettings.hyphenation!); const [marginPx, setMarginPx] = useState(viewSettings.marginPx!); const [gapPercent, setGapPercent] = useState(viewSettings.gapPercent!); const [maxColumnCount, setMaxColumnCount] = useState(viewSettings.maxColumnCount!); const [maxInlineSize, setMaxInlineSize] = useState(viewSettings.maxInlineSize!); const [maxBlockSize, setMaxBlockSize] = useState(viewSettings.maxBlockSize!); useEffect(() => { viewSettings.lineHeight = lineHeight; setViewSettings(bookKey, viewSettings); if (isFontLayoutSettingsGlobal) { settings.globalViewSettings.lineHeight = lineHeight; setSettings(settings); } view?.renderer.setStyles?.(getStyles(viewSettings, themeCode)); // eslint-disable-next-line react-hooks/exhaustive-deps }, [lineHeight]); useEffect(() => { viewSettings.fullJustification = fullJustification; setViewSettings(bookKey, viewSettings); if (isFontLayoutSettingsGlobal) { settings.globalViewSettings.fullJustification = fullJustification; setSettings(settings); } view?.renderer.setStyles?.(getStyles(viewSettings, themeCode)); // eslint-disable-next-line react-hooks/exhaustive-deps }, [fullJustification]); useEffect(() => { viewSettings.hyphenation = hyphenation; setViewSettings(bookKey, viewSettings); if (isFontLayoutSettingsGlobal) { settings.globalViewSettings.hyphenation = hyphenation; setSettings(settings); } view?.renderer.setStyles?.(getStyles(viewSettings, themeCode)); // eslint-disable-next-line react-hooks/exhaustive-deps }, [hyphenation]); useEffect(() => { viewSettings.marginPx = marginPx; setViewSettings(bookKey, viewSettings); if (isFontLayoutSettingsGlobal) { settings.globalViewSettings.marginPx = marginPx; setSettings(settings); } view?.renderer.setAttribute('margin', `${marginPx}px`); // eslint-disable-next-line react-hooks/exhaustive-deps }, [marginPx]); useEffect(() => { viewSettings.gapPercent = gapPercent; setViewSettings(bookKey, viewSettings); if (isFontLayoutSettingsGlobal) { settings.globalViewSettings.gapPercent = gapPercent; setSettings(settings); } view?.renderer.setAttribute('gap', `${gapPercent}%`); if (viewSettings.scrolled) { view?.renderer.setAttribute('flow', 'scrolled'); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [gapPercent]); useEffect(() => { viewSettings.maxColumnCount = maxColumnCount; setViewSettings(bookKey, viewSettings); if (isFontLayoutSettingsGlobal) { settings.globalViewSettings.maxColumnCount = maxColumnCount; setSettings(settings); } view?.renderer.setAttribute('max-column-count', maxColumnCount); view?.renderer.setAttribute( 'max-inline-size', `${maxColumnCount === 1 || viewSettings.scrolled ? ONE_COLUMN_MAX_INLINE_SIZE : maxInlineSize}px`, ); // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxColumnCount]); useEffect(() => { viewSettings.maxInlineSize = maxInlineSize; setViewSettings(bookKey, viewSettings); if (isFontLayoutSettingsGlobal) { settings.globalViewSettings.maxInlineSize = maxInlineSize; setSettings(settings); } view?.renderer.setAttribute( 'max-inline-size', `${maxColumnCount === 1 || viewSettings.scrolled ? ONE_COLUMN_MAX_INLINE_SIZE : maxInlineSize}px`, ); // eslint-disable-next-line react-hooks/exhaustive-deps }, [maxInlineSize]); return (