refactored search bar url shenanigans

This commit is contained in:
mrjvs 2023-10-13 21:41:44 +02:00
parent 9f99049ba1
commit 7222abf567
5 changed files with 25 additions and 53 deletions

View File

@ -1,7 +1,6 @@
import c from "classnames";
import { useState } from "react";
import { MWQuery } from "@/backend/metadata/types/mw";
import { Flare } from "@/components/utils/Flare";
import { Icon, Icons } from "./Icon";
@ -9,22 +8,16 @@ import { TextInputControl } from "./text-inputs/TextInputControl";
export interface SearchBarProps {
placeholder?: string;
onChange: (value: MWQuery, force: boolean) => void;
onChange: (value: string, force: boolean) => void;
onUnFocus: () => void;
value: MWQuery;
value: string;
}
export function SearchBarInput(props: SearchBarProps) {
const [focused, setFocused] = useState(false);
function setSearch(value: string) {
props.onChange(
{
...props.value,
searchQuery: value,
},
false
);
props.onChange(value, false);
}
return (
@ -59,7 +52,7 @@ export function SearchBarInput(props: SearchBarProps) {
}}
onFocus={() => setFocused(true)}
onChange={(val) => setSearch(val)}
value={props.value.searchQuery}
value={props.value}
className="w-full flex-1 bg-transparent px-4 py-4 pl-12 text-search-text placeholder-search-placeholder focus:outline-none sm:py-4 sm:pr-2"
placeholder={props.placeholder}
/>

View File

@ -5,13 +5,12 @@ export function useQueryParams() {
const loc = useLocation();
const queryParams = useMemo(() => {
// Basic absolutely-not-fool-proof URL query param parser
const obj: Record<string, string> = Object.fromEntries(
new URLSearchParams(loc.search).entries()
);
return obj;
}, [loc]);
}, [loc.search]);
return queryParams;
}

View File

@ -1,54 +1,35 @@
import { useState } from "react";
import { useEffect, useState } from "react";
import { generatePath, useHistory, useParams } from "react-router-dom";
import { MWQuery } from "@/backend/metadata/types/mw";
import { useQueryParams } from "@/hooks/useQueryParams";
function getInitialValue(
query: Record<string, string>,
params: Record<string, string>
) {
let searchQuery = decodeURIComponent(params.query || "");
if (query.q) searchQuery = query.q;
return { searchQuery };
}
export function useSearchQuery(): [
MWQuery,
(inp: Partial<MWQuery>, force: boolean) => void,
string,
(inp: string, force?: boolean) => void,
() => void
] {
const history = useHistory();
const query = useQueryParams();
const params = useParams<{ query: string }>();
const [search, setSearch] = useState<MWQuery>(getInitialValue(query, params));
const [search, setSearch] = useState(params.query ?? "");
const updateParams = (inp: Partial<MWQuery>, force: boolean) => {
const copySearch = { ...search };
Object.assign(copySearch, inp);
setSearch(copySearch);
if (!force) return;
if (copySearch.searchQuery.length === 0) {
useEffect(() => {
setSearch(params.query ?? "");
}, [params.query]);
const updateParams = (inp: string, commitToUrl = false) => {
setSearch(inp);
if (!commitToUrl) return;
if (inp.length === 0) {
history.replace("/");
return;
}
history.replace(
generatePath("/browse/:query", {
query: copySearch.searchQuery,
query: inp,
})
);
};
const onUnFocus = () => {
if (search.searchQuery.length === 0) {
history.replace("/");
return;
}
history.replace(
generatePath("/browse/:query", {
query: search.searchQuery,
})
);
updateParams(search, true);
};
return [search, updateParams, onUnFocus];

View File

@ -2,7 +2,6 @@ import { useEffect, useState } from "react";
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { MWQuery } from "@/backend/metadata/types/mw";
import { WideContainer } from "@/components/layout/WideContainer";
import { useDebounce } from "@/hooks/useDebounce";
import { useSearchQuery } from "@/hooks/useSearchQuery";
@ -13,14 +12,14 @@ import { WatchingPart } from "@/pages/parts/home/WatchingPart";
import { SearchListPart } from "@/pages/parts/search/SearchListPart";
import { SearchLoadingPart } from "@/pages/parts/search/SearchLoadingPart";
function useSearch(search: MWQuery) {
function useSearch(search: string) {
const [searching, setSearching] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(false);
const debouncedSearch = useDebounce<MWQuery>(search, 500);
const debouncedSearch = useDebounce<string>(search, 500);
useEffect(() => {
setSearching(search.searchQuery !== "");
setLoading(search.searchQuery !== "");
setSearching(search !== "");
setLoading(search !== "");
}, [search]);
useEffect(() => {
setLoading(false);

View File

@ -44,7 +44,7 @@ function SearchSuffix(props: { failed?: boolean; results?: number }) {
);
}
export function SearchListPart({ searchQuery }: { searchQuery: MWQuery }) {
export function SearchListPart({ searchQuery }: { searchQuery: string }) {
const { t } = useTranslation();
const [results, setResults] = useState<MWMediaMeta[]>([]);
@ -59,7 +59,7 @@ export function SearchListPart({ searchQuery }: { searchQuery: MWQuery }) {
setResults(searchResults);
}
if (searchQuery.searchQuery !== "") runSearch(searchQuery);
if (searchQuery !== "") runSearch({ searchQuery });
}, [searchQuery, runSearchQuery]);
if (loading) return <SearchLoadingPart />;