@tencentcloud/ai-desk-customer-vue 1.5.9 → 1.5.10

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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 1.5.9 @2025.9.18
2
+
3
+ ### Features
4
+ - 支持展示工作台快捷回复的视频。
5
+ - 固定底部弹窗的提交按钮,不随内容滚动,优化产品体验。
6
+ - 优化组件内超链接 的 title 和字体颜色。
7
+
1
8
  ## 1.5.9 @2025.9.8
2
9
 
3
10
  ### Features
@@ -11,10 +11,23 @@ export const marked = new Marked(
11
11
  class="image-container"
12
12
  onclick="onMarkdownImageClicked('${safeHref}')"
13
13
  style="cursor:pointer;" >
14
- <img src="${href}" alt="${text}" onload="onMarkdownImageLoad()"/>
14
+ <img src="${href}" alt="${text}" onload="onMarkdownMediaLoad()"/>
15
15
  </div>
16
16
  `;
17
17
  },
18
+ paragraph(text: string) {
19
+ if (text.startsWith('<video')) {
20
+ const videoSrc = extractVideoSrc(text) || '';
21
+ if (videoSrc) {
22
+ return `<div class="message-video">
23
+ <div class="message-video-box">
24
+ <video class="message-img video-web" src="${videoSrc}" onloadeddata="onMarkdownMediaLoad()" preload="auto" controls/>
25
+ </div>
26
+ </div>`;
27
+ }
28
+ }
29
+ return text
30
+ },
18
31
  link(this: any, href: string | null, title: string | null, text: string) {
19
32
  if (href) {
20
33
  // 匹配以 http:// 或 https:// 开头,所有 URL 主体字符,遇到第一个非主体字符(如中文括号、空格、表情符号等)时停止
@@ -24,7 +37,7 @@ export const marked = new Marked(
24
37
  // 如果 text 里包含 url,我们就用 matchedUrl 作为 a 标签的值;否则用 text 作为值
25
38
  isURLInText = true;
26
39
  }
27
- return `<a target="_blank" rel="noreferrer noopenner" class="message-marked_link" href="${matchedUrl || ''}" title="${title}">${isURLInText ? matchedUrl : text}</a>`;
40
+ return `<a target="_blank" rel="noreferrer noopenner" class="message-marked_link" href="${matchedUrl || ''}" title="${title || ''}">${isURLInText ? matchedUrl : text}</a>`;
28
41
  });
29
42
  if (ret === href) {
30
43
  Log.w(`Unable to extract url, href:${href}`);
@@ -37,6 +50,12 @@ export const marked = new Marked(
37
50
  },
38
51
  );
39
52
 
53
+ const extractVideoSrc = (text: string) => {
54
+ const videoSrcRegex = /<video[^>]*src=["']([^"']*)["'][^>]*>/gi;
55
+ const result = videoSrcRegex.exec(text);
56
+ return result ? result[1] : null;
57
+ }
58
+
40
59
  export const parseMarkdown = (text: string) => {
41
60
  let ret = marked.parse(text);
42
61
  return typeof ret === 'string' ? ret : '';
@@ -15,7 +15,7 @@
15
15
  @onClose="closeDialog"
16
16
  title=""
17
17
  >
18
- <div style="height:100%;">
18
+ <div class="dialog-container">
19
19
  <div class="dialog-title">
20
20
  <div class="dialog-title-tip">
21
21
  {{ props.payload.content.tip }}
@@ -44,10 +44,10 @@
44
44
  </div>
45
45
  </div>
46
46
  </div>
47
- <div class="button-container" v-if="props.payload.nodeStatus === 0">
48
- <div class="button" @click="handleSendForm">
49
- {{ TUITranslateService.t("AIDesk.提交") }}
50
- </div>
47
+ </div>
48
+ <div class="button-container" v-if="props.payload.nodeStatus === 0">
49
+ <div class="button" @click="handleSendForm">
50
+ {{ TUITranslateService.t("AIDesk.提交") }}
51
51
  </div>
52
52
  </div>
53
53
  </div>
@@ -356,6 +356,12 @@ export default {
356
356
  }
357
357
  }
358
358
 
359
+ .dialog-container {
360
+ height: 100%;
361
+ display: flex;
362
+ flex-direction: column;
363
+ }
364
+
359
365
  .dialog-title {
360
366
  display: flex;
361
367
  flex-direction: row;
@@ -27,8 +27,7 @@ interface Props {
27
27
  payload: customerServicePayloadType;
28
28
  }
29
29
  export default {
30
- components: {
31
- },
30
+ components: {},
32
31
  props: {
33
32
  payload: {
34
33
  type: Object as () => customerServicePayloadType,
@@ -41,12 +40,12 @@ export default {
41
40
  const imageList = [];
42
41
  const parsedContent = computed(() => {
43
42
  // @ts-ignore
44
- window.onMarkdownImageClicked = function(href:string) {
43
+ window.onMarkdownImageClicked = function(href: string) {
45
44
  image.value = !image.value;
46
45
  imageSrc.value = decodeURIComponent(href);
47
46
  }
48
47
  // @ts-ignore
49
- window.onMarkdownImageLoad = function() {
48
+ window.onMarkdownMediaLoad = function() {
50
49
  emit('heightChanged');
51
50
  }
52
51
  return parseMarkdown(props.payload.content);
@@ -63,7 +62,7 @@ export default {
63
62
  image,
64
63
  imageSrc,
65
64
  closeImage,
66
- imageList
65
+ imageList,
67
66
  };
68
67
  },
69
68
  };
@@ -93,4 +92,57 @@ export default {
93
92
  overflow: hidden;
94
93
  pointer-events: auto;
95
94
  }
95
+ .message-video {
96
+ position: relative;
97
+ display: flex;
98
+ justify-content: center;
99
+ overflow: hidden;
100
+
101
+ &-box {
102
+ max-width: min(calc(100vw - 180px), 300px);
103
+ font-size: 0;
104
+
105
+ video {
106
+ max-width: min(calc(100vw - 180px), 300px);
107
+ max-height: min(calc(100vw - 180px), 300px);
108
+ width: inherit;
109
+ height: inherit;
110
+ }
111
+ }
112
+ }
113
+ .dialog-video {
114
+ position: fixed;
115
+ z-index: 12;
116
+ width: 100vw;
117
+ height: 100vh;
118
+ top: 0;
119
+ left: 0;
120
+ display: flex;
121
+ flex-direction: column;
122
+ align-items: center;
123
+
124
+ &-close {
125
+ display: flex;
126
+ justify-content: flex-end;
127
+ background: #000;
128
+ width: 100%;
129
+ box-sizing: border-box;
130
+ padding: 10px;
131
+ }
132
+
133
+ &-box {
134
+ display: flex;
135
+ flex: 1;
136
+ max-height: 100%;
137
+ padding: 6rem;
138
+ box-sizing: border-box;
139
+ justify-content: center;
140
+ align-items: center;
141
+
142
+ video {
143
+ max-width: 100%;
144
+ max-height: 100%;
145
+ }
146
+ }
147
+ }
96
148
  </style>
@@ -41,7 +41,7 @@ const props = withDefaults(defineProps<IProps>(), {
41
41
  });
42
42
  const enableURLDetection = ref(state.get('enableURLDetection'));
43
43
  const linkColor = computed(() => {
44
- return props.flow === 'out' && isPC ? '#fff' : '#0052d9';
44
+ return props.flow === 'out' ? '#fff' : '#0052d9';
45
45
  });
46
46
  const textMessageData = computed(() => {
47
47
  const contentCopy = JSON.parse(JSON.stringify(props.content));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tencentcloud/ai-desk-customer-vue",
3
- "version": "1.5.9",
3
+ "version": "1.5.10",
4
4
  "description": "Vue2/Vue3 UIKit for AI Desk",
5
5
  "main": "index",
6
6
  "keywords": [