|
import { type ReadonlyURLSearchParams, usePathname, useRouter, useSearchParams } from 'next/navigation' |
|
import { useCallback, useEffect, useMemo, useState } from 'react' |
|
|
|
type AppsQuery = { |
|
tagIDs?: string[] |
|
keywords?: string |
|
} |
|
|
|
|
|
function parseParams(params: ReadonlyURLSearchParams): AppsQuery { |
|
const tagIDs = params.get('tagIDs')?.split(';') |
|
const keywords = params.get('keywords') || undefined |
|
return { tagIDs, keywords } |
|
} |
|
|
|
|
|
function updateSearchParams(query: AppsQuery, current: URLSearchParams) { |
|
const { tagIDs, keywords } = query || {} |
|
|
|
if (tagIDs && tagIDs.length > 0) |
|
current.set('tagIDs', tagIDs.join(';')) |
|
else |
|
current.delete('tagIDs') |
|
|
|
if (keywords) |
|
current.set('keywords', keywords) |
|
else |
|
current.delete('keywords') |
|
} |
|
|
|
function useAppsQueryState() { |
|
const searchParams = useSearchParams() |
|
const [query, setQuery] = useState<AppsQuery>(() => parseParams(searchParams)) |
|
|
|
const router = useRouter() |
|
const pathname = usePathname() |
|
const syncSearchParams = useCallback((params: URLSearchParams) => { |
|
const search = params.toString() |
|
const query = search ? `?${search}` : '' |
|
router.push(`${pathname}${query}`) |
|
}, [router, pathname]) |
|
|
|
|
|
useEffect(() => { |
|
const params = new URLSearchParams(searchParams) |
|
updateSearchParams(query, params) |
|
syncSearchParams(params) |
|
}, [query, searchParams, syncSearchParams]) |
|
|
|
return useMemo(() => ({ query, setQuery }), [query]) |
|
} |
|
|
|
export default useAppsQueryState |
|
|