Files
suwayomi-material-you-webui/src/features/reader/overlay/navigation/desktop/components/ReaderNavBarDesktopChapterNavigation.tsx

131 lines
5.5 KiB
TypeScript
Raw Normal View History

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-15 22:02:58 +02:00
import { Select } from '@/features/core/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-15 22:02:58 +02:00
import { withPropsFrom } from '@/features/core/hoc/withPropsFrom.tsx';
2024-10-03 04:02:59 +02:00
2024-12-21 03:46:55 +01:00
const BaseReaderNavBarDesktopChapterNavigation = ({
2024-10-03 04:02:59 +02:00
currentChapter,
previousChapter,
nextChapter,
chapters = [],
2024-12-21 03:46:55 +01:00
readerThemeDirection,
openChapter,
}: Pick<ReaderStateChapters, 'chapters' | 'currentChapter' | 'previousChapter' | 'nextChapter'> & {
readerThemeDirection: ReturnType<typeof ReaderService.useGetThemeDirection>;
openChapter: ReturnType<typeof ReaderControls.useOpenChapter>;
}) => {
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();
}, [currentChapter?.id]);
return (
<Stack sx={{ flexDirection: 'row', gap: 1 }} dir="ltr">
<ReaderNavBarDesktopNextPreviousButton
type="previous"
title={t(
getOptionForDirection(
'reader.button.previous_chapter',
'reader.button.next_chapter',
readerThemeDirection,
),
2024-10-03 04:02:59 +02:00
)}
onClick={() => {
openChapter(getOptionForDirection('previous', 'next', readerThemeDirection));
}}
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}
value={currentChapter?.id ?? 0}
// 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 */}
<MenuItem key={currentChapter?.id} value={currentChapter?.id ?? 0}>
{currentChapter ? `#${currentChapter.chapterNumber} ${currentChapter.name}` : ''}
</MenuItem>
</Select>
</FormControl>
<ReaderNavBarDesktopNextPreviousButton
component={Link}
type="next"
title={t(
getOptionForDirection(
'reader.button.next_chapter',
'reader.button.previous_chapter',
readerThemeDirection,
),
2024-10-03 04:02:59 +02:00
)}
onClick={() => {
openChapter(getOptionForDirection('next', 'previous', readerThemeDirection));
}}
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',
}}
currentChapter={currentChapter}
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(),
}),
() => ({
openChapter: ReaderControls.useOpenChapter(),
}),
],
['readerThemeDirection', 'openChapter'],
);