2024-09-28 03:24:16 +02:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) Contributors to the Suwayomi project
|
|
|
|
|
*
|
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { ReaderProgressBarProps, TReaderProgressCurrentPage } from '@/modules/reader/types/ReaderProgressBar.types.ts';
|
2024-12-11 13:59:50 +01:00
|
|
|
import { getOptionForDirection as getOptionForDirectionImpl } from '@/modules/theme/services/ThemeCreator.ts';
|
2024-09-28 03:24:16 +02:00
|
|
|
import { ProgressBarPosition } from '@/modules/reader/types/Reader.types.ts';
|
|
|
|
|
|
|
|
|
|
export const getPage = (pageIndex: number, pages: ReaderProgressBarProps['pages']): TReaderProgressCurrentPage => {
|
|
|
|
|
const pagesIndex = pages.findIndex(({ primary, secondary }) =>
|
|
|
|
|
[primary.index, secondary?.index].includes(pageIndex),
|
|
|
|
|
);
|
|
|
|
|
const page = pages[pagesIndex];
|
|
|
|
|
return {
|
|
|
|
|
...page,
|
|
|
|
|
pagesIndex,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2024-12-07 03:43:18 +01:00
|
|
|
/**
|
|
|
|
|
* for the double page mode the secondary page index has to be used to be able to correctly detect if the last page is visible
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
export const getNextIndexFromPage = (page: ReaderProgressBarProps['pages'][number]) =>
|
|
|
|
|
page.secondary?.index ?? page.primary.index;
|
|
|
|
|
|
2024-09-28 03:24:16 +02:00
|
|
|
export const getNextPageIndex = (
|
|
|
|
|
offset: 'previous' | 'next',
|
|
|
|
|
pagesIndex: number,
|
|
|
|
|
pages: ReaderProgressBarProps['pages'],
|
|
|
|
|
): number => {
|
|
|
|
|
switch (offset) {
|
|
|
|
|
case 'previous':
|
2024-12-07 03:43:18 +01:00
|
|
|
return getNextIndexFromPage(pages[Math.max(0, pagesIndex - 1)]);
|
2024-09-28 03:24:16 +02:00
|
|
|
case 'next':
|
2024-12-07 03:43:18 +01:00
|
|
|
return getNextIndexFromPage(pages[Math.min(pages.length - 1, pagesIndex + 1)]);
|
2024-09-28 03:24:16 +02:00
|
|
|
default:
|
|
|
|
|
throw new Error(`Unexpected offset "${offset}"`);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getPageForMousePos = (
|
|
|
|
|
coordinates: { clientX: number; clientY: number },
|
|
|
|
|
elementRect: DOMRect,
|
|
|
|
|
pages: ReaderProgressBarProps['pages'],
|
|
|
|
|
isHorizontalPosition: boolean,
|
2024-12-28 04:05:29 +01:00
|
|
|
fullSegmentClicks: boolean,
|
2024-09-28 03:24:16 +02:00
|
|
|
getOptionForDirection: typeof getOptionForDirectionImpl,
|
|
|
|
|
): ReaderProgressBarProps['pages'][number] => {
|
|
|
|
|
const pos = isHorizontalPosition ? coordinates.clientX : coordinates.clientY;
|
|
|
|
|
const rectPos = isHorizontalPosition ? elementRect.left : elementRect.top;
|
|
|
|
|
const rectSize = isHorizontalPosition ? elementRect.width : elementRect.height;
|
|
|
|
|
|
2024-12-28 04:05:29 +01:00
|
|
|
const mousePosRelativeToProgressBar = pos - rectPos;
|
|
|
|
|
|
|
|
|
|
const totalPages = pages.length - Number(!fullSegmentClicks);
|
|
|
|
|
|
|
|
|
|
const segmentWidth = rectSize / totalPages;
|
|
|
|
|
const clickedSegmentIndex = Math.floor(mousePosRelativeToProgressBar / segmentWidth);
|
|
|
|
|
const segmentMiddlePoint = (clickedSegmentIndex + (fullSegmentClicks ? 1 : 0.5)) * segmentWidth;
|
|
|
|
|
const actualClickedSegmentIndex =
|
|
|
|
|
mousePosRelativeToProgressBar <= segmentMiddlePoint ? clickedSegmentIndex : clickedSegmentIndex + 1;
|
|
|
|
|
|
|
|
|
|
const minPageIndex = Math.max(0, actualClickedSegmentIndex);
|
|
|
|
|
const maxPageIndex = Math.min(minPageIndex, pages.length - 1);
|
|
|
|
|
const newPageIndex = getOptionForDirection(maxPageIndex, pages.length - 1 - maxPageIndex);
|
2024-09-28 03:24:16 +02:00
|
|
|
|
|
|
|
|
return pages[newPageIndex];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getProgressBarPositionInfo = (
|
|
|
|
|
position: ProgressBarPosition,
|
|
|
|
|
): {
|
|
|
|
|
isBottom: boolean;
|
|
|
|
|
isLeft: boolean;
|
|
|
|
|
isRight: boolean;
|
|
|
|
|
isHorizontal: boolean;
|
|
|
|
|
isVertical: boolean;
|
|
|
|
|
} => {
|
|
|
|
|
const isBottom = position === ProgressBarPosition.BOTTOM;
|
|
|
|
|
const isLeft = position === ProgressBarPosition.LEFT;
|
|
|
|
|
const isRight = position === ProgressBarPosition.RIGHT;
|
|
|
|
|
const isHorizontal = isBottom;
|
|
|
|
|
const isVertical = isLeft || isRight;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
isBottom,
|
|
|
|
|
isLeft,
|
|
|
|
|
isRight,
|
|
|
|
|
isHorizontal,
|
|
|
|
|
isVertical,
|
|
|
|
|
};
|
|
|
|
|
};
|