Skip to content

Commit

Permalink
fix(theme): 修复最后更新时间不一致导致的SSR水合过程错误
Browse files Browse the repository at this point in the history
  • Loading branch information
pengzhanbo committed Mar 25, 2024
1 parent 805374d commit e3f79a8
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 64 deletions.
50 changes: 23 additions & 27 deletions theme/src/client/components/Page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,42 +34,38 @@ onContentUpdated(() => zoom?.refresh())
</script>

<template>
<div
class="plume-page" :class="{
'has-sidebar': hasSidebar,
'has-aside': hasAside,
'is-blog': page.isBlogPost,
'with-encrypt': !isPageDecrypted,
}"
>
<div class="container">
<TransitionFadeSlideY>
<div v-if="enableAside" :key="page.path" class="aside">
<TransitionFadeSlideY>
<div
:key="page.path" class="plume-page" :class="{
'has-sidebar': hasSidebar,
'has-aside': hasAside,
'is-blog': page.isBlogPost,
'with-encrypt': !isPageDecrypted,
}"
>
<div class="container">
<div v-if="enableAside" class="aside">
<div class="aside-container">
<div class="aside-content">
<PageAside />
</div>
</div>
</div>
</TransitionFadeSlideY>
<div class="content">
<div class="content-container">
<TransitionFadeSlideY>
<main :key="page.path" class="main">
<PageMeta />
<EncryptPage v-if="!isPageDecrypted" />
<template v-else>
<Content class="plume-content" />

<PageFooter />
<PageComment v-if="hasComments" :darkmode="isDark" />
</template>
</main>
</TransitionFadeSlideY>
<div class="content">
<div class="content-container">
<PageMeta />
<EncryptPage v-if="!isPageDecrypted" />
<template v-else>
<Content class="plume-content" />

<PageFooter />
<PageComment v-if="hasComments" :darkmode="isDark" />
</template>
</div>
</div>
</div>
</div>
</div>
</TransitionFadeSlideY>
</template>

<style scoped>
Expand Down
24 changes: 6 additions & 18 deletions theme/src/client/components/PageFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import IconEdit from './icons/IconEdit.vue'
const themeLocale = useThemeLocaleData()
const editNavLink = useEditNavLink()
const lastUpdated = useLastUpdated()
const { datetime: lastUpdated, isoDatetime, lastUpdatedText } = useLastUpdated()
const contributors = useContributors()
const { prev, next } = usePageNav()
Expand All @@ -25,20 +25,16 @@ const showFooter = computed(() => {
<footer v-if="showFooter" class="page-footer">
<div v-if="editNavLink || lastUpdated" class="edit-info">
<div v-if="editNavLink" class="edit-link">
<AutoLink
class="edit-link-button"
:href="editNavLink.link"
:no-icon="true"
>
<AutoLink class="edit-link-button" :href="editNavLink.link" :no-icon="true">
<IconEdit class="edit-link-icon" aria-label="edit icon" />
{{ editNavLink.text }}
</AutoLink>
</div>

<div v-if="lastUpdated" class="last-updated">
<p class="last-updated-text">
{{ themeLocale.lastUpdatedText || 'Last updated' }}:
<time :datetime="lastUpdated" class="last-updated-time">
{{ lastUpdatedText }}:
<time :datetime="isoDatetime" class="last-updated-time">
{{ lastUpdated }}
</time>
</p>
Expand All @@ -61,21 +57,13 @@ const showFooter = computed(() => {

<nav v-if="prev?.link || next?.link" class="prev-next">
<div class="pager">
<AutoLink
v-if="prev?.link"
class="pager-link prev"
:href="prev.link"
>
<AutoLink v-if="prev?.link" class="pager-link prev" :href="prev.link">
<span class="desc" v-html="themeLocale.prevPageLabel || 'Previous page'" />
<span class="title" v-html="prev.text" />
</AutoLink>
</div>
<div class="pager">
<AutoLink
v-if="next?.link"
class="pager-link next"
:href="next.link"
>
<AutoLink v-if="next?.link" class="pager-link next" :href="next.link">
<span class="desc" v-html="themeLocale.nextPageLabel || 'Next page'" />
<span class="title" v-html="next.text" />
</AutoLink>
Expand Down
44 changes: 31 additions & 13 deletions theme/src/client/composables/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { usePageData, usePageFrontmatter, usePageLang, useRoute } from 'vuepress
import { isPlainObject, isString } from 'vuepress/shared'
import { useBlogPostData } from '@vuepress-plume/plugin-blog-data/client'
import type { NotesSidebarItem } from '@vuepress-plume/plugin-notes-data'
import { computed } from 'vue'
import { computed, onMounted, ref, watchEffect } from 'vue'
import type { ComputedRef, Ref } from 'vue'
import type {
NavItemWithLink,
Expand Down Expand Up @@ -54,25 +54,43 @@ export function useEditNavLink(): ComputedRef<null | NavItemWithLink> {
})
}

export function useLastUpdated(): ComputedRef<null | string> {
const themeLocale = useThemeLocaleData()
export function useLastUpdated() {
const theme = useThemeLocaleData()
const page = usePageData<PlumeThemePageData>()
const frontmatter = usePageFrontmatter<PlumeThemePageFrontmatter>()
const lang = usePageLang()

return computed(() => {
const showLastUpdated
= frontmatter.value.lastUpdated ?? themeLocale.value.lastUpdated ?? true
const date = computed(() => new Date(page.value.git?.updatedTime ?? ''))
const isoDatetime = computed(() => date.value.toISOString())

if (!showLastUpdated)
return null

if (!page.value.git?.updatedTime)
return null
const datetime = ref('')

const updatedDate = new Date(page.value.git?.updatedTime)
const lastUpdatedText = computed(() => {
if (theme.value.lastUpdated === false)
return
return theme.value.lastUpdated?.text || theme.value.lastUpdatedText || 'Last updated'
})

return updatedDate.toLocaleString()
onMounted(() => {
watchEffect(() => {
if (frontmatter.value.lastUpdated === false || theme.value.lastUpdated === false)
return

datetime.value = new Intl.DateTimeFormat(
theme.value.lastUpdated?.formatOptions?.forceLocale ? lang.value : undefined,
theme.value.lastUpdated?.formatOptions ?? {
dateStyle: 'short',
timeStyle: 'short',
},
).format(date.value)
})
})

return {
datetime,
isoDatetime,
lastUpdatedText,
}
}

export function useContributors(): ComputedRef<
Expand Down
11 changes: 8 additions & 3 deletions theme/src/node/defaultOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ const defaultLocales: NonNullable<PlumeThemeLocaleOptions['locales']> = {
selectLanguageName: 'English',
selectLanguageText: 'Languages',
editLinkText: 'Edit this page',
lastUpdatedText: 'Last Updated',
contributorsText: 'Contributors',
appearanceText: 'Appearance',

lastUpdated: {
text: 'Last Updated',
},

encryptButtonText: 'Confirm',
encryptPlaceholder: 'Enter password',
encryptGlobalText: 'Only password can access this site',
Expand All @@ -28,11 +31,14 @@ const defaultLocales: NonNullable<PlumeThemeLocaleOptions['locales']> = {
returnToTopLabel: '返回顶部',
editLinkText: '编辑此页',
contributorsText: '贡献者',
lastUpdatedText: '上次更新',
appearanceText: '外观',
prevPageLabel: '上一页',
nextPageLabel: '下一页',

lastUpdated: {
text: '最后更新于',
},

notFound: {
code: '404',
title: '页面未找到',
Expand All @@ -54,7 +60,6 @@ export const fallbackLocaleOption: Partial<PlumeThemeLocaleOptions> = {
navbarSocialInclude: ['github', 'twitter', 'discord', 'facebook'],
// page meta
editLink: true,
lastUpdated: true,
contributors: true,
footer: {
message:
Expand Down
26 changes: 23 additions & 3 deletions theme/src/shared/options/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,24 @@ export interface PlumeThemeEncrypt {
}
}

export interface LastUpdatedOptions {
/**
* Set custom last updated text.
*
* @default 'Last updated'
*/
text?: string

/**
* Set options for last updated time formatting.
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat#using_options
*
* @default
* { dateStyle: 'short', timeStyle: 'short' }
*/
formatOptions?: Intl.DateTimeFormatOptions & { forceLocale?: boolean }
}

export interface PlumeThemeLocaleData extends LocaleData {
/**
* 网站站点首页
Expand Down Expand Up @@ -294,12 +312,14 @@ export interface PlumeThemeLocaleData extends LocaleData {
*
* Whether to show "Last Updated" or not
*/
lastUpdated?: boolean
lastUpdated?: false | LastUpdatedOptions

/**
* Page meta - last updated config
* @deprecated Use `lastUpdated.text` instead.
*
* Set custom last updated text.
*
* The text to replace the default "Last Updated"
* @default 'Last updated'
*/
lastUpdatedText?: string

Expand Down

0 comments on commit e3f79a8

Please sign in to comment.