ui: responsive dialog size for portrait screens (#473)

* fix: handle network error in sync API

* fix: reasonable default column width for iPad

* ui: responsive dialog size for portrait screens
This commit is contained in:
Huang Xin
2025-03-01 17:57:29 +01:00
committed by GitHub
parent 2f29295c6c
commit 2db83b8569
16 changed files with 76 additions and 46 deletions
@@ -12,7 +12,6 @@ import { useAutoHideScrollbar } from '../hooks/useAutoHideScrollbar';
import { getStyles, mountAdditionalFonts } from '@/utils/style';
import { getBookDirFromWritingMode } from '@/utils/book';
import { useTheme } from '@/hooks/useTheme';
import { ONE_COLUMN_MAX_INLINE_SIZE } from '@/services/constants';
import {
handleKeydown,
handleMousedown,
@@ -23,6 +22,7 @@ import {
handleTouchMove,
handleTouchEnd,
} from '../utils/iframeEventHandlers';
import { getMaxInlineSize } from '@/utils/config';
const FoliateViewer: React.FC<{
bookKey: string;
@@ -154,10 +154,7 @@ const FoliateViewer: React.FC<{
const gapPercent = viewSettings.gapPercent!;
const animated = viewSettings.animated!;
const maxColumnCount = viewSettings.maxColumnCount!;
const maxInlineSize =
maxColumnCount === 1 || isScrolled
? ONE_COLUMN_MAX_INLINE_SIZE
: viewSettings.maxInlineSize!;
const maxInlineSize = getMaxInlineSize(viewSettings);
const maxBlockSize = viewSettings.maxBlockSize!;
if (animated) {
view.renderer.setAttribute('animated', '');
@@ -5,17 +5,13 @@ import { BiMoon, BiSun } from 'react-icons/bi';
import { TbSunMoon } from 'react-icons/tb';
import { MdZoomOut, MdZoomIn, MdCheck } from 'react-icons/md';
import {
MAX_ZOOM_LEVEL,
MIN_ZOOM_LEVEL,
ONE_COLUMN_MAX_INLINE_SIZE,
ZOOM_STEP,
} from '@/services/constants';
import { MAX_ZOOM_LEVEL, MIN_ZOOM_LEVEL, ZOOM_STEP } from '@/services/constants';
import MenuItem from '@/components/MenuItem';
import { useReaderStore } from '@/store/readerStore';
import { useTranslation } from '@/hooks/useTranslation';
import { useTheme, ThemeMode } from '@/hooks/useTheme';
import { getStyles } from '@/utils/style';
import { getMaxInlineSize } from '@/utils/config';
interface ViewMenuProps {
bookKey: string;
@@ -65,7 +61,7 @@ const ViewMenu: React.FC<ViewMenuProps> = ({
getView(bookKey)?.renderer.setAttribute('flow', isScrolledMode ? 'scrolled' : 'paginated');
getView(bookKey)?.renderer.setAttribute(
'max-inline-size',
`${viewSettings.maxColumnCount === 1 || isScrolledMode ? ONE_COLUMN_MAX_INLINE_SIZE : viewSettings.maxInlineSize}px`,
`${getMaxInlineSize(viewSettings)}px`,
);
getView(bookKey)?.renderer.setStyles?.(getStyles(viewSettings!, themeCode));
viewSettings!.scrolled = isScrolledMode;
@@ -17,9 +17,10 @@ import { useReaderStore } from '@/store/readerStore';
import { useSettingsStore } from '@/store/settingsStore';
import { useTranslation } from '@/hooks/useTranslation';
import { useTheme } from '@/hooks/useTheme';
import { useEnv } from '@/context/EnvContext';
import { getStyles } from '@/utils/style';
import { getOSPlatform } from '@/utils/misc';
import { FONT_ENUM_SUPPORTED_OS_PLATFORMS, getSysFontsList } from '@/utils/font';
import { getSysFontsList } from '@/utils/font';
import { isTauriAppPlatform } from '@/services/environment';
interface FontFaceProps {
@@ -60,6 +61,7 @@ const FontFace = ({
const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const _ = useTranslation();
const { appService } = useEnv();
const { settings, isFontLayoutSettingsGlobal, setSettings } = useSettingsStore();
const { getView, getViewSettings, setViewSettings } = useReaderStore();
const view = getView(bookKey);
@@ -109,7 +111,7 @@ const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const [fontWeight, setFontWeight] = useState(viewSettings.fontWeight!);
useEffect(() => {
if (isTauriAppPlatform() && FONT_ENUM_SUPPORTED_OS_PLATFORMS.includes(osPlatform)) {
if (isTauriAppPlatform() && appService?.hasSysFontsList) {
getSysFontsList().then((fonts) => {
setSysFonts(fonts);
});
@@ -2,13 +2,13 @@ import React, { useEffect, useState } from 'react';
import { MdOutlineAutoMode } from 'react-icons/md';
import { MdOutlineTextRotationDown, MdOutlineTextRotationNone } from 'react-icons/md';
import { ONE_COLUMN_MAX_INLINE_SIZE } from '@/services/constants';
import { useSettingsStore } from '@/store/settingsStore';
import { useReaderStore } from '@/store/readerStore';
import { useBookDataStore } from '@/store/bookDataStore';
import { useTranslation } from '@/hooks/useTranslation';
import { useTheme } from '@/hooks/useTheme';
import { getStyles } from '@/utils/style';
import { getMaxInlineSize } from '@/utils/config';
import { getBookDirFromWritingMode, getBookLangCode } from '@/utils/book';
import NumberInput from './NumberInput';
@@ -147,10 +147,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
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`,
);
view?.renderer.setAttribute('max-inline-size', `${getMaxInlineSize(viewSettings)}px`);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [maxColumnCount]);
@@ -161,10 +158,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.maxInlineSize = maxInlineSize;
setSettings(settings);
}
view?.renderer.setAttribute(
'max-inline-size',
`${maxColumnCount === 1 || viewSettings.scrolled ? ONE_COLUMN_MAX_INLINE_SIZE : maxInlineSize}px`,
);
view?.renderer.setAttribute('max-inline-size', `${getMaxInlineSize(viewSettings)}px`);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [maxInlineSize]);
@@ -353,6 +347,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
label={_('Maximum Inline Size')}
value={maxInlineSize}
onChange={setMaxInlineSize}
disabled={maxColumnCount === 1 || viewSettings.scrolled}
min={500}
max={9999}
step={100}
@@ -9,6 +9,7 @@ interface NumberInputProps {
min: number;
max: number;
step?: number;
disabled?: boolean;
onChange: (value: number) => void;
}
@@ -20,6 +21,7 @@ const NumberInput: React.FC<NumberInputProps> = ({
min,
max,
step,
disabled,
}) => {
const [localValue, setLocalValue] = useState(value);
const numberStep = step || 1;
@@ -74,13 +76,13 @@ const NumberInput: React.FC<NumberInputProps> = ({
/>
<button
onClick={decrement}
className={`btn btn-circle btn-sm ${value === min ? 'btn-disabled !bg-opacity-5' : ''}`}
className={`btn btn-circle btn-sm ${value <= min || disabled ? 'btn-disabled !bg-opacity-5' : ''}`}
>
<FiMinus className='h-4 w-4' />
</button>
<button
onClick={increment}
className={`btn btn-circle btn-sm ${value === max ? 'btn-disabled !bg-opacity-5' : ''}`}
className={`btn btn-circle btn-sm ${value >= max || disabled ? 'btn-disabled !bg-opacity-5' : ''}`}
>
<FiPlus className='h-4 w-4' />
</button>
@@ -64,7 +64,7 @@ const SettingsDialog: React.FC<{ bookKey: string; config: BookConfig }> = ({ boo
isOpen={true}
onClose={handleClose}
className='modal-open'
boxClassName='sm:w-1/2 sm:min-w-[480px] sm:h-[65%]'
boxClassName='sm:min-w-[480px]'
header={
<div className='flex w-full items-center justify-between'>
<button