More things

This commit is contained in:
2026-10-01 02:29:21 +02:00
parent e1df4d3ae1
commit 13b659662e
54 changed files with 4409 additions and 911 deletions

View File

@@ -1,12 +1,27 @@
export interface ViewedArticle {
/** the article read, by its identity — the canonical version's slug. An
* entry written before versions had addresses of their own may hold a
* document's own slug, which the reader still resolves. */
slug: string
title: string
/** the language it was last read in, so a jump returns to that version.
* Absent from entries written when one address stood for the whole article */
lang?: string
viewedAt: number
}
const STORAGE_KEY = 'mathew-recently-viewed'
const MAX_ENTRIES = 8
/** where a jump leads: the version the article was last read in, or — for an
* entry that recorded no language — the short address, which the reader turns
* onto whichever version the slug speaks */
export function viewedHref(viewed: Pick<ViewedArticle, 'slug' | 'lang'>): string {
return viewed.lang
? versionHref(viewed.slug, viewed.lang)
: `/wiki/${encodeURIComponent(viewed.slug)}`
}
let loaded = false
function readStored(): ViewedArticle[] {
@@ -36,14 +51,25 @@ export function useRecentlyViewed() {
if (stored.length) viewed.value = stored
})
function record(article: { slug: string; title: string }) {
function record(article: {
slug: string
title: string
baseSlug?: string | null
language?: string
}) {
/* filed by the article's identity and turned to the language it was read
in: an article read in two languages is still one article remembered
once, at the version it was last opened at */
const entry = {
slug: identityOf(article),
lang: articleLanguage(article),
title: article.title,
}
/* merge with what's already saved so recording before the list has
loaded (e.g. deep-linking straight to an article) can't clobber it */
const base = viewed.value.length ? viewed.value : readStored()
viewed.value = [
{ ...article, viewedAt: Date.now() },
...base.filter((v) => v.slug !== article.slug),
].slice(0, MAX_ENTRIES)
const fresh = { ...entry, viewedAt: Date.now() }
viewed.value = [fresh, ...base.filter((v) => v.slug !== entry.slug)].slice(0, MAX_ENTRIES)
loaded = true
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(viewed.value))