From d71515c7067a8bcde5b58b6055d06d6d5b755329 Mon Sep 17 00:00:00 2001 From: "Amy J. Ko" Date: Mon, 22 Jul 2024 13:55:37 -0700 Subject: [PATCH] Preserve concept on guide page refresh. --- CHANGELOG.md | 1 + src/routes/guide/Guide.svelte | 72 ++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcc899c74..b631fa8bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Dates are in `YYYY-MM-DD` format and versions are in [semantic versioning](http: ### Fixed - Fixed text sorting. +- Preserve concept on guide page refresh. ## 0.10.6 2024-07-20 diff --git a/src/routes/guide/Guide.svelte b/src/routes/guide/Guide.svelte index c075ec8b8..f061e675f 100644 --- a/src/routes/guide/Guide.svelte +++ b/src/routes/guide/Guide.svelte @@ -14,12 +14,9 @@ import { locales } from '@db/Database'; import Project from '@models/Project'; import Source from '@nodes/Source'; - import { setContext } from 'svelte'; + import { onMount, setContext } from 'svelte'; import { writable } from 'svelte/store'; - let locale: string | null = null; - let concept: string | null = null; - // There's no actual project; the documentation component just relies on one to have contexts. $: project = Project.make( null, @@ -30,44 +27,65 @@ ); $: index = ConceptIndex.make(project, $locales); + $: indexStore.set(index); let indexStore = writable(index); setContext(ConceptIndexSymbol, indexStore); - $: indexStore.set(index); - // Create a concept path for children + function getLocaleInURL() { + return ( + $page.url.searchParams.get('locale') ?? + `${$locales.getLocales()[0].language}-${ + $locales.getLocales()[0].region + }` + ); + } + + function getConceptFromURL() { + return $page.url.searchParams.get('concept'); + } + + function getConcept(concept: string | null) { + return concept ? index.getConceptByName(concept) : undefined; + } + + // Initialize locale and concept with URL. + let locale: string | null = getLocaleInURL(); + let concept: string | null = getConceptFromURL(); + + // Create a concept path for children, initialized let path = writable([]); setContext(ConceptPathSymbol, path); + let mounted = false; + onMount(() => { + concept = getConceptFromURL(); + path.set([getConcept(concept)].filter((c) => c !== undefined)); + mounted = true; + }); + // After any navigation, extract the locale and concept from the URL and // ensure the concepts are set to match it. - afterNavigate(async () => { - locale = - $page.url.searchParams.get('locale') ?? - `${$locales.getLocales()[0].language}-${ - $locales.getLocales()[0].region - }`; - concept = $page.url.searchParams.get('concept'); - - if (concept) { - const match = index.getConceptByName(concept); - // Only update the path if the concept exists and is not already in the path. - if ( - match && - ($path.length === 0 || - match.getName($locales, false) !== - $path[0].getName($locales, false)) - ) { - path.set([match]); - } + afterNavigate(() => { + // Set the current locale. + locale = getLocaleInURL(); + const currentConcept = getConcept(concept); + // Only update the path if the concept exists and is not already in the path. + if ( + currentConcept && + ($path.length === 0 || + currentConcept.getName($locales, false) !== + $path[0].getName($locales, false)) + ) { + path.set([currentConcept]); } // Only update if the path isn't already empty. - else if ($path.length !== 0) { + else if (currentConcept === null && $path.length !== 0) { path.set([]); } }); // When the concept path changes, navigate to the corresponding URL. - $: if (browser && $path) { + $: if (browser && $path && mounted) { const current = $path.at(-1); if (current) { concept = current.getName($locales, false);