webapps/packages/layers/content/app/composables/useContentInjected.ts
Dominik Milacher 0dc24c4db7
Some checks failed
Build and deploy updated apps / Build & deploy (push) Failing after 50s
Extend ux layer and overhaul panoramablick-saalbach.at
2025-11-21 21:17:52 +01:00

110 lines
3.3 KiB
TypeScript

import { type JsonValue } from '../utils/content-canonical'
import { buildContent, expandContent } from '../utils/content-reduced'
import { useContentPreference } from './useContentPreference'
import config from 'virtual:content/content.config'
import shortcuts from 'virtual:content/shortcuts'
export function useContentInjected(slug?: string, global?: JsonValue, local?: JsonValue) {
if (!slug) {
throw new Error(
'useContentInjected called without arguments, there might be a problem with the Vite plugin'
)
}
const route = useRoute()
const { preferredLocale, preferredVariant } = useContentPreference()
const lo = computed(() => (route.params.locale as string | undefined) ?? preferredLocale.value)
const va = computed(() => (route.params.variant as string | undefined) ?? preferredVariant.value)
const g = computed(() => getContent('content.global', lo.value, va.value, global, local))
const l = computed(() => getContent(slug, lo.value, va.value, global, local))
function path(page?: string, options?: { locale?: string; variant?: string }) {
return computed(() => {
let result: string // don't touch page, this will mess with reactivity
if (page === undefined) {
result = route.fullPath
function replace(what: string, value: string) {
// replaces only the first occurrence
const expression = new RegExp(`/${what}(?=[/?#]|$)`)
return result.replace(expression, `/${value}`)
}
result = lo.value ? replace(lo.value, '[locale]') : result
result = va.value ? replace(va.value, '[variant]') : result
} else {
const index = page.search(/[?#]/)
const path = index === -1 ? page : page.slice(0, index)
if (path in shortcuts) {
result = shortcuts[path] + page.slice(index === -1 ? page.length : index)
} else {
result = page
}
}
if (!result.startsWith('/')) {
result = '/' + result
}
result = lo.value ? result.replace('[locale]', options?.locale ?? lo.value ?? '') : result
result = va.value ? result.replace('[variant]', options?.variant ?? va.value ?? '') : result
return result
})
}
return {
locale: lo,
variant: va,
global: g as ComputedRef,
local: l as ComputedRef,
g: g as ComputedRef,
l: l as ComputedRef,
path: path,
p: path,
}
}
const cache = new Map<string, JsonValue | undefined>()
function getContent(
slug: string,
locale?: string,
variant?: string,
global?: JsonValue,
local?: JsonValue
): JsonValue | undefined {
const key = `${slug}${locale}${variant}`
const hit = cache.get(key)
if (hit !== undefined) {
return hit
}
const locales: string[] = config.locale?.list.map((l) => l.code) ?? []
const variants: string[] = config.variant?.list.map((v) => v.code) ?? []
const content = slug === 'content.global' ? global : local
let [reduced, expand] =
content === undefined
? [undefined, false]
: buildContent(locale, locales, variant, variants, content)
if (reduced && expand) {
if (slug === 'content.global') {
reduced = expandContent(reduced, [reduced])
} else {
const g = getContent('content.global', locale, variant, global, local)
reduced = expandContent(reduced, g ? [reduced, g] : [reduced])
}
}
cache.set(key, reduced)
return reduced
}