import clsx from 'clsx'; import React, { useEffect, useState } from 'react'; import { useReaderStore } from '@/store/readerStore'; import { useSettingsStore } from '@/store/settingsStore'; import { useTranslation } from '@/hooks/useTranslation'; import { getStyles } from '@/utils/style'; import { useTheme } from '@/hooks/useTheme'; import cssbeautify from 'cssbeautify'; import cssValidate from '@/utils/css'; const MiscPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => { const _ = useTranslation(); const { settings, isFontLayoutSettingsGlobal, setSettings } = useSettingsStore(); const { getView, getViewSettings, setViewSettings } = useReaderStore(); const viewSettings = getViewSettings(bookKey)!; const { themeCode } = useTheme(); const [animated, setAnimated] = useState(viewSettings.animated!); const [isDisableClick, setIsDisableClick] = useState(viewSettings.disableClick!); const [draftStylesheet, setDraftStylesheet] = useState(viewSettings.userStylesheet!); const [draftStylesheetSaved, setDraftStylesheetSaved] = useState(true); const [error, setError] = useState(null); const handleUserStylesheetChange = (e: React.ChangeEvent) => { const cssInput = e.target.value; setDraftStylesheet(cssInput); setDraftStylesheetSaved(false); try { const { isValid, error } = cssValidate(cssInput); if (cssInput && !isValid) { throw new Error(error || 'Invalid CSS'); } setError(null); } catch (err: unknown) { if (err instanceof Error) { setError(err.message); } else { setError('Invalid CSS: Please check your input.'); } console.log('CSS Error:', err); } }; const applyStyles = () => { const formattedCSS = cssbeautify(draftStylesheet, { indent: ' ', openbrace: 'end-of-line', autosemicolon: true, }); setDraftStylesheet(formattedCSS); setDraftStylesheetSaved(true); viewSettings.userStylesheet = formattedCSS; setViewSettings(bookKey, viewSettings); if (isFontLayoutSettingsGlobal) { settings.globalViewSettings.userStylesheet = formattedCSS; setSettings(settings); } getView(bookKey)?.renderer.setStyles?.(getStyles(viewSettings, themeCode)); }; const handleInput = (e: React.FormEvent) => { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); }; useEffect(() => { viewSettings.animated = animated; setViewSettings(bookKey, viewSettings); if (isFontLayoutSettingsGlobal) { settings.globalViewSettings.animated = animated; setSettings(settings); } if (animated) { getView(bookKey)?.renderer.setAttribute('animated', ''); } else { getView(bookKey)?.renderer.removeAttribute('animated'); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [animated]); useEffect(() => { viewSettings.disableClick = isDisableClick; setViewSettings(bookKey, viewSettings); if (isFontLayoutSettingsGlobal) { settings.globalViewSettings.disableClick = isDisableClick; setSettings(settings); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isDisableClick]); return (

{_('Animation')}

{_('Paging Animation')} setAnimated(!animated)} />

{_('Behavior')}

{_('Disable Click-to-Flip')} setIsDisableClick(!isDisableClick)} />

{_('Custom CSS')}