Reader settings

This commit is contained in:
schroda
2024-11-04 18:00:35 +01:00
parent 9c57ace973
commit a607f7f368
70 changed files with 2813 additions and 425 deletions

View File

@@ -0,0 +1,66 @@
/*
* 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 { ReaderSettingProgressBarType } from '@/modules/reader/components/settings/general/ReaderSettingProgressBarType.tsx';
import { ReaderSettingProgressBarSize } from '@/modules/reader/components/settings/general/ReaderSettingProgressBarSize.tsx';
import { ReaderSettingProgressBarPosition } from '@/modules/reader/components/settings/general/ReaderSettingProgressBarPosition.tsx';
import {
IReaderSettings,
ProgressBarType,
ReaderOverlayMode,
ReaderSettingsTypeProps,
} from '@/modules/reader/types/Reader.types.ts';
import { ReaderSettingOverlayMode } from '@/modules/reader/components/settings/general/ReaderSettingOverlayMode.tsx';
import { CheckboxInput } from '@/modules/core/components/inputs/CheckboxInput.tsx';
import { ReaderSettingBackgroundColor } from '@/modules/reader/components/settings/general/ReaderSettingBackgroundColor.tsx';
export const ReaderGeneralSettings = ({
overlayMode,
settings,
updateSetting,
}: Pick<IReaderSettings, 'overlayMode'> & ReaderSettingsTypeProps) => {
const { t } = useTranslation();
return (
<Stack sx={{ gap: 2 }}>
<ReaderSettingOverlayMode
overlayMode={settings.overlayMode}
setOverlayMode={(value) => updateSetting('overlayMode', value)}
/>
<ReaderSettingBackgroundColor
backgroundColor={settings.backgroundColor}
updateSetting={(value) => updateSetting('backgroundColor', value)}
/>
<ReaderSettingProgressBarType
overlayMode={overlayMode}
progressBarType={settings.progressBarType}
setProgressBarType={(value) => updateSetting('progressBarType', value)}
/>
<ReaderSettingProgressBarSize
overlayMode={overlayMode}
progressBarType={settings.progressBarType}
progressBarSize={settings.progressBarSize}
setProgressBarSize={(...args) => updateSetting('progressBarSize', ...args)}
/>
<ReaderSettingProgressBarPosition
overlayMode={overlayMode}
progressBarPosition={settings.progressBarPosition}
setProgressBarPosition={(value) => updateSetting('progressBarPosition', value)}
/>
{(settings.progressBarType === ProgressBarType.HIDDEN || overlayMode === ReaderOverlayMode.MOBILE) && (
<CheckboxInput
label={t('reader.settings.label.show_page_number')}
checked={settings.shouldShowPageNumber}
onChange={(_, checked) => updateSetting('shouldShowPageNumber', checked)}
/>
)}
</Stack>
);
};

View File

@@ -0,0 +1,54 @@
/*
* 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 { ValueToDisplayData } from '@/modules/core/Core.types.ts';
import { ButtonSelectInput } from '@/modules/core/components/inputs/ButtonSelectInput.tsx';
import { IReaderSettingsWithDefaultFlag, ReaderBackgroundColor } from '@/modules/reader/types/Reader.types.ts';
const VALUE_TO_DISPLAY_DATA: ValueToDisplayData<ReaderBackgroundColor> = {
[ReaderBackgroundColor.THEME]: {
title: 'settings.appearance.theme.title',
icon: null,
},
[ReaderBackgroundColor.BLACK]: {
title: 'global.colors.black',
icon: null,
},
[ReaderBackgroundColor.GRAY]: {
title: 'global.colors.gray',
icon: null,
},
[ReaderBackgroundColor.WHITE]: {
title: 'global.colors.white',
icon: null,
},
};
const READER_BACKGROUND_COLOR_VALUES = Object.values(ReaderBackgroundColor).filter(
(value) => typeof value === 'number',
);
export const ReaderSettingBackgroundColor = ({
backgroundColor,
updateSetting,
}: Pick<IReaderSettingsWithDefaultFlag, 'backgroundColor'> & {
updateSetting: (color: ReaderBackgroundColor) => void;
}) => {
const { t } = useTranslation();
return (
<ButtonSelectInput
label={t('reader.settings.background_color')}
value={backgroundColor}
values={READER_BACKGROUND_COLOR_VALUES}
setValue={updateSetting}
valueToDisplayData={VALUE_TO_DISPLAY_DATA}
/>
);
};

View File

@@ -0,0 +1,51 @@
/*
* 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 PhoneIphoneIcon from '@mui/icons-material/PhoneIphone';
import ComputerIcon from '@mui/icons-material/Computer';
import AutoModeIcon from '@mui/icons-material/AutoMode';
import { IReaderSettings, ReaderOverlayMode } from '@/modules/reader/types/Reader.types.ts';
import { ValueToDisplayData } from '@/modules/core/Core.types.ts';
import { ButtonSelectInput } from '@/modules/core/components/inputs/ButtonSelectInput.tsx';
const VALUE_TO_DISPLAY_DATA: ValueToDisplayData<ReaderOverlayMode> = {
[ReaderOverlayMode.AUTO]: {
title: 'global.label.auto',
icon: <AutoModeIcon />,
},
[ReaderOverlayMode.DESKTOP]: {
title: 'global.label.desktop',
icon: <ComputerIcon />,
},
[ReaderOverlayMode.MOBILE]: {
title: 'global.label.mobile',
icon: <PhoneIphoneIcon />,
},
};
const READING_MODE_VALUES = Object.values(ReaderOverlayMode).filter((value) => typeof value === 'number');
export const ReaderSettingOverlayMode = ({
overlayMode,
setOverlayMode,
}: Pick<IReaderSettings, 'overlayMode'> & {
setOverlayMode: (mode: ReaderOverlayMode) => void;
}) => {
const { t } = useTranslation();
return (
<ButtonSelectInput
label={t('reader.settings.overlay_mode')}
value={overlayMode}
values={READING_MODE_VALUES}
setValue={setOverlayMode}
valueToDisplayData={VALUE_TO_DISPLAY_DATA}
/>
);
};

View File

@@ -0,0 +1,55 @@
/*
* 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 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 { ValueToDisplayData } from '@/modules/core/Core.types.ts';
import { ButtonSelectInput } from '@/modules/core/components/inputs/ButtonSelectInput.tsx';
const VALUE_TO_DISPLAY_DATA: ValueToDisplayData<ProgressBarPosition> = {
[ProgressBarPosition.BOTTOM]: {
title: 'global.label.bottom',
icon: <ArrowBackIosNewIcon sx={{ transform: 'rotate(90deg)' }} />,
},
[ProgressBarPosition.LEFT]: {
title: 'global.label.left',
icon: <ArrowForwardIosIcon />,
},
[ProgressBarPosition.RIGHT]: {
title: 'global.label.right',
icon: <ArrowBackIosNewIcon />,
},
};
const PROGRESS_BAR_POSITION_VALUES = Object.values(ProgressBarPosition).filter((value) => typeof value === 'number');
export const ReaderSettingProgressBarPosition = ({
overlayMode,
progressBarPosition,
setProgressBarPosition,
}: Pick<IReaderSettings, 'progressBarPosition' | 'overlayMode'> & {
setProgressBarPosition: (position: ProgressBarPosition) => void;
}) => {
const { t } = useTranslation();
if (overlayMode !== ReaderOverlayMode.DESKTOP) {
return null;
}
return (
<ButtonSelectInput
label={t('reader.settings.progress_bar.position')}
value={progressBarPosition}
values={PROGRESS_BAR_POSITION_VALUES}
setValue={setProgressBarPosition}
valueToDisplayData={VALUE_TO_DISPLAY_DATA}
/>
);
};

View File

@@ -0,0 +1,50 @@
/*
* 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 { IReaderSettings, ProgressBarType, ReaderOverlayMode } from '@/modules/reader/types/Reader.types.ts';
import { SliderInput } from '@/modules/core/components/inputs/SliderInput.tsx';
import { DEFAULT_READER_SETTINGS } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
export const ReaderSettingProgressBarSize = ({
overlayMode,
progressBarType,
progressBarSize,
setProgressBarSize,
}: Pick<IReaderSettings, 'progressBarType' | 'progressBarSize' | 'overlayMode'> & {
setProgressBarSize: (size: number, commit: boolean) => void;
}) => {
const { t } = useTranslation();
const isChangeable = overlayMode === ReaderOverlayMode.DESKTOP && progressBarType === ProgressBarType.STANDARD;
if (!isChangeable) {
return null;
}
return (
<SliderInput
label={t('reader.settings.progress_bar.size')}
value={t('global.value', { value: progressBarSize, unit: t('global.unit.px') })}
slotProps={{
slider: {
defaultValue: DEFAULT_READER_SETTINGS.progressBarSize,
value: progressBarSize,
step: 1,
min: 2,
max: 20,
onChange: (_, value) => {
setProgressBarSize(value as number, false);
},
onChangeCommitted: (_, value) => {
setProgressBarSize(value as number, true);
},
},
}}
/>
);
};

View File

@@ -0,0 +1,51 @@
/*
* 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 { IReaderSettings, ProgressBarType, ReaderOverlayMode } from '@/modules/reader/types/Reader.types.ts';
import { ValueToDisplayData } from '@/modules/core/Core.types.ts';
import { HiddenProgressBarIcon } from '@/assets/icons/svg/HiddenProgressBarIcon.tsx';
import { StandardProgressBarIcon } from '@/assets/icons/svg/StandardProgressBarIcon.tsx';
import { ButtonSelectInput } from '@/modules/core/components/inputs/ButtonSelectInput.tsx';
const VALUE_TO_DISPLAY_DATA: ValueToDisplayData<ProgressBarType> = {
[ProgressBarType.HIDDEN]: {
title: 'global.label.hidden',
icon: <HiddenProgressBarIcon />,
},
[ProgressBarType.STANDARD]: {
title: 'global.label.standard',
icon: <StandardProgressBarIcon />,
},
};
const PROGRESS_BAR_TYPE_VALUES = Object.values(ProgressBarType).filter((value) => typeof value === 'number');
export const ReaderSettingProgressBarType = ({
overlayMode,
progressBarType,
setProgressBarType,
}: Pick<IReaderSettings, 'progressBarType' | 'overlayMode'> & {
setProgressBarType: (progressBarType: ProgressBarType) => void;
}) => {
const { t } = useTranslation();
if (overlayMode !== ReaderOverlayMode.DESKTOP) {
return null;
}
return (
<ButtonSelectInput
label={t('reader.settings.progress_bar.style')}
value={progressBarType}
values={PROGRESS_BAR_TYPE_VALUES}
setValue={setProgressBarType}
valueToDisplayData={VALUE_TO_DISPLAY_DATA}
/>
);
};