More things
This commit is contained in:
@@ -1,15 +1,27 @@
|
||||
/* Before a reader route draws anything — /wiki/<slug> for an article,
|
||||
/wiki/<lang>/<slug> for one of its language versions — put the document it
|
||||
names on the library's shelf. On the server that is what lets the page in
|
||||
view be written out in the first HTML; on the client it is what the stack of
|
||||
open pages grows from, and the title the page is filed under. A page that is
|
||||
already on the shelf comes straight off it and is re-read in the background
|
||||
— so an edit made elsewhere still shows up when you turn to it. */
|
||||
/* Before a reader route draws anything — /wiki/<lang>/<slug> for one language
|
||||
version of an article, /wiki/<slug> for whichever version a bare slug speaks
|
||||
— put the document it names on the library's shelf. On the server that is
|
||||
what lets the page in view be written out in the first HTML; on the client it
|
||||
is what the stack of open pages grows from, and the title the page is filed
|
||||
under. A page that is already on the shelf comes straight off it and is
|
||||
re-read in the background — so an edit made elsewhere still shows up when you
|
||||
turn to it.
|
||||
|
||||
/** How a document is filed in the tab stack: which article, which language. */
|
||||
function tabMeta(article: { slug: string; language?: string; baseSlug?: string | null }) {
|
||||
return { lang: article.language ?? 'en', identity: article.baseSlug || article.slug }
|
||||
}
|
||||
This is also the one place that knows where a version lives: an article's
|
||||
identity is the canonical version's slug, and a version's address is that
|
||||
identity with its own language in front. So a short /wiki/<slug> address — a
|
||||
wiki link, an old bookmark, a graph node — and a versioned one written with a
|
||||
translation's stored slug are both turned onto /wiki/<lang>/<identity> before
|
||||
anything renders. An address naming no language is turned onto the reader's
|
||||
own version when the article speaks it — English as the wiki's common tongue
|
||||
failing that — so opening an article opens it in the language you read the
|
||||
wiki in, and only then in whatever version the slug itself speaks. An address
|
||||
that does name a language is honoured as asked: that is how the version
|
||||
switcher keeps its promise. The address being left behind never reaches the
|
||||
history: the navigation to it is abandoned, not committed, so Back still
|
||||
leads out of the reader to the page the link was pressed on. The address that
|
||||
stays put is the one naming nothing: the route says for itself that the wiki
|
||||
has no such article, and offers to write it. */
|
||||
|
||||
export default defineNuxtRouteMiddleware(async (to) => {
|
||||
const loc = parseReaderPath(to.path)
|
||||
@@ -18,19 +30,34 @@ export default defineNuxtRouteMiddleware(async (to) => {
|
||||
/* taken before any await, while the app context is certainly at hand */
|
||||
const library = useArticleLibrary()
|
||||
const tabs = useArticleTabs()
|
||||
const { locale } = useAppLocale()
|
||||
|
||||
const onShelf = loc.lang
|
||||
? library.getVersion(loc.identity, loc.lang)
|
||||
: library.get(loc.identity)
|
||||
if (onShelf) {
|
||||
tabs.ensureTab(onShelf.slug, onShelf.title, tabMeta(onShelf))
|
||||
library.revalidate(loc.identity, loc.lang ?? undefined)
|
||||
return
|
||||
const article =
|
||||
onShelf ??
|
||||
(loc.lang
|
||||
? await library.loadVersion(loc.identity, loc.lang)
|
||||
: await library.load(loc.identity))
|
||||
|
||||
// nothing at this address: the route speaks its own emptiness
|
||||
if (!article) return
|
||||
|
||||
/* every version answers to one address, whatever form it was asked with;
|
||||
a short address picks the reader's version among the ones the article
|
||||
speaks, English failing that, before its own document speaks for it */
|
||||
const identity = identityOf(article)
|
||||
let lang = articleLanguage(article)
|
||||
if (!loc.lang) {
|
||||
const spoken = (article.versions ?? []).map((v) => v.language)
|
||||
lang = preferredLanguage(spoken, locale.value) ?? lang
|
||||
}
|
||||
if (loc.lang !== lang || loc.identity !== identity)
|
||||
return navigateTo(versionHref(identity, lang), { redirectCode: 302 })
|
||||
|
||||
const article = loc.lang
|
||||
? await library.loadVersion(loc.identity, loc.lang)
|
||||
: await library.load(loc.identity)
|
||||
|
||||
if (article) tabs.ensureTab(article.slug, article.title, tabMeta(article))
|
||||
/* a page already open turns to this version instead of another being added
|
||||
beside it: the article keeps its place in the book */
|
||||
tabs.openVersion(article)
|
||||
if (onShelf) library.revalidate(identity, lang)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user