Skip to content

Commit

Permalink
chore: Clean up navigation helper, lol
Browse files Browse the repository at this point in the history
  • Loading branch information
kiosion committed Oct 3, 2023
1 parent 6bf56eb commit d021955
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<Divider />
<ArrowButton
class="w-full text-left"
href={model === 'post' ? $linkTo('/blog') : $linkTo('/projects')}
href={model === 'post' ? $linkTo('/blog') : $linkTo('/work')}
preload
>
&larr; {$t('Read more')}
Expand Down
4 changes: 2 additions & 2 deletions svelte-app/src/components/layouts/page-transition.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
const { reduce_motion } = Settings;
const dist = 28,
duration = BASE_ANIMATION_DURATION / 1.25;
const dist = 26,
duration = BASE_ANIMATION_DURATION / 1.5;
let navDir: 'forward' | 'backward' = 'forward';
Expand Down
4 changes: 2 additions & 2 deletions svelte-app/src/lib/consts.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export const LIGHT_THEME = 'light';
export const DARK_THEME = 'dark';

export const APP_LANGS = ['en', 'fr'] as const;
export const DEFAULT_APP_LANG = 'en';
export const APP_LANGS = ['en', 'fr'];
export const DEFAULT_APP_LANG = APP_LANGS[0];

export const VALID_DOC_TYPES = ['post', 'project', 'about', 'config'] as const;

Expand Down
38 changes: 20 additions & 18 deletions svelte-app/src/lib/helpers/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get, readable, writable } from 'svelte/store';
import { derived, get, writable } from 'svelte/store';

import { page } from '$app/stores';
import EN from '$langs/en.json';
Expand Down Expand Up @@ -50,8 +50,12 @@ const getKey = <T extends keyof typeof EN>(lang: string, key: T): string | undef
}
};

const _translate = (key: string, params?: Record<string, unknown>): string => {
const lang = get(currentLang) || DEFAULT_APP_LANG;
const _translate = (
currentLang: string | undefined,
key: string,
params?: Record<string, unknown>
): string => {
const lang = currentLang || DEFAULT_APP_LANG;

// For any provided params, replace the corresponding placeholders if any
// e.g. "Hello {name}" with { name: "World" } becomes "Hello World"
Expand All @@ -65,25 +69,19 @@ const _translate = (key: string, params?: Record<string, unknown>): string => {
);
};

const string = getKey(lang || DEFAULT_APP_LANG, key as keyof typeof EN);
const string = getKey(lang, key as keyof typeof EN);

if (string) {
return replaceParams(string);
} else {
notFound(key, lang || DEFAULT_APP_LANG);
notFound(key, lang);
return replaceParams(key);
}
};

// eslint-disable-next-line func-call-spacing
const translate = readable<(key: string, params?: Record<string, unknown>) => string>(
_translate,
(set) => {
const unsubscribe = currentLang.subscribe(() => {
set(_translate);
});
return unsubscribe;
}
const translate = derived(
currentLang,
(val) => (key: string, params?: Record<string, unknown>) => _translate(val, key, params)
);

const addSearchParams = (path: string, params?: URLSearchParams): string => {
Expand All @@ -92,7 +90,8 @@ const addSearchParams = (path: string, params?: URLSearchParams): string => {
return search ? `${path}${path.includes('?') ? '&' : '?'}${search}` : path;
};

const _linkTo: LinkTo = (
const _linkTo = (
currentLang: string | undefined,
path: string,
paramsOrLang?: URLSearchParams | string,
lang?: string
Expand All @@ -109,7 +108,7 @@ const _linkTo: LinkTo = (
params = paramsOrLang;
}

lang = lang || get(currentLang);
lang ||= currentLang || DEFAULT_APP_LANG;

if (
!lang ||
Expand All @@ -135,8 +134,11 @@ interface LinkTo {
(pathname: string, params: URLSearchParams, lang?: string): string;
}

const linkTo = readable<LinkTo>(_linkTo, (set) =>
currentLang.subscribe(() => set(_linkTo))
const linkTo = derived(
currentLang,
(val) =>
((path: string, paramsOrLang?: URLSearchParams | string, lang?: string) =>
_linkTo(val, path, paramsOrLang, lang)) as LinkTo
);

export { check, currentLang, isLocalized, linkTo, translate as t };
103 changes: 47 additions & 56 deletions svelte-app/src/lib/helpers/navigation.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,60 @@
import { derived, get } from 'svelte/store';
import { derived } from 'svelte/store';

import { page } from '$app/stores';
import { currentLang, isLocalized, t } from '$i18n';
import { APP_ROUTES, BASE_PAGE_TITLE, ROUTE_ORDER } from '$lib/consts';
import { isLocalized, t } from '$i18n';
import { APP_LANGS, APP_ROUTES, BASE_PAGE_TITLE, ROUTE_ORDER } from '$lib/consts';

let prevPath: string;

const forward: string[] = [];
ROUTE_ORDER.forEach((route, index) => {
index !== ROUTE_ORDER.length - 1 &&
ROUTE_ORDER.forEach((subRoute, i) => {
!(i <= index) && forward.push(`${route}-${subRoute}`);
});
});
const langRegex = new RegExp(`^/(${APP_LANGS.join('|')})`),
firstSegRegex = /^\/([^/]+)/,
subsequentSegRegex = /\//g;

export const pageTitle = derived([currentLang, page], (_v) => {
const basePathname = get(page)?.url?.pathname ?? '/',
pathname = `/${
(get(isLocalized) ? basePathname.slice(3) : basePathname.slice(1)).split('/')[0]
}`;
const normalizePath = (path: string) => {
if (path.match(langRegex)) {
path = path.slice(3);
}

const route = APP_ROUTES.find((r) => r.path === pathname)?.name;
if (!path || path === '/') {
return 'index';
}

return route?.length ? `${BASE_PAGE_TITLE} | ${get(t)(route)}` : BASE_PAGE_TITLE;
});
const firstSegmentMatch = path.match(firstSegRegex);

export const onNav = (path: string): 'forward' | 'backward' => {
if (get(isLocalized) === true && path) {
path = `/${path.slice(3)}`;
if (!firstSegmentMatch) {
return '';
}

path = path.replace(/^\/{2,}/, '/').replace(/.+\/$/, '');
const subsequentSegmentsCount = (path.match(subsequentSegRegex) || []).length - 1;

return firstSegmentMatch[1] + '/*'.repeat(subsequentSegmentsCount);
};

const forward = new Set<string>();

if (!path) {
return 'forward';
for (let i = 0; i < ROUTE_ORDER.length - 1; ++i) {
for (let j = i + 1; j < ROUTE_ORDER.length; ++j) {
forward.add(`${ROUTE_ORDER[i]}-${ROUTE_ORDER[j]}`);
}
}

let prevPath: string;

export const onNav = (path: string) => {
const newPath = normalizePath(path),
oldPath = prevPath ? prevPath : newPath;

prevPath = newPath;

const prev = prevPath ?? path;
prevPath = path;

const toRoute = path.startsWith('/')
? path
.slice(1)
.split('/')
.map((part, i) => (i === 0 ? part : '*'))
.join('/')
: path
.split('/')
.map((part, i) => (i === 0 ? part : '*'))
.join('/');
const fromRoute = prev.startsWith('/')
? prev
.slice(1)
.split('/')
.map((part, i) => (i === 0 ? part : '*'))
.join('/')
: prev
.split('/')
.map((part, i) => (i === 0 ? part : '*'))
.join('/');

const dirs = [
fromRoute === '' ? 'index' : fromRoute,
toRoute === '' ? 'index' : toRoute
].join('-');

return forward.includes(dirs) ? 'forward' : 'backward';
return forward.has(`${oldPath}-${newPath}`) ? 'forward' : 'backward';
};

export const pageTitle = derived([isLocalized, t, page], (vals) => {
const basePathname = vals[2]?.url?.pathname ?? '/',
pathname = `/${
(vals[0] ? basePathname.slice(4) : basePathname.slice(1)).split('/')[0]
}`,
route = APP_ROUTES.find((r) => r.path === pathname);

return route?.name?.length
? `${BASE_PAGE_TITLE} | ${vals[1](route.name)}`
: BASE_PAGE_TITLE;
});
2 changes: 1 addition & 1 deletion svelte-app/src/routes/+error.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
{#if showStack}
<div transition:slide={{ duration: BASE_ANIMATION_DURATION }}>
<pre
class="mt-4 whitespace-pre-wrap rounded-md border border-dark/40 p-4 font-code text-sm dark:border-light/40">
class="mt-4 whitespace-pre-wrap break-all rounded-md border border-dark/40 p-4 font-code text-sm dark:border-light/40">
{stack}
</pre>
</div>
Expand Down

0 comments on commit d021955

Please sign in to comment.