From ff9f6b62073631ea574eea1db3d920d04ff31344 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Mon, 30 Sep 2024 02:27:10 +0200 Subject: [PATCH] Add hook to get value based on themes "direction" In case the component didn't rerender on a language change, the used value was never updated based on the new "direction" --- src/components/context/AppContext.tsx | 2 +- src/components/menu/NestedMenuItem.tsx | 2 +- src/components/navbar/DefaultNavBar.tsx | 3 ++- src/components/navbar/ReaderNavBar.tsx | 3 ++- src/components/navbar/navigation/DesktopSideBar.tsx | 3 ++- src/components/reader/DoublePage.tsx | 2 +- src/components/tracker/TrackerSearch.tsx | 3 ++- src/lib/ui/AwaitableDialog.tsx | 2 +- src/lib/ui/MediaQuery.tsx | 2 +- .../settings/appearance/theme/ThemePreview.tsx | 2 +- src/{theme.ts => theme.tsx} | 13 ++++++++++++- 11 files changed, 26 insertions(+), 11 deletions(-) rename src/{theme.ts => theme.tsx} (93%) diff --git a/src/components/context/AppContext.tsx b/src/components/context/AppContext.tsx index db2adacb..c0748731 100644 --- a/src/components/context/AppContext.tsx +++ b/src/components/context/AppContext.tsx @@ -17,7 +17,7 @@ import createCache from '@emotion/cache'; import { prefixer } from 'stylis'; import rtlPlugin from 'stylis-plugin-rtl'; import { SnackbarProvider } from 'notistack'; -import { createAndSetTheme } from '@/theme'; +import { createAndSetTheme } from '@/theme.tsx'; import { useLocalStorage } from '@/util/useStorage.tsx'; import { ThemeMode, ThemeModeContext } from '@/components/context/ThemeModeContext.tsx'; import { NavBarContextProvider } from '@/components/navbar/NavBarContextProvider'; diff --git a/src/components/menu/NestedMenuItem.tsx b/src/components/menu/NestedMenuItem.tsx index 5f9d9206..1811a59b 100644 --- a/src/components/menu/NestedMenuItem.tsx +++ b/src/components/menu/NestedMenuItem.tsx @@ -35,7 +35,7 @@ import Box from '@mui/material/Box'; import { OverridableComponent } from '@mui/material/OverridableComponent'; import { SvgIconTypeMap } from '@mui/material/SvgIcon'; import { IconMenuItem } from '@/components/menu/IconMenuItem.tsx'; -import { getOptionForDirection } from '@/theme.ts'; +import { getOptionForDirection } from '@/theme.tsx'; import { MediaQuery } from '@/lib/ui/MediaQuery.tsx'; export type NestedMenuItemProps = Omit & { diff --git a/src/components/navbar/DefaultNavBar.tsx b/src/components/navbar/DefaultNavBar.tsx index f7560378..a3d6eb86 100644 --- a/src/components/navbar/DefaultNavBar.tsx +++ b/src/components/navbar/DefaultNavBar.tsx @@ -29,7 +29,7 @@ import { useTheme } from '@mui/material/styles'; import { NavbarItem } from '@/typings'; import { NavBarContext } from '@/components/context/NavbarContext'; import { useBackButton } from '@/util/useBackButton.ts'; -import { getOptionForDirection } from '@/theme.ts'; +import { useGetOptionForDirection } from '@/theme.tsx'; import { MediaQuery } from '@/lib/ui/MediaQuery.tsx'; import { DesktopSideBar } from '@/components/navbar/navigation/DesktopSideBar.tsx'; import { useResizeObserver } from '@/util/useResizeObserver.tsx'; @@ -78,6 +78,7 @@ export function DefaultNavBar() { useContext(NavBarContext); const theme = useTheme(); + const getOptionForDirection = useGetOptionForDirection(); const { pathname } = useLocation(); const handleBack = useBackButton(); diff --git a/src/components/navbar/ReaderNavBar.tsx b/src/components/navbar/ReaderNavBar.tsx index 36f3fc59..9c1faa20 100644 --- a/src/components/navbar/ReaderNavBar.tsx +++ b/src/components/navbar/ReaderNavBar.tsx @@ -31,7 +31,7 @@ import { AllowedMetadataValueTypes, ChapterOffset, IReaderSettings } from '@/typ import { ReaderSettingsOptions } from '@/components/reader/ReaderSettingsOptions'; import { useBackButton } from '@/util/useBackButton.ts'; import { Select } from '@/components/atoms/Select.tsx'; -import { getOptionForDirection } from '@/theme.ts'; +import { useGetOptionForDirection } from '@/theme.tsx'; import { ChapterType } from '@/lib/graphql/generated/graphql.ts'; import { MangaChapterCountInfo, MangaIdInfo } from '@/lib/data/Mangas.ts'; import { useNavBarContext } from '@/components/context/NavbarContext.tsx'; @@ -107,6 +107,7 @@ export function ReaderNavBar(props: IProps) { const { t } = useTranslation(); const { setReaderNavBarWidth } = useNavBarContext(); const theme = useTheme(); + const getOptionForDirection = useGetOptionForDirection(); const navigate = useNavigate(); const location = useLocation<{ diff --git a/src/components/navbar/navigation/DesktopSideBar.tsx b/src/components/navbar/navigation/DesktopSideBar.tsx index 30fe25dc..6b8e1986 100644 --- a/src/components/navbar/navigation/DesktopSideBar.tsx +++ b/src/components/navbar/navigation/DesktopSideBar.tsx @@ -23,7 +23,7 @@ import ListItem from '@mui/material/ListItem'; import Tooltip from '@mui/material/Tooltip'; import { NavbarItem } from '@/typings.ts'; import { ListItemLink } from '@/components/util/ListItemLink.tsx'; -import { getOptionForDirection } from '@/theme.ts'; +import { useGetOptionForDirection } from '@/theme.tsx'; import { useNavBarContext } from '@/components/context/NavbarContext.tsx'; import { useResizeObserver } from '@/util/useResizeObserver.tsx'; @@ -96,6 +96,7 @@ const MAX_WIDTH_EXTENDED = 400; export const DesktopSideBar = ({ navBarItems }: { navBarItems: NavbarItem[] }) => { const { isCollapsed, setIsCollapsed, navBarWidth, setNavBarWidth } = useNavBarContext(); + const getOptionForDirection = useGetOptionForDirection(); const ref = useRef(null); useResizeObserver( diff --git a/src/components/reader/DoublePage.tsx b/src/components/reader/DoublePage.tsx index 361d7d2f..23e50aa3 100644 --- a/src/components/reader/DoublePage.tsx +++ b/src/components/reader/DoublePage.tsx @@ -11,7 +11,7 @@ import Box from '@mui/material/Box'; import { IReaderSettings } from '@/typings'; import { SpinnerImage } from '@/components/util/SpinnerImage'; import { imageStyle } from '@/components/reader/Page'; -import { getOptionForDirection } from '@/theme.ts'; +import { getOptionForDirection } from '@/theme.tsx'; interface IProps { index: number; diff --git a/src/components/tracker/TrackerSearch.tsx b/src/components/tracker/TrackerSearch.tsx index e966f98e..df5007df 100644 --- a/src/components/tracker/TrackerSearch.tsx +++ b/src/components/tracker/TrackerSearch.tsx @@ -29,7 +29,7 @@ import { SearchTextField } from '@/components/atoms/SearchTextField.tsx'; import { makeToast } from '@/components/util/Toast.tsx'; import { TrackerMangaCard } from '@/components/tracker/TrackerMangaCard.tsx'; import { DIALOG_PADDING } from '@/components/tracker/constants.ts'; -import { getOptionForDirection } from '@/theme.ts'; +import { useGetOptionForDirection } from '@/theme.tsx'; import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; import { MangaType } from '@/lib/graphql/generated/graphql.ts'; import { MangaIdInfo } from '@/lib/data/Mangas.ts'; @@ -46,6 +46,7 @@ export const TrackerSearch = ({ trackedId?: string; }) => { const { t } = useTranslation(); + const getOptionForDirection = useGetOptionForDirection(); const [searchString, setSearchString] = useState(manga.title); const [tmpSearchString, setTmpSearchString] = useState(searchString); diff --git a/src/lib/ui/AwaitableDialog.tsx b/src/lib/ui/AwaitableDialog.tsx index a86e43e2..62468204 100644 --- a/src/lib/ui/AwaitableDialog.tsx +++ b/src/lib/ui/AwaitableDialog.tsx @@ -10,7 +10,7 @@ import { createRoot } from 'react-dom/client'; import { ThemeProvider } from '@mui/material/styles'; import { ConfirmDialog } from '@/components/molecules/ConfirmDialog.tsx'; import { ControlledPromise } from '@/lib/ControlledPromise.ts'; -import { getCurrentTheme } from '@/theme.ts'; +import { getCurrentTheme } from '@/theme.tsx'; export const awaitConfirmation = async ( dialogProps: Omit, 'onCancel' | 'onConfirm'>, diff --git a/src/lib/ui/MediaQuery.tsx b/src/lib/ui/MediaQuery.tsx index 27878a5d..c1488beb 100644 --- a/src/lib/ui/MediaQuery.tsx +++ b/src/lib/ui/MediaQuery.tsx @@ -9,7 +9,7 @@ import useMediaQuery from '@mui/material/useMediaQuery'; import { Breakpoint } from '@mui/material/styles'; import { useCallback, useState } from 'react'; -import { getCurrentTheme } from '@/theme.ts'; +import { getCurrentTheme } from '@/theme.tsx'; import { ThemeMode } from '@/components/context/ThemeModeContext.tsx'; import { AppStorage } from '@/util/AppStorage.ts'; import { useResizeObserver } from '@/util/useResizeObserver.tsx'; diff --git a/src/screens/settings/appearance/theme/ThemePreview.tsx b/src/screens/settings/appearance/theme/ThemePreview.tsx index fff49e78..64c5625f 100644 --- a/src/screens/settings/appearance/theme/ThemePreview.tsx +++ b/src/screens/settings/appearance/theme/ThemePreview.tsx @@ -21,7 +21,7 @@ import EditIcon from '@mui/icons-material/Edit'; import { bindDialog, usePopupState } from 'material-ui-popup-state/hooks'; import { ThemeModeContext } from '@/components/context/ThemeModeContext.tsx'; import { AppTheme, hasMissingFonts, loadThemeFonts } from '@/lib/ui/AppThemes.ts'; -import { createTheme } from '@/theme.ts'; +import { createTheme } from '@/theme.tsx'; import { ThemeCreationDialog } from '@/screens/settings/appearance/theme/CreateThemeDialog.tsx'; import { makeToast } from '@/components/util/Toast'; import { TypographyMaxLines } from '@/components/atoms/TypographyMaxLines.tsx'; diff --git a/src/theme.ts b/src/theme.tsx similarity index 93% rename from src/theme.ts rename to src/theme.tsx index 4a1e5e4f..b4868a66 100644 --- a/src/theme.ts +++ b/src/theme.tsx @@ -14,7 +14,9 @@ import { Palette, responsiveFontSizes, Theme, + useTheme, } from '@mui/material/styles'; +import { useCallback } from 'react'; import { ThemeMode } from '@/components/context/ThemeModeContext.tsx'; import { MediaQuery } from '@/lib/ui/MediaQuery.tsx'; import { AppTheme, loadThemeFonts } from '@/lib/ui/AppThemes.ts'; @@ -146,5 +148,14 @@ export const createAndSetTheme = (...args: Parameters) => { return theme; }; -export const getOptionForDirection = (ltrOption: T, rtlOption: T): T => +export const getOptionForDirection = (ltrOption: T, rtlOption: T): T => (theme?.direction ?? 'ltr') === 'ltr' ? ltrOption : rtlOption; + +export const useGetOptionForDirection = (): typeof getOptionForDirection => { + const muiTheme = useTheme(); + + return useCallback( + (...args: Parameters>) => getOptionForDirection(...args), + [muiTheme.direction], + ); +};