79 lines
2.4 KiB
TypeScript
79 lines
2.4 KiB
TypeScript
import { useState } from 'react'
|
|
import {
|
|
usePersistentState,
|
|
PersistenceOptions,
|
|
} from 'web/hooks/use-persistent-state'
|
|
import { NextRouter, useRouter } from 'next/router'
|
|
|
|
export const SORTS = [
|
|
{ label: 'Newest', value: 'newest' },
|
|
{ label: 'Trending', value: 'score' },
|
|
{ label: 'Most traded', value: 'most-traded' },
|
|
{ label: '24h volume', value: '24-hour-vol' },
|
|
{ label: 'Last updated', value: 'last-updated' },
|
|
{ label: 'Subsidy', value: 'liquidity' },
|
|
{ label: 'Close date', value: 'close-date' },
|
|
{ label: 'Resolve date', value: 'resolve-date' },
|
|
] as const
|
|
|
|
export type Sort = typeof SORTS[number]['value']
|
|
|
|
type UpdatedQueryParams = { [k: string]: string }
|
|
type QuerySortOpts = { useUrl: boolean; persist?: PersistenceOptions }
|
|
|
|
function withURLParams(location: Location, params: UpdatedQueryParams) {
|
|
const newParams = new URLSearchParams(location.search)
|
|
for (const [k, v] of Object.entries(params)) {
|
|
if (!v) {
|
|
newParams.delete(k)
|
|
} else {
|
|
newParams.set(k, v)
|
|
}
|
|
}
|
|
const newUrl = new URL(location.href)
|
|
newUrl.search = newParams.toString()
|
|
return newUrl
|
|
}
|
|
|
|
function updateURL(params: UpdatedQueryParams) {
|
|
// see relevant discussion here https://github.com/vercel/next.js/discussions/18072
|
|
const url = withURLParams(window.location, params).toString()
|
|
const updatedState = { ...window.history.state, as: url, url }
|
|
window.history.replaceState(updatedState, '', url)
|
|
}
|
|
|
|
function getStringURLParam(router: NextRouter, k: string) {
|
|
const v = router.query[k]
|
|
return typeof v === 'string' ? v : null
|
|
}
|
|
|
|
export function useQuery(defaultQuery: string, opts?: QuerySortOpts) {
|
|
const useUrl = opts?.useUrl ?? false
|
|
const router = useRouter()
|
|
const initialQuery = useUrl ? getStringURLParam(router, 'q') : null
|
|
const [query, setQuery] = usePersistentState(
|
|
initialQuery ?? defaultQuery,
|
|
opts?.persist
|
|
)
|
|
if (!useUrl) {
|
|
return [query, setQuery] as const
|
|
} else {
|
|
return [query, (q: string) => (setQuery(q), updateURL({ q }))] as const
|
|
}
|
|
}
|
|
|
|
export function useSort(defaultSort: Sort, opts?: QuerySortOpts) {
|
|
const useUrl = opts?.useUrl ?? false
|
|
const router = useRouter()
|
|
const initialSort = useUrl ? (getStringURLParam(router, 's') as Sort) : null
|
|
const [sort, setSort] = usePersistentState(
|
|
initialSort ?? defaultSort,
|
|
opts?.persist
|
|
)
|
|
if (!useUrl) {
|
|
return [sort, setSort] as const
|
|
} else {
|
|
return [sort, (s: Sort) => (setSort(s), updateURL({ s }))] as const
|
|
}
|
|
}
|