feat: support separate header/footer visibility for paginated and scrolled modes (#859)

This commit is contained in:
Huang Xin
2025-04-11 09:40:26 +08:00
committed by GitHub
parent fe25c3e995
commit ccd467ebcf
29 changed files with 264 additions and 147 deletions
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} ساعة",
"{{value}} hours": "{{value}} ساعات",
"CJK Font": "خط CJK",
"Clear Search": "مسح البحث"
"Clear Search": "مسح البحث",
"Header & Footer": "الرأس والتذييل",
"Apply also in Scrolled Mode": "تطبيق أيضًا في وضع التمرير"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} Stunde",
"{{value}} hours": "{{value}} Stunden",
"CJK Font": "CJK-Schriftart",
"Clear Search": "Suche löschen"
"Clear Search": "Suche löschen",
"Header & Footer": "Kopf- & Fußzeile",
"Apply also in Scrolled Mode": "Auch im Scroll-Modus anwenden"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} ώρα",
"{{value}} hours": "{{value}} ώρες",
"CJK Font": "Γραμματοσειρά CJK",
"Clear Search": "Καθαρισμός αναζήτησης"
"Clear Search": "Καθαρισμός αναζήτησης",
"Header & Footer": "Κεφαλίδα & Υποσέλιδο",
"Apply also in Scrolled Mode": "Εφαρμογή και σε λειτουργία κύλισης"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} hora",
"{{value}} hours": "{{value}} horas",
"CJK Font": "Fuente CJK",
"Clear Search": "Limpiar búsqueda"
"Clear Search": "Limpiar búsqueda",
"Header & Footer": "Encabezado y pie de página",
"Apply also in Scrolled Mode": "Aplicar también en modo desplazamiento"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} heure",
"{{value}} hours": "{{value}} heures",
"CJK Font": "Police CJK",
"Clear Search": "Effacer la recherche"
"Clear Search": "Effacer la recherche",
"Header & Footer": "En-tête et pied de page",
"Apply also in Scrolled Mode": "Appliquer également en mode défilement"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} घंटा",
"{{value}} hours": "{{value}} घंटे",
"CJK Font": "CJK फ़ॉन्ट",
"Clear Search": "खोज साफ करें"
"Clear Search": "खोज साफ करें",
"Header & Footer": "हेडर और फ़ुटर",
"Apply also in Scrolled Mode": "स्क्रॉल मोड में भी लागू करें"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} jam",
"{{value}} hours": "{{value}} jam",
"CJK Font": "Font CJK",
"Clear Search": "Hapus Pencarian"
"Clear Search": "Hapus Pencarian",
"Header & Footer": "Header & Footer",
"Apply also in Scrolled Mode": "Terapkan juga di Mode Gulir"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} ora",
"{{value}} hours": "{{value}} ore",
"CJK Font": "Font CJK",
"Clear Search": "Cancella ricerca"
"Clear Search": "Cancella ricerca",
"Header & Footer": "Intestazione e piè di pagina",
"Apply also in Scrolled Mode": "Applica anche in modalità scorrimento"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}}時間",
"{{value}} hours": "{{value}}時間",
"CJK Font": "CJKフォント",
"Clear Search": "検索をクリア"
"Clear Search": "検索をクリア",
"Header & Footer": "ヘッダーとフッター",
"Apply also in Scrolled Mode": "スクロールモードでも適用"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} 시간",
"{{value}} hours": "{{value}} 시간",
"CJK Font": "CJK 글꼴",
"Clear Search": "검색 지우기"
"Clear Search": "검색 지우기",
"Header & Footer": "헤더 및 푸터",
"Apply also in Scrolled Mode": "스크롤 모드에서도 적용"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} godzina",
"{{value}} hours": "{{value}} godziny",
"CJK Font": "Czcionka CJK",
"Clear Search": "Wyczyść wyszukiwanie"
"Clear Search": "Wyczyść wyszukiwanie",
"Header & Footer": "Nagłówek i stopka",
"Apply also in Scrolled Mode": "Zastosuj również w trybie przewijania"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} hora",
"{{value}} hours": "{{value}} horas",
"CJK Font": "Fonte CJK",
"Clear Search": "Limpar Pesquisa"
"Clear Search": "Limpar Pesquisa",
"Header & Footer": "Cabeçalho e Rodapé",
"Apply also in Scrolled Mode": "Aplicar também no Modo Rolado"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} час",
"{{value}} hours": "{{value}} часа",
"CJK Font": "CJK Шрифт",
"Clear Search": "Очистить поиск"
"Clear Search": "Очистить поиск",
"Header & Footer": "Заголовок и нижний колонтитул",
"Apply also in Scrolled Mode": "Применить также в прокручиваемом режиме"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} saat",
"{{value}} hours": "{{value}} saat",
"CJK Font": "CJK Yazı Tipi",
"Clear Search": "Aramayı Temizle"
"Clear Search": "Aramayı Temizle",
"Header & Footer": "Başlık ve Altbilgi",
"Apply also in Scrolled Mode": "Kaydırılmış Modda da Uygula"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} година",
"{{value}} hours": "{{value}} години",
"CJK Font": "CJK шрифт",
"Clear Search": "Очистити пошук"
"Clear Search": "Очистити пошук",
"Header & Footer": "Заголовок і нижній колонтитул",
"Apply also in Scrolled Mode": "Застосувати також у прокрученому режимі"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}} giờ",
"{{value}} hours": "{{value}} giờ",
"CJK Font": "Phông chữ CJK",
"Clear Search": "Xóa tìm kiếm"
"Clear Search": "Xóa tìm kiếm",
"Header & Footer": "Đầu trang & Chân trang",
"Apply also in Scrolled Mode": "Áp dụng cũng trong chế độ cuộn"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}}小时",
"{{value}} hours": "{{value}}小时",
"CJK Font": "中文字体",
"Clear Search": "清除搜索"
"Clear Search": "清除搜索",
"Header & Footer": "页眉页脚",
"Apply also in Scrolled Mode": "应用到滚动模式"
}
@@ -274,5 +274,7 @@
"{{value}} hour": "{{value}}小時",
"{{value}} hours": "{{value}}小時",
"CJK Font": "中文字體",
"Clear Search": "清除搜索"
"Clear Search": "清除搜索",
"Header & Footer": "頁眉頁腳",
"Apply also in Scrolled Mode": "滾動模式同樣適用"
}
@@ -42,10 +42,7 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
return (
<div
className={clsx(
'grid h-full flex-grow',
appService?.hasSafeAreaInset && 'pt-[env(safe-area-inset-top)]',
)}
className={clsx('grid h-full flex-grow')}
style={{
gridTemplateColumns: gridTemplate.columns,
gridTemplateRows: gridTemplate.rows,
@@ -63,6 +60,10 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
const isBookmarked = getViewState(bookKey)?.ribbonVisible;
const horizontalGapPercent = viewSettings.gapPercent;
const verticalMarginPixels = viewSettings.marginPx;
const scrolled = viewSettings.scrolled;
const showBarsOnScroll = viewSettings.showBarsOnScroll;
const showHeader = viewSettings.showHeader && (scrolled ? showBarsOnScroll : true);
const showFooter = viewSettings.showFooter && (scrolled ? showBarsOnScroll : true);
return (
<div
@@ -70,6 +71,10 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
key={bookKey}
className={clsx(
'relative h-full w-full overflow-hidden',
index === 0 &&
!viewSettings?.scrolled &&
appService?.hasSafeAreaInset &&
'pt-[env(safe-area-inset-top)]',
!isSideBarVisible && appService?.hasRoundedWindow && 'rounded-window',
)}
>
@@ -85,32 +90,36 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
<FoliateViewer bookKey={bookKey} bookDoc={bookDoc} config={config} />
{viewSettings.vertical && viewSettings.scrolled && (
<>
<div
className='bg-base-100 absolute left-0 top-0 h-full'
style={{
width: `calc(${horizontalGapPercent}%)`,
height: `calc(100% - ${verticalMarginPixels}px)`,
}}
/>
<div
className='bg-base-100 absolute right-0 top-0 h-full'
style={{
width: `calc(${horizontalGapPercent}%)`,
height: `calc(100% - ${verticalMarginPixels}px)`,
}}
/>
{(showFooter || viewSettings.doubleBorder) && (
<div
className='bg-base-100 absolute left-0 top-0 h-full'
style={{
width: `calc(${horizontalGapPercent}%)`,
height: `calc(100% - ${verticalMarginPixels}px)`,
}}
/>
)}
{(showHeader || viewSettings.doubleBorder) && (
<div
className='bg-base-100 absolute right-0 top-0 h-full'
style={{
width: `calc(${horizontalGapPercent}%)`,
height: `calc(100% - ${verticalMarginPixels}px)`,
}}
/>
)}
</>
)}
{viewSettings.vertical && viewSettings.doubleBorder && (
<DoubleBorder
showHeader={viewSettings.showHeader}
showFooter={viewSettings.showFooter}
showHeader={showHeader}
showFooter={showFooter}
borderColor={viewSettings.borderColor}
horizontalGap={horizontalGapPercent}
verticalMargin={verticalMarginPixels}
/>
)}
{viewSettings.showHeader && (
{showHeader && (
<SectionInfo
section={sectionLabel}
showDoubleBorder={viewSettings.vertical && viewSettings.doubleBorder}
@@ -127,7 +136,7 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
horizontalGap={horizontalGapPercent}
verticalMargin={verticalMarginPixels}
/>
{viewSettings.showFooter && (
{showFooter && (
<PageInfoView
bookFormat={book.format}
section={section}
@@ -149,7 +149,7 @@ const FooterBar: React.FC<FooterBarProps> = ({
className={clsx(
'footer-bar shadow-xs absolute bottom-0 z-50 flex w-full flex-col',
'sm:h-[52px] sm:justify-center',
'sm:bg-base-100 border-base-300/50 border sm:border-none',
'sm:bg-base-100 border-base-300/50 border-t sm:border-none',
'transition-[opacity,transform] duration-300',
appService?.hasRoundedWindow && 'rounded-window-bottom-right',
!isSideBarVisible && appService?.hasRoundedWindow && 'rounded-window-bottom-left',
@@ -42,7 +42,7 @@ const HeaderBar: React.FC<HeaderBarProps> = ({
cleanupTrafficLightListeners,
} = useTrafficLightStore();
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const { hoveredBookKey, setHoveredBookKey, bookKeys } = useReaderStore();
const { bookKeys, hoveredBookKey, setHoveredBookKey } = useReaderStore();
const { isSideBarVisible } = useSidebarStore();
const iconSize16 = useResponsiveSize(16);
@@ -70,56 +70,78 @@ const HeaderBar: React.FC<HeaderBarProps> = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isSideBarVisible]);
const isVisible = hoveredBookKey === bookKey || isDropdownOpen;
return (
<div
ref={headerRef}
className={clsx(
`header-bar absolute top-0 z-10 flex h-11 w-full items-center pr-4`,
isTrafficLightVisible && isTopLeft && !isSideBarVisible ? 'pl-16' : 'pl-4',
`shadow-xs bg-base-100 transition-opacity duration-300`,
appService?.hasRoundedWindow && 'rounded-window-top-right',
!isSideBarVisible && appService?.hasRoundedWindow && 'rounded-window-top-left',
isHoveredAnim && 'hover-bar-anim',
hoveredBookKey === bookKey || isDropdownOpen ? `visible` : `opacity-0`,
isDropdownOpen && 'header-bar-pinned',
'bg-base-100 absolute top-0 w-full',
appService?.hasSafeAreaInset && 'pt-[env(safe-area-inset-top)]',
)}
onMouseEnter={() => setHoveredBookKey(bookKey)}
onMouseLeave={() => setHoveredBookKey('')}
>
<div className='sidebar-bookmark-toggler bg-base-100 z-20 flex h-full items-center gap-x-4'>
<div className='hidden sm:flex'>
<SidebarToggler bookKey={bookKey} />
<div
className={clsx('absolute top-0 z-10 hidden h-11 w-full sm:flex')}
onMouseEnter={() => !appService?.isMobile && setHoveredBookKey(bookKey)}
onTouchStart={() => !appService?.isMobile && setHoveredBookKey(bookKey)}
/>
<div
className={clsx(
'bg-base-100 absolute left-0 right-0 top-0 z-10 h-[env(safe-area-inset-top)]',
isVisible ? 'visible' : 'hidden',
)}
/>
<div
ref={headerRef}
className={clsx(
`header-bar bg-base-100 absolute top-0 z-10 flex h-11 w-full items-center pr-4`,
`shadow-xs transition-opacity duration-300`,
isTrafficLightVisible && isTopLeft && !isSideBarVisible ? 'pl-16' : 'pl-4',
appService?.hasRoundedWindow && 'rounded-window-top-right',
appService?.hasSafeAreaInset && 'mt-[env(safe-area-inset-top)]',
!isSideBarVisible && appService?.hasRoundedWindow && 'rounded-window-top-left',
isHoveredAnim && 'hover-bar-anim',
isVisible ? 'pointer-events-auto visible' : 'pointer-events-none opacity-0',
isDropdownOpen && 'header-bar-pinned',
)}
onMouseLeave={() => !appService?.isMobile && setHoveredBookKey('')}
>
<div className='sidebar-bookmark-toggler z-20 flex h-full items-center gap-x-4'>
<div className='hidden sm:flex'>
<SidebarToggler bookKey={bookKey} />
</div>
<BookmarkToggler bookKey={bookKey} />
</div>
<BookmarkToggler bookKey={bookKey} />
</div>
<div className='header-title z-15 pointer-events-none absolute inset-0 hidden items-center justify-center sm:flex'>
<h2 className='line-clamp-1 max-w-[50%] text-center text-xs font-semibold'>{bookTitle}</h2>
</div>
<div className='header-title z-15 bg-base-100 pointer-events-none absolute inset-0 hidden items-center justify-center sm:flex'>
<h2 className='line-clamp-1 max-w-[50%] text-center text-xs font-semibold'>
{bookTitle}
</h2>
</div>
<div className='bg-base-100 z-20 ml-auto flex h-full items-center space-x-4'>
<SettingsToggler />
<NotebookToggler bookKey={bookKey} />
<Dropdown
className='exclude-title-bar-mousedown dropdown-bottom dropdown-end'
buttonClassName='btn btn-ghost h-8 min-h-8 w-8 p-0'
toggleButton={<PiDotsThreeVerticalBold size={iconSize16} />}
onToggle={handleToggleDropdown}
>
<ViewMenu bookKey={bookKey} onSetSettingsDialogOpen={onSetSettingsDialogOpen} />
</Dropdown>
<div className='bg-base-100 z-20 ml-auto flex h-full items-center space-x-4'>
<SettingsToggler />
<NotebookToggler bookKey={bookKey} />
<Dropdown
className='exclude-title-bar-mousedown dropdown-bottom dropdown-end'
buttonClassName='btn btn-ghost h-8 min-h-8 w-8 p-0'
toggleButton={<PiDotsThreeVerticalBold size={iconSize16} />}
onToggle={handleToggleDropdown}
>
<ViewMenu bookKey={bookKey} onSetSettingsDialogOpen={onSetSettingsDialogOpen} />
</Dropdown>
<WindowButtons
className='window-buttons flex h-full items-center'
headerRef={headerRef}
showMinimize={
bookKeys.length == 1 && !isTrafficLightVisible && appService?.appPlatform !== 'web'
}
showMaximize={
bookKeys.length == 1 && !isTrafficLightVisible && appService?.appPlatform !== 'web'
}
onClose={() => onCloseBook(bookKey)}
/>
<WindowButtons
className='window-buttons flex h-full items-center'
headerRef={headerRef}
showMinimize={
bookKeys.length == 1 && !isTrafficLightVisible && appService?.appPlatform !== 'web'
}
showMaximize={
bookKeys.length == 1 && !isTrafficLightVisible && appService?.appPlatform !== 'web'
}
onClose={() => onCloseBook(bookKey)}
/>
</div>
</div>
</div>
);
@@ -45,26 +45,35 @@ const HintInfo: React.FC<SectionInfoProps> = ({
}, [hintMessage]);
return (
<div
className={clsx(
'hintinfo absolute flex items-center justify-end overflow-hidden',
hintMessage ? 'bg-base-100' : 'bg-transparent',
isVertical ? 'writing-vertical-rl max-h-[50%]' : 'top-0 h-[44px] max-w-[50%]',
)}
style={
isVertical
? {
bottom: `${verticalMargin * 1.5}px`,
left: `calc(100% - ${horizontalGap}%)`,
width: showDoubleBorder ? '30px' : `${horizontalGap}%`,
}
: { insetInlineEnd: `${horizontalGap}%` }
}
>
<h2 className={clsx('text-neutral-content text-center font-sans text-xs font-light')}>
{hintMessage || ''}
</h2>
</div>
<>
<div
className={clsx(
'absolute left-0 right-0 top-0 z-10 h-[env(safe-area-inset-top)]',
hintMessage ? 'bg-base-100' : 'bg-transparent',
)}
/>
<div
className={clsx(
'hintinfo absolute flex items-center justify-end overflow-hidden ps-2',
'mt-[env(safe-area-inset-top)]',
hintMessage ? 'bg-base-100' : 'bg-transparent',
isVertical ? 'writing-vertical-rl max-h-[50%]' : 'top-0 h-[44px] max-w-[50%]',
)}
style={
isVertical
? {
bottom: `${verticalMargin * 1.5}px`,
left: `calc(100% - ${horizontalGap}%)`,
width: showDoubleBorder ? '30px' : `${horizontalGap}%`,
}
: { insetInlineEnd: `${horizontalGap}%` }
}
>
<h2 className={clsx('text-neutral-content text-center font-sans text-xs font-light')}>
{hintMessage || ''}
</h2>
</div>
</>
);
};
@@ -57,7 +57,9 @@ const PageInfoView: React.FC<PageInfoProps> = ({
}
: {
insetInlineEnd: `${horizontalGap}%`,
paddingBottom: appService?.hasSafeAreaInset ? 'env(safe-area-inset-bottom)' : 0,
paddingBottom: appService?.hasSafeAreaInset
? 'calc(env(safe-area-inset-bottom)*0.67)'
: 0,
}
}
>
@@ -19,32 +19,41 @@ const SectionInfo: React.FC<SectionInfoProps> = ({
verticalMargin,
}) => {
return (
<div
className={clsx(
'sectioninfo absolute flex items-center overflow-hidden',
isVertical ? 'writing-vertical-rl max-h-[85%]' : 'top-0 h-[44px]',
isScrolled && !isVertical && 'bg-base-100',
)}
style={
isVertical
? {
top: `${verticalMargin * 1.5}px`,
left: `calc(100% - ${horizontalGap}%)`,
width: showDoubleBorder ? '32px' : `${horizontalGap}%`,
height: `calc(100% - ${verticalMargin * 2}px)`,
}
: { insetInlineStart: `${horizontalGap}%`, width: `calc(100% - ${horizontalGap * 2}%)` }
}
>
<h2
<>
<div
className={clsx(
'text-neutral-content text-center font-sans text-xs font-light',
isVertical ? '' : 'line-clamp-1',
'absolute left-0 right-0 top-0 z-10 h-[env(safe-area-inset-top)]',
isScrolled && !isVertical && 'bg-base-100',
)}
/>
<div
className={clsx(
'sectioninfo absolute flex items-center overflow-hidden',
'mt-[env(safe-area-inset-top)]',
isVertical ? 'writing-vertical-rl max-h-[85%]' : 'top-0 h-[44px]',
isScrolled && !isVertical && 'bg-base-100',
)}
style={
isVertical
? {
top: `${verticalMargin * 1.5}px`,
left: `calc(100% - ${horizontalGap}%)`,
width: showDoubleBorder ? '32px' : `${horizontalGap}%`,
height: `calc(100% - ${verticalMargin * 2}px)`,
}
: { insetInlineStart: `${horizontalGap}%`, width: `calc(100% - ${horizontalGap * 2}%)` }
}
>
{section || ''}
</h2>
</div>
<h2
className={clsx(
'text-neutral-content text-center font-sans text-xs font-light',
isVertical ? '' : 'line-clamp-1',
)}
>
{section || ''}
</h2>
</div>
</>
);
};
@@ -43,6 +43,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const [borderColor, setBorderColor] = useState(viewSettings.borderColor!);
const [showHeader, setShowHeader] = useState(viewSettings.showHeader!);
const [showFooter, setShowFooter] = useState(viewSettings.showFooter!);
const [showBarsOnScroll, setShowBarsOnScroll] = useState(viewSettings.showBarsOnScroll!);
useEffect(() => {
saveViewSettings(envConfig, bookKey, 'paragraphMargin', paragraphMargin);
@@ -196,6 +197,11 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [showHeader]);
useEffect(() => {
saveViewSettings(envConfig, bookKey, 'showBarsOnScroll', showBarsOnScroll, false, false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [showBarsOnScroll]);
useEffect(() => {
if (showFooter === viewSettings.showFooter) return;
if (showFooter && !viewSettings.vertical) {
@@ -391,24 +397,6 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
<h2 className='mb-2 font-medium'>{_('Page')}</h2>
<div className='card bg-base-100 border-base-200 border shadow'>
<div className='divide-base-200 divide-y'>
<div className='config-item'>
<span className=''>{_('Show Header')}</span>
<input
type='checkbox'
className='toggle'
checked={showHeader}
onChange={() => setShowHeader(!showHeader)}
/>
</div>
<div className='config-item'>
<span className=''>{_('Show Footer')}</span>
<input
type='checkbox'
className='toggle'
checked={showFooter}
onChange={() => setShowFooter(!showFooter)}
/>
</div>
<NumberInput
label={_('Vertical Margins (px)')}
value={marginPx}
@@ -456,6 +444,41 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
</div>
</div>
</div>
<div className='w-full'>
<h2 className='mb-2 font-medium'>{_('Header & Footer')}</h2>
<div className='card bg-base-100 border-base-200 border shadow'>
<div className='divide-base-200 divide-y'>
<div className='config-item'>
<span className=''>{_('Show Header')}</span>
<input
type='checkbox'
className='toggle'
checked={showHeader}
onChange={() => setShowHeader(!showHeader)}
/>
</div>
<div className='config-item'>
<span className=''>{_('Show Footer')}</span>
<input
type='checkbox'
className='toggle'
checked={showFooter}
onChange={() => setShowFooter(!showFooter)}
/>
</div>
<div className='config-item'>
<span className=''>{_('Apply also in Scrolled Mode')}</span>
<input
type='checkbox'
className='toggle'
checked={showBarsOnScroll}
onChange={() => setShowBarsOnScroll(!showBarsOnScroll)}
/>
</div>
</div>
</div>
</div>
</div>
);
};
@@ -31,7 +31,10 @@ export const useClickEvent = (
if (appService?.isMobile) {
windowStartX = 0;
} else {
const windowPosition = await tauriGetWindowLogicalPosition();
const windowPosition = (await tauriGetWindowLogicalPosition()) as {
x: number;
y: number;
};
windowStartX = windowPosition.x;
}
} else {
@@ -52,6 +55,7 @@ export const useClickEvent = (
} else {
if (hoveredBookKey) {
setHoveredBookKey(null);
return;
}
if (!viewSettings.disableClick! && screenX >= viewCenterX) {
if (viewSettings.swapClickArea) {
@@ -90,6 +90,7 @@ export const DEFAULT_BOOK_LAYOUT: BookLayout = {
borderColor: 'red',
showHeader: true,
showFooter: true,
showBarsOnScroll: false,
};
export const DEFAULT_BOOK_STYLE: BookStyle = {
+1
View File
@@ -82,6 +82,7 @@ export interface BookLayout {
borderColor: string;
showHeader: boolean;
showFooter: boolean;
showBarsOnScroll: boolean;
}
export interface BookStyle {
+2 -1
View File
@@ -2,11 +2,12 @@ import { ViewSettings } from '@/types/book';
export const getMaxInlineSize = (viewSettings: ViewSettings) => {
const isScrolled = viewSettings.scrolled!;
const isVertical = viewSettings.vertical!;
const maxColumnCount = viewSettings.maxColumnCount!;
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
return maxColumnCount === 1 || isScrolled
return maxColumnCount === 1 || isScrolled || isVertical
? Math.max(screenWidth, screenHeight, 720)
: viewSettings.maxInlineSize!;
};