Make reader setting slider inputs resettable to default
This commit is contained in:
21
src/modules/core/components/buttons/ResetButton.tsx
Normal file
21
src/modules/core/components/buttons/ResetButton.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* 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 Button, { ButtonProps } from '@mui/material/Button';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import RestartAltIcon from '@mui/icons-material/RestartAlt';
|
||||||
|
|
||||||
|
export const ResetButton = (props: ButtonProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button startIcon={<RestartAltIcon />} {...props}>
|
||||||
|
{t('global.button.reset')}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -9,21 +9,24 @@
|
|||||||
import Slider, { SliderProps } from '@mui/material/Slider';
|
import Slider, { SliderProps } from '@mui/material/Slider';
|
||||||
import Typography, { TypographyProps } from '@mui/material/Typography';
|
import Typography, { TypographyProps } from '@mui/material/Typography';
|
||||||
import Stack from '@mui/material/Stack';
|
import Stack from '@mui/material/Stack';
|
||||||
|
import { ResetButton } from '@/modules/core/components/buttons/ResetButton.tsx';
|
||||||
|
|
||||||
export const SliderInput = ({
|
export const SliderInput = ({
|
||||||
label,
|
label,
|
||||||
value,
|
value,
|
||||||
|
onDefault,
|
||||||
slotProps,
|
slotProps,
|
||||||
}: {
|
}: {
|
||||||
label: string;
|
label: string;
|
||||||
value: number | string;
|
value: number | string;
|
||||||
|
onDefault?: () => void;
|
||||||
slotProps?: {
|
slotProps?: {
|
||||||
label?: TypographyProps;
|
label?: TypographyProps;
|
||||||
value?: TypographyProps;
|
value?: TypographyProps;
|
||||||
slider?: SliderProps;
|
slider?: SliderProps;
|
||||||
};
|
};
|
||||||
}) => (
|
}) => (
|
||||||
<Stack sx={{ flexDirection: 'row', gap: 1, alignItems: 'center' }}>
|
<Stack sx={{ flexDirection: 'row', gap: 2, alignItems: 'center' }}>
|
||||||
<Stack sx={{ flexBasis: '25%' }}>
|
<Stack sx={{ flexBasis: '25%' }}>
|
||||||
<Typography {...slotProps?.label} sx={{ ...slotProps?.label?.sx }}>
|
<Typography {...slotProps?.label} sx={{ ...slotProps?.label?.sx }}>
|
||||||
{label}
|
{label}
|
||||||
@@ -33,5 +36,6 @@ export const SliderInput = ({
|
|||||||
</Typography>
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Slider {...slotProps?.slider} sx={{ flexBasis: '75%', ...slotProps?.slider?.sx }} />
|
<Slider {...slotProps?.slider} sx={{ flexBasis: '75%', ...slotProps?.slider?.sx }} />
|
||||||
|
{onDefault && <ResetButton onClick={onDefault} variant="outlined" />}
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,11 +9,10 @@
|
|||||||
import Stack from '@mui/material/Stack';
|
import Stack from '@mui/material/Stack';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import Button from '@mui/material/Button';
|
|
||||||
import RestartAltIcon from '@mui/icons-material/RestartAlt';
|
|
||||||
import { ReaderSettingsTypeProps } from '@/modules/reader/types/Reader.types.ts';
|
import { ReaderSettingsTypeProps } from '@/modules/reader/types/Reader.types.ts';
|
||||||
import { ReaderSettingHotkey } from '@/modules/reader/components/settings/hotkeys/ReaderSettingHotkey.tsx';
|
import { ReaderSettingHotkey } from '@/modules/reader/components/settings/hotkeys/ReaderSettingHotkey.tsx';
|
||||||
import { DEFAULT_READER_SETTINGS, READER_HOTKEYS } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
|
import { DEFAULT_READER_SETTINGS, READER_HOTKEYS } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
|
||||||
|
import { ResetButton } from '@/modules/core/components/buttons/ResetButton.tsx';
|
||||||
|
|
||||||
export const ReaderHotkeysSettings = ({ settings, updateSetting }: ReaderSettingsTypeProps) => {
|
export const ReaderHotkeysSettings = ({ settings, updateSetting }: ReaderSettingsTypeProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -33,13 +32,7 @@ export const ReaderHotkeysSettings = ({ settings, updateSetting }: ReaderSetting
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<Stack sx={{ alignItems: 'end' }}>
|
<Stack sx={{ alignItems: 'end' }}>
|
||||||
<Button
|
<ResetButton onClick={() => updateSetting('hotkeys', DEFAULT_READER_SETTINGS.hotkeys)} />
|
||||||
variant="contained"
|
|
||||||
startIcon={<RestartAltIcon />}
|
|
||||||
onClick={() => updateSetting('hotkeys', DEFAULT_READER_SETTINGS.hotkeys)}
|
|
||||||
>
|
|
||||||
{t('global.button.reset')}
|
|
||||||
</Button>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ export const ReaderLayoutSettings = ({
|
|||||||
<ReaderSettingPageGap
|
<ReaderSettingPageGap
|
||||||
pageGap={settings.pageGap}
|
pageGap={settings.pageGap}
|
||||||
readingMode={settings.readingMode}
|
readingMode={settings.readingMode}
|
||||||
|
isDefaultable={isDefaultable}
|
||||||
|
onDefault={() => onDefault?.('pageGap')}
|
||||||
updateSetting={(...args) => updateSetting('pageGap', ...args)}
|
updateSetting={(...args) => updateSetting('pageGap', ...args)}
|
||||||
/>
|
/>
|
||||||
<ReaderSettingReadingDirection
|
<ReaderSettingReadingDirection
|
||||||
@@ -88,6 +90,8 @@ export const ReaderLayoutSettings = ({
|
|||||||
<ReaderSettingWidth
|
<ReaderSettingWidth
|
||||||
readerWidth={settings.readerWidth.value}
|
readerWidth={settings.readerWidth.value}
|
||||||
pageScaleMode={settings.pageScaleMode.value}
|
pageScaleMode={settings.pageScaleMode.value}
|
||||||
|
isDefaultable={isDefaultable}
|
||||||
|
onDefault={() => onDefault?.('readerWidth')}
|
||||||
updateSetting={(...args) => updateSetting(...args)}
|
updateSetting={(...args) => updateSetting(...args)}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -7,18 +7,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { IReaderSettingsWithDefaultFlag, ReadingMode } from '@/modules/reader/types/Reader.types.ts';
|
import { IReaderSettings, IReaderSettingsWithDefaultFlag, ReadingMode } from '@/modules/reader/types/Reader.types.ts';
|
||||||
import { SliderInput } from '@/modules/core/components/inputs/SliderInput.tsx';
|
import { SliderInput } from '@/modules/core/components/inputs/SliderInput.tsx';
|
||||||
import { DEFAULT_READER_SETTINGS } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
|
import { DEFAULT_READER_SETTINGS } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
|
||||||
import { isContinuousReadingMode } from '@/modules/reader/utils/ReaderSettings.utils.tsx';
|
import { isContinuousReadingMode } from '@/modules/reader/utils/ReaderSettings.utils.tsx';
|
||||||
|
import { MultiValueButtonDefaultableProps } from '@/modules/core/Core.types.ts';
|
||||||
|
|
||||||
export const ReaderSettingPageGap = ({
|
export const ReaderSettingPageGap = ({
|
||||||
pageGap,
|
pageGap,
|
||||||
readingMode,
|
readingMode,
|
||||||
|
onDefault,
|
||||||
updateSetting,
|
updateSetting,
|
||||||
}: Pick<IReaderSettingsWithDefaultFlag, 'pageGap' | 'readingMode'> & {
|
}: Pick<IReaderSettingsWithDefaultFlag, 'pageGap' | 'readingMode'> &
|
||||||
updateSetting: (gap: number, commit: boolean) => void;
|
Pick<MultiValueButtonDefaultableProps<IReaderSettings['pageGap']>, 'isDefaultable' | 'onDefault'> & {
|
||||||
}) => {
|
updateSetting: (gap: number, commit: boolean) => void;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const isChangeable = readingMode.value !== ReadingMode.WEBTOON && isContinuousReadingMode(readingMode.value);
|
const isChangeable = readingMode.value !== ReadingMode.WEBTOON && isContinuousReadingMode(readingMode.value);
|
||||||
@@ -30,6 +33,7 @@ export const ReaderSettingPageGap = ({
|
|||||||
<SliderInput
|
<SliderInput
|
||||||
label={t('reader.settings.label.page_gap')}
|
label={t('reader.settings.label.page_gap')}
|
||||||
value={t('global.value', { value: pageGap.value, unit: t('global.unit.px') })}
|
value={t('global.value', { value: pageGap.value, unit: t('global.unit.px') })}
|
||||||
|
onDefault={onDefault}
|
||||||
slotProps={{
|
slotProps={{
|
||||||
slider: {
|
slider: {
|
||||||
defaultValue: DEFAULT_READER_SETTINGS.readerWidth.value,
|
defaultValue: DEFAULT_READER_SETTINGS.readerWidth.value,
|
||||||
|
|||||||
@@ -14,14 +14,18 @@ import { ReaderService } from '@/modules/reader/services/ReaderService.ts';
|
|||||||
import { SliderInput } from '@/modules/core/components/inputs/SliderInput.tsx';
|
import { SliderInput } from '@/modules/core/components/inputs/SliderInput.tsx';
|
||||||
import { DEFAULT_READER_SETTINGS } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
|
import { DEFAULT_READER_SETTINGS } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
|
||||||
import { isReaderWidthEditable } from '@/modules/reader/utils/ReaderSettings.utils.tsx';
|
import { isReaderWidthEditable } from '@/modules/reader/utils/ReaderSettings.utils.tsx';
|
||||||
|
import { MultiValueButtonDefaultableProps } from '@/modules/core/Core.types.ts';
|
||||||
|
import { ResetButton } from '@/modules/core/components/buttons/ResetButton.tsx';
|
||||||
|
|
||||||
export const ReaderSettingWidth = ({
|
export const ReaderSettingWidth = ({
|
||||||
readerWidth,
|
readerWidth,
|
||||||
pageScaleMode,
|
pageScaleMode,
|
||||||
|
onDefault,
|
||||||
updateSetting,
|
updateSetting,
|
||||||
}: Pick<IReaderSettings, 'readerWidth' | 'pageScaleMode'> & {
|
}: Pick<IReaderSettings, 'readerWidth' | 'pageScaleMode'> &
|
||||||
updateSetting: (...args: OmitFirst<Parameters<typeof ReaderService.updateSetting>>) => void;
|
Pick<MultiValueButtonDefaultableProps<IReaderSettings['readerWidth']['value']>, 'isDefaultable' | 'onDefault'> & {
|
||||||
}) => {
|
updateSetting: (...args: OmitFirst<Parameters<typeof ReaderService.updateSetting>>) => void;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
if (!isReaderWidthEditable(pageScaleMode)) {
|
if (!isReaderWidthEditable(pageScaleMode)) {
|
||||||
@@ -30,11 +34,14 @@ export const ReaderSettingWidth = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<CheckboxInput
|
<Stack sx={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
||||||
label={t('reader.settings.label.limit_reader_width')}
|
<CheckboxInput
|
||||||
checked={readerWidth.enabled}
|
label={t('reader.settings.label.limit_reader_width')}
|
||||||
onChange={(_, checked) => updateSetting('readerWidth', { ...readerWidth, enabled: checked }, true)}
|
checked={readerWidth.enabled}
|
||||||
/>
|
onChange={(_, checked) => updateSetting('readerWidth', { ...readerWidth, enabled: checked }, true)}
|
||||||
|
/>
|
||||||
|
{onDefault && <ResetButton onClick={onDefault} variant="outlined" />}
|
||||||
|
</Stack>
|
||||||
{readerWidth.enabled && (
|
{readerWidth.enabled && (
|
||||||
<SliderInput
|
<SliderInput
|
||||||
label={t('reader.settings.label.reader_width')}
|
label={t('reader.settings.label.reader_width')}
|
||||||
|
|||||||
Reference in New Issue
Block a user