Introduce "SearchParam" enum
This commit is contained in:
@@ -20,6 +20,7 @@ import { useResizeObserver } from '@/modules/core/hooks/useResizeObserver.tsx';
|
|||||||
import { useAppTitle } from '@/modules/navigation-bar/hooks/useAppTitle.ts';
|
import { useAppTitle } from '@/modules/navigation-bar/hooks/useAppTitle.ts';
|
||||||
import { BrowseTab } from '@/modules/browse/Browse.types.ts';
|
import { BrowseTab } from '@/modules/browse/Browse.types.ts';
|
||||||
import { GROUPED_VIRTUOSO_Z_INDEX } from '@/lib/virtuoso/Virtuoso.constants.ts';
|
import { GROUPED_VIRTUOSO_Z_INDEX } from '@/lib/virtuoso/Virtuoso.constants.ts';
|
||||||
|
import { SearchParam } from '@/modules/core/Core.types.ts';
|
||||||
|
|
||||||
export function Browse() {
|
export function Browse() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -32,7 +33,7 @@ export function Browse() {
|
|||||||
useCallback(() => setTabsMenuHeight(tabsMenuRef.current!.offsetHeight), [tabsMenuRef.current]),
|
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;
|
const tabName = (tabSearchParam as BrowseTab) ?? BrowseTab.SOURCES;
|
||||||
|
|
||||||
if (!tabSearchParam) {
|
if (!tabSearchParam) {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { MangaIdInfo } from '@/modules/manga/Manga.types.ts';
|
|||||||
|
|
||||||
import { ChapterSourceOrderInfo } from '@/modules/chapter/Chapter.types.ts';
|
import { ChapterSourceOrderInfo } from '@/modules/chapter/Chapter.types.ts';
|
||||||
import { BrowseTab } from '@/modules/browse/Browse.types.ts';
|
import { BrowseTab } from '@/modules/browse/Browse.types.ts';
|
||||||
|
import { SearchParam } from '@/modules/core/Core.types.ts';
|
||||||
|
|
||||||
type AppRouteInfo = {
|
type AppRouteInfo = {
|
||||||
match: string;
|
match: string;
|
||||||
@@ -21,7 +22,7 @@ type TAppRoutes = Record<string, AppRouteInfo & { childRoutes?: TAppRoutes }>;
|
|||||||
|
|
||||||
const createParam = (name: string, value: any): string => (value ? `${name}=${encodeURIComponent(value)}` : '');
|
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 addParams = (path: string, ...params: string[]) => {
|
||||||
const joinedParams = params.filter(Boolean).join('&');
|
const joinedParams = params.filter(Boolean).join('&');
|
||||||
@@ -151,7 +152,7 @@ export const AppRoutes = {
|
|||||||
library: {
|
library: {
|
||||||
match: 'library',
|
match: 'library',
|
||||||
path: (tab?: string, search?: string) =>
|
path: (tab?: string, search?: string) =>
|
||||||
addParams('/library', createParam('tab', tab), createQueryParam(search)),
|
addParams('/library', createParam(SearchParam.TAB, tab), createQueryParam(search)),
|
||||||
},
|
},
|
||||||
updates: {
|
updates: {
|
||||||
match: 'updates',
|
match: 'updates',
|
||||||
@@ -167,7 +168,7 @@ export const AppRoutes = {
|
|||||||
},
|
},
|
||||||
browse: {
|
browse: {
|
||||||
match: 'browse',
|
match: 'browse',
|
||||||
path: (tab?: BrowseTab) => addParams('/browse', createParam('tab', tab)),
|
path: (tab?: BrowseTab) => addParams('/browse', createParam(SearchParam.TAB, tab)),
|
||||||
},
|
},
|
||||||
migrate: {
|
migrate: {
|
||||||
match: 'migrate/source/:sourceId',
|
match: 'migrate/source/:sourceId',
|
||||||
|
|||||||
@@ -60,3 +60,8 @@ export enum ScrollDirection {
|
|||||||
Y,
|
Y,
|
||||||
XY,
|
XY,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum SearchParam {
|
||||||
|
TAB = 'tab',
|
||||||
|
QUERY = 'query',
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { useTheme } from '@mui/material/styles';
|
|||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx';
|
import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx';
|
||||||
import { SearchTextField } from '@/modules/core/components/inputs/SearchTextField.tsx';
|
import { SearchTextField } from '@/modules/core/components/inputs/SearchTextField.tsx';
|
||||||
|
import { SearchParam } from '@/modules/core/Core.types.ts';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
isClosable?: boolean;
|
isClosable?: boolean;
|
||||||
@@ -30,7 +31,7 @@ export const AppbarSearch: React.FunctionComponent<IProps> = (props) => {
|
|||||||
const [prevLocationKey, setPrevLocationKey] = useState<string>();
|
const [prevLocationKey, setPrevLocationKey] = useState<string>();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
const [query, setQuery] = useQueryParam('query', StringParam);
|
const [query, setQuery] = useQueryParam(SearchParam.QUERY, StringParam);
|
||||||
const [isSearchOpen, setIsSearchOpen] = useState(!isClosable || !!query);
|
const [isSearchOpen, setIsSearchOpen] = useState(!isClosable || !!query);
|
||||||
const inputRef = React.useRef<HTMLInputElement>(undefined);
|
const inputRef = React.useRef<HTMLInputElement>(undefined);
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import {
|
|||||||
} from '@/modules/settings/services/ServerSettingsMetadata.ts';
|
} from '@/modules/settings/services/ServerSettingsMetadata.ts';
|
||||||
import { MetadataBrowseSettings } from '@/modules/browse/Browse.types.ts';
|
import { MetadataBrowseSettings } from '@/modules/browse/Browse.types.ts';
|
||||||
import { useAppAction } from '@/modules/navigation-bar/hooks/useAppAction.ts';
|
import { useAppAction } from '@/modules/navigation-bar/hooks/useAppAction.ts';
|
||||||
|
import { SearchParam } from '@/modules/core/Core.types.ts';
|
||||||
|
|
||||||
const LANGUAGE = 0;
|
const LANGUAGE = 0;
|
||||||
const EXTENSIONS = 1;
|
const EXTENSIONS = 1;
|
||||||
@@ -131,7 +132,7 @@ export function Extensions({ tabsMenuHeight }: { tabsMenuHeight: number }) {
|
|||||||
keyof Pick<MetadataBrowseSettings, 'extensionLanguages'>
|
keyof Pick<MetadataBrowseSettings, 'extensionLanguages'>
|
||||||
>((e) => makeToast(t('global.error.label.failed_to_save_changes'), 'error', getErrorMessage(e)));
|
>((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<string[]>([]);
|
const [updatingExtensionIds, setUpdatingExtensionIds] = useState<string[]>([]);
|
||||||
const [refetchExtensions, setRefetchExtensions] = useState({});
|
const [refetchExtensions, setRefetchExtensions] = useState({});
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx';
|
|||||||
import { MUIUtil } from '@/lib/mui/MUI.util.ts';
|
import { MUIUtil } from '@/lib/mui/MUI.util.ts';
|
||||||
import { MetadataBrowseSettings } from '@/modules/browse/Browse.types.ts';
|
import { MetadataBrowseSettings } from '@/modules/browse/Browse.types.ts';
|
||||||
import { SourceLanguageSelect } from '@/modules/source/components/SourceLanguageSelect.tsx';
|
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 SourceLoadingState = { isLoading: boolean; hasResults: boolean; emptySearch: boolean; error: any };
|
||||||
type SourceToLoadingStateMap = Map<string, SourceLoadingState>;
|
type SourceToLoadingStateMap = Map<string, SourceLoadingState>;
|
||||||
@@ -238,7 +239,7 @@ export const SearchAll: React.FC = () => {
|
|||||||
const shouldShowOnlyPinnedSources = state?.shouldShowOnlyPinnedSources ?? true;
|
const shouldShowOnlyPinnedSources = state?.shouldShowOnlyPinnedSources ?? true;
|
||||||
const isMigrateMode = pathname.startsWith('/migrate/source');
|
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 searchString = useDebounce(query, TRIGGER_SEARCH_THRESHOLD);
|
||||||
|
|
||||||
const { languages: shownLangs, setLanguages: setShownLangs } = Sources.useLanguages();
|
const { languages: shownLangs, setLanguages: setShownLangs } = Sources.useLanguages();
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import {
|
|||||||
MangaUnreadInfo,
|
MangaUnreadInfo,
|
||||||
} from '@/modules/manga/Manga.types.ts';
|
} from '@/modules/manga/Manga.types.ts';
|
||||||
import { SourceDisplayNameInfo } from '@/modules/source/Source.types.ts';
|
import { SourceDisplayNameInfo } from '@/modules/source/Source.types.ts';
|
||||||
|
import { SearchParam } from '@/modules/core/Core.types.ts';
|
||||||
|
|
||||||
const triStateFilter = (
|
const triStateFilter = (
|
||||||
triState: NullAndUndefined<boolean>,
|
triState: NullAndUndefined<boolean>,
|
||||||
@@ -220,7 +221,7 @@ export const useGetVisibleLibraryMangas = <Manga extends MangaIdInfo & TMangasFi
|
|||||||
showFilteredOutMessage: boolean;
|
showFilteredOutMessage: boolean;
|
||||||
filterKey: string;
|
filterKey: string;
|
||||||
} => {
|
} => {
|
||||||
const [query] = useQueryParam('query', StringParam);
|
const [query] = useQueryParam(SearchParam.QUERY, StringParam);
|
||||||
const options = useGetCategoryMetadata(category ?? DEFAULT_CATEGORY);
|
const options = useGetCategoryMetadata(category ?? DEFAULT_CATEGORY);
|
||||||
const {
|
const {
|
||||||
hasUnreadChapters,
|
hasUnreadChapters,
|
||||||
|
|||||||
@@ -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 { useAppTitle } from '@/modules/navigation-bar/hooks/useAppTitle.ts';
|
||||||
import { useAppAction } from '@/modules/navigation-bar/hooks/useAppAction.ts';
|
import { useAppAction } from '@/modules/navigation-bar/hooks/useAppAction.ts';
|
||||||
import { AppRoutes } from '@/modules/core/AppRoute.constants.ts';
|
import { AppRoutes } from '@/modules/core/AppRoute.constants.ts';
|
||||||
|
import { SearchParam } from '@/modules/core/Core.types.ts';
|
||||||
|
|
||||||
const TitleWithSizeTag = styled('span')({
|
const TitleWithSizeTag = styled('span')({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -87,8 +88,8 @@ export function Library() {
|
|||||||
|
|
||||||
const librarySize = librarySizeResponse.data?.mangas.totalCount ?? 0;
|
const librarySize = librarySizeResponse.data?.mangas.totalCount ?? 0;
|
||||||
|
|
||||||
const [tabSearchParam, setTabSearchParam] = useQueryParam('tab', NumberParam);
|
const [tabSearchParam, setTabSearchParam] = useQueryParam(SearchParam.TAB, NumberParam);
|
||||||
const [query] = useQueryParam('query', StringParam);
|
const [query] = useQueryParam(SearchParam.QUERY, StringParam);
|
||||||
|
|
||||||
const activeTab: (typeof tabs)[number] | undefined = tabs.find((tab) => tab.id === tabSearchParam) ?? tabs[0];
|
const activeTab: (typeof tabs)[number] | undefined = tabs.find((tab) => tab.id === tabSearchParam) ?? tabs[0];
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'
|
|||||||
import { EmptyView } from '@/modules/core/components/feedback/EmptyView.tsx';
|
import { EmptyView } from '@/modules/core/components/feedback/EmptyView.tsx';
|
||||||
import { EmptyViewAbsoluteCentered } from '@/modules/core/components/feedback/EmptyViewAbsoluteCentered.tsx';
|
import { EmptyViewAbsoluteCentered } from '@/modules/core/components/feedback/EmptyViewAbsoluteCentered.tsx';
|
||||||
import { MangaIdInfo } from '@/modules/manga/Manga.types.ts';
|
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 { AppRoutes } from '@/modules/core/AppRoute.constants.ts';
|
||||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||||
import { Sources } from '@/modules/source/services/Sources.ts';
|
import { Sources } from '@/modules/source/services/Sources.ts';
|
||||||
@@ -227,7 +227,7 @@ export function SourceMangas() {
|
|||||||
} = useMetadataServerSettings();
|
} = useMetadataServerSettings();
|
||||||
|
|
||||||
const [sourceGridLayout] = useLocalStorage('source-grid-layout', GridLayout.Compact);
|
const [sourceGridLayout] = useLocalStorage('source-grid-layout', GridLayout.Compact);
|
||||||
const [query] = useQueryParam('query', StringParam);
|
const [query] = useQueryParam(SearchParam.QUERY, StringParam);
|
||||||
const [currentFiltersToApply, setCurrentFiltersToApply] = useSessionStorage<IPos[] | undefined>(
|
const [currentFiltersToApply, setCurrentFiltersToApply] = useSessionStorage<IPos[] | undefined>(
|
||||||
`source-mangas-${sourceId}-filters`,
|
`source-mangas-${sourceId}-filters`,
|
||||||
[],
|
[],
|
||||||
@@ -314,7 +314,7 @@ export function SourceMangas() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (savedSearchQuery) {
|
if (savedSearchQuery) {
|
||||||
searchParams.set('query', savedSearchQuery);
|
searchParams.set(SearchParam.QUERY, savedSearchQuery);
|
||||||
setSearchParams(searchParams);
|
setSearchParams(searchParams);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user