56 lines
2.0 KiB
Vue
56 lines
2.0 KiB
Vue
<script setup lang="ts">
|
|
/* The article route is a thin host for the book that ArticleBookStack draws.
|
|
The open-article middleware has already laid the article on the library's
|
|
shelf — that is what the page in view is made of, and what the stack of
|
|
open pages is filed under — so all that is left to do here is speak for the
|
|
URL: the title, and the visitor's "recently viewed" line.
|
|
When nothing lives at the address, this is what says so, over the top of
|
|
whatever else is open. */
|
|
definePageMeta({ middleware: 'open-article' })
|
|
|
|
const route = useRoute()
|
|
const slug = computed(() => String(route.params.slug))
|
|
|
|
const { t } = useI18n()
|
|
const { th } = useAppLocale()
|
|
const { get, unreadable } = useArticleLibrary()
|
|
const article = computed(() => get(slug.value))
|
|
|
|
const { record } = useRecentlyViewed()
|
|
watch(
|
|
article,
|
|
(a) => {
|
|
if (import.meta.client && a?.slug && a?.title) record({ slug: a.slug, title: a.title })
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
useSeoMeta({
|
|
title: () => article.value?.title ?? t('card.kickerArticle'),
|
|
})
|
|
|
|
/* what the shelf could not bring in, the API said why */
|
|
const missingStatus = computed(() => (article.value ? 0 : unreadable.value[slug.value] ?? 0))
|
|
</script>
|
|
|
|
<template>
|
|
<div class="reader-host">
|
|
<div v-if="!article" class="reader-note">
|
|
<div class="empty" style="padding-top: 64px">
|
|
<template v-if="missingStatus === 404">
|
|
<div class="glyph">∄</div>
|
|
<h3>{{ t('reader.notFoundTitle') }}</h3>
|
|
<p v-html="th('reader.notFoundText', { path: `/wiki/${slug}` })"></p>
|
|
<NuxtLink to="/new" class="btn btn-primary">{{ t('reader.writeTopic') }}</NuxtLink>
|
|
</template>
|
|
<template v-else>
|
|
<div class="glyph">!</div>
|
|
<h3>{{ t('reader.loadFailTitle') }}</h3>
|
|
<p v-html="t('common.apiShort')"></p>
|
|
<NuxtLink to="/" class="btn btn-ghost">{{ t('common.backHome') }}</NuxtLink>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|