Files
readest/apps/readest-app/src/app/reader/components/SectionInfo.tsx
T
Huang Xin 7716f189c3 fix(layout): keep header/footer transparent and fixed in scrolled mode, closes #4157 (#4168)
Remove the redundant "Apply also in Scrolled Mode" options for bars and
margins so scrolled mode renders the header/footer consistently with
paginated mode: transparent, fixed in position, and not obscuring content.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 10:30:43 +02:00

114 lines
3.3 KiB
TypeScript

import clsx from 'clsx';
import React from 'react';
import { Insets } from '@/types/misc';
import { useEnv } from '@/context/EnvContext';
import { useThemeStore } from '@/store/themeStore';
import { useReaderStore } from '@/store/readerStore';
import { useTranslation } from '@/hooks/useTranslation';
import { eventDispatcher } from '@/utils/event';
interface SectionInfoProps {
bookKey: string;
section?: string;
showDoubleBorder: boolean;
isScrolled: boolean;
isVertical: boolean;
isEink: boolean;
horizontalGap: number;
contentInsets: Insets;
gridInsets: Insets;
}
const SectionInfo: React.FC<SectionInfoProps> = ({
bookKey,
section,
showDoubleBorder,
isScrolled,
isVertical,
isEink,
horizontalGap,
contentInsets,
gridInsets,
}) => {
const _ = useTranslation();
const { appService } = useEnv();
const { hoveredBookKey, getView, getViewSettings, setHoveredBookKey } = useReaderStore();
const { systemUIVisible, statusBarHeight } = useThemeStore();
const viewSettings = getViewSettings(bookKey)!;
const topInset = Math.max(
gridInsets.top,
appService?.isAndroidApp && systemUIVisible ? statusBarHeight / 2 : 0,
);
const handleNotchClick = () => {
if (eventDispatcher.dispatchSync('iframe-single-click')) return;
if (isScrolled) {
getView(bookKey)?.renderer.scrollToAnchor?.(0, 'anchor', true);
}
};
const handleSectionClick = () => {
if (eventDispatcher.dispatchSync('iframe-single-click')) return;
setHoveredBookKey(bookKey);
};
return (
<>
<div
className={clsx(
'notch-area absolute left-0 right-0 top-0 z-10',
isScrolled && !isVertical && 'bg-base-100',
)}
role='none'
tabIndex={-1}
onClick={handleNotchClick}
style={{
height: `${topInset}px`,
}}
/>
<div
className={clsx(
'sectioninfo absolute flex items-center overflow-hidden font-sans',
isEink ? 'text-sm font-normal' : 'text-neutral-content text-xs font-light',
isVertical ? 'writing-vertical-rl max-h-[85%]' : 'top-0',
)}
role='none'
tabIndex={-1}
onClick={handleSectionClick}
style={
isVertical
? {
top: `${(contentInsets.top - gridInsets.top) * 1.5}px`,
bottom: `${(contentInsets.bottom - gridInsets.bottom) * 1.5}px`,
right: showDoubleBorder
? `calc(${contentInsets.right}px)`
: `calc(${Math.max(0, contentInsets.right - 32)}px)`,
width: showDoubleBorder ? '32px' : `${contentInsets.right}px`,
}
: {
top: `${topInset}px`,
paddingInline: `calc(${horizontalGap / 2}% + ${contentInsets.left / 2}px)`,
width: '100%',
height: `${viewSettings.marginTopPx}px`,
}
}
>
<span
aria-label={section ? _('Section Title') + `: ${section}` : ''}
className={clsx(
'text-center',
isVertical ? '' : 'line-clamp-1',
!isVertical &&
(hoveredBookKey == bookKey || (hoveredBookKey && appService?.isMobile)) &&
'hidden',
)}
>
{section || ''}
</span>
</div>
</>
);
};
export default SectionInfo;