From 9a9dbab7df9c00fd7a9c66a86174f53e98c5e548 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Wed, 23 Jul 2025 01:52:41 +0200 Subject: [PATCH] Introduce "SearchParam" enum --- src/modules/browse/screens/Browse.tsx | 3 ++- src/modules/core/AppRoute.constants.ts | 7 ++++--- src/modules/core/Core.types.ts | 5 +++++ src/modules/core/components/AppbarSearch.tsx | 3 ++- src/modules/extension/screens/Extensions.tsx | 3 ++- src/modules/global-search/screens/SearchAll.tsx | 3 ++- src/modules/library/hooks/useGetVisibleLibraryMangas.ts | 3 ++- src/modules/library/screens/Library.tsx | 5 +++-- src/modules/source/screens/SourceMangas.tsx | 6 +++--- 9 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/modules/browse/screens/Browse.tsx b/src/modules/browse/screens/Browse.tsx index afa05176..ee077585 100644 --- a/src/modules/browse/screens/Browse.tsx +++ b/src/modules/browse/screens/Browse.tsx @@ -20,6 +20,7 @@ import { useResizeObserver } from '@/modules/core/hooks/useResizeObserver.tsx'; import { useAppTitle } from '@/modules/navigation-bar/hooks/useAppTitle.ts'; import { BrowseTab } from '@/modules/browse/Browse.types.ts'; import { GROUPED_VIRTUOSO_Z_INDEX } from '@/lib/virtuoso/Virtuoso.constants.ts'; +import { SearchParam } from '@/modules/core/Core.types.ts'; export function Browse() { const { t } = useTranslation(); @@ -32,7 +33,7 @@ export function Browse() { useCallback(() => setTabsMenuHeight(tabsMenuRef.current!.offsetHeight), [tabsMenuRef.current]), ); - const [tabSearchParam, setTabSearchParam] = useQueryParam('tab', StringParam, {}); + const [tabSearchParam, setTabSearchParam] = useQueryParam(SearchParam.TAB, StringParam, {}); const tabName = (tabSearchParam as BrowseTab) ?? BrowseTab.SOURCES; if (!tabSearchParam) { diff --git a/src/modules/core/AppRoute.constants.ts b/src/modules/core/AppRoute.constants.ts index 4bc1b5ca..1cbf25b5 100644 --- a/src/modules/core/AppRoute.constants.ts +++ b/src/modules/core/AppRoute.constants.ts @@ -11,6 +11,7 @@ import { MangaIdInfo } from '@/modules/manga/Manga.types.ts'; import { ChapterSourceOrderInfo } from '@/modules/chapter/Chapter.types.ts'; import { BrowseTab } from '@/modules/browse/Browse.types.ts'; +import { SearchParam } from '@/modules/core/Core.types.ts'; type AppRouteInfo = { match: string; @@ -21,7 +22,7 @@ type TAppRoutes = Record; const createParam = (name: string, value: any): string => (value ? `${name}=${encodeURIComponent(value)}` : ''); -const createQueryParam = (query: string | null | undefined): string => createParam('query', query); +const createQueryParam = (query: string | null | undefined): string => createParam(SearchParam.QUERY, query); const addParams = (path: string, ...params: string[]) => { const joinedParams = params.filter(Boolean).join('&'); @@ -151,7 +152,7 @@ export const AppRoutes = { library: { match: 'library', path: (tab?: string, search?: string) => - addParams('/library', createParam('tab', tab), createQueryParam(search)), + addParams('/library', createParam(SearchParam.TAB, tab), createQueryParam(search)), }, updates: { match: 'updates', @@ -167,7 +168,7 @@ export const AppRoutes = { }, browse: { match: 'browse', - path: (tab?: BrowseTab) => addParams('/browse', createParam('tab', tab)), + path: (tab?: BrowseTab) => addParams('/browse', createParam(SearchParam.TAB, tab)), }, migrate: { match: 'migrate/source/:sourceId', diff --git a/src/modules/core/Core.types.ts b/src/modules/core/Core.types.ts index fedbd2ca..3ac5eb4b 100644 --- a/src/modules/core/Core.types.ts +++ b/src/modules/core/Core.types.ts @@ -60,3 +60,8 @@ export enum ScrollDirection { Y, XY, } + +export enum SearchParam { + TAB = 'tab', + QUERY = 'query', +} diff --git a/src/modules/core/components/AppbarSearch.tsx b/src/modules/core/components/AppbarSearch.tsx index 4c8dcd8a..6e604504 100644 --- a/src/modules/core/components/AppbarSearch.tsx +++ b/src/modules/core/components/AppbarSearch.tsx @@ -16,6 +16,7 @@ import { useTheme } from '@mui/material/styles'; import { useHotkeys } from 'react-hotkeys-hook'; import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx'; import { SearchTextField } from '@/modules/core/components/inputs/SearchTextField.tsx'; +import { SearchParam } from '@/modules/core/Core.types.ts'; interface IProps { isClosable?: boolean; @@ -30,7 +31,7 @@ export const AppbarSearch: React.FunctionComponent = (props) => { const [prevLocationKey, setPrevLocationKey] = useState(); const location = useLocation(); - const [query, setQuery] = useQueryParam('query', StringParam); + const [query, setQuery] = useQueryParam(SearchParam.QUERY, StringParam); const [isSearchOpen, setIsSearchOpen] = useState(!isClosable || !!query); const inputRef = React.useRef(undefined); diff --git a/src/modules/extension/screens/Extensions.tsx b/src/modules/extension/screens/Extensions.tsx index 0b28b3a5..cbe988ef 100644 --- a/src/modules/extension/screens/Extensions.tsx +++ b/src/modules/extension/screens/Extensions.tsx @@ -51,6 +51,7 @@ import { } from '@/modules/settings/services/ServerSettingsMetadata.ts'; import { MetadataBrowseSettings } from '@/modules/browse/Browse.types.ts'; import { useAppAction } from '@/modules/navigation-bar/hooks/useAppAction.ts'; +import { SearchParam } from '@/modules/core/Core.types.ts'; const LANGUAGE = 0; const EXTENSIONS = 1; @@ -131,7 +132,7 @@ export function Extensions({ tabsMenuHeight }: { tabsMenuHeight: number }) { keyof Pick >((e) => makeToast(t('global.error.label.failed_to_save_changes'), 'error', getErrorMessage(e))); - const [query] = useQueryParam('query', StringParam); + const [query] = useQueryParam(SearchParam.QUERY, StringParam); const [updatingExtensionIds, setUpdatingExtensionIds] = useState([]); const [refetchExtensions, setRefetchExtensions] = useState({}); diff --git a/src/modules/global-search/screens/SearchAll.tsx b/src/modules/global-search/screens/SearchAll.tsx index b7c56dc8..9c857e72 100644 --- a/src/modules/global-search/screens/SearchAll.tsx +++ b/src/modules/global-search/screens/SearchAll.tsx @@ -53,6 +53,7 @@ import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx'; import { MUIUtil } from '@/lib/mui/MUI.util.ts'; import { MetadataBrowseSettings } from '@/modules/browse/Browse.types.ts'; import { SourceLanguageSelect } from '@/modules/source/components/SourceLanguageSelect.tsx'; +import { SearchParam } from '@/modules/core/Core.types.ts'; type SourceLoadingState = { isLoading: boolean; hasResults: boolean; emptySearch: boolean; error: any }; type SourceToLoadingStateMap = Map; @@ -238,7 +239,7 @@ export const SearchAll: React.FC = () => { const shouldShowOnlyPinnedSources = state?.shouldShowOnlyPinnedSources ?? true; const isMigrateMode = pathname.startsWith('/migrate/source'); - const [query] = useQueryParam('query', StringParam); + const [query] = useQueryParam(SearchParam.QUERY, StringParam); const searchString = useDebounce(query, TRIGGER_SEARCH_THRESHOLD); const { languages: shownLangs, setLanguages: setShownLangs } = Sources.useLanguages(); diff --git a/src/modules/library/hooks/useGetVisibleLibraryMangas.ts b/src/modules/library/hooks/useGetVisibleLibraryMangas.ts index ae73cdfb..2acb9724 100644 --- a/src/modules/library/hooks/useGetVisibleLibraryMangas.ts +++ b/src/modules/library/hooks/useGetVisibleLibraryMangas.ts @@ -23,6 +23,7 @@ import { MangaUnreadInfo, } from '@/modules/manga/Manga.types.ts'; import { SourceDisplayNameInfo } from '@/modules/source/Source.types.ts'; +import { SearchParam } from '@/modules/core/Core.types.ts'; const triStateFilter = ( triState: NullAndUndefined, @@ -220,7 +221,7 @@ export const useGetVisibleLibraryMangas = { - const [query] = useQueryParam('query', StringParam); + const [query] = useQueryParam(SearchParam.QUERY, StringParam); const options = useGetCategoryMetadata(category ?? DEFAULT_CATEGORY); const { hasUnreadChapters, diff --git a/src/modules/library/screens/Library.tsx b/src/modules/library/screens/Library.tsx index 18fbf30f..9d892a86 100644 --- a/src/modules/library/screens/Library.tsx +++ b/src/modules/library/screens/Library.tsx @@ -47,6 +47,7 @@ import { GET_LIBRARY_MANGA_COUNT } from '@/lib/graphql/queries/MangaQuery.ts'; import { useAppTitle } from '@/modules/navigation-bar/hooks/useAppTitle.ts'; import { useAppAction } from '@/modules/navigation-bar/hooks/useAppAction.ts'; import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; +import { SearchParam } from '@/modules/core/Core.types.ts'; const TitleWithSizeTag = styled('span')({ display: 'flex', @@ -87,8 +88,8 @@ export function Library() { const librarySize = librarySizeResponse.data?.mangas.totalCount ?? 0; - const [tabSearchParam, setTabSearchParam] = useQueryParam('tab', NumberParam); - const [query] = useQueryParam('query', StringParam); + const [tabSearchParam, setTabSearchParam] = useQueryParam(SearchParam.TAB, NumberParam); + const [query] = useQueryParam(SearchParam.QUERY, StringParam); const activeTab: (typeof tabs)[number] | undefined = tabs.find((tab) => tab.id === tabSearchParam) ?? tabs[0]; diff --git a/src/modules/source/screens/SourceMangas.tsx b/src/modules/source/screens/SourceMangas.tsx index 417626e8..3df83dee 100644 --- a/src/modules/source/screens/SourceMangas.tsx +++ b/src/modules/source/screens/SourceMangas.tsx @@ -50,7 +50,7 @@ import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts' import { EmptyView } from '@/modules/core/components/feedback/EmptyView.tsx'; import { EmptyViewAbsoluteCentered } from '@/modules/core/components/feedback/EmptyViewAbsoluteCentered.tsx'; import { MangaIdInfo } from '@/modules/manga/Manga.types.ts'; -import { GridLayout } from '@/modules/core/Core.types.ts'; +import { GridLayout, SearchParam } from '@/modules/core/Core.types.ts'; import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; import { getErrorMessage } from '@/lib/HelperFunctions.ts'; import { Sources } from '@/modules/source/services/Sources.ts'; @@ -227,7 +227,7 @@ export function SourceMangas() { } = useMetadataServerSettings(); const [sourceGridLayout] = useLocalStorage('source-grid-layout', GridLayout.Compact); - const [query] = useQueryParam('query', StringParam); + const [query] = useQueryParam(SearchParam.QUERY, StringParam); const [currentFiltersToApply, setCurrentFiltersToApply] = useSessionStorage( `source-mangas-${sourceId}-filters`, [], @@ -314,7 +314,7 @@ export function SourceMangas() { } if (savedSearchQuery) { - searchParams.set('query', savedSearchQuery); + searchParams.set(SearchParam.QUERY, savedSearchQuery); setSearchParams(searchParams); } },