2022-09-22 09:37:49 +00:00
|
|
|
import type { Accessor } from 'solid-js'
|
2022-09-09 13:30:25 +00:00
|
|
|
import { createRouter, createSearchParams } from '@nanostores/router'
|
2022-09-09 11:53:35 +00:00
|
|
|
import { isServer } from 'solid-js/web'
|
2022-09-22 09:37:49 +00:00
|
|
|
import { useStore } from '@nanostores/solid'
|
2022-09-09 11:53:35 +00:00
|
|
|
|
2022-09-22 09:37:49 +00:00
|
|
|
// TODO: more
|
|
|
|
export interface Routes {
|
|
|
|
home: void
|
2022-09-09 11:53:35 +00:00
|
|
|
topics: void
|
2022-09-22 09:37:49 +00:00
|
|
|
topic: 'slug'
|
2022-09-09 11:53:35 +00:00
|
|
|
authors: void
|
2022-09-22 09:37:49 +00:00
|
|
|
author: 'slug'
|
2022-09-09 11:53:35 +00:00
|
|
|
feed: void
|
|
|
|
article: 'slug'
|
|
|
|
search: 'q'
|
2022-09-23 18:27:05 +00:00
|
|
|
dogma: void
|
|
|
|
guide: void
|
|
|
|
help: void
|
|
|
|
manifest: void
|
|
|
|
partners: void
|
|
|
|
projects: void
|
|
|
|
termsOfUse: void
|
|
|
|
thanks: void
|
2022-09-09 11:53:35 +00:00
|
|
|
}
|
|
|
|
|
2022-09-22 09:37:49 +00:00
|
|
|
const searchParamsStore = createSearchParams()
|
|
|
|
const routerStore = createRouter<Routes>(
|
2022-09-09 11:53:35 +00:00
|
|
|
{
|
|
|
|
home: '/',
|
|
|
|
topics: '/topics',
|
2022-09-22 09:37:49 +00:00
|
|
|
topic: '/topic/:slug',
|
2022-09-09 11:53:35 +00:00
|
|
|
authors: '/authors',
|
2022-09-22 09:37:49 +00:00
|
|
|
author: '/author/:slug',
|
2022-09-09 11:53:35 +00:00
|
|
|
feed: '/feed',
|
|
|
|
search: '/search/:q?',
|
2022-09-23 18:27:05 +00:00
|
|
|
article: '/:slug',
|
|
|
|
dogma: '/about/dogma',
|
|
|
|
guide: '/about/guide',
|
|
|
|
help: '/about/help',
|
|
|
|
manifest: '/about/manifest',
|
|
|
|
partners: '/about/partners',
|
|
|
|
projects: '/about/projects',
|
|
|
|
termsOfUse: '/about/terms-of-use',
|
|
|
|
thanks: '/about/thanks'
|
2022-09-09 11:53:35 +00:00
|
|
|
},
|
|
|
|
{
|
2022-09-22 09:37:49 +00:00
|
|
|
search: false,
|
2022-09-09 11:53:35 +00:00
|
|
|
links: false
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2022-09-22 09:37:49 +00:00
|
|
|
export const router = routerStore
|
|
|
|
|
|
|
|
export const handleClientRouteLinkClick = (event) => {
|
|
|
|
const link = event.target.closest('a')
|
|
|
|
if (
|
|
|
|
link &&
|
|
|
|
event.button === 0 &&
|
|
|
|
link.target !== '_blank' &&
|
|
|
|
link.rel !== 'external' &&
|
|
|
|
!link.download &&
|
|
|
|
!event.metaKey &&
|
|
|
|
!event.ctrlKey &&
|
|
|
|
!event.shiftKey &&
|
|
|
|
!event.altKey
|
|
|
|
) {
|
|
|
|
const url = new URL(link.href)
|
|
|
|
if (url.origin === location.origin) {
|
|
|
|
event.preventDefault()
|
|
|
|
// TODO: search params
|
|
|
|
routerStore.open(url.pathname)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export const initRouter = (pathname: string, search: string) => {
|
|
|
|
routerStore.open(pathname)
|
|
|
|
const params = Object.fromEntries(new URLSearchParams(search))
|
|
|
|
searchParamsStore.open(params)
|
2022-09-09 11:53:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!isServer) {
|
2022-09-14 11:28:43 +00:00
|
|
|
const { pathname, search } = window.location
|
2022-09-22 09:37:49 +00:00
|
|
|
initRouter(pathname, search)
|
|
|
|
}
|
|
|
|
|
|
|
|
export const useRouter = <TSearchParams extends Record<string, string> = Record<string, string>>() => {
|
|
|
|
const getPage = useStore(routerStore)
|
|
|
|
const getSearchParams = useStore(searchParamsStore) as unknown as Accessor<TSearchParams>
|
|
|
|
|
|
|
|
const changeSearchParam = <TKey extends keyof TSearchParams>(key: TKey, value: TSearchParams[TKey]) => {
|
|
|
|
searchParamsStore.open({ ...searchParamsStore.get(), [key]: value })
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
getPage,
|
|
|
|
getSearchParams,
|
|
|
|
changeSearchParam
|
|
|
|
}
|
2022-09-09 11:53:35 +00:00
|
|
|
}
|