2024-10-03 04:02:59 +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 Stack from '@mui/material/Stack';
|
|
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
|
import Box from '@mui/material/Box';
|
|
|
|
|
import MenuItem from '@mui/material/MenuItem';
|
2024-12-22 00:41:56 +01:00
|
|
|
import { memo, useLayoutEffect } from 'react';
|
2024-10-03 04:02:59 +02:00
|
|
|
import Popover from '@mui/material/Popover';
|
|
|
|
|
import { bindPopover, bindTrigger, usePopupState } from 'material-ui-popup-state/hooks';
|
|
|
|
|
import FormControl from '@mui/material/FormControl';
|
|
|
|
|
import InputLabel from '@mui/material/InputLabel';
|
|
|
|
|
import { Link } from 'react-router-dom';
|
2025-08-16 02:48:46 +02:00
|
|
|
import { Select } from '@/base/components/inputs/Select.tsx';
|
2025-08-16 02:02:13 +02:00
|
|
|
import { ReaderChapterList } from '@/features/reader/overlay/navigation/components/ReaderChapterList.tsx';
|
|
|
|
|
import { ReaderNavBarDesktopNextPreviousButton } from '@/features/reader/overlay/navigation/desktop/components/ReaderNavBarDesktopNextPreviousButton.tsx';
|
2025-08-15 22:02:58 +02:00
|
|
|
import { getOptionForDirection } from '@/features/theme/services/ThemeCreator.ts';
|
|
|
|
|
import { ReaderService } from '@/features/reader/services/ReaderService.ts';
|
|
|
|
|
import { ReaderControls } from '@/features/reader/services/ReaderControls.ts';
|
2025-08-16 02:02:13 +02:00
|
|
|
import { ReaderStateChapters } from '@/features/reader/Reader.types.ts';
|
2025-08-16 02:48:46 +02:00
|
|
|
import { withPropsFrom } from '@/base/hoc/withPropsFrom.tsx';
|
2025-11-29 15:26:57 +01:00
|
|
|
import { ChapterIdInfo } from '@/features/chapter/Chapter.types.ts';
|
2024-10-03 04:02:59 +02:00
|
|
|
|
2024-12-21 03:46:55 +01:00
|
|
|
const BaseReaderNavBarDesktopChapterNavigation = ({
|
2025-11-29 15:26:57 +01:00
|
|
|
currentChapterId,
|
|
|
|
|
currentChapterName,
|
|
|
|
|
currentChapterNumber,
|
2024-10-03 04:02:59 +02:00
|
|
|
previousChapter,
|
|
|
|
|
nextChapter,
|
|
|
|
|
chapters = [],
|
2024-12-21 03:46:55 +01:00
|
|
|
readerThemeDirection,
|
2025-11-29 15:26:57 +01:00
|
|
|
}: {
|
|
|
|
|
currentChapterId: ChapterIdInfo['id'] | undefined;
|
|
|
|
|
currentChapterName: string | undefined;
|
|
|
|
|
currentChapterNumber: number | undefined;
|
|
|
|
|
} & Pick<ReaderStateChapters, 'chapters' | 'previousChapter' | 'nextChapter'> & {
|
|
|
|
|
readerThemeDirection: ReturnType<typeof ReaderService.useGetThemeDirection>;
|
|
|
|
|
}) => {
|
2024-10-03 04:02:59 +02:00
|
|
|
const { t } = useTranslation();
|
|
|
|
|
|
|
|
|
|
const popupState = usePopupState({ variant: 'popover', popupId: 'reader-nav-bar-desktop-chapter-list' });
|
|
|
|
|
|
|
|
|
|
useLayoutEffect(() => {
|
|
|
|
|
popupState.close();
|
2025-11-29 15:26:57 +01:00
|
|
|
}, [currentChapterId]);
|
2024-10-03 04:02:59 +02:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Stack sx={{ flexDirection: 'row', gap: 1 }} dir="ltr">
|
|
|
|
|
<ReaderNavBarDesktopNextPreviousButton
|
|
|
|
|
type="previous"
|
|
|
|
|
title={t(
|
2024-12-09 13:58:17 +01:00
|
|
|
getOptionForDirection(
|
|
|
|
|
'reader.button.previous_chapter',
|
|
|
|
|
'reader.button.next_chapter',
|
|
|
|
|
readerThemeDirection,
|
|
|
|
|
),
|
2024-10-03 04:02:59 +02:00
|
|
|
)}
|
2024-12-11 22:33:04 +01:00
|
|
|
onClick={() => {
|
2025-09-20 19:51:26 +02:00
|
|
|
ReaderControls.openChapter(getOptionForDirection('previous', 'next', readerThemeDirection));
|
2024-12-09 13:58:17 +01:00
|
|
|
}}
|
2024-12-11 22:33:04 +01:00
|
|
|
disabled={getOptionForDirection(!previousChapter, !nextChapter, readerThemeDirection)}
|
2024-10-03 04:02:59 +02:00
|
|
|
/>
|
|
|
|
|
<FormControl sx={{ flexBasis: '70%', flexGrow: 0, flexShrink: 0 }}>
|
|
|
|
|
<InputLabel id="reader-nav-bar-desktop-chapter-select">{t('chapter.title_one')}</InputLabel>
|
|
|
|
|
<Select
|
|
|
|
|
{...bindTrigger(popupState)}
|
|
|
|
|
open={popupState.isOpen}
|
2025-11-29 15:26:57 +01:00
|
|
|
value={currentChapterId ?? 0}
|
2024-10-03 04:02:59 +02:00
|
|
|
// hide actual select menu
|
|
|
|
|
MenuProps={{ sx: { visibility: 'hidden' } }}
|
|
|
|
|
label={t('chapter.title_one')}
|
|
|
|
|
labelId="reader-nav-bar-desktop-chapter-select"
|
|
|
|
|
>
|
|
|
|
|
{/* hacky way to use the select component with a custom menu, the only possible value that is needed is the current chapter */}
|
2025-11-29 15:26:57 +01:00
|
|
|
<MenuItem key={currentChapterId} value={currentChapterId ?? 0}>
|
|
|
|
|
{currentChapterNumber !== undefined ? `#${currentChapterNumber} ${currentChapterName}` : ''}
|
2024-10-03 04:02:59 +02:00
|
|
|
</MenuItem>
|
|
|
|
|
</Select>
|
|
|
|
|
</FormControl>
|
|
|
|
|
<ReaderNavBarDesktopNextPreviousButton
|
|
|
|
|
component={Link}
|
|
|
|
|
type="next"
|
|
|
|
|
title={t(
|
2024-12-09 13:58:17 +01:00
|
|
|
getOptionForDirection(
|
|
|
|
|
'reader.button.next_chapter',
|
|
|
|
|
'reader.button.previous_chapter',
|
|
|
|
|
readerThemeDirection,
|
|
|
|
|
),
|
2024-10-03 04:02:59 +02:00
|
|
|
)}
|
2024-12-11 22:33:04 +01:00
|
|
|
onClick={() => {
|
2025-09-20 19:51:26 +02:00
|
|
|
ReaderControls.openChapter(getOptionForDirection('next', 'previous', readerThemeDirection));
|
2024-12-09 13:58:17 +01:00
|
|
|
}}
|
2024-12-11 22:33:04 +01:00
|
|
|
disabled={getOptionForDirection(!nextChapter, !previousChapter, readerThemeDirection)}
|
2024-10-03 04:02:59 +02:00
|
|
|
/>
|
|
|
|
|
<Popover
|
|
|
|
|
{...bindPopover(popupState)}
|
|
|
|
|
anchorOrigin={{
|
|
|
|
|
vertical: 'bottom',
|
|
|
|
|
horizontal: 'left',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Box sx={{ mb: 1 }}>
|
|
|
|
|
<ReaderChapterList
|
|
|
|
|
style={{
|
|
|
|
|
width: '500px',
|
|
|
|
|
maxWidth: '90vw',
|
|
|
|
|
minHeight: '150px',
|
|
|
|
|
maxHeight: '300px',
|
|
|
|
|
}}
|
2025-11-29 15:26:57 +01:00
|
|
|
currentChapterId={currentChapterId}
|
2024-10-03 04:02:59 +02:00
|
|
|
chapters={chapters}
|
|
|
|
|
/>
|
|
|
|
|
</Box>
|
|
|
|
|
</Popover>
|
|
|
|
|
</Stack>
|
|
|
|
|
);
|
|
|
|
|
};
|
2024-12-21 03:46:55 +01:00
|
|
|
|
|
|
|
|
export const ReaderNavBarDesktopChapterNavigation = withPropsFrom(
|
2024-12-22 00:41:56 +01:00
|
|
|
memo(BaseReaderNavBarDesktopChapterNavigation),
|
2024-12-21 03:46:55 +01:00
|
|
|
[
|
|
|
|
|
() => ({
|
|
|
|
|
readerThemeDirection: ReaderService.useGetThemeDirection(),
|
|
|
|
|
}),
|
|
|
|
|
],
|
2025-09-20 19:51:26 +02:00
|
|
|
['readerThemeDirection'],
|
2024-12-21 03:46:55 +01:00
|
|
|
);
|