perf(theme): 重命名 avatarprofile

This commit is contained in:
pengzhanbo 2024-06-15 17:42:29 +08:00
parent 830bae053f
commit 7e065208a9
11 changed files with 83 additions and 59 deletions

View File

@ -10,8 +10,8 @@ export const theme: Theme = themePlume({
docsRepo: 'https://github.com/pengzhanbo/vuepress-theme-plume',
docsDir: 'docs',
avatar: {
url: '/plume.png',
profile: {
avatar: '/plume.png',
name: 'Plume Theme',
description: 'The Theme for Vuepress 2.0',
location: 'GuangZhou, China',

View File

@ -29,8 +29,8 @@ const type = computed(() => {
<template>
<div class="vp-blog">
<div class="blog-container" :class="{ 'no-avatar': !theme.avatar }">
<VPBlogNav v-if="!theme.avatar" is-local />
<div class="blog-container" :class="{ 'no-profile': !theme.profile }">
<VPBlogNav v-if="!theme.profile" is-local />
<VPTransitionFadeSlideY>
<component :is="com[type]" />
@ -57,7 +57,7 @@ const type = computed(() => {
margin: 0 auto;
}
.blog-container.no-avatar {
.blog-container.no-profile {
display: block;
max-width: 784px;
padding-right: 24px;

View File

@ -7,7 +7,7 @@ const { theme } = useData()
</script>
<template>
<div v-if="theme.avatar" class="vp-blog-aside">
<div v-if="theme.profile" class="vp-blog-aside">
<VPBlogProfile />
<VPBlogNav />
</div>

View File

@ -11,9 +11,9 @@ import { inBrowser } from '../../utils/index.js'
const { theme } = useData()
const route = useRoute()
const avatar = computed(() => theme.value.avatar)
const profile = computed(() => theme.value.profile)
const imageUrl = computed(() => {
const url = avatar.value?.url
const url = profile.value?.avatar ?? profile.value?.url
if (!url)
return ''
if (isLinkHttp(url))
@ -52,7 +52,7 @@ watch(
)
const showBlogExtract = computed(() => {
return avatar.value || hasBlogExtract.value
return profile.value || hasBlogExtract.value
})
</script>
@ -64,28 +64,28 @@ const showBlogExtract = computed(() => {
<Transition name="fade">
<div v-show="open" class="blog-modal" @click.self="open = false">
<div class="blog-modal-container" :class="{ open: lazyOpen }">
<div v-if="avatar" class="avatar-profile">
<div v-if="profile" class="profile">
<p v-if="imageUrl" class="avatar">
<img :src="imageUrl" :alt="avatar.name">
<img :src="imageUrl" :alt="profile.name">
</p>
<div>
<h3>{{ avatar.name }}</h3>
<h3>{{ profile.name }}</h3>
<p class="desc">
{{ avatar.description }}
{{ profile.description }}
</p>
<div class="avatar-info">
<div v-if="avatar.location" class="avatar-location">
<div class="profile-info">
<div v-if="profile.location" class="profile-location">
<span class="vpi-location" />
<p v-if="avatar.location" v-html="avatar.location" />
<p v-if="profile.location" v-html="profile.location" />
</div>
<div v-if="avatar.organization" class="avatar-organization">
<div v-if="profile.organization" class="profile-organization">
<span class="vpi-organization" />
<p v-if="avatar.organization" v-html="avatar.organization" />
<p v-if="profile.organization" v-html="profile.organization" />
</div>
</div>
</div>
</div>
<div v-if="hasBlogExtract" class="blog-nav" :class="{ 'no-avatar': !avatar }">
<div v-if="hasBlogExtract" class="blog-nav" :class="{ 'no-profile': !profile }">
<VPLink class="nav-link" :href="tags.link" no-icon>
<span class="vpi-tag icon" />
<span>{{ tags.text }}</span>
@ -185,21 +185,21 @@ const showBlogExtract = computed(() => {
transform: translateY(0);
}
.avatar-profile {
.profile {
display: flex;
align-items: center;
}
.avatar-profile .avatar {
.profile .avatar {
width: 64px;
margin-right: 16px;
}
.avatar-profile h3 {
.profile h3 {
font-weight: 600;
}
.avatar-profile .desc {
.profile .desc {
font-size: 14px;
}
@ -212,7 +212,7 @@ const showBlogExtract = computed(() => {
border-top: solid 1px var(--vp-c-divider);
}
.blog-nav.no-avatar {
.blog-nav.no-profile {
padding-top: 0;
margin: 0;
border-top: none;
@ -234,15 +234,15 @@ const showBlogExtract = computed(() => {
margin-right: 4px;
}
.avatar-info {
.profile-info {
display: flex;
flex-wrap: wrap;
gap: 0 20px;
align-items: center;
}
.avatar-location,
.avatar-organization {
.profile-location,
.profile-organization {
display: flex;
align-items: center;
justify-content: center;
@ -251,8 +251,8 @@ const showBlogExtract = computed(() => {
transition: color var(--t-color);
}
.avatar-location p,
.avatar-organization p {
.profile-location p,
.profile-organization p {
margin: 0 4px;
}
</style>

View File

@ -6,9 +6,9 @@ import VPSocialLinks from '@theme/VPSocialLinks.vue'
import { useData } from '../../composables/data.js'
const { theme } = useData()
const avatar = computed(() => theme.value.avatar)
const profile = computed(() => theme.value.profile)
const imageUrl = computed(() => {
const url = avatar.value?.url
const url = profile.value?.avatar ?? profile.value?.url
if (!url)
return ''
if (isLinkHttp(url))
@ -18,20 +18,20 @@ const imageUrl = computed(() => {
</script>
<template>
<div v-if="avatar" class="vp-blog-profile">
<p v-if="imageUrl" :class="{ circle: !!avatar.circle }">
<img :src="imageUrl" :alt="avatar.name">
<div v-if="profile" class="vp-blog-profile">
<p v-if="imageUrl" :class="{ circle: !!profile.circle }">
<img :src="imageUrl" :alt="profile.name">
</p>
<div class="profile-info">
<h3>{{ avatar.name }}</h3>
<p v-if="avatar.description" v-html="avatar.description" />
<div v-if="avatar.location" class="profile-location">
<h3>{{ profile.name }}</h3>
<p v-if="profile.description" v-html="profile.description" />
<div v-if="profile.location" class="profile-location">
<span class="vpi-location" />
<p v-if="avatar.location" v-html="avatar.location" />
<p v-if="profile.location" v-html="profile.location" />
</div>
<div v-if="avatar.organization" class="profile-organization">
<div v-if="profile.organization" class="profile-organization">
<span class="vpi-organization" />
<p v-if="avatar.organization" v-html="avatar.organization" />
<p v-if="profile.organization" v-html="profile.organization" />
</div>
</div>
<div v-if="theme.social" class="profile-social">

View File

@ -9,14 +9,14 @@ const props = defineProps<PlumeThemeHomeProfile>()
const { theme } = useData()
const avatar = computed(() => theme.value.avatar)
const rawProfile = computed(() => theme.value.profile)
const profile = computed(() => {
return {
name: props.name || avatar.value?.name,
description: props.description || avatar.value?.description,
avatar: props.avatar || avatar.value?.url,
circle: props.circle || avatar.value?.circle,
name: props.name || rawProfile.value?.name,
description: props.description || rawProfile.value?.description,
avatar: props.avatar || rawProfile.value?.avatar || rawProfile.value?.url,
circle: props.circle || rawProfile.value?.circle,
}
})
</script>

View File

@ -8,16 +8,16 @@ import { useGlobalEncrypt } from '../composables/encrypt.js'
const { theme, site } = useData()
const { compareGlobal } = useGlobalEncrypt()
const avatar = computed(() => theme.value.avatar)
const title = computed(() => avatar.value?.name || site.value.title)
const profile = computed(() => theme.value.profile)
const title = computed(() => profile.value?.name || site.value.title)
</script>
<template>
<div class="vp-global-encrypt">
<div class="global-encrypt-container">
<div v-if="avatar || title" class="profile">
<p v-if="avatar" class="avatar" :class="{ circle: avatar.circle }">
<img :src="avatar.url" :alt="avatar.name">
<div v-if="profile || title" class="profile">
<p v-if="profile" class="avatar" :class="{ circle: profile.circle }">
<img :src="profile.avatar ?? profile.url" :alt="profile.name">
</p>
<h3 v-if="title">
{{ title }}

View File

@ -4,7 +4,7 @@ import type { NavItem, PlumeThemeLocaleOptions } from '../../shared/index.js'
import { PRESET_LOCALES } from '../locales/index.js'
import { withBase } from '../utils.js'
const EXCLUDE_LIST = ['locales', 'sidebar', 'navbar', 'notes', 'article']
const EXCLUDE_LIST = ['locales', 'sidebar', 'navbar', 'notes', 'article', 'avatar']
// 过滤不需要出现在多语言配置中的字段
const EXCLUDE_LOCALE_LIST = [...EXCLUDE_LIST, 'blog', 'appearance']
@ -17,12 +17,22 @@ export function resolveThemeData(app: App, options: PlumeThemeLocaleOptions): Pl
themeData[key] = value
})
// TODO: 正式版中需删除此代码
if (options.avatar) {
themeData.profile ??= options.avatar
}
entries(options.locales || {}).forEach(([locale, opt]) => {
themeData.locales![locale] = {}
entries(opt).forEach(([key, value]) => {
if (!EXCLUDE_LOCALE_LIST.includes(key))
themeData.locales![locale][key] = value
})
// TODO: 正式版中需删除此代码
if (opt.avatar) {
themeData.locales![locale].profile ??= opt.avatar
}
})
const blog = options.blog || {}

View File

@ -187,7 +187,7 @@ export function getPlugins({
if (pluginOptions.seo !== false && hostname && isProd) {
plugins.push(seoPlugin({
hostname,
author: localeOptions.locales?.['/'].avatar?.name || localeOptions.avatar?.name,
author: localeOptions.locales?.['/'].profile?.name || localeOptions.profile?.name || localeOptions.locales?.['/'].avatar?.name || localeOptions.avatar?.name,
}))
}

View File

@ -56,9 +56,9 @@ export function resolveAutoFrontmatterOptions(
return author
if (data.friends)
return
const avatar = resolveOptions(relativePath).avatar
const profile = resolveOptions(relativePath).profile ?? resolveOptions(relativePath).avatar
return avatar?.name || pkg.author || ''
return profile?.name || pkg.author || ''
},
createTime(formatTime: string, { createTime }, data: any) {
if (formatTime)

View File

@ -31,11 +31,16 @@ export interface PlumeThemeLocaleData extends LocaleData {
darkModeSwitchTitle?: string
/**
*
*
*
* @deprecated 使 `profile`
*/
avatar?: PlumeThemeAvatar
avatar?: PlumeThemeProfile
/**
*
*
*
*/
profile?: PlumeThemeProfile
/**
*
@ -238,11 +243,20 @@ export interface PlumeThemeLocaleData extends LocaleData {
/** =========================== Avatar ================================ */
export interface PlumeThemeAvatar {
/**
*
*/
export interface PlumeThemeProfile {
/**
* @deprecated 使 `avatar`
*
*/
url?: string
/**
*
*/
avatar?: string
/**
*
*/