Skip to content

Commit

Permalink
tmp - Reader overlay desktop nav bar
Browse files Browse the repository at this point in the history
  • Loading branch information
schroda committed Oct 18, 2024
1 parent 1979e96 commit b261d80
Show file tree
Hide file tree
Showing 22 changed files with 905 additions and 15 deletions.
19 changes: 15 additions & 4 deletions public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -752,9 +752,12 @@
"chapter_list": "Chapter list",
"close_menu": "Close menu",
"exit": "Exit reader",
"next_chapter": "Next Chapter",
"next_chapter": "Next chapter",
"next_page": "Next page",
"open_menu": "Open menu",
"previous_chapter": "Previous Chapter"
"previous_chapter": "Previous chapter",
"previous_page": "Previous page",
"retry_load_pages": "Retry errored pages"
},
"error": {
"label": {
Expand All @@ -766,7 +769,8 @@
"page_info": {
"label": {
"currently_on_page": "Currently on page",
"of_max_pages": "of {{maxPages}}"
"of_max_pages": "of {{maxPages}}",
"page": "Page"
}
},
"settings": {
Expand All @@ -779,7 +783,7 @@
"label": {
"fit_page_to_window": "Fit page to window",
"load_next_chapter": "Load next chapter at ending",
"offset_first_page": "Offset first page",
"offset_double_spread": "Offset double spreads",
"reader_type": "Reader type",
"reader_width": "Reader width",
"reading_direction": "Reading direction",
Expand All @@ -789,6 +793,13 @@
"skip_dup_chapters": "Skip duplicate chapters",
"static_navigation": "Static navigation"
},
"page_scale": {
"height": "Fit height",
"original": "Original size",
"screen": "Fit screen",
"stretch": "Stretch small pages",
"width": "Fit width"
},
"reader_type": {
"label": {
"continuous_horizontal": "Continues horizontal",
Expand Down
40 changes: 40 additions & 0 deletions src/modules/core/components/buttons/ValueRotationButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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 { useTranslation } from 'react-i18next';
import { useMemo } from 'react';
import Button from '@mui/material/Button';
import { ValueToDisplayData } from '@/modules/core/Core.types.ts';

export const ValueRotationButton = <Value extends string | number>({
value,
values,
setValue,
valueToDisplayData,
}: {
value: Value;
values: Value[];
setValue: (value: Value) => void;
valueToDisplayData: ValueToDisplayData<Value>;
}) => {
const { t } = useTranslation();

const indexOfValue = useMemo(() => values.indexOf(value), [value, values]);

return (
<Button
onClick={() => setValue(values[(indexOfValue + 1) % values.length])}
sx={{ justifyContent: 'start', textTransform: 'unset', flexGrow: 1 }}
variant="contained"
startIcon={valueToDisplayData[value].icon}
size="large"
>
{t(valueToDisplayData[value].title)}
</Button>
);
};
26 changes: 25 additions & 1 deletion src/modules/metadata/Metadata.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import { AppMetadataKeys, IMetadataMigration } from '@/modules/metadata/Metadata.types.ts';
import { ReadingMode } from '@/modules/reader-deprecated/Reader.types.ts';
import { ReaderPageScaleMode, ReadingMode } from '@/modules/reader-deprecated/Reader.types.ts';

export const APP_METADATA_KEY_PREFIX = 'webUI_';

Expand Down Expand Up @@ -138,6 +138,18 @@ export const METADATA_MIGRATIONS: IMetadataMigration[] = [
oldKey: 'readerType',
newKey: 'readingMode',
},
{
oldKey: 'offsetFirstPage',
newKey: 'shouldOffsetDoubleSpreads',
},
{
oldKey: 'fitPageToWindow',
newKey: 'pageScaleMode',
},
{
oldKey: 'scalePage',
newKey: 'shouldScalePage',
},
],
values: [
// START: readerType
Expand Down Expand Up @@ -182,6 +194,18 @@ export const METADATA_MIGRATIONS: IMetadataMigration[] = [
newValue: `${ReadingMode.CONTINUOUS_HORIZONTAL}`,
},
// END: readerType
// START: fitPageToWindow
{
key: 'fitPageToWindow',
oldValue: 'false',
newValue: `${ReaderPageScaleMode.ORIGINAL}`,
},
{
key: 'fitPageToWindow',
oldValue: 'true',
newValue: `${ReaderPageScaleMode.SCREEN}`,
},
// END: fitPageToWindow
],
},
];
12 changes: 11 additions & 1 deletion src/modules/reader-deprecated/Reader.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

import { IReaderSettings, ReadingDirection, ReadingMode } from '@/modules/reader-deprecated/Reader.types.ts';
import {
IReaderSettings,
ReaderPageScaleMode,
ReadingDirection,
ReadingMode,
} from '@/modules/reader-deprecated/Reader.types.ts';
import { TapZoneLayouts } from '@/modules/reader/types/TapZoneLayout.types.ts';

export const DEFAULT_READER_SETTINGS: IReaderSettings = {
staticNav: false,
Expand All @@ -18,6 +24,10 @@ export const DEFAULT_READER_SETTINGS: IReaderSettings = {
readerType: 'ContinuesVertical',
offsetFirstPage: false,
readerWidth: 50,
tapZoneLayout: TapZoneLayouts.STANDARD,
pageScaleMode: ReaderPageScaleMode.ORIGINAL,
shouldScalePage: false,
shouldOffsetDoubleSpreads: false,
readingDirection: ReadingDirection.LTR,
readingMode: ReadingMode.SINGLE_PAGE,
};
5 changes: 5 additions & 0 deletions src/modules/reader-deprecated/Reader.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { GetChaptersReaderQuery, MangaReaderFieldsFragment } from '@/lib/graphql/generated/graphql.ts';
import { TapZoneLayouts } from '@/modules/reader/types/TapZoneLayout.types.ts';

export type ReaderType =
| 'ContinuesVertical'
Expand Down Expand Up @@ -49,6 +50,10 @@ export interface IReaderSettings {
readerType: ReaderType;
offsetFirstPage: boolean;
readerWidth: number;
tapZoneLayout: TapZoneLayouts;
pageScaleMode: ReaderPageScaleMode;
shouldScalePage: boolean;
shouldOffsetDoubleSpreads: boolean;
readingDirection: ReadingDirection;
readingMode: ReadingMode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

import { Virtuoso } from 'react-virtuoso';
import { Virtuoso, VirtuosoProps } from 'react-virtuoso';
import { useMemo } from 'react';
import { IChapterWithMeta } from '@/modules/chapter/components/ChapterList.tsx';
import { ChapterCard } from '@/modules/chapter/components/cards/ChapterCard.tsx';
Expand All @@ -16,12 +16,13 @@ import { ReaderStateChapters } from '@/modules/reader/types/Reader.types.ts';
export const ReaderChapterList = ({
currentChapter,
chapters,
}: Required<Pick<ReaderStateChapters, 'chapters' | 'currentChapter'>>) => {
style,
}: Pick<ReaderStateChapters, 'chapters' | 'currentChapter'> & Pick<VirtuosoProps<any, any>, 'style'>) => {
const { data: downloaderData } = requestManager.useGetDownloadStatus();
const queue = downloaderData?.downloadStatus.queue ?? [];

const currentChapterIndex = useMemo(
() => chapters.findIndex((chapter) => chapter.id === currentChapter.id),
() => chapters.findIndex((chapter) => chapter.id === currentChapter?.id),
[currentChapter, chapters],
);

Expand All @@ -43,8 +44,7 @@ export const ReaderChapterList = ({
<Virtuoso
style={{
height: `calc(${chaptersWithMeta.length} * 100px)`,
minHeight: '15vh',
maxHeight: '75vh',
...style,
}}
initialTopMostItemIndex={currentChapterIndex}
totalCount={chaptersWithMeta.length}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* 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 Tooltip from '@mui/material/Tooltip';
import { useTranslation } from 'react-i18next';
import IconButton from '@mui/material/IconButton';
import ArrowBack from '@mui/icons-material/ArrowBack';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import PushPinIcon from '@mui/icons-material/PushPin';
import Divider from '@mui/material/Divider';
import { useCallback, useRef, useState } from 'react';
import Drawer from '@mui/material/Drawer';
import { useGetOptionForDirection } from '@/theme.tsx';
import { ReaderNavBarDesktopProps } from '@/modules/reader/types/ReaderOverlay.types.ts';
import { useBackButton } from '@/modules/core/hooks/useBackButton.ts';
import { ReaderNavContainer } from '@/modules/reader/components/overlay/navigation/desktop/ReaderNavContainer.tsx';
import { ReaderNavBarDesktopMetadata } from '@/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopMetadata.tsx';
import { ReaderNavBarDesktopPageNavigation } from '@/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopPageNavigation.tsx';
import { ReaderNavBarDesktopChapterNavigation } from '@/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopChapterNavigation.tsx';
import { ReaderNavBarDesktopQuickSettings } from '@/modules/reader/components/overlay/navigation/desktop/quick-settings/ReaderNavBarDesktopQuickSettings.tsx';
import { ReaderNavBarDesktopActions } from '@/modules/reader/components/overlay/navigation/desktop/ReaderNavBarDesktopActions.tsx';
import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx';
import { useResizeObserver } from '@/modules/core/hooks/useResizeObserver.tsx';
import { useReaderStateMangaContext } from '@/modules/reader/contexts/state/ReaderStateMangaContext.tsx';
import {
createUpdateReaderSettings,
getReaderSettingsFor,
useDefaultReaderSettings,
} from '@/modules/reader-deprecated/services/ReaderSettingsMetadata.ts';
import { makeToast } from '@/modules/core/utils/Toast.ts';
import { userReaderStatePagesContext } from '@/modules/reader/contexts/state/ReaderStatePagesContext.tsx';
import { useReaderStateChaptersContext } from '@/modules/reader/contexts/state/ReaderStateChaptersContext.tsx';

const useGetPreviousNavBarStaticValue = (isVisible: boolean, staticNav: boolean) => {
const wasNavBarStaticRef = useRef(staticNav);
const wasNavBarStaticPreviousRef = useRef(staticNav);

const resetWasNavBarStaticValue = wasNavBarStaticPreviousRef.current !== wasNavBarStaticRef.current && !isVisible;
if (resetWasNavBarStaticValue) {
wasNavBarStaticRef.current = false;
}

const didNavBarStaticValueChange = wasNavBarStaticPreviousRef.current !== staticNav;
if (didNavBarStaticValueChange) {
wasNavBarStaticRef.current = wasNavBarStaticPreviousRef.current;
wasNavBarStaticPreviousRef.current = staticNav;
}

return wasNavBarStaticRef.current;
};

export const ReaderNavBarDesktop = ({ isVisible, setIsVisible }: ReaderNavBarDesktopProps) => {
const { t } = useTranslation();
const { setReaderNavBarWidth } = useNavBarContext();
const { manga } = useReaderStateMangaContext();
const { chapters, currentChapter, nextChapter, previousChapter } = useReaderStateChaptersContext();
const { pages, currentPageIndex, setCurrentPageIndex } = userReaderStatePagesContext();

const handleBack = useBackButton();
const getOptionForDirection = useGetOptionForDirection();

const updateReaderSettings = createUpdateReaderSettings(manga ?? { id: -1 }, () =>
makeToast(t('reader.settings.error.label.failed_to_save_settings')),
);

const defaultReaderSettings = useDefaultReaderSettings();
const readerSettings = getReaderSettingsFor(manga, defaultReaderSettings.settings);

const [navBarElement, setNavBarElement] = useState<HTMLDivElement | null>();
useResizeObserver(
navBarElement,
useCallback(() => {
if (!readerSettings?.staticNav) {
return;
}

setReaderNavBarWidth(navBarElement!.clientWidth);
}, [navBarElement, readerSettings?.staticNav]),
);

const wasNavBarStatic = useGetPreviousNavBarStaticValue(isVisible, readerSettings.staticNav);
const changedNavBarStaticValue = wasNavBarStatic && isVisible;
const drawerTransitionDuration = changedNavBarStaticValue ? 0 : undefined;

if (!manga || !currentChapter) {
return null;
}

return (
<Drawer
variant={readerSettings.staticNav ? 'permanent' : 'temporary'}
open={isVisible || readerSettings.staticNav}
onClose={() => {
setIsVisible(false);
setReaderNavBarWidth(0);
}}
transitionDuration={drawerTransitionDuration}
>
<ReaderNavContainer
ref={(ref) => setNavBarElement(ref)}
sx={{ backgroundColor: 'background.paper', pointerEvents: 'all' }}
>
<Stack sx={{ p: 2, gap: 2, backgroundColor: 'action.hover' }}>
<Stack sx={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
<Tooltip title={t('reader.button.exit')}>
<IconButton onClick={handleBack} color="inherit">
{getOptionForDirection(<ArrowBack />, <ArrowForwardIcon />)}
</IconButton>
</Tooltip>
<Tooltip title={t('reader.settings.label.static_navigation')}>
<IconButton
onClick={() => {
setReaderNavBarWidth(0);
updateReaderSettings('staticNav', !readerSettings.staticNav);
}}
color={readerSettings.staticNav ? 'primary' : 'inherit'}
>
<PushPinIcon />
</IconButton>
</Tooltip>
</Stack>
<ReaderNavBarDesktopMetadata mangaTitle={manga.title} chapterTitle={currentChapter.name} />
<ReaderNavBarDesktopActions currentChapter={currentChapter} />
</Stack>
<Stack sx={{ p: 2, gap: 2 }}>
<Stack sx={{ gap: 1 }}>
<ReaderNavBarDesktopPageNavigation
currentPageIndex={currentPageIndex}
setCurrentPageIndex={setCurrentPageIndex}
pages={pages}
/>
<ReaderNavBarDesktopChapterNavigation
chapters={chapters}
currentChapter={currentChapter}
nextChapter={nextChapter}
previousChapter={previousChapter}
/>
</Stack>
<Divider />
<ReaderNavBarDesktopQuickSettings settings={readerSettings} updateSetting={updateReaderSettings} />
</Stack>
</ReaderNavContainer>
</Drawer>
);
};
Loading

0 comments on commit b261d80

Please sign in to comment.