@datawhale/prosemirror-render 0.0.1 → 0.0.2

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 (198) hide show
  1. package/dist/{AttachmentBlock-ChMNTUOo.mjs → AttachmentBlock-BTIBSu4p.js} +2 -2
  2. package/dist/AttachmentBlock-W05YY8zN.cjs +1 -0
  3. package/dist/{AttachmentInline-tbC8BJBy.mjs → AttachmentInline-BF7QTLxZ.js} +2 -2
  4. package/dist/AttachmentInline-CgV-t0WF.cjs +1 -0
  5. package/dist/{AttachmentMenu-B5x8P9_n.mjs → AttachmentMenu-BjM7LAlw.js} +1 -1
  6. package/dist/AttachmentMenu-vc18PNLc.cjs +1 -0
  7. package/dist/{Callout-Cu6HI-xq.mjs → Callout-BH6_xPHP.js} +2 -2
  8. package/dist/Callout-BgG8-zJn.cjs +1 -0
  9. package/dist/{CellOutput-DiKZlIFa.js → CellOutput-CXb77W7X.cjs} +1 -1
  10. package/dist/{CellOutput-C33VK0df.mjs → CellOutput-DJqn5MJH.js} +1 -1
  11. package/dist/{CodeBlock-DWniNUQB.js → CodeBlock-BejcPvxj.cjs} +1 -1
  12. package/dist/{CodeBlock-Cjuxuq7B.mjs → CodeBlock-D9lrTXj3.js} +1 -1
  13. package/dist/FoldBlock-CMDkkdoU.cjs +1 -0
  14. package/dist/{FoldBlock-DRdlU-DX.mjs → FoldBlock-CZwxKsSG.js} +2 -2
  15. package/dist/{Grid-GfmJxM93.mjs → Grid-B53O57Vv.js} +1 -1
  16. package/dist/Grid-Cw9joyDF.cjs +1 -0
  17. package/dist/IFrame-CP2oHuDb.cjs +1 -0
  18. package/dist/{IFrame-CaAOVLGN.mjs → IFrame-DRvqa1hl.js} +1 -1
  19. package/dist/Image-B9Rer9RA.cjs +1 -0
  20. package/dist/{Image-C8v5dCij.mjs → Image-BjIZuyk1.js} +1 -1
  21. package/dist/{MathDisplay-CoGsFzXW.mjs → MathDisplay-BficZWEq.js} +2 -2
  22. package/dist/MathDisplay-D5rx_pee.cjs +1 -0
  23. package/dist/{MathInline-0xTZoIIq.mjs → MathInline-Ca8s53fu.js} +2 -2
  24. package/dist/MathInline-DZ86cc6g.cjs +1 -0
  25. package/dist/{McChoices-Aj394G5E.mjs → McChoices-B8W03KdG.js} +1 -1
  26. package/dist/McChoices-CW1gsp_V.cjs +1 -0
  27. package/dist/McQuestion-DwBWk5S2.cjs +1 -0
  28. package/dist/{McQuestion-DvD-J47M.mjs → McQuestion-WyxeDFjM.js} +1 -1
  29. package/dist/McSolution-BtY7RBEb.cjs +1 -0
  30. package/dist/{McSolution-C5sTXz3y.mjs → McSolution-CRahjdmW.js} +1 -1
  31. package/dist/{MultipleChoice-Dv-k1zUU.mjs → MultipleChoice-BgGHy-NW.js} +4 -4
  32. package/dist/MultipleChoice-mFFm3sQv.cjs +1 -0
  33. package/dist/{Paragraph-DGcZy8t_.mjs → Paragraph-C3uQVRMm.js} +1 -1
  34. package/dist/Paragraph-CU-CMQz2.cjs +1 -0
  35. package/dist/{SlotNode-6OpoUcOa.mjs → SlotNode-BThSEhpr.js} +1 -1
  36. package/dist/SlotNode-ivBAGFTX.cjs +1 -0
  37. package/dist/Text-3RT27QJn.cjs +1 -0
  38. package/dist/{Text-Br_pcGz4.mjs → Text-cG9dlJgd.js} +1 -1
  39. package/dist/{index-DVmWCrQE.mjs → index-C97tUvOp.js} +30 -30
  40. package/dist/index-DuVSDVpW.cjs +1 -0
  41. package/dist/index.cjs.js +1 -1
  42. package/dist/index.es.js +1 -1
  43. package/package.json +8 -2
  44. package/dist/AttachmentBlock-DsmJP3Kw.js +0 -1
  45. package/dist/AttachmentInline-Dc3dp0g-.js +0 -1
  46. package/dist/AttachmentMenu-ExoCOe4B.js +0 -1
  47. package/dist/Callout-DPdOqTb4.js +0 -1
  48. package/dist/FoldBlock-ZPMf0QsR.js +0 -1
  49. package/dist/Grid-QToZdaRT.js +0 -1
  50. package/dist/IFrame-DcCpSoDC.js +0 -1
  51. package/dist/Image-cHL85CXs.js +0 -1
  52. package/dist/MathDisplay-CESKZV46.js +0 -1
  53. package/dist/MathInline-C_1SJUVz.js +0 -1
  54. package/dist/McChoices-B4euzY7M.js +0 -1
  55. package/dist/McQuestion-Dq0aM5tC.js +0 -1
  56. package/dist/McSolution-N79CllH9.js +0 -1
  57. package/dist/MultipleChoice-DTCF3Q8m.js +0 -1
  58. package/dist/Paragraph-CzRSCJNr.js +0 -1
  59. package/dist/SlotNode-DMG0R6Vf.js +0 -1
  60. package/dist/Text-DlUfrsNI.js +0 -1
  61. package/dist/index-D2CtpNvR.js +0 -1
  62. package/src/apis/monitor.ts +0 -8
  63. package/src/apis/tingwu.ts +0 -22
  64. package/src/apis/types.ts +0 -45
  65. package/src/components/TreeRecursive.vue +0 -47
  66. package/src/components/TreeRender.vue +0 -404
  67. package/src/components/collections/async/AsyncError.vue +0 -17
  68. package/src/components/collections/async/AsyncLoading.vue +0 -1
  69. package/src/components/collections/attachment/AttachmentBlock.vue +0 -561
  70. package/src/components/collections/attachment/AttachmentInline.vue +0 -90
  71. package/src/components/collections/attachment/AttachmentMenu.vue +0 -359
  72. package/src/components/collections/attachment/VideoDetail.vue +0 -375
  73. package/src/components/collections/attachment/index.ts +0 -6
  74. package/src/components/collections/basic/Blockquote.vue +0 -15
  75. package/src/components/collections/basic/BulletList.vue +0 -15
  76. package/src/components/collections/basic/HardBreak.vue +0 -11
  77. package/src/components/collections/basic/Heading.vue +0 -15
  78. package/src/components/collections/basic/HorizontalRule.vue +0 -11
  79. package/src/components/collections/basic/ListItem.vue +0 -15
  80. package/src/components/collections/basic/OrderedList.vue +0 -15
  81. package/src/components/collections/basic/Paragraph.vue +0 -19
  82. package/src/components/collections/basic/Text.vue +0 -73
  83. package/src/components/collections/basic/index.ts +0 -13
  84. package/src/components/collections/callout/Callout.vue +0 -77
  85. package/src/components/collections/callout/index.ts +0 -5
  86. package/src/components/collections/code/CellOutput.vue +0 -72
  87. package/src/components/collections/code/CodeBlock.vue +0 -83
  88. package/src/components/collections/code/index.ts +0 -6
  89. package/src/components/collections/fold/FoldBlock.vue +0 -130
  90. package/src/components/collections/fold/index.ts +0 -5
  91. package/src/components/collections/grid/Grid.vue +0 -70
  92. package/src/components/collections/grid/index.ts +0 -5
  93. package/src/components/collections/iframe/IFrame.vue +0 -19
  94. package/src/components/collections/iframe/index.ts +0 -5
  95. package/src/components/collections/img/Image.vue +0 -318
  96. package/src/components/collections/img/index.ts +0 -5
  97. package/src/components/collections/index.ts +0 -29
  98. package/src/components/collections/math/MathDisplay.vue +0 -42
  99. package/src/components/collections/math/MathInline.vue +0 -42
  100. package/src/components/collections/math/index.ts +0 -6
  101. package/src/components/collections/multipleChoice/McChoices.vue +0 -72
  102. package/src/components/collections/multipleChoice/McQuestion.vue +0 -61
  103. package/src/components/collections/multipleChoice/McSolution.vue +0 -47
  104. package/src/components/collections/multipleChoice/MultipleChoice.vue +0 -62
  105. package/src/components/collections/multipleChoice/index.ts +0 -8
  106. package/src/components/collections/table/TableCell.vue +0 -20
  107. package/src/components/collections/table/TableContainer.vue +0 -32
  108. package/src/components/collections/table/TableHeader.vue +0 -15
  109. package/src/components/collections/table/TableRow.vue +0 -15
  110. package/src/components/collections/table/index.ts +0 -8
  111. package/src/components/collections/utils.ts +0 -17
  112. package/src/components/collections/wrapper/Doc.vue +0 -15
  113. package/src/components/collections/wrapper/SlotNode.vue +0 -5
  114. package/src/components/collections/wrapper/index.ts +0 -6
  115. package/src/components/index.ts +0 -1
  116. package/src/icons/Attachment/CardView.vue +0 -21
  117. package/src/icons/Attachment/Code/Bat.vue +0 -26
  118. package/src/icons/Attachment/Code/C.vue +0 -26
  119. package/src/icons/Attachment/Code/Cpp.vue +0 -26
  120. package/src/icons/Attachment/Code/Css.vue +0 -34
  121. package/src/icons/Attachment/Code/Go.vue +0 -26
  122. package/src/icons/Attachment/Code/Html.vue +0 -34
  123. package/src/icons/Attachment/Code/Java.vue +0 -42
  124. package/src/icons/Attachment/Code/Js.vue +0 -26
  125. package/src/icons/Attachment/Code/Json.vue +0 -26
  126. package/src/icons/Attachment/Code/Jsx.vue +0 -30
  127. package/src/icons/Attachment/Code/Md.vue +0 -26
  128. package/src/icons/Attachment/Code/Php.vue +0 -26
  129. package/src/icons/Attachment/Code/Python.vue +0 -30
  130. package/src/icons/Attachment/Code/Rb.vue +0 -26
  131. package/src/icons/Attachment/Code/Sh.vue +0 -30
  132. package/src/icons/Attachment/Code/Sql.vue +0 -30
  133. package/src/icons/Attachment/Code/Swift.vue +0 -26
  134. package/src/icons/Attachment/Code/Ts.vue +0 -26
  135. package/src/icons/Attachment/Code/Tsx.vue +0 -30
  136. package/src/icons/Attachment/Code/Vue.vue +0 -24
  137. package/src/icons/Attachment/Excel.vue +0 -26
  138. package/src/icons/Attachment/Eye.vue +0 -15
  139. package/src/icons/Attachment/FullScreen.vue +0 -15
  140. package/src/icons/Attachment/InlineView.vue +0 -21
  141. package/src/icons/Attachment/Pdf.vue +0 -25
  142. package/src/icons/Attachment/Ppt.vue +0 -26
  143. package/src/icons/Attachment/PreviewView.vue +0 -21
  144. package/src/icons/Attachment/UnknownFile.vue +0 -26
  145. package/src/icons/Attachment/VideoIcon.vue +0 -25
  146. package/src/icons/Attachment/VideoPlay.vue +0 -15
  147. package/src/icons/Attachment/Word.vue +0 -26
  148. package/src/icons/Code/Confirm.vue +0 -38
  149. package/src/icons/Code/Paste.vue +0 -8
  150. package/src/icons/Common/Choice.vue +0 -28
  151. package/src/icons/Common/Close.vue +0 -15
  152. package/src/icons/Common/Comment.vue +0 -16
  153. package/src/icons/Common/CopyAnchorLink.vue +0 -15
  154. package/src/icons/Common/Delete.vue +0 -15
  155. package/src/icons/Common/Download.vue +0 -15
  156. package/src/icons/Common/FoldClose.vue +0 -9
  157. package/src/icons/Common/FoldOpen.vue +0 -9
  158. package/src/icons/Common/Plate.vue +0 -23
  159. package/src/icons/Common/Question.vue +0 -8
  160. package/src/icons/Common/ShareTextLink.vue +0 -15
  161. package/src/index.ts +0 -3
  162. package/src/types.ts +0 -236
  163. package/src/utils/common.ts +0 -6
  164. package/src/utils/emoji.ts +0 -3715
  165. package/src/utils/globalStatus.ts +0 -19
  166. package/src/utils/shiki.ts +0 -25
  167. package/src/utils/useAttachment.ts +0 -215
  168. package/tsconfig.build.json +0 -10
  169. package/tsconfig.json +0 -23
  170. package/vite.config.ts +0 -24
  171. /package/dist/{Blockquote-BamWUQND.mjs → Blockquote-BamWUQND.js} +0 -0
  172. /package/dist/{Blockquote-CQSBFnsu.js → Blockquote-CQSBFnsu.cjs} +0 -0
  173. /package/dist/{BulletList-BQTUD69X.mjs → BulletList-BQTUD69X.js} +0 -0
  174. /package/dist/{BulletList-CFjF3U-l.js → BulletList-CFjF3U-l.cjs} +0 -0
  175. /package/dist/{Doc-6s4VMDsx.mjs → Doc-6s4VMDsx.js} +0 -0
  176. /package/dist/{Doc-D2yvlSII.js → Doc-D2yvlSII.cjs} +0 -0
  177. /package/dist/{HardBreak-B2tFO31P.mjs → HardBreak-B2tFO31P.js} +0 -0
  178. /package/dist/{HardBreak-Dbf5Zg5o.js → HardBreak-Dbf5Zg5o.cjs} +0 -0
  179. /package/dist/{Heading-BElRvhGn.mjs → Heading-BElRvhGn.js} +0 -0
  180. /package/dist/{Heading-BUnffIAz.js → Heading-BUnffIAz.cjs} +0 -0
  181. /package/dist/{HorizontalRule-BRG45oT0.mjs → HorizontalRule-BRG45oT0.js} +0 -0
  182. /package/dist/{HorizontalRule-CE09LZGf.js → HorizontalRule-CE09LZGf.cjs} +0 -0
  183. /package/dist/{ListItem-BrjxeGxz.js → ListItem-BrjxeGxz.cjs} +0 -0
  184. /package/dist/{ListItem-X0T7a_z8.mjs → ListItem-X0T7a_z8.js} +0 -0
  185. /package/dist/{OrderedList-B8v1gchv.mjs → OrderedList-B8v1gchv.js} +0 -0
  186. /package/dist/{OrderedList-DMl3tvwP.js → OrderedList-DMl3tvwP.cjs} +0 -0
  187. /package/dist/{TableCell-BY9gdldc.js → TableCell-BY9gdldc.cjs} +0 -0
  188. /package/dist/{TableCell-Bp52L368.mjs → TableCell-Bp52L368.js} +0 -0
  189. /package/dist/{TableContainer-C5KXY6f7.js → TableContainer-C5KXY6f7.cjs} +0 -0
  190. /package/dist/{TableContainer-C9PhNGlz.mjs → TableContainer-C9PhNGlz.js} +0 -0
  191. /package/dist/{TableHeader-BTuqvorM.js → TableHeader-BTuqvorM.cjs} +0 -0
  192. /package/dist/{TableHeader-C7KKz3e1.mjs → TableHeader-C7KKz3e1.js} +0 -0
  193. /package/dist/{TableRow-D4F6AKFt.js → TableRow-D4F6AKFt.cjs} +0 -0
  194. /package/dist/{TableRow-OzpVq1qW.mjs → TableRow-OzpVq1qW.js} +0 -0
  195. /package/dist/{emoji-Bk6FG72F.js → emoji-Bk6FG72F.cjs} +0 -0
  196. /package/dist/{emoji-CmOToDEU.mjs → emoji-CmOToDEU.js} +0 -0
  197. /package/dist/{katex-CS0ZfoxP.js → katex-CS0ZfoxP.cjs} +0 -0
  198. /package/dist/{katex-r9TeExgs.mjs → katex-r9TeExgs.js} +0 -0
@@ -1,561 +0,0 @@
1
- <template>
2
- <div @mouseenter="isHovered = true" @mouseleave="handleMouseLeave" class="attachment-block-container">
3
- <div v-if="node.attrs.dispType === 'card'" class="attachment-block-card-container">
4
- <div class="attachment-block-card-icon">
5
- <component :is="icon" class="attachment-block-card-icon-svg" />
6
- </div>
7
- <div class="attachment-block-card-info">
8
- <div class="attachment-block-card-info-name">{{ node.attrs.fileName }}.{{ node.attrs.fileType }}</div>
9
- <div class="attachment-block-card-info-size" v-if="!uploading && !node.attrs.uploadError">
10
- {{ calculatedFileSize }}
11
- </div>
12
- <div class="attachment-block-card-info-size" v-else-if="uploading && !node.attrs.uploadError">
13
- 附件正在上传中,请等待...
14
- </div>
15
- <div class="attachment-block-card-info-size" v-else style="color: rgb(247, 78, 0)">
16
- 附件出错,请等待管理员处理
17
- </div>
18
- </div>
19
- <div class="attachment-block-card-preview">
20
- <!-- TODO:不使用Element-Plus的v-loading,为图标添加上传时的loading状态 -->
21
- <div class="attachment-block-card-preview-wrapper" @click="handleFullScreen">
22
- <component :is="isVideo(node.attrs.fileType) ? VideoPlay : Eye" class="attachment-block-card-preview-btn" />
23
- </div>
24
- </div>
25
- <div class="attachment-block-card-menu" v-show="isHovered && !uploading && !node.attrs.uploadError"
26
- @mouseenter="handleEnterMenu">
27
- <AttachmentMenu :node="node" v-model:show-full-screen-dialog="showFullScreenPreview" />
28
- </div>
29
- </div>
30
- <div v-else-if="node.attrs.dispType === 'preview'" class="attachment-block-preview-container">
31
- <!-- 判断是否是视频文件类型 -->
32
- <div v-if="isVideo(node.attrs.fileType)" class="video-block-preview-container">
33
- <div class="video-block-container" :class="{ 'has-sidebar': showAiPanel }">
34
- <div class="video-main-section">
35
- <div class="video-player-wrapper" v-if="!uploading && !node.attrs.uploadError">
36
- <video ref="videoPreviewRef" :src="resolvedFileUrl(node.attrs.src)" controls
37
- class="video-element"></video>
38
- </div>
39
-
40
- <div class="video-uploading-wrapper" v-else>
41
- <div class="uploading-content" v-if="!node.attrs.uploadError">
42
- <div class="spinner"></div>
43
- <span>视频正在上传中,请等待...</span>
44
- </div>
45
- <div class="error-content" v-else>
46
- <span>⚠️ 视频出错,请等待管理员处理</span>
47
- </div>
48
- </div>
49
-
50
- <div class="video-toolbar" v-if="!uploading && node.attrs.tingwuTaskId">
51
- <div class="toolbar-info">
52
- <span class="toolbar-title">分析</span>
53
- <span class="toolbar-desc">摘要与章节</span>
54
- </div>
55
- <button class="ai-toggle-btn" :class="{ active: showAiPanel }" @click="toggleAiPanel">
56
- <i class="icon-ai">✨</i> {{ showAiPanel ? '收起助手' : 'AI 助手' }}
57
- </button>
58
- </div>
59
- </div>
60
-
61
- <div class="video-sidebar-section" v-if="showAiPanel">
62
- <VideoDetail :taskId="node.attrs.tingwuTaskId!" :videoRef="videoPreviewRef" @close="showAiPanel = false" />
63
- </div>
64
- </div>
65
- </div>
66
- <!-- 非视频类型的文件预览 -->
67
- <div v-else class="notVideo-block-preview-container">
68
- <div class="attachment-block-preview-content" :class="{ 'attachment-block-preview-dark-bg': !canPreview }">
69
- <component v-if="canPreview" class="attachment-block-preview-iframe"
70
- :src="resolvedFileUrl(genPreviewSrc(node.attrs.src))"
71
- :is="node.attrs.fileType === 'pdf' ? 'embed' : 'iframe'"></component>
72
- <div class="attachment-block-preview-unable" v-else>
73
- <img class="attachment-block-preview-unable-img" :src="cannotPreviewImgDataUrl" alt="该文件类型无法预览" />
74
- <div class="attachment-block-preview-unable-text">
75
- <strong style="font-weight: bold">.{{ node.attrs.fileType }}</strong>文件类型无法预览
76
- </div>
77
- <div class="attachment-block-preview-unable-text">
78
- {{ node.attrs.fileName }}.{{ node.attrs.fileType }}&nbsp;·&nbsp;{{ calculatedFileSize }}
79
- </div>
80
- </div>
81
- </div>
82
- <div class="attachment-block-preview-footer" :class="{ 'attachment-block-preview-dark-bg': !canPreview }">
83
- <component :is="icon" class="attachment-block-preview-icon-svg" />
84
- <span class="attachment-block-preview-info">{{ node.attrs.fileName }}.{{ node.attrs.fileType }}</span>
85
- </div>
86
- </div>
87
- <div class="attachment-block-preview-menu" v-show="isHovered && !uploading && !node.attrs.uploadError"
88
- @mouseenter="handleEnterMenu">
89
- <AttachmentMenu :node="node" />
90
- </div>
91
- </div>
92
- </div>
93
- </template>
94
-
95
- <script setup lang="ts">
96
- import { computed, inject, ref, useTemplateRef } from 'vue';
97
- import { monitorApi } from '@datawhale/dipwap-render/apis/monitor';
98
- import { axiosKey } from '@datawhale/dipwap-render/apis/types';
99
- import Eye from '@datawhale/dipwap-render/icons/Attachment/Eye.vue';
100
- import VideoPlay from '@datawhale/dipwap-render/icons/Attachment/VideoPlay.vue';
101
- import { resolvedFileUrl } from '@datawhale/dipwap-render/utils/common';
102
- import { useAttachment } from '@datawhale/dipwap-render/utils/useAttachment';
103
- import type { PMAttachmentBlock } from '@datawhale/dipwap-types/index';
104
- import AttachmentMenu from './AttachmentMenu.vue';
105
- import VideoDetail from './VideoDetail.vue';
106
-
107
- const { node } = defineProps<{
108
- node: PMAttachmentBlock;
109
- }>();
110
-
111
- const service = inject(axiosKey);
112
-
113
- const videoPreviewRef = useTemplateRef('videoPreviewRef');
114
-
115
- const uploading = computed(() => node.attrs.uploadProgress === undefined || node.attrs.uploadProgress < 1);
116
-
117
- const { icon, calculatedFileSize, cannotPreviewImgDataUrl, canPreview, genPreviewSrc } = useAttachment(
118
- node.attrs.fileType,
119
- node.attrs.fileSize,
120
- );
121
-
122
- // 检查文件类型是否是视频
123
- const isVideo = (fileType: string) => {
124
- const videoTypes = ['mp4', 'avi', 'mkv', 'mov'];
125
- return videoTypes.includes(fileType);
126
- };
127
-
128
- const showAiPanel = ref(false);
129
-
130
- const toggleAiPanel = async () => {
131
- showAiPanel.value = !showAiPanel.value;
132
- if (service && showAiPanel.value && node.attrs.tingwuTaskId) {
133
- // @ts-ignore
134
- await monitorApi(service, {
135
- log: JSON.stringify({
136
- name: 'toggleVideoAiPanel',
137
- tingwuTaskId: node.attrs.tingwuTaskId,
138
- videoPageUrl: window.location.href,
139
- }),
140
- });
141
- }
142
- };
143
-
144
- const showFullScreenPreview = ref(false);
145
- const handleFullScreen = () => {
146
- showFullScreenPreview.value = true;
147
- alert('全屏预览功能将在后续版本中开放');
148
- };
149
-
150
- // 菜单相关
151
- // 菜单与节点之间有缝隙,所以需要延迟关闭菜单的时间,使得鼠标在移动到菜单上时经过缝隙而不会关闭菜单
152
- const isHovered = ref(false); // 鼠标是否在节点上
153
- const timer = ref<number | null>(null);
154
-
155
- const handleMouseLeave = () => {
156
- timer.value = setTimeout(() => {
157
- isHovered.value = false;
158
- }, 200) as unknown as number;
159
- };
160
-
161
- const handleEnterMenu = () => {
162
- if (timer.value) {
163
- clearTimeout(timer.value);
164
- timer.value = null;
165
- }
166
- };
167
- </script>
168
-
169
- <style scoped lang="scss">
170
- // 变量定义
171
- $primary-color: #2563eb;
172
- $border-color: #e5e7eb;
173
- $bg-gray: #f9fafb;
174
- $text-main: #111827;
175
- $text-sub: #6b7280;
176
-
177
- .attachment-block-container {
178
- margin: 16px 0;
179
- }
180
-
181
- .attachment-block-card-container {
182
- display: flex;
183
- position: relative;
184
- align-items: center;
185
- justify-content: center;
186
- width: 100%;
187
- max-width: 400px;
188
- height: 65.14px;
189
- box-sizing: border-box;
190
- background-color: #fff;
191
- border-radius: 8px;
192
- border: 1px solid rgb(222, 224, 227);
193
- cursor: pointer;
194
-
195
- &:hover {
196
- border-color: rgb(194, 212, 255);
197
- box-shadow: rgb(194, 212, 255) 0px 0px 0px 1px;
198
- }
199
-
200
- .attachment-block-card-icon {
201
- width: 48px;
202
- height: 48px;
203
- margin: 8px 12px 8px 8px;
204
- box-sizing: border-box;
205
-
206
- .attachment-block-card-icon-svg {
207
- width: 48px;
208
- height: 48px;
209
- }
210
- }
211
-
212
- .attachment-block-card-info {
213
- flex: 1;
214
- display: flex;
215
- flex-direction: column;
216
- justify-content: center;
217
-
218
- .attachment-block-card-info-name {
219
- user-select: none;
220
- display: -webkit-box;
221
- -webkit-line-clamp: 2;
222
- -webkit-box-orient: vertical;
223
- text-overflow: ellipsis;
224
- text-align: left;
225
- overflow: hidden;
226
- color: #1f2329;
227
- max-height: 44px;
228
- max-width: 260px;
229
- line-height: 22px;
230
- }
231
-
232
- .attachment-block-card-info-size {
233
- height: 17px;
234
- white-space: nowrap;
235
- font-size: 12px;
236
- color: #646a73;
237
- user-select: none;
238
- line-height: 1.8;
239
- }
240
- }
241
-
242
- .attachment-block-card-preview {
243
- padding-right: 4px;
244
- margin: auto;
245
- height: 48px;
246
- display: flex;
247
- align-items: center;
248
- box-sizing: border-box;
249
-
250
- .attachment-block-card-preview-wrapper {
251
- text-decoration: none;
252
- text-overflow: ellipsis;
253
- white-space: nowrap;
254
- height: 34px;
255
- width: 34px;
256
- text-align: center;
257
- position: relative;
258
- overflow: unset;
259
- margin: 0 16px;
260
- cursor: pointer;
261
- padding: 4px;
262
- line-height: 24px;
263
- display: flex;
264
- justify-content: center;
265
- align-items: center;
266
- box-sizing: border-box;
267
-
268
- &:hover {
269
- background-color: rgba(31, 35, 41, 0.08);
270
- border-radius: 6px;
271
- }
272
-
273
- .attachment-block-card-preview-btn {
274
- height: 20px;
275
- width: 20px;
276
- }
277
- }
278
- }
279
-
280
- .attachment-block-card-menu {
281
- position: absolute;
282
- top: -46px;
283
- left: 200px;
284
- z-index: 86;
285
- transform: translateX(-50%);
286
- }
287
- }
288
-
289
- .attachment-block-preview-container {
290
- position: relative;
291
-
292
- .attachment-block-preview-menu {
293
- position: absolute;
294
- top: -46px;
295
- left: 410px;
296
- z-index: 86;
297
- transform: translateX(-50%);
298
- }
299
-
300
- .video-block-preview-container {
301
- display: flex;
302
- flex-direction: column;
303
- justify-content: center;
304
- align-items: center;
305
- margin-bottom: 16px;
306
-
307
- // --- 灰色大卡片容器 ---
308
- .video-block-container {
309
- // 【关键 1】作为定位锚点
310
- position: relative;
311
-
312
- display: flex;
313
- flex-direction: column;
314
- gap: 16px;
315
- background-color: $bg-gray; // 确保有这个变量,或者用 #f9fafb
316
- border: 1px solid $border-color;
317
- border-radius: 12px;
318
- padding: 16px;
319
- margin: 16px 0;
320
- transition: all 0.3s ease;
321
-
322
- // 【关键 2】允许子元素(侧边栏)显示在盒子外部
323
- overflow: visible;
324
- }
325
-
326
- .video-main-section {
327
- flex: 1;
328
- width: 100%;
329
- min-width: 0;
330
- display: flex;
331
- flex-direction: column;
332
- gap: 12px;
333
- }
334
-
335
- // --- 视频播放器 ---
336
- .video-player-wrapper {
337
- width: 100%;
338
- aspect-ratio: 16 / 9;
339
- background-color: #000;
340
- border-radius: 8px;
341
- overflow: hidden;
342
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
343
-
344
- .video-element {
345
- width: 100%;
346
- height: 100%;
347
- object-fit: contain;
348
- }
349
- }
350
-
351
- // --- 上传状态 ---
352
- .video-uploading-wrapper {
353
- width: 100%;
354
- aspect-ratio: 16 / 9;
355
- background-color: #fff;
356
- border-radius: 8px;
357
- display: flex;
358
- align-items: center;
359
- justify-content: center;
360
- border: 1px dashed $border-color;
361
-
362
- .uploading-content,
363
- .error-content {
364
- display: flex;
365
- flex-direction: column;
366
- align-items: center;
367
- gap: 8px;
368
- font-size: 14px;
369
- color: $text-sub;
370
- }
371
-
372
- .error-content {
373
- color: #ef4444;
374
- }
375
-
376
- .spinner {
377
- width: 24px;
378
- height: 24px;
379
- border: 2px solid #e5e7eb;
380
- border-top-color: $primary-color;
381
- border-radius: 50%;
382
- animation: spin 1s linear infinite;
383
- }
384
- }
385
-
386
- // --- 工具栏 ---
387
- .video-toolbar {
388
- display: flex;
389
- justify-content: space-between;
390
- align-items: center;
391
- background: #fff;
392
- padding: 12px;
393
- border-radius: 8px;
394
- border: 1px solid $border-color;
395
-
396
- .toolbar-info {
397
- display: flex;
398
- flex-direction: column;
399
-
400
- .toolbar-title {
401
- font-weight: 500;
402
- color: $text-main;
403
- font-size: 14px;
404
- }
405
-
406
- .toolbar-desc {
407
- font-size: 12px;
408
- color: $text-sub;
409
-
410
- @media (max-width: 380px) {
411
- display: none;
412
- }
413
- }
414
- }
415
-
416
- .ai-toggle-btn {
417
- display: flex;
418
- align-items: center;
419
- gap: 6px;
420
- padding: 8px 16px;
421
- border-radius: 6px;
422
- font-size: 14px;
423
- font-weight: 500;
424
- cursor: pointer;
425
- border: none;
426
- background-color: $primary-color;
427
- color: white;
428
- -webkit-tap-highlight-color: transparent;
429
-
430
- &:active {
431
- opacity: 0.9;
432
- }
433
-
434
- &.active {
435
- background-color: #eff6ff;
436
- color: $primary-color;
437
- border: 1px solid #bfdbfe;
438
- }
439
- }
440
- }
441
-
442
- // --- 【关键 3】完全位于右侧外部的 AI 面板 ---
443
- .video-sidebar-section {
444
- width: 100%; // 移动端默认样式
445
-
446
- // 桌面端逻辑 (大于 768px 或根据你的布局宽度调整)
447
- @media (min-width: 768px) {
448
- // 1. 绝对定位
449
- position: absolute;
450
-
451
- // 2. 顶部与卡片对齐
452
- top: 0;
453
-
454
- // 3. 位于卡片右侧外部 (left: 100% 表示从容器最右边开始)
455
- left: 100%;
456
-
457
- // 4. 间距调整
458
- margin-left: 16px;
459
-
460
- // 5. 尺寸与高度 (由内容自动撑开,不强制拉伸)
461
- width: 320px;
462
- height: auto;
463
- // max-height: 100%; // 如果你想限制高度不超过视频卡片,取消这行注释
464
-
465
- // 6. 视觉样式 (因为它在外面,需要单独的卡片样式)
466
- background-color: #fff;
467
- border: 1px solid $border-color;
468
- border-radius: 12px;
469
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
470
- padding: 0; // 如果 VideoDetail 自带 padding,这里设为 0
471
- z-index: 1;
472
-
473
- // 7. 动画
474
- animation: fadeInRight 0.3s ease-out;
475
- }
476
- }
477
-
478
- @keyframes spin {
479
- to {
480
- transform: rotate(360deg);
481
- }
482
- }
483
-
484
- @keyframes fadeInRight {
485
- from {
486
- opacity: 0;
487
- transform: translateX(-10px);
488
- }
489
-
490
- to {
491
- opacity: 1;
492
- transform: translateX(0);
493
- }
494
- }
495
- }
496
-
497
- .notVideo-block-preview-container {
498
- max-width: 820px;
499
- border-radius: 8px;
500
- border: 1px solid #dee0e3;
501
-
502
- .attachment-block-preview-content {
503
- height: 409px;
504
- box-sizing: border-box;
505
- display: flex;
506
- flex-direction: column;
507
- align-items: center;
508
- justify-content: center;
509
-
510
- .attachment-block-preview-iframe {
511
- width: 100%;
512
- height: 100%;
513
- border-top-left-radius: 8px;
514
- border-top-right-radius: 8px;
515
- }
516
-
517
- .attachment-block-preview-unable {
518
- width: 100%;
519
- display: flex;
520
- flex-direction: column;
521
- align-items: center;
522
- justify-content: center;
523
-
524
- .attachment-block-preview-unable-img {
525
- width: 120px;
526
- height: 120px;
527
- display: block;
528
- margin-bottom: 16px;
529
- }
530
-
531
- .attachment-block-preview-unable-text {
532
- font-size: 14px;
533
- color: rgb(100, 106, 115);
534
- margin-top: 4px;
535
- line-height: 1.8;
536
- }
537
- }
538
- }
539
-
540
- .attachment-block-preview-footer {
541
- height: 42px;
542
- box-sizing: border-box;
543
- padding: 0 12px;
544
- display: flex;
545
- align-items: center;
546
- border-top: 1px solid #dee0e3;
547
- background-color: #fff;
548
-
549
- .attachment-block-preview-icon-svg {
550
- width: 18px;
551
- height: 18px;
552
- margin-right: 8px;
553
- }
554
- }
555
-
556
- .attachment-block-preview-dark-bg {
557
- background-color: rgb(242, 243, 245);
558
- }
559
- }
560
- }
561
- </style>
@@ -1,90 +0,0 @@
1
- <template>
2
- <div class="attachment-inline-container" @mouseenter="isHovered = true" @mouseleave="handleMouseLeave">
3
- <component :is="icon" class="attachment-inline-icon" ref="iconRef" />
4
- <span class="attachment-inline-text" ref="textRef">{{ node.attrs.fileName }}.{{ node.attrs.fileType }}</span>
5
- <div class="attachment-inline-menu" v-show="isHovered" @mouseenter="handleEnterMenu">
6
- <AttachmentMenu :node="node" />
7
- </div>
8
- </div>
9
- </template>
10
-
11
- <script setup lang="ts">
12
- import { nextTick, onMounted, ref } from 'vue';
13
- import { useAttachment } from '@datawhale/dipwap-render/utils/useAttachment';
14
- import type { PMAttachmentInline } from '@datawhale/dipwap-types/index';
15
- import AttachmentMenu from './AttachmentMenu.vue';
16
-
17
- const { node } = defineProps<{ node: PMAttachmentInline }>();
18
- const { icon } = useAttachment(node.attrs.fileType, node.attrs.fileSize);
19
-
20
- const textRef = ref<HTMLSpanElement | null>(null);
21
-
22
- const totalWidth = ref(`0px`);
23
-
24
- onMounted(async () => {
25
- const iconWidth = 1.15 * parseFloat(getComputedStyle(document.documentElement).fontSize);
26
- await nextTick();
27
- if (textRef.value) {
28
- totalWidth.value = `${(iconWidth + textRef.value!.offsetWidth + 2) / 2}px`;
29
- }
30
- });
31
-
32
- // 菜单相关
33
- // 菜单与节点之间有缝隙,所以需要延迟关闭菜单的时间,使得鼠标在移动到菜单上时经过缝隙而不会关闭菜单
34
- const isHovered = ref(false); // 鼠标是否在节点上
35
- const timer = ref<number | null>(null);
36
-
37
- const handleMouseLeave = () => {
38
- // esl
39
- timer.value = setTimeout(() => {
40
- isHovered.value = false;
41
- }, 200) as unknown as number;
42
- };
43
-
44
- const handleEnterMenu = () => {
45
- if (timer.value) {
46
- clearTimeout(timer.value);
47
- timer.value = null;
48
- }
49
- };
50
- </script>
51
-
52
- <style scoped lang="scss">
53
- .attachment-inline-container {
54
- display: inline-block;
55
- height: 100%;
56
- box-sizing: border-box;
57
- line-height: 1.15em;
58
- padding: 3px 2px;
59
- position: relative;
60
- cursor: pointer;
61
-
62
- &:hover {
63
- background-color: rgba(51, 109, 244, 0.1);
64
- border-radius: 4px;
65
- }
66
-
67
- .attachment-inline-icon {
68
- width: 1.15em;
69
- height: 1.15em;
70
- -webkit-transform: translateY(2px);
71
- transform: translateY(2px);
72
- }
73
-
74
- .attachment-inline-text {
75
- margin-left: 2px;
76
- color: rgb(20, 86, 240);
77
- }
78
-
79
- .attachment-inline-loading {
80
- color: rgb(119, 164, 226);
81
- }
82
-
83
- .attachment-inline-menu {
84
- position: absolute;
85
- top: -46px;
86
- left: v-bind(totalWidth);
87
- transform: translateX(-50%);
88
- }
89
- }
90
- </style>