First commit
This commit is contained in:
57
frontend/app/utils/routes.ts
Normal file
57
frontend/app/utils/routes.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
/* Route-shape helpers for the reader experience.
|
||||
|
||||
An article route is a page of the open book drawn by ArticleBookStack —
|
||||
pages laid out side by side, older ones parked with their spines showing —
|
||||
while the article edit page and the new-article page remain plain,
|
||||
full-height pages. An article lives at /wiki/<slug>; one of its language
|
||||
versions at /wiki/<lang>/<slug>, e.g. /wiki/fr/bayes-theorem. */
|
||||
|
||||
const READER_PATH = /^\/wiki\/([^/]+?)\/?$/
|
||||
const VERSION_READER_PATH = /^\/wiki\/([a-z]{2})\/([^/]+?)\/?$/
|
||||
const WIKI_SUB_PATH = /^\/wiki\/[^/]+\/[^/]+/
|
||||
|
||||
/** What a reader address names: the article's identity, and which language
|
||||
* version the address asks for (null for the article's own version). */
|
||||
export interface ReaderLocation {
|
||||
identity: string
|
||||
lang: string | null
|
||||
}
|
||||
|
||||
export function parseReaderPath(path: string): ReaderLocation | null {
|
||||
const version = VERSION_READER_PATH.exec(path)
|
||||
// /wiki/<x>/edit is the editor whatever <x> is — never a version address
|
||||
if (version && version[2]!.toLowerCase() !== 'edit') {
|
||||
return { identity: decodeURIComponent(version[2]!), lang: version[1]! }
|
||||
}
|
||||
const plain = READER_PATH.exec(path)
|
||||
if (plain) return { identity: decodeURIComponent(plain[1]!), lang: null }
|
||||
return null
|
||||
}
|
||||
|
||||
export function isReaderPath(path: string): boolean {
|
||||
return parseReaderPath(path) !== null
|
||||
}
|
||||
|
||||
export function wikiSlugFromPath(path: string): string | null {
|
||||
return parseReaderPath(path)?.identity ?? null
|
||||
}
|
||||
|
||||
/**
|
||||
* The address of one language version: the canonical document lives at the
|
||||
* article's own URL, translations at /wiki/<lang>/<identity>.
|
||||
*/
|
||||
export function versionHref(identity: string, version: { language?: string; slug: string }): string {
|
||||
if (version.slug === identity) return `/wiki/${encodeURIComponent(identity)}`
|
||||
return `/wiki/${encodeURIComponent(version.language ?? 'en')}/${encodeURIComponent(identity)}`
|
||||
}
|
||||
|
||||
/**
|
||||
* The "reading surface": the reader itself plus the edit/new-article pages —
|
||||
* the pages that belong to the open book. The stack of open pages survives the
|
||||
* whole session either way; this marks the pages outside it (the list, the
|
||||
* graph, home), which are the places worth returning to once the last page is
|
||||
* closed.
|
||||
*/
|
||||
export function isReadingSurface(path: string): boolean {
|
||||
return isReaderPath(path) || WIKI_SUB_PATH.test(path) || path === '/new'
|
||||
}
|
||||
Reference in New Issue
Block a user