refactor(theme): migrate contributors and changelog to @vuepress/plugin-git built-in component (#536)
This commit is contained in:
parent
9dd5a21676
commit
6235833e7f
@ -71,5 +71,5 @@ export const theme: Theme = plumeTheme({
|
||||
},
|
||||
},
|
||||
|
||||
plugins: { git: true },
|
||||
// plugins: { git: true },
|
||||
})
|
||||
|
||||
17
pnpm-lock.yaml
generated
17
pnpm-lock.yaml
generated
@ -301,8 +301,8 @@ catalogs:
|
||||
specifier: 2.0.0-rc.86
|
||||
version: 2.0.0-rc.86
|
||||
'@vuepress/plugin-git':
|
||||
specifier: 2.0.0-rc.79
|
||||
version: 2.0.0-rc.79
|
||||
specifier: 2.0.0-rc.87
|
||||
version: 2.0.0-rc.87
|
||||
'@vuepress/plugin-markdown-hint':
|
||||
specifier: 2.0.0-rc.86
|
||||
version: 2.0.0-rc.86
|
||||
@ -705,7 +705,7 @@ importers:
|
||||
version: 2.0.0-rc.86(@algolia/client-search@5.18.0)(search-insights@2.17.3)(typescript@5.8.2)(vuepress@2.0.0-rc.20(@vuepress/bundler-vite@2.0.0-rc.20(@types/node@22.13.11)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.86.0)(sass@1.86.0)(stylus@0.64.0)(typescript@5.8.2)(yaml@2.7.0))(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)))
|
||||
'@vuepress/plugin-git':
|
||||
specifier: catalog:vuepress
|
||||
version: 2.0.0-rc.79(vuepress@2.0.0-rc.20(@vuepress/bundler-vite@2.0.0-rc.20(@types/node@22.13.11)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.86.0)(sass@1.86.0)(stylus@0.64.0)(typescript@5.8.2)(yaml@2.7.0))(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)))
|
||||
version: 2.0.0-rc.87(typescript@5.8.2)(vuepress@2.0.0-rc.20(@vuepress/bundler-vite@2.0.0-rc.20(@types/node@22.13.11)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.86.0)(sass@1.86.0)(stylus@0.64.0)(typescript@5.8.2)(yaml@2.7.0))(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)))
|
||||
'@vuepress/plugin-markdown-hint':
|
||||
specifier: catalog:vuepress
|
||||
version: 2.0.0-rc.86(markdown-it@14.1.0)(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2))(vuepress@2.0.0-rc.20(@vuepress/bundler-vite@2.0.0-rc.20(@types/node@22.13.11)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.86.0)(sass@1.86.0)(stylus@0.64.0)(typescript@5.8.2)(yaml@2.7.0))(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)))
|
||||
@ -2559,8 +2559,8 @@ packages:
|
||||
peerDependencies:
|
||||
vuepress: 2.0.0-rc.20
|
||||
|
||||
'@vuepress/plugin-git@2.0.0-rc.79':
|
||||
resolution: {integrity: sha512-f3S3VieD0+K2V5feSbs85rzMXm4Pwk7ieP4UnAEDGfEXKTsPDJIuf5mLrbxL+9dwfopylO6A2rugtUqESQ2VKQ==}
|
||||
'@vuepress/plugin-git@2.0.0-rc.87':
|
||||
resolution: {integrity: sha512-kiZJyiLl2tkt3i/iuhc/g9FlnWKr1Yylj+iNf5gZYMwnO8rGnIdLFVw8a8mqqAc3587RYao6upvL/Kd75hKVfA==}
|
||||
peerDependencies:
|
||||
vuepress: 2.0.0-rc.20
|
||||
|
||||
@ -8735,10 +8735,15 @@ snapshots:
|
||||
- search-insights
|
||||
- typescript
|
||||
|
||||
'@vuepress/plugin-git@2.0.0-rc.79(vuepress@2.0.0-rc.20(@vuepress/bundler-vite@2.0.0-rc.20(@types/node@22.13.11)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.86.0)(sass@1.86.0)(stylus@0.64.0)(typescript@5.8.2)(yaml@2.7.0))(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)))':
|
||||
'@vuepress/plugin-git@2.0.0-rc.87(typescript@5.8.2)(vuepress@2.0.0-rc.20(@vuepress/bundler-vite@2.0.0-rc.20(@types/node@22.13.11)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.86.0)(sass@1.86.0)(stylus@0.64.0)(typescript@5.8.2)(yaml@2.7.0))(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)))':
|
||||
dependencies:
|
||||
'@vuepress/helper': 2.0.0-rc.86(typescript@5.8.2)(vuepress@2.0.0-rc.20(@vuepress/bundler-vite@2.0.0-rc.20(@types/node@22.13.11)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.86.0)(sass@1.86.0)(stylus@0.64.0)(typescript@5.8.2)(yaml@2.7.0))(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)))
|
||||
'@vueuse/core': 13.0.0(vue@3.5.13(typescript@5.8.2))
|
||||
execa: 9.5.2
|
||||
vue: 3.5.13(typescript@5.8.2)
|
||||
vuepress: 2.0.0-rc.20(@vuepress/bundler-vite@2.0.0-rc.20(@types/node@22.13.11)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.86.0)(sass@1.86.0)(stylus@0.64.0)(typescript@5.8.2)(yaml@2.7.0))(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2))
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@vuepress/plugin-markdown-hint@2.0.0-rc.86(markdown-it@14.1.0)(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2))(vuepress@2.0.0-rc.20(@vuepress/bundler-vite@2.0.0-rc.20(@types/node@22.13.11)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.86.0)(sass@1.86.0)(stylus@0.64.0)(typescript@5.8.2)(yaml@2.7.0))(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)))':
|
||||
dependencies:
|
||||
|
||||
@ -118,7 +118,7 @@ catalogs:
|
||||
'@vuepress/plugin-comment': 2.0.0-rc.86
|
||||
'@vuepress/plugin-copy-code': 2.0.0-rc.86
|
||||
'@vuepress/plugin-docsearch': 2.0.0-rc.86
|
||||
'@vuepress/plugin-git': 2.0.0-rc.79
|
||||
'@vuepress/plugin-git': 2.0.0-rc.87
|
||||
'@vuepress/plugin-markdown-hint': 2.0.0-rc.86
|
||||
'@vuepress/plugin-markdown-image': 2.0.0-rc.86
|
||||
'@vuepress/plugin-markdown-include': 2.0.0-rc.86
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import VPDocAside from '@theme/VPDocAside.vue'
|
||||
import VPDocBreadcrumbs from '@theme/VPDocBreadcrumbs.vue'
|
||||
import VPDocChangelog from '@theme/VPDocChangelog.vue'
|
||||
import VPDocContributor from '@theme/VPDocContributor.vue'
|
||||
import VPDocCopyright from '@theme/VPDocCopyright.vue'
|
||||
import VPDocFooter from '@theme/VPDocFooter.vue'
|
||||
import VPDocMeta from '@theme/VPDocMeta.vue'
|
||||
@ -12,6 +10,7 @@ import { computed, nextTick, ref, resolveComponent, watch } from 'vue'
|
||||
import { useRoute } from 'vuepress/client'
|
||||
import {
|
||||
useBlogPageData,
|
||||
useContributors,
|
||||
useData,
|
||||
useEncrypt,
|
||||
useHeaders,
|
||||
@ -25,6 +24,7 @@ const { hasSidebar, hasAside, leftAside } = useSidebar()
|
||||
const { isBlogPost } = useBlogPageData()
|
||||
const headers = useHeaders()
|
||||
const { isPageDecrypted } = useEncrypt()
|
||||
const { mode: contributorsMode } = useContributors()
|
||||
|
||||
const hasComments = computed(() => {
|
||||
return resolveComponent('CommentService') !== 'CommentService' && page.value.frontmatter.comments !== false && isPageDecrypted.value
|
||||
@ -129,8 +129,10 @@ watch(
|
||||
:class="[pageName, enabledExternalLinkIcon && 'external-link-icon-enabled']" vp-content
|
||||
>
|
||||
<Content />
|
||||
<VPDocContributor />
|
||||
<VPDocChangelog />
|
||||
|
||||
<DocGitContributors v-if="contributorsMode === 'block'" />
|
||||
<DocGitChangelog />
|
||||
|
||||
<VPDocCopyright />
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@ -1,175 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import VPDocHeader from '@theme/VPDocHeader.vue'
|
||||
import VPLink from '@theme/VPLink.vue'
|
||||
import { computed } from 'vue'
|
||||
import { usePageLang } from 'vuepress/client'
|
||||
import { useData, useLastUpdated, useThemeData } from '../composables/index.js'
|
||||
|
||||
const { theme, frontmatter, page } = useData()
|
||||
const themeData = useThemeData()
|
||||
const lang = usePageLang()
|
||||
const { datetime, lastUpdatedText } = useLastUpdated()
|
||||
|
||||
const list = computed(() => {
|
||||
const list = page.value.git?.changelog || []
|
||||
const formatter = new Intl.DateTimeFormat(lang.value, { dateStyle: 'short' })
|
||||
// TODO: plugin-git
|
||||
return [...list].reverse().map(({ date, ...item }) => {
|
||||
const datetime = formatter.format(date)
|
||||
return { datetime, ...item }
|
||||
})
|
||||
})
|
||||
|
||||
const hasChangelog = computed(() =>
|
||||
list.value.length && (frontmatter.value.changelog ?? !!themeData.value.changelog),
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="hasChangelog" class="vp-doc-changelog">
|
||||
<VPDocHeader anchor="doc-changelog">
|
||||
{{ theme.changelogText || 'Changelog' }}
|
||||
</VPDocHeader>
|
||||
|
||||
<details class="hint-container details">
|
||||
<summary class="changelog-header">
|
||||
<span><span class="vpi-changelog" /><span>{{ lastUpdatedText }}:</span> <span>{{ datetime }}</span></span>
|
||||
<span class="changelog-button"><span class="vpi-menu" /><span>{{ theme.changelogButtonText || 'View All Changelog' }}</span></span>
|
||||
</summary>
|
||||
|
||||
<ul class="changelog-list">
|
||||
<template v-for="item in list" :key="item.hash">
|
||||
<li v-if="item.tag" class="changelog release-tag">
|
||||
<div>
|
||||
<VPLink :href="item.tagUrl" no-icon class="release-tag">
|
||||
<code>{{ item.tag }}</code>
|
||||
</VPLink>
|
||||
<span class="datetime" data-allow-mismatch>{{ theme.changelogOnText }} {{ item.datetime }}</span>
|
||||
</div>
|
||||
</li>
|
||||
<li v-else class="changelog commit">
|
||||
<div>
|
||||
<VPLink :href="item.commitUrl" no-icon class="hash">
|
||||
<code>{{ item.hash.slice(0, 5) }}</code>
|
||||
</VPLink>
|
||||
<span class="divider">-</span>
|
||||
</div>
|
||||
<div>
|
||||
<p class="message" v-html="item.message" />
|
||||
<span class="datetime" data-allow-mismatch>{{ theme.changelogOnText }} {{ item.datetime }}</span>
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</details>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.vp-doc-changelog .changelog-header {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.vp-doc-changelog {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-header > span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (min-width: 440px) {
|
||||
.vp-doc-changelog .changelog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-header [class*="vpi-"] {
|
||||
margin-right: 4px;
|
||||
color: var(--vp-c-text-2);
|
||||
transition: color var(--vp-t-color);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-header .changelog-button:hover,
|
||||
.vp-doc-changelog .changelog-header .changelog-button:hover .vpi-menu {
|
||||
color: var(--vp-c-brand-1);
|
||||
transition: color var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-list {
|
||||
padding-left: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-list .changelog {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding-left: 20px;
|
||||
transition: color var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-list .changelog::before {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 0;
|
||||
display: inline-block;
|
||||
width: 1.25em;
|
||||
height: 1.25em;
|
||||
color: var(--vp-c-text-3);
|
||||
content: "";
|
||||
background-color: currentcolor;
|
||||
-webkit-mask: var(--icon) no-repeat;
|
||||
mask: var(--icon) no-repeat;
|
||||
-webkit-mask-size: 100% 100%;
|
||||
mask-size: 100% 100%;
|
||||
transition: color var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-list .changelog.commit::before {
|
||||
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 12a3 3 0 1 0 6 0a3 3 0 1 0-6 0m3-9v6m0 6v6'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-list .changelog.release-tag::before {
|
||||
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M6.5 7.5a1 1 0 1 0 2 0a1 1 0 1 0-2 0'/%3E%3Cpath d='M3 6v5.172a2 2 0 0 0 .586 1.414l7.71 7.71a2.41 2.41 0 0 0 3.408 0l5.592-5.592a2.41 2.41 0 0 0 0-3.408l-7.71-7.71A2 2 0 0 0 11.172 3H6a3 3 0 0 0-3 3'/%3E%3C/g%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-list .changelog .release-tag {
|
||||
margin-right: 4px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-list .changelog .release-tag code {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-list .changelog .hash {
|
||||
margin-right: 4px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-list .changelog .divider {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-list .changelog .message {
|
||||
display: inline;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-list .changelog .message :deep(a::after) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vp-doc-changelog .changelog-list .changelog .datetime {
|
||||
font-size: 12px;
|
||||
color: var(--vp-c-text-3);
|
||||
transition: color var(--vp-t-color);
|
||||
}
|
||||
</style>
|
||||
@ -1,59 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import VPDocHeader from '@theme/VPDocHeader.vue'
|
||||
import VPLink from '@theme/VPLink.vue'
|
||||
import { computed } from 'vue'
|
||||
import { useContributors, useData } from '../composables/index.js'
|
||||
|
||||
const { theme } = useData()
|
||||
|
||||
const { contributors, mode } = useContributors()
|
||||
const hasContributors = computed(() => Boolean(contributors.value.length) && mode.value === 'block')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="hasContributors" class="vp-doc-contributor">
|
||||
<VPDocHeader anchor="doc-contributors">
|
||||
{{ theme.contributorsText || 'Contributors' }}
|
||||
</VPDocHeader>
|
||||
|
||||
<ul class="contributor-list">
|
||||
<li v-for="contributor in contributors" :key="contributor.name + contributor.email" class="contributor">
|
||||
<VPLink :href="contributor.url" no-icon>
|
||||
<img v-if="contributor.avatar" :src="contributor.avatar" :alt="contributor.name">
|
||||
<span>{{ contributor.name }}</span>
|
||||
</VPLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.vp-doc-contributor .contributor-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 24px 16px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding-left: 0;
|
||||
margin-top: 32px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.vp-doc-contributor .contributor-list li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.contributor-list .contributor img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.contributor-list .contributor :deep(.vp-link) {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
@ -1,5 +1,6 @@
|
||||
import type { ComputedRef } from 'vue'
|
||||
import type { GitContributor } from '../../shared/index.js'
|
||||
import { useContributors as _useContributors } from '@vuepress/plugin-git/client'
|
||||
import { computed } from 'vue'
|
||||
import { isPlainObject } from 'vuepress/shared'
|
||||
import { useData } from '../composables/data.js'
|
||||
@ -8,8 +9,11 @@ import { useThemeData } from './theme-data.js'
|
||||
export function useContributors(): {
|
||||
mode: ComputedRef<'inline' | 'block'>
|
||||
contributors: ComputedRef<GitContributor[]>
|
||||
hasContributors: ComputedRef<boolean>
|
||||
} {
|
||||
const { page, frontmatter } = useData()
|
||||
const { frontmatter } = useData()
|
||||
const list = _useContributors()
|
||||
|
||||
const theme = useThemeData()
|
||||
|
||||
const mode = computed(() => {
|
||||
@ -25,8 +29,10 @@ export function useContributors(): {
|
||||
if (config === false)
|
||||
return []
|
||||
|
||||
return (page.value.git?.contributors ?? [])
|
||||
return list.value
|
||||
})
|
||||
|
||||
return { mode, contributors }
|
||||
const hasContributors = computed(() => contributors.value.length > 0)
|
||||
|
||||
return { mode, contributors, hasContributors }
|
||||
}
|
||||
|
||||
@ -44,4 +44,18 @@ export function globalComponents(app: App) {
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
app.component('DocGitContributors', () => {
|
||||
if (hasGlobalComponent('GitContributors')) {
|
||||
return h(resolveComponent('GitContributors'))
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
app.component('DocGitChangelog', () => {
|
||||
if (hasGlobalComponent('GitChangelog')) {
|
||||
return h(resolveComponent('GitChangelog'))
|
||||
}
|
||||
return null
|
||||
})
|
||||
}
|
||||
|
||||
@ -16,3 +16,19 @@
|
||||
.vp-comment {
|
||||
margin-top: 80px;
|
||||
}
|
||||
|
||||
/* ------------------ Plugin Git ------------------ */
|
||||
.vp-doc #doc-contributors,
|
||||
.vp-doc #doc-changelog {
|
||||
border-top: 1px solid var(--vp-c-divider);
|
||||
}
|
||||
|
||||
.vp-doc .vp-changelog-wrapper {
|
||||
background-color: var(--vp-c-default-soft);
|
||||
}
|
||||
|
||||
.vp-doc .vp-changelog-wrapper .vp-changelog-list {
|
||||
padding-left: 0;
|
||||
margin-block: 8px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ export function extendsBundlerOptions(bundlerOptions: any, app: App): void {
|
||||
addViteOptimizeDepsInclude(
|
||||
bundlerOptions,
|
||||
app,
|
||||
['@vueuse/core', 'bcrypt-ts/browser', '@vuepress/helper/client', '@iconify/vue', '@iconify/vue/offline'],
|
||||
['@vueuse/core', 'bcrypt-ts/browser', '@vuepress/helper/client', '@iconify/vue', '@iconify/vue/offline', '@vuepress/plugin-git/client'],
|
||||
)
|
||||
addViteOptimizeDepsExclude(bundlerOptions, app, '@theme')
|
||||
|
||||
|
||||
@ -114,9 +114,9 @@ export function setupPlugins(
|
||||
...options.contributors === true ? {} : options.contributors,
|
||||
}
|
||||
: false,
|
||||
changelog: options.changelog && (options.docsRepo || changelogOptions.repoUrl)
|
||||
changelog: options.changelog && options.docsRepo
|
||||
? { repoUrl: options.docsRepo, ...changelogOptions }
|
||||
: false,
|
||||
: options.changelog,
|
||||
filter(page) {
|
||||
if (page.frontmatter.home || excludes.includes(page.frontmatter.pageLayout as string))
|
||||
return false
|
||||
|
||||
@ -8,4 +8,8 @@ export type * from './pageData.js'
|
||||
export type * from './plugins.js'
|
||||
export type * from './resolved/index.js'
|
||||
export type * from './utils.js'
|
||||
export type { GitChangelog, GitContributor } from '@vuepress/plugin-git'
|
||||
|
||||
export type {
|
||||
GitChangelogInfo as GitChangelog,
|
||||
GitContributorInfo as GitContributor,
|
||||
} from '@vuepress/plugin-git'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user