@tnotesjs/core 0.0.6 → 0.0.8

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 (116) hide show
  1. package/README.md +87 -84
  2. package/dist/{chunk-JDVN2QYW.js → chunk-JUMVJKWV.js} +615 -614
  3. package/dist/cli/index.js +125 -125
  4. package/dist/vitepress/config/index.js +184 -210
  5. package/package.json +15 -3
  6. package/types/config.ts +61 -61
  7. package/types/index.ts +11 -11
  8. package/types/note.ts +33 -33
  9. package/types/shims.d.ts +3 -4
  10. package/vitepress/assets/icons/icon__check.svg +3 -3
  11. package/vitepress/assets/icons/icon__clipboard.svg +7 -7
  12. package/vitepress/assets/icons/icon__close.svg +1 -1
  13. package/vitepress/assets/icons/icon__collapse.svg +1 -1
  14. package/vitepress/assets/icons/icon__confirm.svg +1 -1
  15. package/vitepress/assets/icons/icon__copy.svg +4 -4
  16. package/vitepress/assets/icons/icon__focus.svg +1 -1
  17. package/vitepress/assets/icons/icon__fold.svg +3 -3
  18. package/vitepress/assets/icons/icon__folder.svg +1 -1
  19. package/vitepress/assets/icons/icon__fullscreen.svg +1 -1
  20. package/vitepress/assets/icons/icon__fullscreen_exit.svg +1 -1
  21. package/vitepress/assets/icons/icon__github.svg +3 -3
  22. package/vitepress/assets/icons/icon__mindmap.svg +1 -1
  23. package/vitepress/assets/icons/icon__next.svg +1 -1
  24. package/vitepress/assets/icons/icon__number_gray.svg +1 -1
  25. package/vitepress/assets/icons/icon__number_purple.svg +1 -1
  26. package/vitepress/assets/icons/icon__prev.svg +1 -1
  27. package/vitepress/assets/icons/icon__restore.svg +1 -1
  28. package/vitepress/assets/icons/icon__rotate.svg +4 -4
  29. package/vitepress/assets/icons/icon__search.svg +1 -1
  30. package/vitepress/assets/icons/icon__sidebar_collapsed.svg +1 -1
  31. package/vitepress/assets/icons/icon__sidebar_opened.svg +1 -1
  32. package/vitepress/assets/icons/icon__totop.svg +5 -5
  33. package/vitepress/assets/icons/icon__vscode.svg +5 -5
  34. package/vitepress/assets/icons/icon__zoom_fit.svg +1 -1
  35. package/vitepress/assets/icons/icon__zoom_in.svg +1 -1
  36. package/vitepress/assets/icons/icon__zoom_out.svg +1 -1
  37. package/vitepress/assets/icons/icon__zoom_reset.svg +1 -1
  38. package/vitepress/assets/icons/index.ts +38 -38
  39. package/vitepress/components/BilibiliOutsidePlayer/BilibiliOutsidePlayer.vue +20 -20
  40. package/vitepress/components/CodeBlockFullscreen/CodeBlockFullscreen.vue +373 -372
  41. package/vitepress/components/CodeBlockFullscreen/index.ts +115 -114
  42. package/vitepress/components/CodeBlockFullscreen/styles.css +64 -64
  43. package/vitepress/components/Discussions/Discussions.module.scss +32 -32
  44. package/vitepress/components/Discussions/Discussions.vue +211 -210
  45. package/vitepress/components/EnWordList/EnWordList.module.scss +124 -124
  46. package/vitepress/components/EnWordList/EnWordList.vue +543 -542
  47. package/vitepress/components/EnWordList/RightClickMenu.module.scss +22 -22
  48. package/vitepress/components/EnWordList/RightClickMenu.vue +66 -66
  49. package/vitepress/components/Footprints/Footprints.module.scss +93 -93
  50. package/vitepress/components/Footprints/Footprints.vue +377 -377
  51. package/vitepress/components/Layout/AboutModal.module.scss +233 -233
  52. package/vitepress/components/Layout/AboutModal.vue +105 -105
  53. package/vitepress/components/Layout/AboutPanel.vue +270 -265
  54. package/vitepress/components/Layout/ContentCollapse.vue +603 -602
  55. package/vitepress/components/Layout/CustomSidebar.vue +608 -605
  56. package/vitepress/components/Layout/DocBeforeControls.vue +149 -139
  57. package/vitepress/components/Layout/DocFooter.vue +233 -232
  58. package/vitepress/components/Layout/ImagePreview.module.scss +201 -201
  59. package/vitepress/components/Layout/ImagePreview.vue +281 -280
  60. package/vitepress/components/Layout/Layout.module.scss +661 -661
  61. package/vitepress/components/Layout/Layout.vue +539 -542
  62. package/vitepress/components/Layout/NoteStatus.vue +140 -139
  63. package/vitepress/components/Layout/SidebarItems.vue +267 -262
  64. package/vitepress/components/Layout/SidebarNavBefore.vue +92 -92
  65. package/vitepress/components/Layout/Swiper.vue +167 -167
  66. package/vitepress/components/Layout/ToggleFullContent.module.scss +11 -11
  67. package/vitepress/components/Layout/ToggleFullContent.vue +35 -34
  68. package/vitepress/components/Layout/ToggleSidebar.module.scss +11 -11
  69. package/vitepress/components/Layout/ToggleSidebar.vue +36 -35
  70. package/vitepress/components/Layout/composables/useCollapseControl.ts +88 -88
  71. package/vitepress/components/Layout/composables/useNoteConfig.ts +119 -121
  72. package/vitepress/components/Layout/composables/useNoteSave.ts +173 -172
  73. package/vitepress/components/Layout/composables/useNoteValidation.ts +85 -85
  74. package/vitepress/components/Layout/composables/useRedirect.ts +113 -110
  75. package/vitepress/components/Layout/composables/useVSCodeIntegration.ts +86 -83
  76. package/vitepress/components/Layout/homeReadme.data.ts +124 -124
  77. package/vitepress/components/LoadingPage/LoadingPage.vue +192 -192
  78. package/vitepress/components/MarkMap/MarkMap.module.scss +159 -159
  79. package/vitepress/components/MarkMap/MarkMap.vue +405 -404
  80. package/vitepress/components/Mermaid/Mermaid.module.scss +275 -275
  81. package/vitepress/components/Mermaid/Mermaid.vue +365 -363
  82. package/vitepress/components/NotesTable/NotesTable.module.scss +77 -77
  83. package/vitepress/components/NotesTable/NotesTable.vue +98 -97
  84. package/vitepress/components/NotesTable/README.md +67 -67
  85. package/vitepress/components/Settings/Settings.module.scss +433 -433
  86. package/vitepress/components/Settings/Settings.vue +306 -305
  87. package/vitepress/components/SidebarCard/MindMapView.vue +484 -483
  88. package/vitepress/components/SidebarCard/NotesTrendChart.vue +108 -108
  89. package/vitepress/components/SidebarCard/SidebarCard.vue +946 -948
  90. package/vitepress/components/Tooltip/Tooltip.vue +70 -70
  91. package/vitepress/components/constants.ts +91 -91
  92. package/vitepress/components/notesConfig.data.ts +73 -73
  93. package/vitepress/components/sidebar.data.ts +59 -59
  94. package/vitepress/components/tnotes-config.data.ts +21 -21
  95. package/vitepress/components/utils.ts +26 -26
  96. package/vitepress/config/index.ts +160 -146
  97. package/vitepress/configs/constants.ts +26 -26
  98. package/vitepress/configs/head.config.ts +25 -24
  99. package/vitepress/configs/index.ts +9 -9
  100. package/vitepress/configs/markdown-it.d.ts +23 -20
  101. package/vitepress/configs/markdown.config.ts +366 -365
  102. package/vitepress/configs/theme.config.ts +108 -108
  103. package/vitepress/plugins/buildProgressPlugin.ts +434 -470
  104. package/vitepress/plugins/getNoteByConfigIdPlugin.ts +107 -106
  105. package/vitepress/plugins/renameNotePlugin.ts +60 -59
  106. package/vitepress/plugins/updateConfigPlugin.ts +63 -62
  107. package/vitepress/theme/index.ts +95 -93
  108. package/vitepress/theme/styles/base.scss +50 -50
  109. package/vitepress/theme/styles/components/404.scss +31 -31
  110. package/vitepress/theme/styles/components/collapse.scss +175 -175
  111. package/vitepress/theme/styles/components/markmap.scss +101 -101
  112. package/vitepress/theme/styles/components/swiper.scss +255 -255
  113. package/vitepress/theme/styles/index.scss +25 -25
  114. package/vitepress/theme/styles/layout.scss +62 -62
  115. package/vitepress/theme/styles/utilities.scss +39 -39
  116. package/vitepress/theme/styles/vitepress-override.scss +25 -25
@@ -1,306 +1,307 @@
1
- <template>
2
- <div :class="$style.settingsWrapper">
3
- <!-- 本地路径配置 -->
4
- <div :class="$style.settingItem">
5
- <div :class="$style.itemHeader">
6
- <div :class="$style.itemTitle">
7
- <span :class="$style.itemIcon">📁</span>
8
- <span :class="$style.itemName">本地知识库路径</span>
9
- </div>
10
- <span :class="$style.statusBadge" v-if="path">✓</span>
11
- </div>
12
-
13
- <div :class="$style.helpText">
14
- 适用于 PC 桌面环境,需要本地安装 VS Code
15
- 编辑器。配置后可在侧边栏快速打开笔记。
16
- </div>
17
-
18
- <div :class="$style.inputGroup">
19
- <input
20
- v-model="path"
21
- type="text"
22
- placeholder="例如: C:\notes 或 /Users/username/notes"
23
- :class="$style.input"
24
- />
25
- <button
26
- v-if="path"
27
- @click="clearPath"
28
- :class="$style.clearBtn"
29
- title="清空"
30
- >
31
-
32
- </button>
33
- </div>
34
- </div>
35
-
36
- <!-- 内容宽度配置 -->
37
- <div :class="$style.settingItem">
38
- <div :class="$style.itemHeader">
39
- <div :class="$style.itemTitle">
40
- <span :class="$style.itemIcon">📏</span>
41
- <span :class="$style.itemName">内容区宽度</span>
42
- </div>
43
- <span :class="$style.currentValue">{{ contentWidth }}</span>
44
- </div>
45
-
46
- <div :class="$style.helpText">
47
- 调整文章内容区域的最大宽度(全屏模式下不限制宽度)。
48
- </div>
49
-
50
- <select
51
- v-model="contentWidth"
52
- @change="applyContentWidth"
53
- :class="$style.select"
54
- >
55
- <option value="688px">标准 (688px)</option>
56
- <option value="755px">较大 (755px)</option>
57
- </select>
58
- </div>
59
-
60
- <!-- 侧边栏配置 -->
61
- <div :class="$style.settingItem">
62
- <div :class="$style.itemHeader">
63
- <div :class="$style.itemTitle">
64
- <span :class="$style.itemIcon">📑</span>
65
- <span :class="$style.itemName">侧边栏配置</span>
66
- </div>
67
- <span :class="$style.statusBadge" v-if="showNoteId">显示编号</span>
68
- </div>
69
-
70
- <div :class="$style.helpText">
71
- 控制侧边栏中是否显示笔记编号(如 "0001. ")。
72
- </div>
73
-
74
- <div :class="$style.field">
75
- <label :class="$style.checkboxLabel">
76
- <input
77
- v-model="showNoteId"
78
- type="checkbox"
79
- :class="$style.checkbox"
80
- />
81
- <span>显示笔记编号</span>
82
- </label>
83
- <div :class="$style.fieldHelp">
84
- 勾选后,侧边栏将显示完整的笔记标题(包含编号),例如 "0001. TNotes
85
- 简介"
86
- </div>
87
- </div>
88
- </div>
89
-
90
- <!-- MarkMap 配置 -->
91
- <div :class="$style.settingItem">
92
- <div :class="$style.itemHeader">
93
- <div :class="$style.itemTitle">
94
- <span :class="$style.itemIcon">💡</span>
95
- <span :class="$style.itemName">MarkMap 思维导图</span>
96
- </div>
97
- </div>
98
-
99
- <div :class="$style.helpText">配置思维导图的默认显示效果。</div>
100
-
101
- <div :class="$style.field">
102
- <div :class="$style.fieldLabel">
103
- <span>分支主题</span>
104
- </div>
105
- <div :class="$style.fieldHelp">选择思维导图分支的配色方案</div>
106
- <select v-model="markmapTheme" :class="$style.select">
107
- <option value="default">默认主题</option>
108
- <option value="colorful">多彩主题</option>
109
- <option value="dark">深色主题</option>
110
- </select>
111
- </div>
112
-
113
- <div :class="$style.field">
114
- <div :class="$style.fieldLabel">
115
- <span>展开层级</span>
116
- </div>
117
- <div :class="$style.fieldHelp">
118
- 设置思维导图初始展开的层级深度(1-100)
119
- </div>
120
- <div :class="$style.inputWithUnit">
121
- <input
122
- v-model.number="markmapExpandLevel"
123
- type="number"
124
- min="1"
125
- max="100"
126
- :class="$style.input"
127
- />
128
- <span :class="$style.unit">层</span>
129
- </div>
130
- </div>
131
- </div>
132
-
133
- <!-- 操作栏 -->
134
- <div :class="$style.actionBar">
135
- <button
136
- @click="save"
137
- :class="[$style.saveBtn, { [$style.disabled]: !hasChanges }]"
138
- :disabled="!hasChanges"
139
- >
140
- {{ saveText }}
141
- </button>
142
- <button v-if="hasChanges" @click="reset" :class="$style.resetBtn">
143
- 重置
144
- </button>
145
- </div>
146
-
147
- <!-- 保存成功提示 -->
148
- <Transition name="toast">
149
- <div v-if="showSuccessToast" :class="$style.toast">✓ 保存成功</div>
150
- </Transition>
151
- </div>
152
- </template>
153
-
154
- <script setup lang="ts">
1
+ <template>
2
+ <div :class="$style.settingsWrapper">
3
+ <!-- 本地路径配置 -->
4
+ <div :class="$style.settingItem">
5
+ <div :class="$style.itemHeader">
6
+ <div :class="$style.itemTitle">
7
+ <span :class="$style.itemIcon">📁</span>
8
+ <span :class="$style.itemName">本地知识库路径</span>
9
+ </div>
10
+ <span :class="$style.statusBadge" v-if="path">✓</span>
11
+ </div>
12
+
13
+ <div :class="$style.helpText">
14
+ 适用于 PC 桌面环境,需要本地安装 VS Code
15
+ 编辑器。配置后可在侧边栏快速打开笔记。
16
+ </div>
17
+
18
+ <div :class="$style.inputGroup">
19
+ <input
20
+ v-model="path"
21
+ type="text"
22
+ placeholder="例如: C:\notes 或 /Users/username/notes"
23
+ :class="$style.input"
24
+ />
25
+ <button
26
+ v-if="path"
27
+ @click="clearPath"
28
+ :class="$style.clearBtn"
29
+ title="清空"
30
+ >
31
+
32
+ </button>
33
+ </div>
34
+ </div>
35
+
36
+ <!-- 内容宽度配置 -->
37
+ <div :class="$style.settingItem">
38
+ <div :class="$style.itemHeader">
39
+ <div :class="$style.itemTitle">
40
+ <span :class="$style.itemIcon">📏</span>
41
+ <span :class="$style.itemName">内容区宽度</span>
42
+ </div>
43
+ <span :class="$style.currentValue">{{ contentWidth }}</span>
44
+ </div>
45
+
46
+ <div :class="$style.helpText">
47
+ 调整文章内容区域的最大宽度(全屏模式下不限制宽度)。
48
+ </div>
49
+
50
+ <select
51
+ v-model="contentWidth"
52
+ @change="applyContentWidth"
53
+ :class="$style.select"
54
+ >
55
+ <option value="688px">标准 (688px)</option>
56
+ <option value="755px">较大 (755px)</option>
57
+ </select>
58
+ </div>
59
+
60
+ <!-- 侧边栏配置 -->
61
+ <div :class="$style.settingItem">
62
+ <div :class="$style.itemHeader">
63
+ <div :class="$style.itemTitle">
64
+ <span :class="$style.itemIcon">📑</span>
65
+ <span :class="$style.itemName">侧边栏配置</span>
66
+ </div>
67
+ <span :class="$style.statusBadge" v-if="showNoteId">显示编号</span>
68
+ </div>
69
+
70
+ <div :class="$style.helpText">
71
+ 控制侧边栏中是否显示笔记编号(如 "0001. ")。
72
+ </div>
73
+
74
+ <div :class="$style.field">
75
+ <label :class="$style.checkboxLabel">
76
+ <input
77
+ v-model="showNoteId"
78
+ type="checkbox"
79
+ :class="$style.checkbox"
80
+ />
81
+ <span>显示笔记编号</span>
82
+ </label>
83
+ <div :class="$style.fieldHelp">
84
+ 勾选后,侧边栏将显示完整的笔记标题(包含编号),例如 "0001. TNotes
85
+ 简介"
86
+ </div>
87
+ </div>
88
+ </div>
89
+
90
+ <!-- MarkMap 配置 -->
91
+ <div :class="$style.settingItem">
92
+ <div :class="$style.itemHeader">
93
+ <div :class="$style.itemTitle">
94
+ <span :class="$style.itemIcon">💡</span>
95
+ <span :class="$style.itemName">MarkMap 思维导图</span>
96
+ </div>
97
+ </div>
98
+
99
+ <div :class="$style.helpText">配置思维导图的默认显示效果。</div>
100
+
101
+ <div :class="$style.field">
102
+ <div :class="$style.fieldLabel">
103
+ <span>分支主题</span>
104
+ </div>
105
+ <div :class="$style.fieldHelp">选择思维导图分支的配色方案</div>
106
+ <select v-model="markmapTheme" :class="$style.select">
107
+ <option value="default">默认主题</option>
108
+ <option value="colorful">多彩主题</option>
109
+ <option value="dark">深色主题</option>
110
+ </select>
111
+ </div>
112
+
113
+ <div :class="$style.field">
114
+ <div :class="$style.fieldLabel">
115
+ <span>展开层级</span>
116
+ </div>
117
+ <div :class="$style.fieldHelp">
118
+ 设置思维导图初始展开的层级深度(1-100)
119
+ </div>
120
+ <div :class="$style.inputWithUnit">
121
+ <input
122
+ v-model.number="markmapExpandLevel"
123
+ type="number"
124
+ min="1"
125
+ max="100"
126
+ :class="$style.input"
127
+ />
128
+ <span :class="$style.unit">层</span>
129
+ </div>
130
+ </div>
131
+ </div>
132
+
133
+ <!-- 操作栏 -->
134
+ <div :class="$style.actionBar">
135
+ <button
136
+ @click="save"
137
+ :class="[$style.saveBtn, { [$style.disabled]: !hasChanges }]"
138
+ :disabled="!hasChanges"
139
+ >
140
+ {{ saveText }}
141
+ </button>
142
+ <button v-if="hasChanges" @click="reset" :class="$style.resetBtn">
143
+ 重置
144
+ </button>
145
+ </div>
146
+
147
+ <!-- 保存成功提示 -->
148
+ <Transition name="toast">
149
+ <div v-if="showSuccessToast" :class="$style.toast">✓ 保存成功</div>
150
+ </Transition>
151
+ </div>
152
+ </template>
153
+
154
+ <script setup lang="ts">
155
155
  import { ref, computed, onMounted } from 'vue'
156
- import {
157
- NOTES_DIR_KEY,
158
- MARKMAP_THEME_KEY,
159
- MARKMAP_EXPAND_LEVEL_KEY,
160
- SIDEBAR_SHOW_NOTE_ID_KEY,
161
- } from '../constants'
162
- // @ts-expect-error - VitePress Data Loader
163
- import { data as tnotesConfig } from '../tnotes-config.data'
164
-
165
- const CONTENT_WIDTH_KEY = 'tnotes-content-width'
166
-
167
- // ===================================
168
- // #region 响应式数据
169
- // ===================================
170
- const path = ref('')
171
- const originalPath = ref('')
172
- const markmapTheme = ref('default')
173
- const originalMarkmapTheme = ref('default')
174
- const markmapExpandLevel = ref(5)
175
- const originalMarkmapExpandLevel = ref(5)
176
- const contentWidth = ref('688px')
177
- const showNoteId = ref(false)
178
- const originalShowNoteId = ref(false)
179
- const showSuccessToast = ref(false)
180
- // #endregion
181
-
182
- // ===================================
183
- // #region 计算属性
184
- // ===================================
185
- const hasChanges = computed(
186
- () =>
187
- path.value !== originalPath.value ||
188
- markmapTheme.value !== originalMarkmapTheme.value ||
189
- markmapExpandLevel.value !== originalMarkmapExpandLevel.value ||
190
- showNoteId.value !== originalShowNoteId.value
191
- )
192
-
193
- const saveText = computed(() => {
194
- if (!hasChanges.value) return '无更改'
195
- return '保存配置'
196
- })
197
- // #endregion
198
-
199
- // ===================================
200
- // #region 生命周期
201
- // ===================================
202
- onMounted(() => {
203
- if (typeof window !== 'undefined') {
204
- const savedPath = localStorage.getItem(NOTES_DIR_KEY) || ''
205
- path.value = savedPath
206
- originalPath.value = savedPath
207
-
208
- const savedTheme = localStorage.getItem(MARKMAP_THEME_KEY) || 'default'
209
- markmapTheme.value = savedTheme
210
- originalMarkmapTheme.value = savedTheme
211
-
212
- const savedLevel = localStorage.getItem(MARKMAP_EXPAND_LEVEL_KEY) || '5'
213
- markmapExpandLevel.value = parseInt(savedLevel)
214
- originalMarkmapExpandLevel.value = parseInt(savedLevel)
215
-
216
- const savedWidth = localStorage.getItem(CONTENT_WIDTH_KEY) || '688px'
217
- contentWidth.value = savedWidth
218
- applyContentWidth()
219
-
220
- // 读取侧边栏显示笔记 ID 配置
221
- // 优先使用 localStorage 中的用户自定义配置,否则使用配置文件中的默认值
222
- const savedShowNoteId = localStorage.getItem(SIDEBAR_SHOW_NOTE_ID_KEY)
223
- if (savedShowNoteId !== null) {
224
- showNoteId.value = savedShowNoteId === 'true'
225
- } else {
226
- showNoteId.value = tnotesConfig?.sidebarShowNoteId ?? false
227
- }
228
- originalShowNoteId.value = showNoteId.value
229
- }
230
- })
231
- // #endregion
232
-
233
- // ===================================
234
- // #region 事件处理
235
- // ===================================
236
- function handlePathChange() {
237
- // 可以在这里添加路径格式验证
238
- }
239
-
240
- function clearPath() {
241
- path.value = ''
242
- }
243
-
244
- function save() {
245
- if (!hasChanges.value) return
246
-
247
- try {
248
- // 保存前先记录是否需要刷新页面
249
- const needReload = showNoteId.value !== originalShowNoteId.value
250
-
251
- localStorage.setItem(NOTES_DIR_KEY, path.value)
252
- localStorage.setItem(MARKMAP_THEME_KEY, markmapTheme.value)
253
- localStorage.setItem(
254
- MARKMAP_EXPAND_LEVEL_KEY,
255
- markmapExpandLevel.value.toString()
256
- )
257
- localStorage.setItem(SIDEBAR_SHOW_NOTE_ID_KEY, showNoteId.value.toString())
258
-
259
- console.log('💾 [Settings] Saved showNoteId:', showNoteId.value)
260
-
261
- originalPath.value = path.value
262
- originalMarkmapTheme.value = markmapTheme.value
263
- originalMarkmapExpandLevel.value = markmapExpandLevel.value
264
- originalShowNoteId.value = showNoteId.value
265
-
266
- // 显示成功提示
267
- showSuccessToast.value = true
268
- setTimeout(() => {
269
- showSuccessToast.value = false
270
- }, 3000)
271
-
272
- // 触发页面刷新以应用侧边栏配置变化
273
- if (needReload) {
274
- console.log(
275
- '🔄 [Settings] Reloading page to apply sidebar config change...'
276
- )
277
- setTimeout(() => {
278
- window.location.reload()
279
- }, 500)
280
- }
281
- } catch (error) {
282
- console.error('保存配置失败:', error)
283
- alert('保存失败,请检查浏览器设置')
284
- }
285
- }
286
-
287
- function reset() {
288
- path.value = originalPath.value
289
- markmapTheme.value = originalMarkmapTheme.value
290
- markmapExpandLevel.value = originalMarkmapExpandLevel.value
291
- showNoteId.value = originalShowNoteId.value
292
- }
293
-
294
- // 应用内容宽度(通过 CSS 变量)
295
- function applyContentWidth() {
296
- if (typeof document === 'undefined') return
297
- document.documentElement.style.setProperty(
298
- '--tn-content-width',
299
- contentWidth.value
300
- )
301
- localStorage.setItem(CONTENT_WIDTH_KEY, contentWidth.value)
302
- }
303
- // #endregion
304
- </script>
305
-
306
- <style module src="./Settings.module.scss"></style>
156
+
157
+ import {
158
+ NOTES_DIR_KEY,
159
+ MARKMAP_THEME_KEY,
160
+ MARKMAP_EXPAND_LEVEL_KEY,
161
+ SIDEBAR_SHOW_NOTE_ID_KEY,
162
+ } from '../constants'
163
+ // @ts-expect-error - VitePress Data Loader
164
+ import { data as tnotesConfig } from '../tnotes-config.data'
165
+
166
+ const CONTENT_WIDTH_KEY = 'tnotes-content-width'
167
+
168
+ // ===================================
169
+ // #region 响应式数据
170
+ // ===================================
171
+ const path = ref('')
172
+ const originalPath = ref('')
173
+ const markmapTheme = ref('default')
174
+ const originalMarkmapTheme = ref('default')
175
+ const markmapExpandLevel = ref(5)
176
+ const originalMarkmapExpandLevel = ref(5)
177
+ const contentWidth = ref('688px')
178
+ const showNoteId = ref(false)
179
+ const originalShowNoteId = ref(false)
180
+ const showSuccessToast = ref(false)
181
+ // #endregion
182
+
183
+ // ===================================
184
+ // #region 计算属性
185
+ // ===================================
186
+ const hasChanges = computed(
187
+ () =>
188
+ path.value !== originalPath.value ||
189
+ markmapTheme.value !== originalMarkmapTheme.value ||
190
+ markmapExpandLevel.value !== originalMarkmapExpandLevel.value ||
191
+ showNoteId.value !== originalShowNoteId.value
192
+ )
193
+
194
+ const saveText = computed(() => {
195
+ if (!hasChanges.value) return '无更改'
196
+ return '保存配置'
197
+ })
198
+ // #endregion
199
+
200
+ // ===================================
201
+ // #region 生命周期
202
+ // ===================================
203
+ onMounted(() => {
204
+ if (typeof window !== 'undefined') {
205
+ const savedPath = localStorage.getItem(NOTES_DIR_KEY) || ''
206
+ path.value = savedPath
207
+ originalPath.value = savedPath
208
+
209
+ const savedTheme = localStorage.getItem(MARKMAP_THEME_KEY) || 'default'
210
+ markmapTheme.value = savedTheme
211
+ originalMarkmapTheme.value = savedTheme
212
+
213
+ const savedLevel = localStorage.getItem(MARKMAP_EXPAND_LEVEL_KEY) || '5'
214
+ markmapExpandLevel.value = parseInt(savedLevel)
215
+ originalMarkmapExpandLevel.value = parseInt(savedLevel)
216
+
217
+ const savedWidth = localStorage.getItem(CONTENT_WIDTH_KEY) || '688px'
218
+ contentWidth.value = savedWidth
219
+ applyContentWidth()
220
+
221
+ // 读取侧边栏显示笔记 ID 配置
222
+ // 优先使用 localStorage 中的用户自定义配置,否则使用配置文件中的默认值
223
+ const savedShowNoteId = localStorage.getItem(SIDEBAR_SHOW_NOTE_ID_KEY)
224
+ if (savedShowNoteId !== null) {
225
+ showNoteId.value = savedShowNoteId === 'true'
226
+ } else {
227
+ showNoteId.value = tnotesConfig?.sidebarShowNoteId ?? false
228
+ }
229
+ originalShowNoteId.value = showNoteId.value
230
+ }
231
+ })
232
+ // #endregion
233
+
234
+ // ===================================
235
+ // #region 事件处理
236
+ // ===================================
237
+ function handlePathChange() {
238
+ // 可以在这里添加路径格式验证
239
+ }
240
+
241
+ function clearPath() {
242
+ path.value = ''
243
+ }
244
+
245
+ function save() {
246
+ if (!hasChanges.value) return
247
+
248
+ try {
249
+ // 保存前先记录是否需要刷新页面
250
+ const needReload = showNoteId.value !== originalShowNoteId.value
251
+
252
+ localStorage.setItem(NOTES_DIR_KEY, path.value)
253
+ localStorage.setItem(MARKMAP_THEME_KEY, markmapTheme.value)
254
+ localStorage.setItem(
255
+ MARKMAP_EXPAND_LEVEL_KEY,
256
+ markmapExpandLevel.value.toString()
257
+ )
258
+ localStorage.setItem(SIDEBAR_SHOW_NOTE_ID_KEY, showNoteId.value.toString())
259
+
260
+ console.log('💾 [Settings] Saved showNoteId:', showNoteId.value)
261
+
262
+ originalPath.value = path.value
263
+ originalMarkmapTheme.value = markmapTheme.value
264
+ originalMarkmapExpandLevel.value = markmapExpandLevel.value
265
+ originalShowNoteId.value = showNoteId.value
266
+
267
+ // 显示成功提示
268
+ showSuccessToast.value = true
269
+ setTimeout(() => {
270
+ showSuccessToast.value = false
271
+ }, 3000)
272
+
273
+ // 触发页面刷新以应用侧边栏配置变化
274
+ if (needReload) {
275
+ console.log(
276
+ '🔄 [Settings] Reloading page to apply sidebar config change...'
277
+ )
278
+ setTimeout(() => {
279
+ window.location.reload()
280
+ }, 500)
281
+ }
282
+ } catch (error) {
283
+ console.error('保存配置失败:', error)
284
+ alert('保存失败,请检查浏览器设置')
285
+ }
286
+ }
287
+
288
+ function reset() {
289
+ path.value = originalPath.value
290
+ markmapTheme.value = originalMarkmapTheme.value
291
+ markmapExpandLevel.value = originalMarkmapExpandLevel.value
292
+ showNoteId.value = originalShowNoteId.value
293
+ }
294
+
295
+ // 应用内容宽度(通过 CSS 变量)
296
+ function applyContentWidth() {
297
+ if (typeof document === 'undefined') return
298
+ document.documentElement.style.setProperty(
299
+ '--tn-content-width',
300
+ contentWidth.value
301
+ )
302
+ localStorage.setItem(CONTENT_WIDTH_KEY, contentWidth.value)
303
+ }
304
+ // #endregion
305
+ </script>
306
+
307
+ <style module src="./Settings.module.scss"></style>