mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-04-17 19:08:11 -05:00
95 lines
2.1 KiB
TypeScript
95 lines
2.1 KiB
TypeScript
import { NextRouter, useRouter } from "next/router";
|
|
import type { URLSearchParams as URLSearchParamsType } from "url";
|
|
import * as z from "zod";
|
|
|
|
type SearchParamsType =
|
|
| string
|
|
| string[]
|
|
| number
|
|
| number[]
|
|
| boolean
|
|
| boolean[]
|
|
| null
|
|
| undefined;
|
|
|
|
type SearchParamsTuple = [key: string, value: SearchParamsType];
|
|
|
|
export const adjustedSearchParams = (
|
|
url: string,
|
|
newParams: SearchParamsTuple[],
|
|
clearOthers: boolean
|
|
): URLSearchParams => {
|
|
const result = clearOthers
|
|
? new URLSearchParams()
|
|
: new URL(url).searchParams;
|
|
|
|
for (const [key, value] of newParams) {
|
|
result.delete(key);
|
|
|
|
if (!value && typeof value !== "boolean") {
|
|
continue;
|
|
}
|
|
|
|
if (Array.isArray(value)) {
|
|
for (const element of value) {
|
|
result.append(key, String(element));
|
|
}
|
|
continue;
|
|
}
|
|
|
|
result.set(key, String(value));
|
|
}
|
|
|
|
result.sort();
|
|
|
|
return result;
|
|
};
|
|
|
|
const isSearchParamsTuple = (
|
|
newParams: SearchParamsTuple | SearchParamsTuple[]
|
|
): newParams is SearchParamsTuple => {
|
|
return !Array.isArray(newParams[0]);
|
|
};
|
|
|
|
const setRouterSearchParams = (
|
|
router: NextRouter,
|
|
newParams: SearchParamsTuple | SearchParamsTuple[],
|
|
clearOthers: boolean
|
|
) => {
|
|
const newSearchParams = adjustedSearchParams(
|
|
window.location.href,
|
|
isSearchParamsTuple(newParams) ? [newParams] : newParams,
|
|
clearOthers
|
|
);
|
|
|
|
router.replace(
|
|
`${router.pathname}?${newSearchParams.toString()}`,
|
|
undefined,
|
|
{
|
|
shallow: true,
|
|
}
|
|
);
|
|
};
|
|
|
|
const resetSearchParams = (router: NextRouter) =>
|
|
router.replace(router.pathname, undefined, { shallow: true });
|
|
|
|
export const useMyRouter = (): NextRouter & {
|
|
resetSearchParams: () => void;
|
|
setSearchParams: (
|
|
newParams: SearchParamsTuple | SearchParamsTuple[],
|
|
clearOthers?: boolean
|
|
) => void;
|
|
} => {
|
|
const router = useRouter();
|
|
|
|
return {
|
|
...router,
|
|
resetSearchParams: () => resetSearchParams(router),
|
|
setSearchParams: (
|
|
newParams: SearchParamsTuple | SearchParamsTuple[],
|
|
clearOthers?: boolean
|
|
) => setRouterSearchParams(router, newParams, clearOthers ?? false),
|
|
};
|
|
};
|