webapp/src/stores/router.ts

77 lines
1.7 KiB
TypeScript
Raw Normal View History

2022-09-09 13:30:25 +00:00
import { createRouter, createSearchParams } from '@nanostores/router'
import { onMount } from 'nanostores'
import { createEffect, createMemo, createSignal } from 'solid-js'
2022-09-09 11:53:35 +00:00
import { isServer } from 'solid-js/web'
// Types for :params in route templates
interface Routes {
home: void // TODO: more
topics: void
authors: void
feed: void
post: 'slug'
article: 'slug'
expo: 'slug'
create: 'collab'
search: 'q'
inbox: 'chat'
author: 'slug'
topic: 'slug'
}
2022-09-09 13:30:25 +00:00
export const params = createSearchParams()
2022-09-09 11:53:35 +00:00
export const router = createRouter<Routes>(
{
home: '/',
topics: '/topics',
authors: '/authors',
feed: '/feed',
create: '/create/:collab?',
inbox: '/inbox/:chat?',
search: '/search/:q?',
post: '/:slug',
article: '/articles/:slug',
expo: '/expo/:layout/:topic/:slug',
author: '/author/:slug',
topic: '/topic/:slug'
},
{
// enabling search query params passing
search: true,
links: false
}
)
2022-09-09 13:30:25 +00:00
const [resource, setResource] = createSignal<string>('')
const slug = createMemo<string>(() => {
const s = resource().split('/').pop()
return (Boolean(s) && router.routes.filter((x) => x[0] === s).length === 0 && s) || ''
})
2022-09-09 11:53:35 +00:00
const _route = (ev) => {
const href: string = ev.target.href
console.log('[router] faster link', href)
ev.stopPropoganation()
ev.preventDefault()
router.open(href)
}
const route = (ev) => {
if (typeof ev === 'function') {
return _route
} else if (!isServer && ev?.target && ev.target.href) {
_route(ev)
}
}
if (!isServer) {
console.log('[router] client runtime')
createEffect(() => router.open(window.location.pathname), [window.location])
}
2022-09-09 13:30:25 +00:00
onMount(router, () => {
router.listen((r) => setResource(r.path))
})
export { slug, route, resource }