clarity-theme 0.1.0

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.
Files changed (151) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +276 -0
  3. package/README.zh-CN.md +297 -0
  4. package/app/app.config.ts +110 -0
  5. package/app/app.vue +5 -0
  6. package/app/assets/css/_variable.scss +8 -0
  7. package/app/assets/css/animation.scss +50 -0
  8. package/app/assets/css/article.scss +152 -0
  9. package/app/assets/css/color.scss +58 -0
  10. package/app/assets/css/font.scss +35 -0
  11. package/app/assets/css/main.scss +230 -0
  12. package/app/assets/css/reusable.scss +186 -0
  13. package/app/assets/icons/solar-rewind-back-bold-duotone.svg +1 -0
  14. package/app/assets/icons/solar-rewind-forward-bold-duotone.svg +1 -0
  15. package/app/components/blog/BlogAside.vue +63 -0
  16. package/app/components/blog/BlogFooter.vue +61 -0
  17. package/app/components/blog/BlogHeader.global.vue +146 -0
  18. package/app/components/blog/BlogPanel.vue +79 -0
  19. package/app/components/blog/BlogSidebar.vue +160 -0
  20. package/app/components/blog/BlogWidget.vue +134 -0
  21. package/app/components/blog/Mask.vue +42 -0
  22. package/app/components/blog/SkipToContent.vue +22 -0
  23. package/app/components/blog/ThemeToggle.vue +50 -0
  24. package/app/components/content/Alert.vue +96 -0
  25. package/app/components/content/Badge.vue +90 -0
  26. package/app/components/content/Blur.vue +22 -0
  27. package/app/components/content/CardList.vue +32 -0
  28. package/app/components/content/Chat.vue +79 -0
  29. package/app/components/content/Copy.vue +134 -0
  30. package/app/components/content/EmojiClock.vue +53 -0
  31. package/app/components/content/FeedCard.vue +212 -0
  32. package/app/components/content/FeedGroup.vue +130 -0
  33. package/app/components/content/Folding.vue +69 -0
  34. package/app/components/content/Key.vue +164 -0
  35. package/app/components/content/LinkBanner.vue +59 -0
  36. package/app/components/content/LinkCard.vue +74 -0
  37. package/app/components/content/MdTitle.vue +26 -0
  38. package/app/components/content/Mermaid.vue +133 -0
  39. package/app/components/content/MusicScore.vue +178 -0
  40. package/app/components/content/Pic.vue +55 -0
  41. package/app/components/content/Poetry.vue +41 -0
  42. package/app/components/content/ProseA.vue +40 -0
  43. package/app/components/content/ProseCode.vue +95 -0
  44. package/app/components/content/ProsePre.vue +291 -0
  45. package/app/components/content/ProseTable.vue +70 -0
  46. package/app/components/content/Quote.vue +51 -0
  47. package/app/components/content/Tab.vue +100 -0
  48. package/app/components/content/Timeline.vue +73 -0
  49. package/app/components/content/Tip.vue +52 -0
  50. package/app/components/content/VideoEmbed.vue +127 -0
  51. package/app/components/partial/Button.vue +98 -0
  52. package/app/components/partial/DlGroup.vue +69 -0
  53. package/app/components/partial/Dropdown.vue +54 -0
  54. package/app/components/partial/Error.vue +70 -0
  55. package/app/components/partial/Expand.vue +51 -0
  56. package/app/components/partial/IconNavList.vue +42 -0
  57. package/app/components/partial/Pagination.vue +113 -0
  58. package/app/components/partial/RadioGroup.vue +77 -0
  59. package/app/components/partial/Secret.vue +23 -0
  60. package/app/components/partial/Slider.vue +96 -0
  61. package/app/components/partial/Toggle.vue +70 -0
  62. package/app/components/popover/Lightbox.vue +77 -0
  63. package/app/components/popover/Search.vue +214 -0
  64. package/app/components/popover/SearchItem.vue +64 -0
  65. package/app/components/post/Archive.vue +104 -0
  66. package/app/components/post/Article.vue +138 -0
  67. package/app/components/post/Comment.vue +275 -0
  68. package/app/components/post/Excerpt.vue +66 -0
  69. package/app/components/post/OrderToggle.vue +101 -0
  70. package/app/components/post/PostFooter.vue +80 -0
  71. package/app/components/post/PostHeader.vue +147 -0
  72. package/app/components/post/PostSurround.vue +111 -0
  73. package/app/components/post/Slide.vue +215 -0
  74. package/app/components/util/Date.vue +62 -0
  75. package/app/components/util/HydrateSafe.vue +10 -0
  76. package/app/components/util/Img.vue +38 -0
  77. package/app/components/util/Link.vue +11 -0
  78. package/app/components/widget/BlogLog.vue +27 -0
  79. package/app/components/widget/BlogStats.vue +39 -0
  80. package/app/components/widget/BlogTech.vue +65 -0
  81. package/app/components/widget/Empty.vue +3 -0
  82. package/app/components/widget/Toc.vue +129 -0
  83. package/app/composables/useArticle.ts +118 -0
  84. package/app/composables/useAvoid.ts +87 -0
  85. package/app/composables/useCopy.ts +21 -0
  86. package/app/composables/usePagination.ts +70 -0
  87. package/app/composables/useShiki.ts +129 -0
  88. package/app/composables/useToc.ts +57 -0
  89. package/app/composables/useWidgets.ts +56 -0
  90. package/app/error.vue +34 -0
  91. package/app/layouts/default.vue +66 -0
  92. package/app/pages/[...slug].vue +59 -0
  93. package/app/pages/archive.vue +207 -0
  94. package/app/pages/index.vue +83 -0
  95. package/app/pages/link.vue +65 -0
  96. package/app/pages/preview.vue +59 -0
  97. package/app/plugins/easter-egg.ts +23 -0
  98. package/app/plugins/init.ts +6 -0
  99. package/app/plugins/tippy.ts +22 -0
  100. package/app/shiki.config.ts +8 -0
  101. package/app/stores/layout.ts +34 -0
  102. package/app/stores/search.ts +37 -0
  103. package/app/types/article.ts +16 -0
  104. package/app/types/feed.ts +1 -0
  105. package/app/types/index.ts +14 -0
  106. package/app/types/modal.ts +16 -0
  107. package/app/types/nav.ts +11 -0
  108. package/app/utils/anim.ts +37 -0
  109. package/app/utils/img.ts +83 -0
  110. package/config/app.ts +88 -0
  111. package/config/content.d.mts +1 -0
  112. package/config/content.mjs +69 -0
  113. package/config/content.ts +91 -0
  114. package/config/define.mjs +21 -0
  115. package/config/define.ts +23 -0
  116. package/config/feed.ts +42 -0
  117. package/config/feeds.empty.ts +4 -0
  118. package/config/index.d.mts +1 -0
  119. package/config/index.mjs +6 -0
  120. package/config/index.ts +6 -0
  121. package/config/public.ts +71 -0
  122. package/config/schema.d.mts +1 -0
  123. package/config/schema.mjs +103 -0
  124. package/config/schema.ts +129 -0
  125. package/config/server.ts +35 -0
  126. package/img/index.d.mts +1 -0
  127. package/img/index.mjs +78 -0
  128. package/img/index.ts +8 -0
  129. package/modules/clarity-config/anti-mirror-client.ts +11 -0
  130. package/modules/clarity-config/index.ts +324 -0
  131. package/nuxt.config.ts +225 -0
  132. package/package.json +148 -0
  133. package/public/assets/atom.css +274 -0
  134. package/public/assets/atom.xsl +110 -0
  135. package/public/fonts/AlimamaFangYuanTi.woff2 +0 -0
  136. package/remark-plugins/rehype-meta-slots.d.mts +1 -0
  137. package/remark-plugins/rehype-meta-slots.mjs +49 -0
  138. package/remark-plugins/rehype-meta-slots.ts +58 -0
  139. package/remark-plugins/remark-code-component.d.mts +1 -0
  140. package/remark-plugins/remark-code-component.mjs +25 -0
  141. package/remark-plugins/remark-code-component.ts +41 -0
  142. package/server/api/stats.get.ts +109 -0
  143. package/server/routes/atom.xml.get.ts +101 -0
  144. package/server/routes/subscriptions.opml.get.ts +70 -0
  145. package/server/utils/clarity.ts +11 -0
  146. package/shared/types/content.ts +30 -0
  147. package/shared/utils/clarity.ts +34 -0
  148. package/shared/utils/icon.ts +218 -0
  149. package/shared/utils/link.ts +52 -0
  150. package/shared/utils/str.ts +88 -0
  151. package/shared/utils/time.ts +116 -0
@@ -0,0 +1,116 @@
1
+ import { Temporal } from 'temporal-polyfill'
2
+
3
+ export function isSameUnit(date1: string, date2: string, unit: 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second', timeZone = 'UTC') {
4
+ try {
5
+ const p1 = toZonedTemporal(date1, timeZone).toPlainDateTime()
6
+ const p2 = toZonedTemporal(date2, timeZone).toPlainDateTime()
7
+ return p1.until(p2, {
8
+ largestUnit: unit,
9
+ smallestUnit: unit,
10
+ roundingMode: 'trunc',
11
+ }).blank
12
+ }
13
+ catch {
14
+ return false
15
+ }
16
+ }
17
+
18
+ /** 检查两个时间相对现在是否相差显著 */
19
+ export function isTimeDiffSignificant(
20
+ date1?: string,
21
+ date2?: string,
22
+ timeZone = 'UTC',
23
+ /** 对于时间差的敏感程度,0~1 之间,1:不同则认为显著,>1:始终认为显著 */
24
+ threshold = 0.6,
25
+ ) {
26
+ if (!date1 || !date2 || threshold <= 0)
27
+ return false
28
+ if (threshold > 1)
29
+ return true
30
+ try {
31
+ const now = Temporal.Now.instant().epochMilliseconds
32
+ const diff1 = now - toZonedTemporal(date1, timeZone).epochMilliseconds
33
+ const diff2 = now - toZonedTemporal(date2, timeZone).epochMilliseconds
34
+ return diff1 / diff2 < threshold || diff2 / diff1 < threshold
35
+ }
36
+ catch {
37
+ return true
38
+ }
39
+ }
40
+
41
+ const timeIntervals = [
42
+ { label: '世纪', threshold: 60 * 60 * 24 * 365.2422 * 100 },
43
+ { label: '年', threshold: 60 * 60 * 24 * 365.2422 },
44
+ { label: '个月', threshold: 60 * 60 * 24 * 30.44 },
45
+ { label: '天', threshold: 60 * 60 * 24 },
46
+ { label: '小时', threshold: 60 * 60 },
47
+ { label: '分', threshold: 60 },
48
+ { label: '秒', threshold: 1 },
49
+ ]
50
+
51
+ export function timeElapse(date: string | Temporal.PlainDateTime, maxDepth = 2) {
52
+ let timeString = ''
53
+ let secRemained = Temporal.Now.plainDateTimeISO().since(date, { largestUnit: 'second' }).seconds
54
+ for (const interval of timeIntervals) {
55
+ const count = Math.floor(secRemained / interval.threshold)
56
+ if (count <= 0)
57
+ continue
58
+ timeString += `${count}${interval.label}`
59
+ secRemained -= count * interval.threshold
60
+ if (--maxDepth <= 0)
61
+ break
62
+ }
63
+ return timeString || '刚刚'
64
+ }
65
+
66
+ export function toInstantString(date: string | Temporal.ZonedDateTime, timeZone = 'UTC') {
67
+ return (typeof date === 'string' ? toZonedTemporal(date, timeZone) : date).toInstant().toString()
68
+ }
69
+
70
+ /**
71
+ * 将日期字符串解析为带时区的 Temporal 对象
72
+ * @param date 日期字符串
73
+ * @param timeZone 无时区信息时使用的默认时区(来自站点配置)
74
+ */
75
+ export function toZonedTemporal(date: string, timeZone = 'UTC') {
76
+ try {
77
+ return Temporal.ZonedDateTime.from(date)
78
+ }
79
+ catch {
80
+ try {
81
+ return Temporal.Instant.from(date).toZonedDateTimeISO(timeZone)
82
+ }
83
+ catch {
84
+ return Temporal.PlainDateTime.from(date).toZonedDateTime(timeZone)
85
+ }
86
+ }
87
+ }
88
+
89
+ export const dateTimeFormat = {
90
+ date: {
91
+ year: 'numeric',
92
+ month: '2-digit',
93
+ day: '2-digit',
94
+ },
95
+ monthDay: {
96
+ month: '2-digit',
97
+ day: '2-digit',
98
+ },
99
+ full: {
100
+ year: 'numeric',
101
+ month: '2-digit',
102
+ day: '2-digit',
103
+ weekday: 'long',
104
+ hour: '2-digit',
105
+ minute: '2-digit',
106
+ second: '2-digit',
107
+ timeZoneName: 'long',
108
+ },
109
+ } satisfies Record<string, Intl.DateTimeFormatOptions>
110
+
111
+ export type dateTimeFormatOptions = keyof typeof dateTimeFormat | Intl.DateTimeFormatOptions
112
+
113
+ export function toZdtLocaleString(date: string | Temporal.ZonedDateTime, format: dateTimeFormatOptions = 'full', timeZone = 'UTC') {
114
+ return (typeof date === 'string' ? toZonedTemporal(date, timeZone) : date)
115
+ .toLocaleString(undefined, typeof format === 'string' ? dateTimeFormat[format] : format)
116
+ }