@sugarat/theme 0.2.23 → 0.2.25
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
CHANGED
|
@@ -61,7 +61,7 @@ declare namespace Theme {
|
|
|
61
61
|
/**
|
|
62
62
|
* 手动控制相关文章列表的顺序
|
|
63
63
|
*/
|
|
64
|
-
recommend?: number | false;
|
|
64
|
+
recommend?: number | false | string | string[] | [...string[], number];
|
|
65
65
|
/**
|
|
66
66
|
* TODO: 待开发
|
|
67
67
|
* 时间线
|
|
@@ -168,6 +168,11 @@ declare namespace Theme {
|
|
|
168
168
|
}
|
|
169
169
|
interface ArticleConfig {
|
|
170
170
|
readingTime?: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* 阅读时间分析展示位置
|
|
173
|
+
* @default 'inline'
|
|
174
|
+
*/
|
|
175
|
+
readingTimePosition?: 'inline' | 'newLine' | 'top';
|
|
171
176
|
hiddenCover?: boolean;
|
|
172
177
|
}
|
|
173
178
|
interface Alert {
|
|
@@ -403,7 +408,7 @@ declare namespace Theme {
|
|
|
403
408
|
type RSSOptions = RSSPluginOptions;
|
|
404
409
|
interface Footer {
|
|
405
410
|
/**
|
|
406
|
-
*
|
|
411
|
+
* 自定义补充信息(支持配置为HTML)
|
|
407
412
|
*/
|
|
408
413
|
message?: string | string[];
|
|
409
414
|
/**
|
package/node.js
CHANGED
|
@@ -39,7 +39,7 @@ module.exports = __toCommonJS(node_exports);
|
|
|
39
39
|
// src/utils/node/mdPlugins.ts
|
|
40
40
|
var import_module = require("module");
|
|
41
41
|
|
|
42
|
-
// ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@1.0.0-rc.
|
|
42
|
+
// ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@1.0.0-rc.45_vue@3.4.21/node_modules/vitepress-plugin-tabs/dist/index.js
|
|
43
43
|
var tabsMarker = "=tabs";
|
|
44
44
|
var tabsMarkerLen = tabsMarker.length;
|
|
45
45
|
var ruleBlockTabs = (state, startLine, endLine, silent) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sugarat/theme",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.25",
|
|
4
4
|
"description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
|
|
5
5
|
"author": "sugar",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"swiper": "^11.0.5",
|
|
46
46
|
"vitepress-markdown-timeline": "^1.2.1",
|
|
47
47
|
"vitepress-plugin-mermaid": "2.0.13",
|
|
48
|
-
"vitepress-plugin-pagefind": "0.2.
|
|
48
|
+
"vitepress-plugin-pagefind": "0.2.13",
|
|
49
49
|
"vitepress-plugin-rss": "0.2.2",
|
|
50
50
|
"vitepress-plugin-tabs": "0.2.0"
|
|
51
51
|
},
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"pagefind": "1.0.3",
|
|
57
57
|
"sass": "^1.56.1",
|
|
58
58
|
"typescript": "^4.8.2",
|
|
59
|
-
"vitepress": "1.0.0-rc.
|
|
60
|
-
"vue": "^3.
|
|
59
|
+
"vitepress": "1.0.0-rc.45",
|
|
60
|
+
"vue": "^3.4.21"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"dev": "npm run build:node && npm run dev:docs",
|
|
@@ -17,6 +17,8 @@ import type { Theme } from '../composables/config'
|
|
|
17
17
|
import BlogDocCover from './BlogDocCover.vue'
|
|
18
18
|
|
|
19
19
|
const { article, authorList } = useBlogConfig()
|
|
20
|
+
const readingTimePosition = article?.readingTimePosition || 'inline'
|
|
21
|
+
|
|
20
22
|
const { frontmatter } = useData()
|
|
21
23
|
const tags = computed(() => {
|
|
22
24
|
const { tag, tags, categories } = frontmatter.value
|
|
@@ -136,7 +138,7 @@ watch(
|
|
|
136
138
|
</script>
|
|
137
139
|
|
|
138
140
|
<template>
|
|
139
|
-
<div v-if="showAnalyze" class="doc-analyze" data-pagefind-ignore="all">
|
|
141
|
+
<div v-if="showAnalyze && readingTimePosition === 'top'" class="doc-analyze" data-pagefind-ignore="all">
|
|
140
142
|
<span>
|
|
141
143
|
<ElIcon><EditPen /></ElIcon>
|
|
142
144
|
字数:{{ wordCount }} 个字
|
|
@@ -148,8 +150,8 @@ watch(
|
|
|
148
150
|
</div>
|
|
149
151
|
<div id="hack-article-des" ref="$des" class="meta-des">
|
|
150
152
|
<!-- TODO:是否需要原创?转载等标签,理论上可以添加标签解决,可以参考 charles7c -->
|
|
151
|
-
<span v-if="author && !hiddenAuthor" class="author">
|
|
152
|
-
<ElIcon
|
|
153
|
+
<span v-if="author && !hiddenAuthor" class="author" title="本文作者">
|
|
154
|
+
<ElIcon><UserFilled /></ElIcon>
|
|
153
155
|
<a
|
|
154
156
|
v-if="currentAuthorInfo"
|
|
155
157
|
class="link"
|
|
@@ -162,15 +164,37 @@ watch(
|
|
|
162
164
|
{{ author }}
|
|
163
165
|
</template>
|
|
164
166
|
</span>
|
|
165
|
-
<span v-if="publishDate && !hiddenTime" class="publishDate">
|
|
166
|
-
<ElIcon
|
|
167
|
+
<span v-if="publishDate && !hiddenTime" class="publishDate" :title="timeTitle">
|
|
168
|
+
<ElIcon><Clock /></ElIcon>
|
|
167
169
|
{{ publishDate }}
|
|
168
170
|
</span>
|
|
169
|
-
<span v-if="tags.length" class="tags">
|
|
170
|
-
<ElIcon
|
|
171
|
+
<span v-if="tags.length" class="tags" title="标签">
|
|
172
|
+
<ElIcon><CollectionTag /></ElIcon>
|
|
171
173
|
<a v-for="tag in tags" :key="tag" class="link" :href="`/?tag=${tag}`">{{ tag }}
|
|
172
174
|
</a>
|
|
173
175
|
</span>
|
|
176
|
+
<template v-if="readingTimePosition === 'inline' && showAnalyze">
|
|
177
|
+
<span title="文章字数">
|
|
178
|
+
<ElIcon><EditPen /></ElIcon>
|
|
179
|
+
{{ wordCount }} 个字
|
|
180
|
+
</span>
|
|
181
|
+
<span title="预计阅读时间">
|
|
182
|
+
<ElIcon><AlarmClock /></ElIcon>
|
|
183
|
+
{{ readTime }} 分钟
|
|
184
|
+
</span>
|
|
185
|
+
</template>
|
|
186
|
+
<template v-if="readingTimePosition === 'newLine' && showAnalyze">
|
|
187
|
+
<div style="width: 100%;" class="new-line-meta-des">
|
|
188
|
+
<span title="文章字数">
|
|
189
|
+
<ElIcon><EditPen /></ElIcon>
|
|
190
|
+
{{ wordCount }} 个字
|
|
191
|
+
</span>
|
|
192
|
+
<span title="预计阅读时间">
|
|
193
|
+
<ElIcon><AlarmClock /></ElIcon>
|
|
194
|
+
{{ readTime }} 分钟
|
|
195
|
+
</span>
|
|
196
|
+
</div>
|
|
197
|
+
</template>
|
|
174
198
|
<!-- 封面展示 -->
|
|
175
199
|
<ClientOnly>
|
|
176
200
|
<BlogDocCover />
|
|
@@ -194,14 +218,14 @@ watch(
|
|
|
194
218
|
}
|
|
195
219
|
}
|
|
196
220
|
}
|
|
197
|
-
.meta-des {
|
|
221
|
+
.meta-des,.new-line-meta-des {
|
|
198
222
|
text-align: left;
|
|
199
223
|
color: var(--vp-c-text-2);
|
|
200
224
|
font-size: 14px;
|
|
201
225
|
margin-top: 6px;
|
|
202
226
|
display: flex;
|
|
203
227
|
flex-wrap: wrap;
|
|
204
|
-
span {
|
|
228
|
+
>span {
|
|
205
229
|
margin-right: 16px;
|
|
206
230
|
display: flex;
|
|
207
231
|
align-items: center;
|
|
@@ -5,6 +5,7 @@ import { ElButton, ElLink } from 'element-plus'
|
|
|
5
5
|
import { formatShowDate } from '../utils/client'
|
|
6
6
|
import { useArticles, useBlogConfig } from '../composables/config/blog'
|
|
7
7
|
import { recommendSVG } from '../constants/svg'
|
|
8
|
+
import type { Theme } from '../composables/config/index'
|
|
8
9
|
|
|
9
10
|
const { recommend: _recommend } = useBlogConfig()
|
|
10
11
|
|
|
@@ -27,18 +28,47 @@ const docs = useArticles()
|
|
|
27
28
|
|
|
28
29
|
const route = useRoute()
|
|
29
30
|
|
|
31
|
+
function getRecommendCategory(page?: Theme.PageData): string[] {
|
|
32
|
+
if (!page)
|
|
33
|
+
return []
|
|
34
|
+
const { meta } = page
|
|
35
|
+
if (Array.isArray(meta.recommend)) {
|
|
36
|
+
return meta.recommend.filter(v => typeof v === 'string') as string[]
|
|
37
|
+
}
|
|
38
|
+
if (typeof meta.recommend === 'string') {
|
|
39
|
+
return [meta.recommend]
|
|
40
|
+
}
|
|
41
|
+
return []
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getRecommendValue(page?: Theme.PageData) {
|
|
45
|
+
return Array.isArray(page?.meta?.recommend) ? page.meta.recommend[page.meta.recommend.length - 1] : page?.meta.recommend
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function hasIntersection(arr1: any[], arr2: any[]) {
|
|
49
|
+
return arr1.some(item => arr2.includes(item))
|
|
50
|
+
}
|
|
51
|
+
|
|
30
52
|
const recommendList = computed(() => {
|
|
31
53
|
// 中文支持
|
|
32
54
|
const paths = decodeURIComponent(route.path).split('/')
|
|
33
|
-
|
|
55
|
+
const currentPage = docs.value.find(v => isCurrentDoc(v.route))
|
|
56
|
+
const currentRecommendCategory = getRecommendCategory(currentPage)
|
|
34
57
|
const origin = docs.value
|
|
35
58
|
.map(v => ({ ...v, route: withBase(v.route) }))
|
|
36
|
-
// 过滤出公共路由前缀
|
|
37
|
-
// 限制为同路由前缀
|
|
38
59
|
.filter(
|
|
39
|
-
v =>
|
|
40
|
-
|
|
60
|
+
(v) => {
|
|
61
|
+
// 筛选出类别有交集的
|
|
62
|
+
if (currentRecommendCategory.length) {
|
|
63
|
+
return hasIntersection(currentRecommendCategory, getRecommendCategory(v))
|
|
64
|
+
}
|
|
65
|
+
// 如果没有自定义归类则保持原逻辑
|
|
66
|
+
// 过滤出公共路由前缀
|
|
67
|
+
// 限制为同路由前缀
|
|
68
|
+
return v.route.split('/').length === paths.length
|
|
41
69
|
&& v.route.startsWith(paths.slice(0, paths.length - 1).join('/'))
|
|
70
|
+
}
|
|
71
|
+
|
|
42
72
|
)
|
|
43
73
|
// 过滤出带标题的
|
|
44
74
|
.filter(v => !!v.meta.title)
|
|
@@ -50,12 +80,16 @@ const recommendList = computed(() => {
|
|
|
50
80
|
)
|
|
51
81
|
// 过滤掉不需要展示的
|
|
52
82
|
.filter(v => v.meta.recommend !== false)
|
|
83
|
+
// 自定义过滤
|
|
53
84
|
.filter(v => recommend.value?.filter?.(v) ?? true)
|
|
54
85
|
|
|
55
|
-
const topList = origin.filter(v =>
|
|
56
|
-
|
|
86
|
+
const topList = origin.filter((v) => {
|
|
87
|
+
const value = getRecommendValue(v)
|
|
88
|
+
return typeof value === 'number'
|
|
89
|
+
})
|
|
90
|
+
topList.sort((a, b) => Number(getRecommendValue(a)) - Number(getRecommendValue(b)))
|
|
57
91
|
|
|
58
|
-
const normalList = origin.filter(v =>
|
|
92
|
+
const normalList = origin.filter(v => typeof getRecommendValue(v) !== 'number')
|
|
59
93
|
|
|
60
94
|
// 排序
|
|
61
95
|
const sortMode = recommend.value?.sort ?? 'date'
|
|
@@ -104,19 +138,12 @@ const showChangeBtn = computed(() => {
|
|
|
104
138
|
})
|
|
105
139
|
|
|
106
140
|
onMounted(() => {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// TODO:存在理论闪烁情况,未来优化
|
|
117
|
-
setTimeout(checkHaveActive)
|
|
118
|
-
}
|
|
119
|
-
checkHaveActive()
|
|
141
|
+
// 更新当前页,确保访问页面在列表中
|
|
142
|
+
const currentPageIndex = recommendList.value.findIndex(v => isCurrentDoc(v.route))
|
|
143
|
+
if (currentPageIndex === -1)
|
|
144
|
+
return
|
|
145
|
+
const currentPageNum = Math.floor(currentPageIndex / pageSize.value) + 1
|
|
146
|
+
currentPage.value = currentPageNum
|
|
120
147
|
})
|
|
121
148
|
</script>
|
|
122
149
|
|
|
@@ -66,7 +66,7 @@ export namespace Theme {
|
|
|
66
66
|
/**
|
|
67
67
|
* 手动控制相关文章列表的顺序
|
|
68
68
|
*/
|
|
69
|
-
recommend?: number | false
|
|
69
|
+
recommend?: number | false | string | string[] | [...string[], number]
|
|
70
70
|
/**
|
|
71
71
|
* TODO: 待开发
|
|
72
72
|
* 时间线
|
|
@@ -178,6 +178,11 @@ export namespace Theme {
|
|
|
178
178
|
|
|
179
179
|
export interface ArticleConfig {
|
|
180
180
|
readingTime?: boolean
|
|
181
|
+
/**
|
|
182
|
+
* 阅读时间分析展示位置
|
|
183
|
+
* @default 'inline'
|
|
184
|
+
*/
|
|
185
|
+
readingTimePosition?: 'inline' | 'newLine' | 'top'
|
|
181
186
|
hiddenCover?: boolean
|
|
182
187
|
}
|
|
183
188
|
export interface Alert {
|
|
@@ -440,7 +445,7 @@ export namespace Theme {
|
|
|
440
445
|
|
|
441
446
|
export interface Footer {
|
|
442
447
|
/**
|
|
443
|
-
*
|
|
448
|
+
* 自定义补充信息(支持配置为HTML)
|
|
444
449
|
*/
|
|
445
450
|
message?: string | string[]
|
|
446
451
|
/**
|