import { computed } from 'vue' import { useRoute } from '#app' import content from '~/assets/content.yaml' const specializations: Record = {} function buildSpecialization(locale: string, variant: string): object { const config = useAppConfig() const locales = config.content.locales.map(l => l.code) const variants = config.content.variants.map(v => v.code) const allTags = new Set([...locales, ...variants]) function split(key: string): {base?: string; tags: string[]} { const parts = key.split('@') if (allTags.has(parts[0])) { return {base: undefined, tags: parts} } return {base: parts[0], tags: parts.slice(1)} } function relevant(tags: string[]): boolean { if (tags.length < 1) { return true } for (const tag of tags) { if (tag !== locale && tag !== variant) { return false } } return true } function filterObject(object: any): any { if (Array.isArray(object)) { return object.map(e => filterObject(e)).filter(e => e !== undefined) } if (typeof object !== 'object') { return object } const copy: Record = {} let anonymous: [number, any][] = [] for (const key in object) { const {base, tags} = split(key) if (!relevant(tags)) { continue } const value = filterObject(object[key]) if (base === undefined) { anonymous.push([tags.length, value]) } else { copy[base] = value } } if (Object.keys(copy).length > 0 && anonymous.length > 0) { console.warn(`Invalid mixing of keys in object ${object}`) } if (Object.keys(copy).length > 0) { return copy } anonymous.sort((a, b) => b[0] - a[0]) if (anonymous[0][0] > 2) { console.warn(`More than two tags per key in object ${object}`) } return anonymous[0][1] } return filterObject(content) } function getSpecialization(locale: string, variant: string): object { const key = locale + '/' + variant if (!(key in specializations)) { specializations[key] = buildSpecialization(locale, variant) } return specializations[key] } export function useContent() { const config = useAppConfig() const route = useRoute() console.log("miau") console.log(route) const locales = config.content.locales.map(l => l.code) const variants = config.content.variants.map(v => v.code) const localeCookie = useCookie('locale', { sameSite: 'lax', maxAge: config.content.cookieMaxAge }) const variantCookie = useCookie('variant', { sameSite: 'lax', maxAge: config.content.cookieMaxAge }) const currentLocale = computed(() => route.params.locale || localeCookie.value || config.content.defaultLocale) const currentVariant = computed(() => route.params.variant || variantCookie.value || config.content.defaultVariant) function preferLocale(locale: string) { if (locale in locales) { localeCookie.value = locale } } function preferVariant(variant: string) { if (variant in variants) { variantCookie.value = variant } } function matrixPath(options: { page?: string; anchor?: string; locale?: string; variant?: string }): string { let prefix: string[] = [] const showLocale = locales.length > 1 const showVariant = variants.length > 1 if (showLocale) { prefix.push(options.locale ?? currentLocale.value) } if (showVariant) { prefix.push(options.variant ?? currentVariant.value) } // TODO preserve anchor when taking route.path let page = (options.page ?? route.path).split('/').filter(Boolean) if (!options.page) { page = page.slice([showLocale, showVariant].filter(Boolean).length) } const base = '/' + [...prefix, ...page].join('/') return options.anchor ? `${base}#${options.anchor}` : base } function p(page: string, anchor?: string): string { return matrixPath({page: page, anchor: anchor}) } const specialization = computed(() => getSpecialization(currentLocale.value, currentVariant.value)) return { locale: currentLocale, locales: locales, preferLocale: preferLocale, variant: currentVariant, variants: variants, preferVariant: preferVariant, matrixPath: matrixPath, p: p, c: specialization, } }