@sugarat/theme 0.5.5 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/node.d.ts +6 -1
- package/node.js +28 -12
- package/node.mjs +29 -13
- package/package.json +5 -5
- package/src/components/BlogApp.vue +29 -2
- package/src/components/BlogArticleAnalyze.vue +42 -20
- package/src/composables/config/blog.ts +5 -1
- package/src/composables/config/index.ts +6 -1
- package/src/node.ts +7 -7
- package/src/utils/node/theme.ts +14 -6
- package/src/utils/node/vitePlugins.ts +14 -1
package/node.d.ts
CHANGED
|
@@ -181,6 +181,11 @@ declare namespace Theme {
|
|
|
181
181
|
* 首页数据分析卡片
|
|
182
182
|
*/
|
|
183
183
|
analysis?: HomeAnalysis;
|
|
184
|
+
/**
|
|
185
|
+
* 首页博客信息卡片是否在移动端折叠展示
|
|
186
|
+
* @default false
|
|
187
|
+
*/
|
|
188
|
+
blogInfoCollapsible?: boolean;
|
|
184
189
|
}
|
|
185
190
|
interface ArticleConfig {
|
|
186
191
|
/**
|
|
@@ -377,7 +382,7 @@ declare namespace Theme {
|
|
|
377
382
|
works?: UserWorks;
|
|
378
383
|
/**
|
|
379
384
|
* https://mermaid.js.org/config/setup/modules/mermaidAPI.html#mermaidapi-configuration-defaults for options
|
|
380
|
-
* @default
|
|
385
|
+
* @default false
|
|
381
386
|
*/
|
|
382
387
|
mermaid?: any;
|
|
383
388
|
/**
|
package/node.js
CHANGED
|
@@ -41,7 +41,7 @@ module.exports = __toCommonJS(node_exports);
|
|
|
41
41
|
// src/utils/node/mdPlugins.ts
|
|
42
42
|
var import_module = require("module");
|
|
43
43
|
|
|
44
|
-
// ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@
|
|
44
|
+
// ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@https+++pkg.pr.new+vitepress@3d61619_@types+node@_fc84fc5ced1bdf672a18932976f96d0a/node_modules/vitepress-plugin-tabs/dist/index.js
|
|
45
45
|
var tabsMarker = "=tabs";
|
|
46
46
|
var tabsMarkerLen = tabsMarker.length;
|
|
47
47
|
var ruleBlockTabs = (state, startLine, endLine, silent) => {
|
|
@@ -386,8 +386,9 @@ function patchDefaultThemeSideBar(cfg) {
|
|
|
386
386
|
} : void 0;
|
|
387
387
|
}
|
|
388
388
|
var defaultTimeZoneOffset = (/* @__PURE__ */ new Date()).getTimezoneOffset() / -60;
|
|
389
|
-
async function getArticleMeta(filepath, route, timeZone = defaultTimeZoneOffset,
|
|
390
|
-
const fileContent = baseContent || await import_node_fs.default.promises.readFile(filepath, "utf-8");
|
|
389
|
+
async function getArticleMeta(filepath, route, timeZone = defaultTimeZoneOffset, ops) {
|
|
390
|
+
const fileContent = ops?.baseContent || await import_node_fs.default.promises.readFile(filepath, "utf-8");
|
|
391
|
+
const cacheDir = ops?.cacheDir;
|
|
391
392
|
const { data: frontmatter, excerpt, content } = (0, import_theme_shared2.grayMatter)(fileContent, {
|
|
392
393
|
excerpt: true
|
|
393
394
|
});
|
|
@@ -398,7 +399,7 @@ async function getArticleMeta(filepath, route, timeZone = defaultTimeZoneOffset,
|
|
|
398
399
|
meta.title = (0, import_theme_shared2.getDefaultTitle)(content);
|
|
399
400
|
}
|
|
400
401
|
const utcValue = timeZone >= 0 ? `+${timeZone}` : `${timeZone}`;
|
|
401
|
-
const date = await (meta.date && /* @__PURE__ */ new Date(`${new Date(meta.date).toUTCString()}${utcValue}`) || (0, import_theme_shared2.getFileLastModifyTime)(filepath));
|
|
402
|
+
const date = await (meta.date && /* @__PURE__ */ new Date(`${new Date(meta.date).toUTCString()}${utcValue}`) || (0, import_theme_shared2.getFileLastModifyTime)(filepath, cacheDir));
|
|
402
403
|
meta.date = formatDate(date || /* @__PURE__ */ new Date(), "yyyy/MM/dd hh:mm:ss");
|
|
403
404
|
meta.categories = typeof meta.categories === "string" ? [meta.categories] : meta.categories;
|
|
404
405
|
meta.tags = typeof meta.tags === "string" ? [meta.tags] : meta.tags;
|
|
@@ -417,7 +418,12 @@ async function getArticles(cfg, vpConfig) {
|
|
|
417
418
|
const pages = (0, import_theme_shared2.getVitePressPages)(vpConfig);
|
|
418
419
|
const metaResults = pages.reduce((prev, value) => {
|
|
419
420
|
const { page, route, originRoute, filepath, isDynamic, dynamicRoute } = value;
|
|
420
|
-
const metaPromise = isDynamic && dynamicRoute ? getArticleMeta(filepath, originRoute, cfg?.timeZone,
|
|
421
|
+
const metaPromise = isDynamic && dynamicRoute ? getArticleMeta(filepath, originRoute, cfg?.timeZone, {
|
|
422
|
+
baseContent: (0, import_theme_shared2.renderDynamicMarkdown)(filepath, dynamicRoute.params, dynamicRoute.content),
|
|
423
|
+
cacheDir: vpConfig.cacheDir
|
|
424
|
+
}) : getArticleMeta(filepath, originRoute, cfg?.timeZone, {
|
|
425
|
+
cacheDir: vpConfig.cacheDir
|
|
426
|
+
});
|
|
421
427
|
prev[page] = {
|
|
422
428
|
route,
|
|
423
429
|
metaPromise
|
|
@@ -542,6 +548,7 @@ function themeReloadPlugin() {
|
|
|
542
548
|
// src/utils/node/vitePlugins.ts
|
|
543
549
|
function getVitePlugins(cfg = {}) {
|
|
544
550
|
const plugins = [];
|
|
551
|
+
plugins.push(cacheAllGitTimestampsPlugin());
|
|
545
552
|
plugins.push(coverImgTransform());
|
|
546
553
|
if (cfg.themeColor) {
|
|
547
554
|
plugins.push(setThemeScript(cfg.themeColor));
|
|
@@ -723,6 +730,15 @@ function providePageData(cfg) {
|
|
|
723
730
|
}
|
|
724
731
|
};
|
|
725
732
|
}
|
|
733
|
+
function cacheAllGitTimestampsPlugin() {
|
|
734
|
+
return {
|
|
735
|
+
name: "@sugarat/theme-plugin-cache-all-git-timestamps",
|
|
736
|
+
async config(config) {
|
|
737
|
+
const { srcDir } = config.vitepress;
|
|
738
|
+
await (0, import_theme_shared4.cacheAllGitTimestamps)(srcDir);
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
}
|
|
726
742
|
function setThemeScript(themeColor) {
|
|
727
743
|
let resolveConfig;
|
|
728
744
|
const pluginOps = {
|
|
@@ -759,13 +775,13 @@ function getThemeConfig(cfg = {}) {
|
|
|
759
775
|
const extraVPConfig = {
|
|
760
776
|
vite: {
|
|
761
777
|
// see https://sass-lang.com/documentation/breaking-changes/legacy-js-api/
|
|
762
|
-
css: {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
},
|
|
778
|
+
// css: {
|
|
779
|
+
// preprocessorOptions: {
|
|
780
|
+
// scss: {
|
|
781
|
+
// api: 'modern',
|
|
782
|
+
// },
|
|
783
|
+
// },
|
|
784
|
+
// },
|
|
769
785
|
build: {
|
|
770
786
|
// https://vite.dev/config/build-options.html#build-chunksizewarninglimit
|
|
771
787
|
chunkSizeWarningLimit: 2048
|
package/node.mjs
CHANGED
|
@@ -9,7 +9,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
9
9
|
// src/utils/node/mdPlugins.ts
|
|
10
10
|
import { createRequire } from "module";
|
|
11
11
|
|
|
12
|
-
// ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@
|
|
12
|
+
// ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@https+++pkg.pr.new+vitepress@3d61619_@types+node@_fc84fc5ced1bdf672a18932976f96d0a/node_modules/vitepress-plugin-tabs/dist/index.js
|
|
13
13
|
var tabsMarker = "=tabs";
|
|
14
14
|
var tabsMarkerLen = tabsMarker.length;
|
|
15
15
|
var ruleBlockTabs = (state, startLine, endLine, silent) => {
|
|
@@ -352,8 +352,9 @@ function patchDefaultThemeSideBar(cfg) {
|
|
|
352
352
|
} : void 0;
|
|
353
353
|
}
|
|
354
354
|
var defaultTimeZoneOffset = (/* @__PURE__ */ new Date()).getTimezoneOffset() / -60;
|
|
355
|
-
async function getArticleMeta(filepath, route, timeZone = defaultTimeZoneOffset,
|
|
356
|
-
const fileContent = baseContent || await fs.promises.readFile(filepath, "utf-8");
|
|
355
|
+
async function getArticleMeta(filepath, route, timeZone = defaultTimeZoneOffset, ops) {
|
|
356
|
+
const fileContent = ops?.baseContent || await fs.promises.readFile(filepath, "utf-8");
|
|
357
|
+
const cacheDir = ops?.cacheDir;
|
|
357
358
|
const { data: frontmatter, excerpt, content } = grayMatter(fileContent, {
|
|
358
359
|
excerpt: true
|
|
359
360
|
});
|
|
@@ -364,7 +365,7 @@ async function getArticleMeta(filepath, route, timeZone = defaultTimeZoneOffset,
|
|
|
364
365
|
meta.title = getDefaultTitle(content);
|
|
365
366
|
}
|
|
366
367
|
const utcValue = timeZone >= 0 ? `+${timeZone}` : `${timeZone}`;
|
|
367
|
-
const date = await (meta.date && /* @__PURE__ */ new Date(`${new Date(meta.date).toUTCString()}${utcValue}`) || getFileLastModifyTime(filepath));
|
|
368
|
+
const date = await (meta.date && /* @__PURE__ */ new Date(`${new Date(meta.date).toUTCString()}${utcValue}`) || getFileLastModifyTime(filepath, cacheDir));
|
|
368
369
|
meta.date = formatDate(date || /* @__PURE__ */ new Date(), "yyyy/MM/dd hh:mm:ss");
|
|
369
370
|
meta.categories = typeof meta.categories === "string" ? [meta.categories] : meta.categories;
|
|
370
371
|
meta.tags = typeof meta.tags === "string" ? [meta.tags] : meta.tags;
|
|
@@ -383,7 +384,12 @@ async function getArticles(cfg, vpConfig) {
|
|
|
383
384
|
const pages = getVitePressPages(vpConfig);
|
|
384
385
|
const metaResults = pages.reduce((prev, value) => {
|
|
385
386
|
const { page, route, originRoute, filepath, isDynamic, dynamicRoute } = value;
|
|
386
|
-
const metaPromise = isDynamic && dynamicRoute ? getArticleMeta(filepath, originRoute, cfg?.timeZone,
|
|
387
|
+
const metaPromise = isDynamic && dynamicRoute ? getArticleMeta(filepath, originRoute, cfg?.timeZone, {
|
|
388
|
+
baseContent: renderDynamicMarkdown(filepath, dynamicRoute.params, dynamicRoute.content),
|
|
389
|
+
cacheDir: vpConfig.cacheDir
|
|
390
|
+
}) : getArticleMeta(filepath, originRoute, cfg?.timeZone, {
|
|
391
|
+
cacheDir: vpConfig.cacheDir
|
|
392
|
+
});
|
|
387
393
|
prev[page] = {
|
|
388
394
|
route,
|
|
389
395
|
metaPromise
|
|
@@ -426,7 +432,7 @@ import {
|
|
|
426
432
|
pagefindPlugin
|
|
427
433
|
} from "vitepress-plugin-pagefind";
|
|
428
434
|
import { RssPlugin } from "vitepress-plugin-rss";
|
|
429
|
-
import { joinPath as joinPath2 } from "@sugarat/theme-shared";
|
|
435
|
+
import { cacheAllGitTimestamps, joinPath as joinPath2 } from "@sugarat/theme-shared";
|
|
430
436
|
import { AnnouncementPlugin } from "vitepress-plugin-announcement";
|
|
431
437
|
import { groupIconVitePlugin } from "vitepress-plugin-group-icons";
|
|
432
438
|
|
|
@@ -510,6 +516,7 @@ function themeReloadPlugin() {
|
|
|
510
516
|
// src/utils/node/vitePlugins.ts
|
|
511
517
|
function getVitePlugins(cfg = {}) {
|
|
512
518
|
const plugins = [];
|
|
519
|
+
plugins.push(cacheAllGitTimestampsPlugin());
|
|
513
520
|
plugins.push(coverImgTransform());
|
|
514
521
|
if (cfg.themeColor) {
|
|
515
522
|
plugins.push(setThemeScript(cfg.themeColor));
|
|
@@ -691,6 +698,15 @@ function providePageData(cfg) {
|
|
|
691
698
|
}
|
|
692
699
|
};
|
|
693
700
|
}
|
|
701
|
+
function cacheAllGitTimestampsPlugin() {
|
|
702
|
+
return {
|
|
703
|
+
name: "@sugarat/theme-plugin-cache-all-git-timestamps",
|
|
704
|
+
async config(config) {
|
|
705
|
+
const { srcDir } = config.vitepress;
|
|
706
|
+
await cacheAllGitTimestamps(srcDir);
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
}
|
|
694
710
|
function setThemeScript(themeColor) {
|
|
695
711
|
let resolveConfig;
|
|
696
712
|
const pluginOps = {
|
|
@@ -727,13 +743,13 @@ function getThemeConfig(cfg = {}) {
|
|
|
727
743
|
const extraVPConfig = {
|
|
728
744
|
vite: {
|
|
729
745
|
// see https://sass-lang.com/documentation/breaking-changes/legacy-js-api/
|
|
730
|
-
css: {
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
},
|
|
746
|
+
// css: {
|
|
747
|
+
// preprocessorOptions: {
|
|
748
|
+
// scss: {
|
|
749
|
+
// api: 'modern',
|
|
750
|
+
// },
|
|
751
|
+
// },
|
|
752
|
+
// },
|
|
737
753
|
build: {
|
|
738
754
|
// https://vite.dev/config/build-options.html#build-chunksizewarninglimit
|
|
739
755
|
chunkSizeWarningLimit: 2048
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sugarat/theme",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
4
|
"description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
|
|
5
5
|
"author": "sugar",
|
|
6
6
|
"license": "MIT",
|
|
@@ -53,10 +53,10 @@
|
|
|
53
53
|
"vitepress-plugin-group-icons": "1.2.4",
|
|
54
54
|
"vitepress-plugin-mermaid": "2.0.13",
|
|
55
55
|
"vitepress-plugin-tabs": "0.2.0",
|
|
56
|
-
"
|
|
57
|
-
"vitepress-plugin-pagefind": "0.4.14",
|
|
56
|
+
"vitepress-plugin-pagefind": "0.4.15",
|
|
58
57
|
"vitepress-plugin-announcement": "0.1.5",
|
|
59
|
-
"vitepress-plugin-rss": "0.3.
|
|
58
|
+
"vitepress-plugin-rss": "0.3.2",
|
|
59
|
+
"@sugarat/theme-shared": "0.0.6"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@element-plus/icons-vue": "^2.3.1",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"sass": "^1.80.6",
|
|
67
67
|
"typescript": "^5.4.5",
|
|
68
68
|
"vite": "^5.4.9",
|
|
69
|
-
"vitepress": "
|
|
69
|
+
"vitepress": "https://pkg.pr.new/vitepress@3d61619",
|
|
70
70
|
"vue": "^3.5.12",
|
|
71
71
|
"vitepress-plugin-51la": "0.1.0"
|
|
72
72
|
},
|
|
@@ -3,7 +3,7 @@ import Theme from 'vitepress/theme'
|
|
|
3
3
|
import { useData } from 'vitepress'
|
|
4
4
|
import { computed } from 'vue'
|
|
5
5
|
import { useDarkTransition } from '../hooks/useDarkTransition'
|
|
6
|
-
import { useBlogThemeMode, useDarkTransitionConfig } from '../composables/config/blog'
|
|
6
|
+
import { useBlogInfoCollapsible, useBlogThemeMode, useDarkTransitionConfig } from '../composables/config/blog'
|
|
7
7
|
import BlogHomeInfo from './BlogHomeInfo.vue'
|
|
8
8
|
import BlogHomeBanner from './BlogHomeBanner.vue'
|
|
9
9
|
import BlogList from './BlogList.vue'
|
|
@@ -26,6 +26,8 @@ const layout = computed(() => frontmatter.value.layout)
|
|
|
26
26
|
const isBlogTheme = useBlogThemeMode()
|
|
27
27
|
const { Layout } = Theme
|
|
28
28
|
|
|
29
|
+
const blogInfoCollapsible = useBlogInfoCollapsible()
|
|
30
|
+
|
|
29
31
|
// 切换深色模式过渡
|
|
30
32
|
// https://vitepress.dev/zh/guide/extending-default-theme#on-appearance-toggle
|
|
31
33
|
useDarkTransition()
|
|
@@ -67,7 +69,11 @@ const openTransition = useDarkTransitionConfig()
|
|
|
67
69
|
<div class="blog-list-wrapper">
|
|
68
70
|
<BlogList />
|
|
69
71
|
</div>
|
|
70
|
-
<div
|
|
72
|
+
<div
|
|
73
|
+
:class="{
|
|
74
|
+
'normal-mode': blogInfoCollapsible,
|
|
75
|
+
}" class="blog-info-wrapper"
|
|
76
|
+
>
|
|
71
77
|
<BlogHomeInfo />
|
|
72
78
|
</div>
|
|
73
79
|
</div>
|
|
@@ -108,6 +114,9 @@ const openTransition = useDarkTransitionConfig()
|
|
|
108
114
|
<slot name="nav-screen-content-before" />
|
|
109
115
|
</template>
|
|
110
116
|
<template #nav-screen-content-after>
|
|
117
|
+
<div v-if="blogInfoCollapsible" class="minify-mode blog-info-wrapper">
|
|
118
|
+
<BlogHomeInfo />
|
|
119
|
+
</div>
|
|
111
120
|
<slot name="nav-screen-content-after" />
|
|
112
121
|
</template>
|
|
113
122
|
|
|
@@ -226,6 +235,24 @@ const openTransition = useDarkTransitionConfig()
|
|
|
226
235
|
margin: 20px 0;
|
|
227
236
|
width: 100%;
|
|
228
237
|
}
|
|
238
|
+
|
|
239
|
+
.normal-mode {
|
|
240
|
+
display: none;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.minify-mode {
|
|
244
|
+
display: block;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
@media screen and (min-width: 768px) {
|
|
249
|
+
.minify-mode {
|
|
250
|
+
display: none;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.normal-mode {
|
|
254
|
+
display: block;
|
|
255
|
+
}
|
|
229
256
|
}
|
|
230
257
|
</style>
|
|
231
258
|
|
|
@@ -131,24 +131,25 @@ const timeTitle = computed(() =>
|
|
|
131
131
|
<template>
|
|
132
132
|
<div v-if="showAnalyze && readingTimePosition === 'top'" class="doc-analyze" data-pagefind-ignore="all">
|
|
133
133
|
<span>
|
|
134
|
-
<ElIcon
|
|
134
|
+
<ElIcon>
|
|
135
|
+
<EditPen />
|
|
136
|
+
</ElIcon>
|
|
135
137
|
{{ topWordCount }}
|
|
136
138
|
</span>
|
|
137
139
|
<span>
|
|
138
|
-
<ElIcon
|
|
140
|
+
<ElIcon>
|
|
141
|
+
<AlarmClock />
|
|
142
|
+
</ElIcon>
|
|
139
143
|
{{ topReadTime }}
|
|
140
144
|
</span>
|
|
141
145
|
</div>
|
|
142
146
|
<div id="hack-article-des" ref="$des" class="meta-des">
|
|
143
147
|
<!-- TODO:是否需要原创?转载等标签,理论上可以添加标签解决,可以参考 charles7c -->
|
|
144
148
|
<span v-if="author && !hiddenAuthor" class="author" :title="authorTitle">
|
|
145
|
-
<ElIcon
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
:href="currentAuthorInfo.url"
|
|
150
|
-
:title="currentAuthorInfo.des"
|
|
151
|
-
>
|
|
149
|
+
<ElIcon>
|
|
150
|
+
<UserFilled />
|
|
151
|
+
</ElIcon>
|
|
152
|
+
<a v-if="currentAuthorInfo" class="link" :href="currentAuthorInfo.url" :title="currentAuthorInfo.des">
|
|
152
153
|
{{ currentAuthorInfo.nickname }}
|
|
153
154
|
</a>
|
|
154
155
|
<template v-else>
|
|
@@ -156,36 +157,48 @@ const timeTitle = computed(() =>
|
|
|
156
157
|
</template>
|
|
157
158
|
</span>
|
|
158
159
|
<span v-if="publishDate && !hiddenTime" class="publishDate" :title="timeTitle + hoverDate">
|
|
159
|
-
<ElIcon
|
|
160
|
+
<ElIcon>
|
|
161
|
+
<Clock />
|
|
162
|
+
</ElIcon>
|
|
160
163
|
{{ publishDate }}
|
|
161
164
|
</span>
|
|
162
|
-
<span v-if="tags.length" class="tags" :title="tagTitle">
|
|
163
|
-
<ElIcon><CollectionTag /></ElIcon>
|
|
164
|
-
<a v-for="tag in tags" :key="tag" class="link" :href="`/?tag=${tag}`">{{ tag }}
|
|
165
|
-
</a>
|
|
166
|
-
</span>
|
|
167
165
|
<template v-if="readingTimePosition === 'inline' && showAnalyze">
|
|
168
166
|
<span :title="wordCountTitle">
|
|
169
|
-
<ElIcon
|
|
167
|
+
<ElIcon>
|
|
168
|
+
<EditPen />
|
|
169
|
+
</ElIcon>
|
|
170
170
|
{{ inlineWordCount }}
|
|
171
171
|
</span>
|
|
172
172
|
<span :title="readTimeTitle">
|
|
173
|
-
<ElIcon
|
|
173
|
+
<ElIcon>
|
|
174
|
+
<AlarmClock />
|
|
175
|
+
</ElIcon>
|
|
174
176
|
{{ inlineReadTime }}
|
|
175
177
|
</span>
|
|
176
178
|
</template>
|
|
177
179
|
<template v-if="readingTimePosition === 'newLine' && showAnalyze">
|
|
178
180
|
<div style="width: 100%;" class="new-line-meta-des">
|
|
179
181
|
<span :title="wordCountTitle">
|
|
180
|
-
<ElIcon
|
|
182
|
+
<ElIcon>
|
|
183
|
+
<EditPen />
|
|
184
|
+
</ElIcon>
|
|
181
185
|
{{ inlineWordCount }}
|
|
182
186
|
</span>
|
|
183
187
|
<span :title="readTimeTitle">
|
|
184
|
-
<ElIcon
|
|
188
|
+
<ElIcon>
|
|
189
|
+
<AlarmClock />
|
|
190
|
+
</ElIcon>
|
|
185
191
|
{{ inlineReadTime }}
|
|
186
192
|
</span>
|
|
187
193
|
</div>
|
|
188
194
|
</template>
|
|
195
|
+
<span v-if="tags.length" class="tags" :title="tagTitle">
|
|
196
|
+
<ElIcon>
|
|
197
|
+
<CollectionTag />
|
|
198
|
+
</ElIcon>
|
|
199
|
+
<a v-for="tag in tags" :key="tag" class="link" :href="`/?tag=${tag}`">{{ tag }}
|
|
200
|
+
</a>
|
|
201
|
+
</span>
|
|
189
202
|
<!-- 封面展示 -->
|
|
190
203
|
<ClientOnly>
|
|
191
204
|
<BlogDocCover />
|
|
@@ -200,26 +213,33 @@ const timeTitle = computed(() =>
|
|
|
200
213
|
margin-bottom: 20px;
|
|
201
214
|
display: flex;
|
|
202
215
|
justify-content: center;
|
|
216
|
+
|
|
203
217
|
span {
|
|
204
218
|
margin-right: 16px;
|
|
205
219
|
display: flex;
|
|
206
220
|
align-items: center;
|
|
221
|
+
|
|
207
222
|
.el-icon {
|
|
208
223
|
margin-right: 4px;
|
|
209
224
|
}
|
|
210
225
|
}
|
|
211
226
|
}
|
|
212
|
-
|
|
227
|
+
|
|
228
|
+
.meta-des,
|
|
229
|
+
.new-line-meta-des {
|
|
213
230
|
text-align: left;
|
|
214
231
|
color: var(--vp-c-text-2);
|
|
215
232
|
font-size: 14px;
|
|
216
233
|
margin-top: 6px;
|
|
217
234
|
display: flex;
|
|
218
235
|
flex-wrap: wrap;
|
|
236
|
+
|
|
219
237
|
>span {
|
|
220
238
|
margin-right: 16px;
|
|
221
239
|
display: flex;
|
|
222
240
|
align-items: center;
|
|
241
|
+
flex-wrap: wrap;
|
|
242
|
+
|
|
223
243
|
.el-icon {
|
|
224
244
|
margin-right: 4px;
|
|
225
245
|
}
|
|
@@ -227,12 +247,14 @@ const timeTitle = computed(() =>
|
|
|
227
247
|
|
|
228
248
|
.link {
|
|
229
249
|
color: var(--vp-c-text-2);
|
|
250
|
+
|
|
230
251
|
&:hover {
|
|
231
252
|
color: var(--vp-c-brand-1);
|
|
232
253
|
cursor: pointer;
|
|
233
254
|
}
|
|
234
255
|
}
|
|
235
256
|
}
|
|
257
|
+
|
|
236
258
|
.tags {
|
|
237
259
|
a.link:not(:last-child) {
|
|
238
260
|
&::after {
|
|
@@ -186,6 +186,10 @@ export function useBlogThemeMode() {
|
|
|
186
186
|
return inject(configSymbol)!.value?.blog?.blog ?? true
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
+
export function useBlogInfoCollapsible() {
|
|
190
|
+
return inject(configSymbol)!.value?.blog?.home?.blogInfoCollapsible ?? false
|
|
191
|
+
}
|
|
192
|
+
|
|
189
193
|
export function useArticles() {
|
|
190
194
|
const blogConfig = useConfig()
|
|
191
195
|
const { localeIndex, site } = useData()
|
|
@@ -357,7 +361,7 @@ export function useHomeAnalysis() {
|
|
|
357
361
|
}
|
|
358
362
|
|
|
359
363
|
export function useAnalyzeTitles(wordCount: Ref<number>, readTime: ComputedRef<number>) {
|
|
360
|
-
const article =
|
|
364
|
+
const article = useArticleConfig()
|
|
361
365
|
|
|
362
366
|
const topWordCount = computed(() =>
|
|
363
367
|
replaceValue(article.value?.analyzeTitles?.topWordCount || '字数:{{value}} 个字', wordCount.value)
|
|
@@ -186,6 +186,11 @@ export namespace Theme {
|
|
|
186
186
|
* 首页数据分析卡片
|
|
187
187
|
*/
|
|
188
188
|
analysis?: HomeAnalysis
|
|
189
|
+
/**
|
|
190
|
+
* 首页博客信息卡片是否在移动端折叠展示
|
|
191
|
+
* @default false
|
|
192
|
+
*/
|
|
193
|
+
blogInfoCollapsible?: boolean
|
|
189
194
|
}
|
|
190
195
|
|
|
191
196
|
export interface ArticleConfig {
|
|
@@ -403,7 +408,7 @@ export namespace Theme {
|
|
|
403
408
|
works?: UserWorks
|
|
404
409
|
/**
|
|
405
410
|
* https://mermaid.js.org/config/setup/modules/mermaidAPI.html#mermaidapi-configuration-defaults for options
|
|
406
|
-
* @default
|
|
411
|
+
* @default false
|
|
407
412
|
*/
|
|
408
413
|
mermaid?: any
|
|
409
414
|
/**
|
package/src/node.ts
CHANGED
|
@@ -25,13 +25,13 @@ export function getThemeConfig(cfg: Partial<Theme.BlogConfig> = {}) {
|
|
|
25
25
|
const extraVPConfig: any = {
|
|
26
26
|
vite: {
|
|
27
27
|
// see https://sass-lang.com/documentation/breaking-changes/legacy-js-api/
|
|
28
|
-
css: {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
},
|
|
28
|
+
// css: {
|
|
29
|
+
// preprocessorOptions: {
|
|
30
|
+
// scss: {
|
|
31
|
+
// api: 'modern',
|
|
32
|
+
// },
|
|
33
|
+
// },
|
|
34
|
+
// },
|
|
35
35
|
build: {
|
|
36
36
|
// https://vite.dev/config/build-options.html#build-chunksizewarninglimit
|
|
37
37
|
chunkSizeWarningLimit: 2048
|
package/src/utils/node/theme.ts
CHANGED
|
@@ -26,9 +26,12 @@ export function getPageRoute(filepath: string, srcDir: string) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const defaultTimeZoneOffset = new Date().getTimezoneOffset() / -60
|
|
29
|
-
export async function getArticleMeta(filepath: string, route: string, timeZone = defaultTimeZoneOffset,
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
export async function getArticleMeta(filepath: string, route: string, timeZone = defaultTimeZoneOffset, ops?: {
|
|
30
|
+
baseContent?: string
|
|
31
|
+
cacheDir?: string
|
|
32
|
+
}) {
|
|
33
|
+
const fileContent = ops?.baseContent || await fs.promises.readFile(filepath, 'utf-8')
|
|
34
|
+
const cacheDir = ops?.cacheDir
|
|
32
35
|
const { data: frontmatter, excerpt, content } = grayMatter(fileContent, {
|
|
33
36
|
excerpt: true,
|
|
34
37
|
})
|
|
@@ -44,7 +47,7 @@ export async function getArticleMeta(filepath: string, route: string, timeZone =
|
|
|
44
47
|
const date = await (
|
|
45
48
|
(meta.date
|
|
46
49
|
&& new Date(`${new Date(meta.date).toUTCString()}${utcValue}`))
|
|
47
|
-
|| getFileLastModifyTime(filepath)
|
|
50
|
+
|| getFileLastModifyTime(filepath, cacheDir)
|
|
48
51
|
)
|
|
49
52
|
// 无法获取时兜底当前时间
|
|
50
53
|
meta.date = formatDate(date || new Date(), 'yyyy/MM/dd hh:mm:ss')
|
|
@@ -86,8 +89,13 @@ export async function getArticles(cfg: Partial<Theme.BlogConfig>, vpConfig: Site
|
|
|
86
89
|
const { page, route, originRoute, filepath, isDynamic, dynamicRoute } = value
|
|
87
90
|
|
|
88
91
|
const metaPromise = (isDynamic && dynamicRoute)
|
|
89
|
-
? getArticleMeta(filepath, originRoute, cfg?.timeZone,
|
|
90
|
-
|
|
92
|
+
? getArticleMeta(filepath, originRoute, cfg?.timeZone, {
|
|
93
|
+
baseContent: renderDynamicMarkdown(filepath, dynamicRoute.params, dynamicRoute.content),
|
|
94
|
+
cacheDir: vpConfig.cacheDir
|
|
95
|
+
})
|
|
96
|
+
: getArticleMeta(filepath, originRoute, cfg?.timeZone, {
|
|
97
|
+
cacheDir: vpConfig.cacheDir
|
|
98
|
+
})
|
|
91
99
|
|
|
92
100
|
// 提前获取,有缓存取缓存
|
|
93
101
|
prev[page] = {
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from 'vitepress-plugin-pagefind'
|
|
5
5
|
import { RssPlugin } from 'vitepress-plugin-rss'
|
|
6
6
|
import type { PluginOption } from 'vite'
|
|
7
|
-
import { joinPath } from '@sugarat/theme-shared'
|
|
7
|
+
import { cacheAllGitTimestamps, joinPath } from '@sugarat/theme-shared'
|
|
8
8
|
import { AnnouncementPlugin } from 'vitepress-plugin-announcement'
|
|
9
9
|
import { groupIconVitePlugin } from 'vitepress-plugin-group-icons'
|
|
10
10
|
import type { Theme } from '../../composables/config/index'
|
|
@@ -15,6 +15,9 @@ import { getArticles } from './theme'
|
|
|
15
15
|
export function getVitePlugins(cfg: Partial<Theme.BlogConfig> = {}) {
|
|
16
16
|
const plugins: any[] = []
|
|
17
17
|
|
|
18
|
+
// 缓存所有文章的 git 提交时间
|
|
19
|
+
plugins.push(cacheAllGitTimestampsPlugin())
|
|
20
|
+
|
|
18
21
|
// 处理 cover image 的路径(暂只支持自动识别的文章首图)
|
|
19
22
|
plugins.push(coverImgTransform())
|
|
20
23
|
|
|
@@ -266,6 +269,16 @@ export function providePageData(cfg: Partial<Theme.BlogConfig>) {
|
|
|
266
269
|
} as PluginOption
|
|
267
270
|
}
|
|
268
271
|
|
|
272
|
+
export function cacheAllGitTimestampsPlugin() {
|
|
273
|
+
return {
|
|
274
|
+
name: '@sugarat/theme-plugin-cache-all-git-timestamps',
|
|
275
|
+
async config(config: any) {
|
|
276
|
+
const { srcDir } = config.vitepress
|
|
277
|
+
await cacheAllGitTimestamps(srcDir)
|
|
278
|
+
},
|
|
279
|
+
} as PluginOption
|
|
280
|
+
}
|
|
281
|
+
|
|
269
282
|
export function setThemeScript(
|
|
270
283
|
themeColor: Theme.ThemeColor
|
|
271
284
|
) {
|