Optionally adjust progress bar position based on available size
This commit is contained in:
@@ -14,10 +14,16 @@ import { ButtonSelect } from '@/modules/core/components/buttons/ButtonSelect.tsx
|
||||
|
||||
export const ButtonSelectInput = <Value extends string | number>({
|
||||
label,
|
||||
description,
|
||||
...buttonSelectProps
|
||||
}: ComponentProps<typeof ButtonSelect<Value>> & { label: string }) => (
|
||||
}: ComponentProps<typeof ButtonSelect<Value>> & { label: string; description?: string }) => (
|
||||
<Stack>
|
||||
<Typography>{label}</Typography>
|
||||
{description && (
|
||||
<Typography variant="body2" color="textDisabled">
|
||||
{description}
|
||||
</Typography>
|
||||
)}
|
||||
<ButtonSelect {...buttonSelectProps} />
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -263,7 +263,6 @@ export const ReaderProgressBar = withPropsFrom(
|
||||
'pageLoadStates',
|
||||
'totalPages',
|
||||
'currentPageIndex',
|
||||
'progressBarPosition',
|
||||
'readingMode',
|
||||
],
|
||||
);
|
||||
|
||||
@@ -18,7 +18,7 @@ import { useReaderStateChaptersContext } from '@/modules/reader/contexts/state/R
|
||||
import { ReaderService } from '@/modules/reader/services/ReaderService.ts';
|
||||
import { getPage } from '@/modules/reader/utils/ReaderProgressBar.utils.tsx';
|
||||
import { getOptionForDirection } from '@/modules/theme/services/ThemeCreator.ts';
|
||||
import { ReaderResumeMode, ReaderStateChapters } from '@/modules/reader/types/Reader.types.ts';
|
||||
import { ProgressBarPosition, ReaderResumeMode, ReaderStateChapters } from '@/modules/reader/types/Reader.types.ts';
|
||||
import { ReaderProgressBarDirectionWrapper } from '@/modules/reader/components/overlay/progress-bar/ReaderProgressBarDirectionWrapper.tsx';
|
||||
import { useReaderProgressBarContext } from '@/modules/reader/contexts/ReaderProgressBarContext.tsx';
|
||||
import { useReaderOverlayContext } from '@/modules/reader/contexts/ReaderOverlayContext.tsx';
|
||||
@@ -147,6 +147,7 @@ const BaseMobileReaderProgressBar = ({
|
||||
{getOptionForDirection(<SkipPreviousIcon />, <SkipNextIcon />, direction)}
|
||||
</IconButton>
|
||||
<ReaderProgressBar
|
||||
progressBarPosition={ProgressBarPosition.BOTTOM}
|
||||
fullSegmentClicks={false}
|
||||
createProgressBarSlot={useCallback(
|
||||
(page, pagesIndex, _2, _3, _4, _5, isTrailingPage, totalPages) => (
|
||||
|
||||
@@ -7,11 +7,17 @@
|
||||
*/
|
||||
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { memo, useCallback, useState } from 'react';
|
||||
import { ReaderProgressBar } from '@/modules/reader/components/overlay/progress-bar/ReaderProgressBar.tsx';
|
||||
import { userReaderStatePagesContext } from '@/modules/reader/contexts/state/ReaderStatePagesContext.tsx';
|
||||
import { ReaderService } from '@/modules/reader/services/ReaderService.ts';
|
||||
import { IReaderSettings, ProgressBarType, TReaderScrollbarContext } from '@/modules/reader/types/Reader.types.ts';
|
||||
import {
|
||||
IReaderSettings,
|
||||
ProgressBarPosition,
|
||||
ProgressBarPositionAutoVertical,
|
||||
ProgressBarType,
|
||||
TReaderScrollbarContext,
|
||||
} from '@/modules/reader/types/Reader.types.ts';
|
||||
import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts';
|
||||
import { getProgressBarPositionInfo } from '@/modules/reader/utils/ReaderProgressBar.utils.tsx';
|
||||
import { ReaderProgressBarDirectionWrapper } from '@/modules/reader/components/overlay/progress-bar/ReaderProgressBarDirectionWrapper.tsx';
|
||||
@@ -22,6 +28,7 @@ import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContex
|
||||
import { useReaderProgressBarContext } from '@/modules/reader/contexts/ReaderProgressBarContext.tsx';
|
||||
import { useReaderScrollbarContext } from '@/modules/reader/contexts/ReaderScrollbarContext.tsx';
|
||||
import { ReaderProgressBarSlotDesktop } from '@/modules/reader/components/overlay/progress-bar/desktop/ReaderProgressBarSlotDesktop.tsx';
|
||||
import { useResizeObserver } from '@/modules/core/hooks/useResizeObserver.tsx';
|
||||
|
||||
const BaseStandardReaderProgressBar = ({
|
||||
readerNavBarWidth,
|
||||
@@ -31,20 +38,37 @@ const BaseStandardReaderProgressBar = ({
|
||||
progressBarType,
|
||||
progressBarSize,
|
||||
progressBarPosition,
|
||||
progressBarPositionAutoVertical,
|
||||
readerDirection,
|
||||
scrollbarXSize,
|
||||
scrollbarYSize,
|
||||
totalPages,
|
||||
}: Pick<NavbarContextType, 'readerNavBarWidth'> &
|
||||
Pick<TReaderProgressBarContext, 'isMaximized' | 'setIsMaximized' | 'isDragging'> &
|
||||
Pick<IReaderSettings, 'progressBarType' | 'progressBarSize' | 'progressBarPosition'> &
|
||||
Pick<
|
||||
IReaderSettings,
|
||||
'progressBarType' | 'progressBarSize' | 'progressBarPosition' | 'progressBarPositionAutoVertical'
|
||||
> &
|
||||
Pick<TReaderScrollbarContext, 'scrollbarXSize' | 'scrollbarYSize'> &
|
||||
Pick<ReaderProgressBarProps, 'totalPages'> & {
|
||||
readerDirection: ReturnType<typeof ReaderService.useGetThemeDirection>;
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { isBottom, isLeft, isRight, isVertical, isHorizontal } = getProgressBarPositionInfo(progressBarPosition);
|
||||
const [, setRefreshProgressBarPosition] = useState({});
|
||||
useResizeObserver(
|
||||
window.document.documentElement,
|
||||
useCallback(() => setRefreshProgressBarPosition({}), []),
|
||||
);
|
||||
|
||||
const finalProgressBarPosition =
|
||||
window.innerHeight > window.innerWidth &&
|
||||
progressBarPositionAutoVertical !== ProgressBarPositionAutoVertical.OFF
|
||||
? (progressBarPositionAutoVertical as unknown as ProgressBarPosition)
|
||||
: progressBarPosition;
|
||||
|
||||
const { isBottom, isLeft, isRight, isVertical, isHorizontal } =
|
||||
getProgressBarPositionInfo(finalProgressBarPosition);
|
||||
|
||||
const arePagesLoaded = !!totalPages;
|
||||
const isHidden = progressBarType === ProgressBarType.HIDDEN;
|
||||
@@ -55,6 +79,7 @@ const BaseStandardReaderProgressBar = ({
|
||||
return (
|
||||
<ReaderProgressBarDirectionWrapper>
|
||||
<ReaderProgressBar
|
||||
progressBarPosition={finalProgressBarPosition}
|
||||
fullSegmentClicks
|
||||
createProgressBarSlot={useCallback(
|
||||
(
|
||||
@@ -73,13 +98,13 @@ const BaseStandardReaderProgressBar = ({
|
||||
pageUrl={page.primary.url}
|
||||
primaryPageLoadState={primaryPageLoadState}
|
||||
secondaryPageLoadState={secondaryPageLoadState}
|
||||
progressBarPosition={progressBarPosition}
|
||||
progressBarPosition={finalProgressBarPosition}
|
||||
isCurrentPage={isCurrentPage}
|
||||
isLeadingPage={isLeadingPage}
|
||||
showDraggingStyle={showDraggingStyle}
|
||||
/>
|
||||
),
|
||||
[progressBarPosition],
|
||||
[finalProgressBarPosition],
|
||||
)}
|
||||
slotProps={{
|
||||
container: {
|
||||
@@ -243,6 +268,7 @@ export const StandardReaderProgressBar = withPropsFrom(
|
||||
'progressBarType',
|
||||
'progressBarSize',
|
||||
'progressBarPosition',
|
||||
'progressBarPositionAutoVertical',
|
||||
'readerDirection',
|
||||
'scrollbarXSize',
|
||||
'scrollbarYSize',
|
||||
|
||||
@@ -52,9 +52,9 @@ export const ReaderGeneralSettings = ({
|
||||
onDefault={() => onDefault?.('progressBarSize')}
|
||||
/>
|
||||
<ReaderSettingProgressBarPosition
|
||||
overlayMode={overlayMode}
|
||||
progressBarPosition={settings.progressBarPosition}
|
||||
setProgressBarPosition={(value) => updateSetting('progressBarPosition', value)}
|
||||
progressBarPositionAutoVertical={settings.progressBarPositionAutoVertical}
|
||||
updateSetting={updateSetting}
|
||||
/>
|
||||
{(settings.progressBarType === ProgressBarType.HIDDEN || overlayMode === ReaderOverlayMode.MOBILE) && (
|
||||
<CheckboxInput
|
||||
|
||||
@@ -9,7 +9,12 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
|
||||
import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
|
||||
import { IReaderSettings, ProgressBarPosition, ReaderOverlayMode } from '@/modules/reader/types/Reader.types.ts';
|
||||
import NotInterestedIcon from '@mui/icons-material/NotInterested';
|
||||
import {
|
||||
IReaderSettings,
|
||||
ProgressBarPosition,
|
||||
ProgressBarPositionAutoVertical,
|
||||
} from '@/modules/reader/types/Reader.types.ts';
|
||||
import { ValueToDisplayData } from '@/modules/core/Core.types.ts';
|
||||
import { ButtonSelectInput } from '@/modules/core/components/inputs/ButtonSelectInput.tsx';
|
||||
|
||||
@@ -30,26 +35,53 @@ const VALUE_TO_DISPLAY_DATA: ValueToDisplayData<ProgressBarPosition> = {
|
||||
|
||||
const PROGRESS_BAR_POSITION_VALUES = Object.values(ProgressBarPosition).filter((value) => typeof value === 'number');
|
||||
|
||||
const VALUE_TO_DISPLAY_DATA_AUTO_VERTICAL: ValueToDisplayData<ProgressBarPositionAutoVertical> = {
|
||||
...VALUE_TO_DISPLAY_DATA,
|
||||
[ProgressBarPositionAutoVertical.OFF]: {
|
||||
title: 'global.label.disabled',
|
||||
icon: <NotInterestedIcon />,
|
||||
},
|
||||
};
|
||||
|
||||
const PROGRESS_BAR_AUTO_VERTICAL_POSITION_VALUES = Object.values(ProgressBarPositionAutoVertical).filter(
|
||||
(value) => typeof value === 'number',
|
||||
);
|
||||
|
||||
export const ReaderSettingProgressBarPosition = ({
|
||||
overlayMode,
|
||||
progressBarPosition,
|
||||
setProgressBarPosition,
|
||||
}: Pick<IReaderSettings, 'progressBarPosition' | 'overlayMode'> & {
|
||||
setProgressBarPosition: (position: ProgressBarPosition) => void;
|
||||
progressBarPositionAutoVertical,
|
||||
updateSetting,
|
||||
}: Pick<IReaderSettings, 'progressBarPosition' | 'progressBarPositionAutoVertical'> & {
|
||||
updateSetting: <
|
||||
Position extends keyof Pick<IReaderSettings, 'progressBarPosition' | 'progressBarPositionAutoVertical'>,
|
||||
>(
|
||||
filter: Position,
|
||||
value: IReaderSettings[Position],
|
||||
) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (overlayMode !== ReaderOverlayMode.DESKTOP) {
|
||||
return null;
|
||||
}
|
||||
const supportsAutoVerticalPosition = progressBarPosition === ProgressBarPosition.BOTTOM;
|
||||
|
||||
return (
|
||||
<ButtonSelectInput
|
||||
label={t('reader.settings.progress_bar.position')}
|
||||
value={progressBarPosition}
|
||||
values={PROGRESS_BAR_POSITION_VALUES}
|
||||
setValue={setProgressBarPosition}
|
||||
valueToDisplayData={VALUE_TO_DISPLAY_DATA}
|
||||
/>
|
||||
<>
|
||||
<ButtonSelectInput
|
||||
label={t('reader.settings.progress_bar.position')}
|
||||
value={progressBarPosition}
|
||||
values={PROGRESS_BAR_POSITION_VALUES}
|
||||
setValue={(position) => updateSetting('progressBarPosition', position)}
|
||||
valueToDisplayData={VALUE_TO_DISPLAY_DATA}
|
||||
/>
|
||||
{supportsAutoVerticalPosition && (
|
||||
<ButtonSelectInput
|
||||
label={t('reader.settings.progress_bar.auto_vertical_position.title')}
|
||||
description={t('reader.settings.progress_bar.auto_vertical_position.description')}
|
||||
value={progressBarPositionAutoVertical}
|
||||
values={PROGRESS_BAR_AUTO_VERTICAL_POSITION_VALUES}
|
||||
setValue={(position) => updateSetting('progressBarPositionAutoVertical', position)}
|
||||
valueToDisplayData={VALUE_TO_DISPLAY_DATA_AUTO_VERTICAL}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -50,6 +50,7 @@ const GLOBAL_READER_SETTING_OBJECT: Record<keyof IReaderSettingsGlobal, undefine
|
||||
progressBarType: undefined,
|
||||
progressBarSize: undefined,
|
||||
progressBarPosition: undefined,
|
||||
progressBarPositionAutoVertical: undefined,
|
||||
shouldShowPageNumber: undefined,
|
||||
isStaticNav: undefined,
|
||||
backgroundColor: undefined,
|
||||
@@ -73,6 +74,7 @@ export const DEFAULT_READER_SETTINGS: IReaderSettings = {
|
||||
progressBarType: ProgressBarType.STANDARD,
|
||||
progressBarSize: 4,
|
||||
progressBarPosition: ProgressBarPosition.BOTTOM,
|
||||
progressBarPositionAutoVertical: ProgressBarPosition.RIGHT,
|
||||
pageScaleMode: ReaderPageScaleMode.ORIGINAL,
|
||||
shouldStretchPage: false,
|
||||
shouldOffsetDoubleSpreads: false,
|
||||
|
||||
@@ -25,6 +25,12 @@ export enum ProgressBarPosition {
|
||||
RIGHT,
|
||||
}
|
||||
|
||||
export enum ProgressBarPositionAutoVertical {
|
||||
OFF = -1,
|
||||
LEFT = ProgressBarPosition.LEFT,
|
||||
RIGHT = ProgressBarPosition.RIGHT,
|
||||
}
|
||||
|
||||
export enum ReadingDirection {
|
||||
LTR,
|
||||
RTL,
|
||||
@@ -119,6 +125,7 @@ export interface IReaderSettingsGlobal {
|
||||
*/
|
||||
progressBarSize: number;
|
||||
progressBarPosition: ProgressBarPosition;
|
||||
progressBarPositionAutoVertical: ProgressBarPositionAutoVertical;
|
||||
shouldShowPageNumber: boolean;
|
||||
isStaticNav: boolean;
|
||||
backgroundColor: ReaderBackgroundColor;
|
||||
|
||||
Reference in New Issue
Block a user