From 78e2a9984790090c14d677371eec2cbda216a08b Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Tue, 2 Jun 2026 15:00:39 +0200 Subject: [PATCH] Simplify changing reader desktop quick settings --- CHANGELOG.md | 2 +- src/base/components/buttons/SelectButton.tsx | 173 +++++++++++++++++- src/base/components/texts/Superscript.tsx | 3 +- .../ReaderNavBarDesktopPageScale.tsx | 5 +- .../ReaderNavBarDesktopReadingDirection.tsx | 5 +- .../ReaderNavBarDesktopReadingMode.tsx | 5 +- src/i18n/locales/en.po | 4 + 7 files changed, 179 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59e10ce4..cf6979fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - (**Migration**) Change migration match exclude/include icons - (**Migration**) Show the exclude/include button only for an entry with a selected match - (**Source/Extension**) Rename language "All" to "Multi" -- +- (**Reader**) Simplify changing settings in desktop sidebar ### Fixed diff --git a/src/base/components/buttons/SelectButton.tsx b/src/base/components/buttons/SelectButton.tsx index 691ca660..884bcbb4 100644 --- a/src/base/components/buttons/SelectButton.tsx +++ b/src/base/components/buttons/SelectButton.tsx @@ -6,12 +6,20 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import type { StackProps } from '@mui/material/Stack'; import Stack from '@mui/material/Stack'; +import type { ButtonProps } from '@mui/material/Button'; import Button from '@mui/material/Button'; import { useLingui } from '@lingui/react/macro'; import { CustomTooltip } from '@/base/components/CustomTooltip.tsx'; import { Superscript } from '@/base/components/texts/Superscript.tsx'; import type { ValueToDisplayData } from '@/base/Base.types.ts'; +import type { ReactNode, RefObject } from 'react'; +import { useCallback, useState } from 'react'; +import ClickAwayListener from '@mui/material/ClickAwayListener'; +import { assertIsDefined } from '@/base/Asserts.ts'; +import RestartAltIcon from '@mui/icons-material/RestartAlt'; +import { useElementSize } from '@mantine/hooks'; export interface SelectButtonBaseProps { value: MultiValue; @@ -19,6 +27,9 @@ export interface SelectButtonBaseProps void; valueToDisplayData: ValueToDisplayData; + isCollapsible?: MultiValue extends Value[] ? never : boolean; + tooltip?: MultiValue extends Value[] ? never : ReactNode; + defaultIcon?: MultiValue extends Value[] ? never : ReactNode; } export interface SelectButtonDefaultableProps< @@ -33,7 +44,8 @@ export type SelectButtonProps & PropertiesNever>) | SelectButtonDefaultableProps; -export const SelectButton = ({ +const SelectButtonBase = ({ + ref, value, values, defaultValue, @@ -41,15 +53,37 @@ export const SelectButton = ) => { + slotProps, +}: SelectButtonProps & { + ref?: RefObject; + slotProps?: { + stack?: StackProps; + defaultButton?: ButtonProps & { hideText?: boolean }; + button?: ButtonProps & { hideText?: boolean; tooltip?: (isDefault: boolean, title: string) => ReactNode }; + }; +}) => { const { t } = useLingui(); return ( - + {isDefaultable && ( - + + + )} {values.map((displayValue) => { const isDefault = value === undefined && displayValue === defaultValue; @@ -74,13 +108,27 @@ export const SelectButton = + ); @@ -88,3 +136,108 @@ export const SelectButton = ); }; + +const SelectButtonCollapsible = ( + props: SelectButtonProps, +) => { + const { tooltip, value, valueToDisplayData, defaultValue, onDefault, setValue, defaultIcon } = props; + + const { t } = useLingui(); + const { ref, height } = useElementSize(); + + const [isExpanded, setIsExpanded] = useState(false); + + const finalOnDefault = useCallback(() => { + setIsExpanded(false); + onDefault?.(); + }, [onDefault]); + + const finalSetValue = useCallback( + (...args: Parameters) => { + setIsExpanded(false); + setValue(...args); + }, + [setValue], + ); + + if (!isExpanded) { + return ( + + + + ); + } + + return ( + setIsExpanded(false)}> + , + size: 'large', + sx: { + flexGrow: 1, + height, + minWidth: 'unset', + px: '10px', + }, + }, + button: { + hideText: true, + tooltip: (isDefault, title) => (isDefault ? t`Active setting (${title})` : title), + size: 'large', + sx: { + flexGrow: 1, + height, + minWidth: 'unset', + px: '10px', + }, + }, + }} + /> + + ); +}; + +export const SelectButton = ( + props: SelectButtonProps, +) => { + const { isCollapsible } = props; + + if (isCollapsible) { + return ; + } + + return ; +}; diff --git a/src/base/components/texts/Superscript.tsx b/src/base/components/texts/Superscript.tsx index c5b8baaf..066a9cf2 100644 --- a/src/base/components/texts/Superscript.tsx +++ b/src/base/components/texts/Superscript.tsx @@ -8,10 +8,11 @@ import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; +import type { ReactNode } from 'react'; interface SuperscriptProps { superscript: string; - text: string; + text: ReactNode; } /** diff --git a/src/features/reader/overlay/navigation/desktop/quick-settings/components/ReaderNavBarDesktopPageScale.tsx b/src/features/reader/overlay/navigation/desktop/quick-settings/components/ReaderNavBarDesktopPageScale.tsx index ec1d224d..15e93f97 100644 --- a/src/features/reader/overlay/navigation/desktop/quick-settings/components/ReaderNavBarDesktopPageScale.tsx +++ b/src/features/reader/overlay/navigation/desktop/quick-settings/components/ReaderNavBarDesktopPageScale.tsx @@ -10,7 +10,6 @@ import Stack from '@mui/material/Stack'; import FitScreenIcon from '@mui/icons-material/FitScreen'; import { useLingui } from '@lingui/react/macro'; import { CustomTooltip } from '@/base/components/CustomTooltip.tsx'; -import { ValueRotationButton } from '@/base/components/buttons/ValueRotationButton.tsx'; import type { IReaderSettings, IReaderSettingsWithDefaultFlag, @@ -23,6 +22,7 @@ import { } from '@/features/reader/settings/ReaderSettings.constants.tsx'; import { CustomIconButton } from '@/base/components/buttons/CustomIconButton.tsx'; import type { SelectButtonDefaultableProps } from '@/base/components/buttons/SelectButton.tsx'; +import { SelectButton } from '@/base/components/buttons/SelectButton.tsx'; export const ReaderNavBarDesktopPageScale = ({ pageScaleMode, @@ -40,7 +40,7 @@ export const ReaderNavBarDesktopPageScale = ({ return ( - {...buttonSelectInputProps} tooltip={t`Scale type`} value={pageScaleMode.isDefault ? undefined : pageScaleMode.value} @@ -49,6 +49,7 @@ export const ReaderNavBarDesktopPageScale = ({ setValue={(value) => updateSetting('pageScaleMode', value)} valueToDisplayData={PAGE_SCALE_VALUE_TO_DISPLAY_DATA} defaultIcon={PAGE_SCALE_VALUE_TO_DISPLAY_DATA[pageScaleMode.value].icon} + isCollapsible /> {READER_PAGE_SCALE_MODE_TO_SCALING_ALLOWED[pageScaleMode.value] && ( diff --git a/src/features/reader/overlay/navigation/desktop/quick-settings/components/ReaderNavBarDesktopReadingDirection.tsx b/src/features/reader/overlay/navigation/desktop/quick-settings/components/ReaderNavBarDesktopReadingDirection.tsx index 2e19cb35..08682887 100644 --- a/src/features/reader/overlay/navigation/desktop/quick-settings/components/ReaderNavBarDesktopReadingDirection.tsx +++ b/src/features/reader/overlay/navigation/desktop/quick-settings/components/ReaderNavBarDesktopReadingDirection.tsx @@ -7,7 +7,6 @@ */ import { useLingui } from '@lingui/react/macro'; -import { ValueRotationButton } from '@/base/components/buttons/ValueRotationButton.tsx'; import type { IReaderSettingsWithDefaultFlag, ReadingDirection } from '@/features/reader/Reader.types.ts'; import { READING_DIRECTION_VALUES, @@ -15,6 +14,7 @@ import { } from '@/features/reader/settings/ReaderSettings.constants.tsx'; import type { SelectButtonDefaultableProps } from '@/base/components/buttons/SelectButton.tsx'; +import { SelectButton } from '@/base/components/buttons/SelectButton.tsx'; export const ReaderNavBarDesktopReadingDirection = ({ readingDirection, @@ -27,7 +27,7 @@ export const ReaderNavBarDesktopReadingDirection = ({ const { t } = useLingui(); return ( - ); }; diff --git a/src/features/reader/overlay/navigation/desktop/quick-settings/components/ReaderNavBarDesktopReadingMode.tsx b/src/features/reader/overlay/navigation/desktop/quick-settings/components/ReaderNavBarDesktopReadingMode.tsx index 486fee0a..fc14ac5d 100644 --- a/src/features/reader/overlay/navigation/desktop/quick-settings/components/ReaderNavBarDesktopReadingMode.tsx +++ b/src/features/reader/overlay/navigation/desktop/quick-settings/components/ReaderNavBarDesktopReadingMode.tsx @@ -7,7 +7,6 @@ */ import { useLingui } from '@lingui/react/macro'; -import { ValueRotationButton } from '@/base/components/buttons/ValueRotationButton.tsx'; import type { IReaderSettingsWithDefaultFlag, ReadingMode } from '@/features/reader/Reader.types.ts'; import { READING_MODE_VALUE_TO_DISPLAY_DATA, @@ -15,6 +14,7 @@ import { } from '@/features/reader/settings/ReaderSettings.constants.tsx'; import type { SelectButtonDefaultableProps } from '@/base/components/buttons/SelectButton.tsx'; +import { SelectButton } from '@/base/components/buttons/SelectButton.tsx'; export const ReaderNavBarDesktopReadingMode = ({ readingMode, @@ -27,7 +27,7 @@ export const ReaderNavBarDesktopReadingMode = ({ const { t } = useLingui(); return ( - ); }; diff --git a/src/i18n/locales/en.po b/src/i18n/locales/en.po index 7795a719..b58ac21b 100644 --- a/src/i18n/locales/en.po +++ b/src/i18n/locales/en.po @@ -358,6 +358,10 @@ msgstr "Active device" msgid "Active setting" msgstr "Active setting" +#: src/base/components/buttons/SelectButton.tsx +msgid "Active setting ({title})" +msgstr "Active setting ({title})" + #: src/base/components/settings/MutableListSetting.tsx #: src/features/manga/hooks/useManageMangaLibraryState.tsx #: src/features/reader/hotkeys/settings/components/ReaderSettingHotkey.tsx