@tnotesjs/core 0.1.20 → 0.1.22
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/dist/{chunk-4MO7F7Q4.js → chunk-BSTQOJVE.js} +1 -1
- package/dist/{chunk-SQVHJR2Z.js → chunk-O4DCXHOV.js} +0 -3
- package/dist/cli/index.js +2 -2
- package/dist/index.js +1 -1
- package/dist/vitepress/config/index.js +2 -2
- package/package.json +3 -4
- package/types/config.ts +0 -1
- package/vitepress/components/CodeBlockFullscreen/CodeBlockFullscreen.vue +2 -2
- package/vitepress/components/CodeBlockFullscreen/index.ts +1 -5
- package/vitepress/components/CodeBlockFullscreen/styles.css +4 -4
- package/vitepress/components/Discussions/Discussions.vue +37 -4
- package/vitepress/components/EnWordList/EnWordList.vue +135 -15
- package/vitepress/components/EnWordList/RightClickMenu.vue +33 -10
- package/vitepress/components/Footprints/Footprints.vue +105 -10
- package/vitepress/components/Layout/AboutModal.vue +242 -16
- package/vitepress/components/Layout/AboutPanel.vue +258 -44
- package/vitepress/components/Layout/ContentCollapse.vue +1 -14
- package/vitepress/components/Layout/DocBeforeControls.vue +221 -19
- package/vitepress/components/Layout/ImagePreview.vue +212 -9
- package/vitepress/components/Layout/Layout.vue +133 -10
- package/vitepress/components/Layout/NavBarSettingsTrigger.vue +0 -2
- package/vitepress/components/Layout/SidebarNavBefore.vue +0 -1
- package/vitepress/components/Layout/SidebarResizeHandle.vue +2 -10
- package/vitepress/components/Layout/ToggleFullContent.vue +14 -2
- package/vitepress/components/Layout/ToggleSidebar.vue +14 -3
- package/vitepress/components/LoadingPage/LoadingPage.vue +1 -6
- package/vitepress/components/MarkMap/MarkMap.vue +162 -3
- package/vitepress/components/Mermaid/Mermaid.vue +300 -22
- package/vitepress/components/NotesTable/NotesTable.vue +86 -10
- package/vitepress/components/Settings/Settings.vue +434 -57
- package/vitepress/components/Settings/SettingsDialog.vue +1 -11
- package/vitepress/components/SidebarCard/MindMapView.vue +28 -28
- package/vitepress/components/SidebarCard/SidebarCard.vue +3 -4
- package/vitepress/components/Tooltip/Tooltip.vue +28 -28
- package/vitepress/configs/markdown.config.ts +3 -2
- package/vitepress/theme/styles/base.scss +2 -2
- package/vitepress/components/Discussions/Discussions.module.scss +0 -32
- package/vitepress/components/EnWordList/EnWordList.module.scss +0 -124
- package/vitepress/components/EnWordList/RightClickMenu.module.scss +0 -22
- package/vitepress/components/Footprints/Footprints.module.scss +0 -93
- package/vitepress/components/Layout/AboutModal.module.scss +0 -233
- package/vitepress/components/Layout/ImagePreview.module.scss +0 -201
- package/vitepress/components/Layout/Layout.module.scss +0 -661
- package/vitepress/components/Layout/ToggleFullContent.module.scss +0 -11
- package/vitepress/components/Layout/ToggleSidebar.module.scss +0 -11
- package/vitepress/components/MarkMap/MarkMap.module.scss +0 -159
- package/vitepress/components/Mermaid/Mermaid.module.scss +0 -275
- package/vitepress/components/NotesTable/NotesTable.module.scss +0 -77
- package/vitepress/components/Settings/Settings.module.scss +0 -375
|
@@ -57,21 +57,18 @@ function getDefaultConfig(repoName) {
|
|
|
57
57
|
// 社交链接
|
|
58
58
|
socialLinks: [
|
|
59
59
|
{
|
|
60
|
-
ariaLabel: "Tdahuyou \u8BED\u96C0\u4E3B\u9875\u94FE\u63A5",
|
|
61
60
|
link: "https://www.yuque.com/tdahuyou",
|
|
62
61
|
icon: {
|
|
63
62
|
svg: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M17.28 2.955c2.97.203 3.756 2.342 3.84 2.597l1.297.096c.13 0 .169.18.054.236c-1.323.716-1.727 2.17-1.49 3.118c.09.358.254.69.412 1.02c.307.642.651 1.418.707 2.981c.117 3.24-2.51 6.175-5.789 6.593c1.17-1.187 1.815-2.444 2.12-3.375c.606-1.846.508-3.316.055-4.44a4.46 4.46 0 0 0-1.782-2.141c-1.683-1.02-3.22-1.09-4.444-.762c.465-.594.876-1.201 1.2-1.864c.584-1.65-.102-2.848-.704-3.519c-.192-.246-.061-.655.305-.655c1.41 0 2.813.02 4.22.115M3.32 19.107c1.924-2.202 4.712-5.394 7.162-8.15c.559-.63 2.769-2.338 5.748-.533c.878.532 2.43 2.165 1.332 5.51c-.803 2.446-4.408 7.796-15.76 5.844c-.227-.039-.511-.354-.218-.687z"/></svg>'
|
|
64
63
|
}
|
|
65
64
|
},
|
|
66
65
|
{
|
|
67
|
-
ariaLabel: "Tdahuyou B \u7AD9\u4E3B\u9875\u94FE\u63A5",
|
|
68
66
|
link: "https://space.bilibili.com/407241004",
|
|
69
67
|
icon: {
|
|
70
68
|
svg: '<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024"><g fill="currentColor"><path d="M310.134 596.45c-7.999-4.463-16.498-8.43-24.997-11.9a274 274 0 0 0-26.996-7.438c-2.5-.992-2.5.991-2.5 1.487c0 7.934.5 18.843 1.5 27.768c1 7.438 2 15.372 4 22.81c0 .496 0 .991.5 1.487c.999.992 1.999 1.488 2.999.496c7.999-4.463 15.998-8.43 22.997-13.388c7.499-5.454 15.498-11.9 21.997-18.347c1.5-1.487 0-2.479.5-2.975m323.96-11.9a274 274 0 0 0-26.997-7.438c-2.5-.992-2.5.991-2.5 1.487c0 7.934.5 18.843 1.5 27.768c1 7.438 2 15.372 4 22.81c0 .496 0 .991.5 1.487c1 .992 2 1.488 3 .496c7.999-4.463 15.998-8.43 22.997-13.388c7.499-5.454 15.498-11.9 21.997-18.347c2-1.487.5-2.479.5-2.975c-7.5-4.463-16.498-8.43-24.997-11.9"/><path d="M741.496 112H283c-94.501 0-171 76.5-171 171.5v458c.5 94 77 170.5 170.999 170.5h457.997c94.5 0 171.002-76.5 171.002-170.5v-458c.497-95-76.002-171.5-170.502-171.5m95 343.5h15.5v48h-15.5zm-95.5-1.5l2 43l-13.5 1.5l-5-44.5zm-23.5 0l4 45.5l-14.5 1.5l-6.5-47.5h17zm-230.498 1.5h15v48h-15zm-96-1.5l2 43l-13.5 1.5l-5-44.5zm-23.5 0l4 45.5l-14.5 2l-6-47.5zm-3.5 149C343.498 668.5 216 662.5 204.5 660.5C195.5 499 181.5 464 170 385l54.5-22.5c1 71.5 9 185 9 185s108.5-15.5 132 47c.5 3 0 6-1.5 8.5m20.5 35.5l-23.5-124h35.5l13 123zm44.5-8l-27-235l33.5-1.5l21 236H429zm34-175h17.5v48H467zm41 190h-26.5l-9.5-126h36zm209.998-43C693.496 668 565.997 662 554.497 660c-9-161-23-196-34.5-275l54.5-22.5c1 71.5 9 185 9 185s108.5-15.5 132 46.5c.5 3 0 6-1.5 8.5m19.5 36l-23-124h35.5l13 123zm45.5-8l-27.5-235l33.5-1.5l21 236h-27zm33.5-175h17.5v48h-13zm41 190h-26.5l-9.5-126h36z"/></g></svg>'
|
|
71
69
|
}
|
|
72
70
|
},
|
|
73
71
|
{
|
|
74
|
-
ariaLabel: `${name} github \u4ED3\u5E93\u94FE\u63A5`,
|
|
75
72
|
link: `https://github.com/tnotesjs/${name}`,
|
|
76
73
|
icon: "github"
|
|
77
74
|
}
|
package/dist/cli/index.js
CHANGED
|
@@ -22,10 +22,10 @@ import {
|
|
|
22
22
|
parseArgs,
|
|
23
23
|
parseReadmeCompletedNotes,
|
|
24
24
|
runCommand
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-BSTQOJVE.js";
|
|
26
26
|
import {
|
|
27
27
|
ConfigManager
|
|
28
|
-
} from "../chunk-
|
|
28
|
+
} from "../chunk-O4DCXHOV.js";
|
|
29
29
|
|
|
30
30
|
// commands/update/UpdateCommand.ts
|
|
31
31
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
package/dist/index.js
CHANGED
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
UpdateNoteConfigCommand,
|
|
8
8
|
generateAnchor,
|
|
9
9
|
logger
|
|
10
|
-
} from "../../chunk-
|
|
11
|
-
import "../../chunk-
|
|
10
|
+
} from "../../chunk-BSTQOJVE.js";
|
|
11
|
+
import "../../chunk-O4DCXHOV.js";
|
|
12
12
|
|
|
13
13
|
// vitepress/config/index.ts
|
|
14
14
|
import fs2 from "fs";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tnotesjs/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
4
4
|
"description": "TNotes 知识库核心框架 —— 基于 VitePress 的笔记管理系统",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@10.17.1",
|
|
@@ -62,14 +62,13 @@
|
|
|
62
62
|
"@eslint/js": "^9.39.4",
|
|
63
63
|
"@types/markdown-it": "^14.1.2",
|
|
64
64
|
"@types/node": "^24.6.2",
|
|
65
|
-
"@typescript-eslint/parser": "^8.59.0",
|
|
66
65
|
"eslint": "^9.39.4",
|
|
67
66
|
"eslint-plugin-import": "^2.32.0",
|
|
68
67
|
"eslint-plugin-vue": "^10.9.0",
|
|
69
|
-
"globals": "^17.
|
|
68
|
+
"globals": "^17.6.0",
|
|
70
69
|
"tsup": "^8.5.1",
|
|
71
70
|
"typescript": "^5.9.3",
|
|
72
|
-
"typescript-eslint": "^8.59.
|
|
71
|
+
"typescript-eslint": "^8.59.1",
|
|
73
72
|
"vue-eslint-parser": "^10.4.0",
|
|
74
73
|
"vue-tsc": "^3.2.7"
|
|
75
74
|
},
|
package/types/config.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<div class="code-fullscreen-actions">
|
|
18
18
|
<!-- 旋转按钮(仅移动端) -->
|
|
19
19
|
<button
|
|
20
|
-
class="action-btn
|
|
20
|
+
class="action-btn mobile-only"
|
|
21
21
|
@click="toggleOrientation"
|
|
22
22
|
:title="isLandscape ? '切换为竖屏' : '切换为横屏'"
|
|
23
23
|
>
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
</button>
|
|
26
26
|
<!-- 复制按钮 -->
|
|
27
27
|
<button
|
|
28
|
-
class="action-btn
|
|
28
|
+
class="action-btn"
|
|
29
29
|
@click="copyCode"
|
|
30
30
|
:title="copied ? '已复制' : '复制代码'"
|
|
31
31
|
>
|
|
@@ -7,7 +7,7 @@ type CopyState = 'idle' | 'copied' | 'failed'
|
|
|
7
7
|
|
|
8
8
|
const CODE_BLOCK_SELECTOR = 'div[class*="language-"]'
|
|
9
9
|
const CODE_ACTIONS_CLASS = 'tn-code-actions'
|
|
10
|
-
const COPY_RESET_DELAY =
|
|
10
|
+
const COPY_RESET_DELAY = 1000
|
|
11
11
|
|
|
12
12
|
export function useCodeBlockFullscreen() {
|
|
13
13
|
let fullscreenApp: any = null
|
|
@@ -28,7 +28,6 @@ export function useCodeBlockFullscreen() {
|
|
|
28
28
|
|
|
29
29
|
const actions = document.createElement('div')
|
|
30
30
|
actions.className = CODE_ACTIONS_CLASS
|
|
31
|
-
actions.setAttribute('aria-label', '代码块操作')
|
|
32
31
|
|
|
33
32
|
const fullscreenButton = createActionButton({
|
|
34
33
|
className: 'tn-code-action-fullscreen',
|
|
@@ -65,7 +64,6 @@ export function useCodeBlockFullscreen() {
|
|
|
65
64
|
button.className = `tn-code-action ${options.className}`
|
|
66
65
|
button.type = 'button'
|
|
67
66
|
button.title = options.title
|
|
68
|
-
button.setAttribute('aria-label', options.title)
|
|
69
67
|
button.innerHTML = `<img src="${options.icon}" alt="${options.alt}" />`
|
|
70
68
|
|
|
71
69
|
return button
|
|
@@ -98,7 +96,6 @@ export function useCodeBlockFullscreen() {
|
|
|
98
96
|
button.parentElement.dataset.copyState = state
|
|
99
97
|
}
|
|
100
98
|
button.title = getCopyTitle(state)
|
|
101
|
-
button.setAttribute('aria-label', getCopyTitle(state))
|
|
102
99
|
|
|
103
100
|
const icon = button.querySelector('img')
|
|
104
101
|
if (icon) {
|
|
@@ -112,7 +109,6 @@ export function useCodeBlockFullscreen() {
|
|
|
112
109
|
button.parentElement.dataset.copyState = 'idle'
|
|
113
110
|
}
|
|
114
111
|
button.title = getCopyTitle('idle')
|
|
115
|
-
button.setAttribute('aria-label', getCopyTitle('idle'))
|
|
116
112
|
icon?.setAttribute('src', icon__clipboard)
|
|
117
113
|
icon?.setAttribute('alt', '复制')
|
|
118
114
|
copyResetTimers.delete(button)
|
|
@@ -76,8 +76,8 @@ div[class*='language-']:hover .tn-code-actions,
|
|
|
76
76
|
|
|
77
77
|
.tn-code-action-copy::after {
|
|
78
78
|
position: absolute;
|
|
79
|
-
top:
|
|
80
|
-
right:
|
|
79
|
+
top: 50%;
|
|
80
|
+
right: calc(100% + 6px);
|
|
81
81
|
padding: 4px 7px;
|
|
82
82
|
color: var(--vp-c-text-1);
|
|
83
83
|
background: var(--vp-c-bg-elv);
|
|
@@ -89,7 +89,7 @@ div[class*='language-']:hover .tn-code-actions,
|
|
|
89
89
|
line-height: 18px;
|
|
90
90
|
opacity: 0;
|
|
91
91
|
pointer-events: none;
|
|
92
|
-
transform: translateY(-2px);
|
|
92
|
+
transform: translateY(-50%) translateX(2px);
|
|
93
93
|
transition:
|
|
94
94
|
opacity 0.16s ease,
|
|
95
95
|
transform 0.16s ease;
|
|
@@ -99,7 +99,7 @@ div[class*='language-']:hover .tn-code-actions,
|
|
|
99
99
|
.tn-code-action-copy[data-copy-state='copied']::after,
|
|
100
100
|
.tn-code-action-copy[data-copy-state='failed']::after {
|
|
101
101
|
opacity: 1;
|
|
102
|
-
transform: translateY(0);
|
|
102
|
+
transform: translateY(-50%) translateX(0);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/* .dark .tn-code-action-copy img {
|
|
@@ -193,15 +193,15 @@ watch(isDark, (newVal) => {
|
|
|
193
193
|
</script>
|
|
194
194
|
|
|
195
195
|
<template>
|
|
196
|
-
<h2
|
|
196
|
+
<h2 class="h2">
|
|
197
197
|
<Tooltip text="在 GitHub 上发表评论(支持上传图片)">
|
|
198
198
|
<a
|
|
199
199
|
:href="githubDiscussionsUrl"
|
|
200
200
|
target="_blank"
|
|
201
201
|
rel="noopener noreferrer"
|
|
202
|
-
|
|
202
|
+
class="discussionsLink"
|
|
203
203
|
>
|
|
204
|
-
<img :src="icon__github" alt=""
|
|
204
|
+
<img :src="icon__github" alt="" class="githubIcon" />
|
|
205
205
|
Discussions
|
|
206
206
|
</a>
|
|
207
207
|
</Tooltip>
|
|
@@ -209,4 +209,37 @@ watch(isDark, (newVal) => {
|
|
|
209
209
|
<div id="giscus-comments"></div>
|
|
210
210
|
</template>
|
|
211
211
|
|
|
212
|
-
<style
|
|
212
|
+
<style scoped lang="scss">
|
|
213
|
+
/* #region:same as vitepress theme */
|
|
214
|
+
.h2 {
|
|
215
|
+
margin: 48px 0 16px;
|
|
216
|
+
border-top: 1px solid var(--vp-c-divider);
|
|
217
|
+
padding-top: 24px;
|
|
218
|
+
letter-spacing: -0.02em;
|
|
219
|
+
line-height: 32px;
|
|
220
|
+
font-size: 1.2rem;
|
|
221
|
+
text-align: center;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* #endregion:same as vitepress theme */
|
|
225
|
+
|
|
226
|
+
.discussionsLink {
|
|
227
|
+
display: inline-flex;
|
|
228
|
+
align-items: center;
|
|
229
|
+
gap: 0.5em;
|
|
230
|
+
color: var(--vp-c-brand-1);
|
|
231
|
+
text-decoration: none;
|
|
232
|
+
opacity: 0.9;
|
|
233
|
+
transition: opacity 0.25s;
|
|
234
|
+
|
|
235
|
+
&:hover {
|
|
236
|
+
opacity: 0.5;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.githubIcon {
|
|
241
|
+
width: 1em;
|
|
242
|
+
height: 1em;
|
|
243
|
+
flex-shrink: 0;
|
|
244
|
+
}
|
|
245
|
+
</style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { marked } from 'marked'
|
|
3
|
-
import { computed, ref, onMounted, onUnmounted, nextTick } from 'vue'
|
|
3
|
+
import { computed, ref, onMounted, onUnmounted, nextTick } from 'vue'
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
EN_WORDS_REPO_BASE_URL,
|
|
@@ -448,17 +448,16 @@ onUnmounted(() => {
|
|
|
448
448
|
</script>
|
|
449
449
|
|
|
450
450
|
<template>
|
|
451
|
-
<div
|
|
451
|
+
<div class="enWordList">
|
|
452
452
|
<ol>
|
|
453
453
|
<li
|
|
454
454
|
v-for="(word, index) in sortedWords"
|
|
455
455
|
:key="word"
|
|
456
456
|
:class="{
|
|
457
|
-
|
|
458
|
-
isPronouncingAll && currentPronounceAllIndex === index + 1,
|
|
457
|
+
pronounced: isPronouncingAll && currentPronounceAllIndex === index + 1,
|
|
459
458
|
}"
|
|
460
459
|
>
|
|
461
|
-
<span
|
|
460
|
+
<span class="index">{{ index + 1 }}.</span>
|
|
462
461
|
<input
|
|
463
462
|
type="checkbox"
|
|
464
463
|
:id="word"
|
|
@@ -471,8 +470,8 @@ onUnmounted(() => {
|
|
|
471
470
|
word.toLowerCase().replaceAll(/\s/g, '_')
|
|
472
471
|
)}.md`"
|
|
473
472
|
:class="{
|
|
474
|
-
|
|
475
|
-
|
|
473
|
+
lineThrough: checkedStates[word],
|
|
474
|
+
textRed: failedWords[word],
|
|
476
475
|
}"
|
|
477
476
|
@mouseenter="(e) => isAutoShowCard && showWordCard(e, word)"
|
|
478
477
|
@mouseleave="handleMouseLeave"
|
|
@@ -486,18 +485,18 @@ onUnmounted(() => {
|
|
|
486
485
|
</ol>
|
|
487
486
|
|
|
488
487
|
<div
|
|
489
|
-
|
|
488
|
+
class="wordCard"
|
|
490
489
|
:style="{ left: cardX + 'px', top: cardY + 'px' }"
|
|
491
490
|
v-if="showCard"
|
|
492
491
|
>
|
|
493
|
-
<div
|
|
492
|
+
<div class="wordCardContent" v-html="cardContent"></div>
|
|
494
493
|
</div>
|
|
495
494
|
|
|
496
495
|
<!-- pinned cards -->
|
|
497
496
|
<div
|
|
498
497
|
v-for="card in pinnedCards"
|
|
499
498
|
:key="card.id"
|
|
500
|
-
|
|
499
|
+
class="wordCard"
|
|
501
500
|
:style="{
|
|
502
501
|
left: card.x + 'px',
|
|
503
502
|
top: card.y + 'px',
|
|
@@ -508,14 +507,14 @@ onUnmounted(() => {
|
|
|
508
507
|
@mousedown="(e) => startDrag(card, e)"
|
|
509
508
|
@click="bringToFront(card)"
|
|
510
509
|
>
|
|
511
|
-
<div
|
|
512
|
-
<div
|
|
510
|
+
<div class="wordCardContentWrapper">
|
|
511
|
+
<div class="wordCardContent" v-html="card.content"></div>
|
|
513
512
|
</div>
|
|
514
|
-
<button
|
|
513
|
+
<button class="closeBtn" @click.stop="removeCard(card.id)">
|
|
515
514
|
✖
|
|
516
515
|
</button>
|
|
517
516
|
<div
|
|
518
|
-
|
|
517
|
+
class="resizeHandle"
|
|
519
518
|
@mousedown.stop="startResize(card, $event)"
|
|
520
519
|
></div>
|
|
521
520
|
</div>
|
|
@@ -541,4 +540,125 @@ onUnmounted(() => {
|
|
|
541
540
|
/>
|
|
542
541
|
</template>
|
|
543
542
|
|
|
544
|
-
<style
|
|
543
|
+
<style scoped lang="scss">
|
|
544
|
+
/* EnWordList 组件样式 */
|
|
545
|
+
|
|
546
|
+
.enWordList {
|
|
547
|
+
// Checkbox 样式
|
|
548
|
+
input[type='checkbox'] {
|
|
549
|
+
margin: 8px;
|
|
550
|
+
transform: scale(1.3);
|
|
551
|
+
cursor: pointer;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// 链接样式
|
|
555
|
+
a {
|
|
556
|
+
text-decoration: none;
|
|
557
|
+
color: #4fc3f7;
|
|
558
|
+
|
|
559
|
+
&:hover {
|
|
560
|
+
text-decoration: underline !important;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
&.lineThrough {
|
|
564
|
+
color: #999;
|
|
565
|
+
text-decoration: line-through;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
&.textRed {
|
|
569
|
+
color: #f40 !important;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// 单词列表样式
|
|
574
|
+
ol {
|
|
575
|
+
list-style-type: decimal;
|
|
576
|
+
padding-left: 20px;
|
|
577
|
+
|
|
578
|
+
li {
|
|
579
|
+
display: flex;
|
|
580
|
+
align-items: center;
|
|
581
|
+
margin-bottom: 8px;
|
|
582
|
+
transition: all 0.3s ease;
|
|
583
|
+
|
|
584
|
+
&.pronounced {
|
|
585
|
+
background-color: rgba(255, 255, 0, 0.1);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// 序号样式
|
|
591
|
+
.index {
|
|
592
|
+
margin-right: 10px;
|
|
593
|
+
color: #aaa;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// 单词卡片样式(🌑 暗色悬浮卡片)
|
|
598
|
+
.wordCard {
|
|
599
|
+
position: fixed;
|
|
600
|
+
z-index: 9999;
|
|
601
|
+
background: #1e1e1e;
|
|
602
|
+
border: 1px solid #333;
|
|
603
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
|
|
604
|
+
padding: 12px 16px;
|
|
605
|
+
max-width: 600px;
|
|
606
|
+
min-width: 200px;
|
|
607
|
+
min-height: 100px;
|
|
608
|
+
font-size: 14px;
|
|
609
|
+
line-height: 1.4;
|
|
610
|
+
border-radius: 8px;
|
|
611
|
+
color: #eee;
|
|
612
|
+
pointer-events: auto;
|
|
613
|
+
font-family: sans-serif;
|
|
614
|
+
cursor: move;
|
|
615
|
+
|
|
616
|
+
// 关闭按钮
|
|
617
|
+
.closeBtn {
|
|
618
|
+
position: absolute;
|
|
619
|
+
right: 5px;
|
|
620
|
+
top: 5px;
|
|
621
|
+
background: none;
|
|
622
|
+
border: none;
|
|
623
|
+
font-size: 16px;
|
|
624
|
+
cursor: pointer;
|
|
625
|
+
color: #ccc;
|
|
626
|
+
|
|
627
|
+
&:hover {
|
|
628
|
+
color: white;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// 卡片内容包裹器
|
|
634
|
+
.wordCardContentWrapper {
|
|
635
|
+
width: 100%;
|
|
636
|
+
height: 100%;
|
|
637
|
+
overflow: auto;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// 卡片内容样式
|
|
641
|
+
.wordCardContent {
|
|
642
|
+
:deep(ul) {
|
|
643
|
+
margin: 0.5rem 0;
|
|
644
|
+
padding-left: 1rem;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// 调整大小手柄
|
|
649
|
+
.resizeHandle {
|
|
650
|
+
position: absolute;
|
|
651
|
+
right: 0;
|
|
652
|
+
bottom: 0;
|
|
653
|
+
width: 12px;
|
|
654
|
+
height: 12px;
|
|
655
|
+
background-color: #666;
|
|
656
|
+
cursor: nwse-resize;
|
|
657
|
+
z-index: 2;
|
|
658
|
+
border-radius: 50%;
|
|
659
|
+
|
|
660
|
+
&:hover {
|
|
661
|
+
background-color: #aaa;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
</style>
|
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
v-if="show"
|
|
4
|
-
|
|
4
|
+
class="rightClickMenu"
|
|
5
5
|
:style="{ left: x + 'px', top: y + 'px' }"
|
|
6
6
|
>
|
|
7
|
-
<div
|
|
8
|
-
<div
|
|
7
|
+
<div class="menuItem" @click="handlePin">📌 Pin</div>
|
|
8
|
+
<div class="menuItem" @click="(e) => handlePronounce(e, 'en-GB')">
|
|
9
9
|
📢 Pronounce(英)
|
|
10
10
|
</div>
|
|
11
|
-
<div
|
|
11
|
+
<div class="menuItem" @click="(e) => handlePronounce(e, 'en-US')">
|
|
12
12
|
📢 Pronounce(美)
|
|
13
13
|
</div>
|
|
14
14
|
<div
|
|
15
|
-
|
|
15
|
+
class="menuItem"
|
|
16
16
|
@click="(e) => handlePronounceAll(e, 'en-GB')"
|
|
17
17
|
>
|
|
18
18
|
📢 Pronounce All(英)
|
|
19
19
|
</div>
|
|
20
20
|
<div
|
|
21
|
-
|
|
21
|
+
class="menuItem"
|
|
22
22
|
@click="(e) => handlePronounceAll(e, 'en-US')"
|
|
23
23
|
>
|
|
24
24
|
📢 Pronounce All(美)
|
|
25
25
|
</div>
|
|
26
|
-
<div
|
|
26
|
+
<div class="menuItem" @click="handleAutoShowCard">
|
|
27
27
|
🔍 Auto Show Card({{ isAutoShowCard ? '关' : '开' }})
|
|
28
28
|
</div>
|
|
29
|
-
<div
|
|
30
|
-
<div
|
|
29
|
+
<div class="menuItem" @click="handleCheckAll">✅ Check All</div>
|
|
30
|
+
<div class="menuItem" @click="handleReset">❌ Reset</div>
|
|
31
31
|
</div>
|
|
32
32
|
</template>
|
|
33
33
|
|
|
@@ -63,4 +63,27 @@ const handleReset = () => {
|
|
|
63
63
|
}
|
|
64
64
|
</script>
|
|
65
65
|
|
|
66
|
-
<style
|
|
66
|
+
<style scoped lang="scss">
|
|
67
|
+
// RightClickMenu 组件样式
|
|
68
|
+
|
|
69
|
+
.rightClickMenu {
|
|
70
|
+
position: fixed;
|
|
71
|
+
z-index: 99999;
|
|
72
|
+
background: #2c2c2c;
|
|
73
|
+
border: 1px solid #444;
|
|
74
|
+
border-radius: 6px;
|
|
75
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
|
|
76
|
+
font-size: 13px;
|
|
77
|
+
color: #eee;
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
user-select: none;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.menuItem {
|
|
83
|
+
padding: 8px 16px;
|
|
84
|
+
|
|
85
|
+
&:hover {
|
|
86
|
+
background-color: #444;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
</style>
|
|
@@ -331,23 +331,24 @@ const formattedTime = computed(() => {
|
|
|
331
331
|
</script>
|
|
332
332
|
|
|
333
333
|
<template>
|
|
334
|
-
<div
|
|
334
|
+
<div class="textContainer">
|
|
335
335
|
<div
|
|
336
|
-
|
|
336
|
+
class="textContent"
|
|
337
|
+
:class="{ collapsed: isCollapsed }"
|
|
337
338
|
ref="textContainer"
|
|
338
339
|
>
|
|
339
340
|
<slot name="text-area"></slot>
|
|
340
341
|
</div>
|
|
341
342
|
<button
|
|
342
343
|
v-if="isExpandable"
|
|
343
|
-
|
|
344
|
+
class="toggleButton"
|
|
344
345
|
@click="toggleCollapse"
|
|
345
346
|
>
|
|
346
347
|
{{ isCollapsed ? '全文' : '收起' }}
|
|
347
348
|
</button>
|
|
348
349
|
</div>
|
|
349
350
|
|
|
350
|
-
<div
|
|
351
|
+
<div class="imageContainer" ref="imageContainer">
|
|
351
352
|
<slot
|
|
352
353
|
name="image-list"
|
|
353
354
|
:openModal="openModal"
|
|
@@ -356,22 +357,116 @@ const formattedTime = computed(() => {
|
|
|
356
357
|
:isModalVisible="isModalVisible"
|
|
357
358
|
></slot>
|
|
358
359
|
</div>
|
|
359
|
-
<div
|
|
360
|
-
<span
|
|
360
|
+
<div class="modal" v-show="isModalVisible" @click.self="closeModal">
|
|
361
|
+
<span class="close" @click="closeModal">×</span>
|
|
361
362
|
<img
|
|
362
|
-
:class="[
|
|
363
|
+
:class="['modalContent', `__dynamic__modal-content-${instanceId}`]"
|
|
363
364
|
:src="currentImage"
|
|
364
365
|
alt="Preview"
|
|
365
366
|
@mousedown="handleMouseDown"
|
|
366
367
|
/>
|
|
367
368
|
</div>
|
|
368
369
|
|
|
369
|
-
<div
|
|
370
|
+
<div class="timeContainer">
|
|
370
371
|
<p>{{ formattedTime }}</p>
|
|
371
372
|
</div>
|
|
372
|
-
<div
|
|
373
|
+
<div class="otherInfoContainer">
|
|
373
374
|
<slot name="other-info"></slot>
|
|
374
375
|
</div>
|
|
375
376
|
</template>
|
|
376
377
|
|
|
377
|
-
<style
|
|
378
|
+
<style scoped lang="scss">
|
|
379
|
+
// Footprints 组件样式
|
|
380
|
+
|
|
381
|
+
// 其他信息容器和时间容器
|
|
382
|
+
.otherInfoContainer,
|
|
383
|
+
.timeContainer {
|
|
384
|
+
font-size: 0.8rem;
|
|
385
|
+
color: gray;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// 文本容器
|
|
389
|
+
.textContainer {
|
|
390
|
+
position: relative;
|
|
391
|
+
margin-bottom: 1rem;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// 文本内容
|
|
395
|
+
.textContent {
|
|
396
|
+
overflow: hidden;
|
|
397
|
+
transition: max-height 0.3s ease;
|
|
398
|
+
|
|
399
|
+
// 折叠状态:隐藏从第三个开始的所有一级子元素
|
|
400
|
+
&.collapsed > :nth-child(n + 3) {
|
|
401
|
+
display: none;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// 切换按钮
|
|
406
|
+
.toggleButton {
|
|
407
|
+
display: block;
|
|
408
|
+
margin-top: 0.5rem;
|
|
409
|
+
background-color: transparent;
|
|
410
|
+
color: #007bff;
|
|
411
|
+
border: none;
|
|
412
|
+
cursor: pointer;
|
|
413
|
+
text-align: left;
|
|
414
|
+
font-size: 1rem;
|
|
415
|
+
|
|
416
|
+
&:hover {
|
|
417
|
+
text-decoration: underline;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// 图片容器
|
|
422
|
+
.imageContainer {
|
|
423
|
+
display: flex;
|
|
424
|
+
width: 100%;
|
|
425
|
+
flex-wrap: wrap;
|
|
426
|
+
|
|
427
|
+
img {
|
|
428
|
+
width: calc(33.33% - 10px);
|
|
429
|
+
aspect-ratio: 1; // 设置宽高比为 1:1
|
|
430
|
+
object-fit: cover;
|
|
431
|
+
cursor: pointer;
|
|
432
|
+
margin: 0.3rem;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// 模态框
|
|
437
|
+
.modal {
|
|
438
|
+
display: flex;
|
|
439
|
+
position: fixed;
|
|
440
|
+
z-index: 1000;
|
|
441
|
+
left: 0;
|
|
442
|
+
top: 0;
|
|
443
|
+
width: 100%;
|
|
444
|
+
height: 100%;
|
|
445
|
+
overflow: auto;
|
|
446
|
+
background-color: rgba(0, 0, 0, 1);
|
|
447
|
+
align-items: center;
|
|
448
|
+
justify-content: center;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// 模态框内容(图片)
|
|
452
|
+
.modalContent {
|
|
453
|
+
position: absolute;
|
|
454
|
+
top: 50%;
|
|
455
|
+
left: 50%;
|
|
456
|
+
transform: translate(-50%, -50%);
|
|
457
|
+
max-width: 90%;
|
|
458
|
+
max-height: 90%;
|
|
459
|
+
cursor: grab;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// 关闭按钮
|
|
463
|
+
.close {
|
|
464
|
+
position: absolute;
|
|
465
|
+
top: 20px;
|
|
466
|
+
right: 30px;
|
|
467
|
+
color: white;
|
|
468
|
+
font-size: 30px;
|
|
469
|
+
font-weight: bold;
|
|
470
|
+
cursor: pointer;
|
|
471
|
+
}
|
|
472
|
+
</style>
|