@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.43_vue@3.3.4/node_modules/vitepress-plugin-tabs/dist/index.js
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.23",
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.12",
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.43",
60
- "vue": "^3.3.4"
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 title="本文作者"><UserFilled /></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 :title="timeTitle"><Clock /></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 :title="timeTitle"><CollectionTag /></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
- v.route.split('/').length === paths.length
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 => v.meta?.recommend)
56
- topList.sort((a, b) => Number(a.meta.recommend) - Number(b.meta.recommend))
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 => !v.meta?.recommend)
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
- const checkHaveActive = () => {
108
- const have = currentWikiData.value.some(v => isCurrentDoc(v.route))
109
- if (have) {
110
- return
111
- }
112
- if (currentPage.value >= changePage()) {
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
  /**