@vunk/plus 1.3.1 → 1.3.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.
- package/components/broadcasting-markdown/index.mjs +32 -16
- package/components/broadcasting-markdown/src/ctx.d.ts +8 -0
- package/components/broadcasting-markdown/src/custom-speech.vue.d.ts +9 -1
- package/components/broadcasting-markdown/src/index.vue.d.ts +25 -0
- package/components/broadcasting-markdown/src/web-speech.vue.d.ts +8 -0
- package/components/bubble-list/index.mjs +2 -316
- package/components/bubble-list/src/index.vue.d.ts +25 -0
- package/components/bubble-templates/index.mjs +2 -161
- package/components/bubble-templates/src/index.vue.d.ts +25 -0
- package/components/chat-independent/index.mjs +42 -34
- package/components/chat-independent/src/index.vue.d.ts +25 -0
- package/components/typing-markdown/index.mjs +2 -2
- package/index.css +0 -38
- package/package.json +1 -7
- package/components/bubble-list/index.css +0 -18
- package/components/bubble-templates/index.css +0 -18
- package/components/index2.mjs +0 -35980
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { VkTypingMarkdown } from '@vunk/plus/components/typing-markdown';
|
|
2
2
|
import { setData } from '@vunk/core';
|
|
3
3
|
import { defineComponent, createElementBlock, openBlock, createElementVNode, Fragment, createVNode, unref, withCtx, computed, onBeforeUnmount, onMounted, watch, shallowRef, nextTick, renderSlot, createCommentVNode, ref, watchEffect, resolveComponent, renderList, createBlock } from 'vue';
|
|
4
|
-
import markdownIt from 'markdown-it';
|
|
5
4
|
import { useDeferred } from '@vunk/core/composables';
|
|
6
5
|
import { ElIcon } from 'element-plus';
|
|
7
6
|
import { noop } from '@vunk/shared/function';
|
|
8
7
|
import { Deferred } from '@vunk/shared/promise';
|
|
9
8
|
import { _ as _export_sfc } from '../_plugin-vue_export-helper.mjs';
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
function markdownToPlainText(md) {
|
|
11
|
+
return md.replace(/!\[.*?\]\(.*?\)/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^#{1,6}\s+/gm, "").replace(/\*\*(.*?)\*\*/g, "$1").replace(/__(.*?)__/g, "$1").replace(/\*(.*?)\*/g, "$1").replace(/_(.*?)_/g, "$1").replace(/`(.*?)`/g, "$1").replace(/```[\s\S]*?```/g, "").replace(/\n{2,}/g, "\n").replace(/-{3,}/g, "").replace(/^\s*-\s+/gm, "").replace(/\|/g, "").trim();
|
|
12
|
+
}
|
|
12
13
|
function defaultRender(mdText) {
|
|
13
|
-
|
|
14
|
-
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
15
|
-
return doc.body.textContent || "";
|
|
14
|
+
return markdownToPlainText(mdText);
|
|
16
15
|
}
|
|
17
16
|
var ParagraphStatus = /* @__PURE__ */ ((ParagraphStatus2) => {
|
|
18
17
|
ParagraphStatus2["initial"] = "initial";
|
|
@@ -32,6 +31,13 @@ var Broadcast = /* @__PURE__ */ ((Broadcast2) => {
|
|
|
32
31
|
})(Broadcast || {});
|
|
33
32
|
|
|
34
33
|
const props = {
|
|
34
|
+
/**
|
|
35
|
+
* @description md文本转纯文本的函数
|
|
36
|
+
*/
|
|
37
|
+
render: {
|
|
38
|
+
type: Function,
|
|
39
|
+
default: defaultRender
|
|
40
|
+
},
|
|
35
41
|
/**
|
|
36
42
|
* @description 段落详情
|
|
37
43
|
*/
|
|
@@ -178,10 +184,14 @@ var _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
178
184
|
url: {
|
|
179
185
|
type: String,
|
|
180
186
|
default: ""
|
|
187
|
+
},
|
|
188
|
+
render: {
|
|
189
|
+
type: Function,
|
|
190
|
+
required: true
|
|
181
191
|
}
|
|
182
192
|
},
|
|
183
193
|
setup(props) {
|
|
184
|
-
const value =
|
|
194
|
+
const value = props.render(props.data.value);
|
|
185
195
|
const theData = computed(() => props.data);
|
|
186
196
|
if (!value.trim()) {
|
|
187
197
|
props.deferred.resolve(true);
|
|
@@ -327,13 +337,15 @@ var _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
327
337
|
pause: {
|
|
328
338
|
type: Boolean,
|
|
329
339
|
default: false
|
|
340
|
+
},
|
|
341
|
+
render: {
|
|
342
|
+
type: Function,
|
|
343
|
+
required: true
|
|
330
344
|
}
|
|
331
345
|
},
|
|
332
346
|
setup(props) {
|
|
333
|
-
const value =
|
|
334
|
-
const theData = computed(() =>
|
|
335
|
-
return props.data;
|
|
336
|
-
});
|
|
347
|
+
const value = props.render(props.data.value);
|
|
348
|
+
const theData = computed(() => props.data);
|
|
337
349
|
if (!value.trim()) {
|
|
338
350
|
props.deferred.resolve(true);
|
|
339
351
|
theData.value.broadcast = Broadcast.ended;
|
|
@@ -415,7 +427,10 @@ var _sfc_main = defineComponent({
|
|
|
415
427
|
if (!props2.textToSpeech) {
|
|
416
428
|
return;
|
|
417
429
|
}
|
|
418
|
-
const value =
|
|
430
|
+
const value = props2.render(paragraph.value);
|
|
431
|
+
if (!value) {
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
419
434
|
return props2.textToSpeech(`${value}`).then((url) => {
|
|
420
435
|
paragraph.url = url;
|
|
421
436
|
});
|
|
@@ -597,19 +612,20 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
597
612
|
data: item,
|
|
598
613
|
deferred
|
|
599
614
|
}, () => [
|
|
600
|
-
|
|
601
|
-
|
|
615
|
+
createVNode(_component_CustomSpeechView, {
|
|
616
|
+
render: _ctx.render,
|
|
602
617
|
url: item.url,
|
|
603
618
|
pause: _ctx.pause,
|
|
604
619
|
deferred,
|
|
605
620
|
data: item
|
|
606
|
-
}, null, 8, ["url", "pause", "deferred", "data"])
|
|
621
|
+
}, null, 8, ["render", "url", "pause", "deferred", "data"]),
|
|
607
622
|
_ctx.webSpeech ? (openBlock(), createBlock(_component_WebSpeechView, {
|
|
608
|
-
key:
|
|
623
|
+
key: 0,
|
|
624
|
+
render: _ctx.render,
|
|
609
625
|
pause: _ctx.pause,
|
|
610
626
|
deferred,
|
|
611
627
|
data: item
|
|
612
|
-
}, null, 8, ["pause", "deferred", "data"])) : createCommentVNode("v-if", true)
|
|
628
|
+
}, null, 8, ["render", "pause", "deferred", "data"])) : createCommentVNode("v-if", true)
|
|
613
629
|
])
|
|
614
630
|
]),
|
|
615
631
|
_: 2
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import type { SetDataEvent } from '@vunk/core';
|
|
2
2
|
import type { PropType } from 'vue';
|
|
3
3
|
import type { Paragraph, TextToSpeech } from './types';
|
|
4
|
+
import { defaultRender } from './const';
|
|
4
5
|
export declare const props: {
|
|
6
|
+
/**
|
|
7
|
+
* @description md文本转纯文本的函数
|
|
8
|
+
*/
|
|
9
|
+
render: {
|
|
10
|
+
type: PropType<(text: string) => string>;
|
|
11
|
+
default: typeof defaultRender;
|
|
12
|
+
};
|
|
5
13
|
/**
|
|
6
14
|
* @description 段落详情
|
|
7
15
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { Deferred } from '@vunk/shared/promise';
|
|
1
2
|
import type { PropType } from 'vue';
|
|
2
3
|
import type { Paragraph } from './types';
|
|
3
|
-
import { type Deferred } from '@vunk/shared/promise';
|
|
4
4
|
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
5
5
|
data: {
|
|
6
6
|
type: PropType<Paragraph>;
|
|
@@ -21,6 +21,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
21
21
|
type: StringConstructor;
|
|
22
22
|
default: string;
|
|
23
23
|
};
|
|
24
|
+
render: {
|
|
25
|
+
type: PropType<(text: string) => string>;
|
|
26
|
+
required: true;
|
|
27
|
+
};
|
|
24
28
|
}>, (() => null) | (() => JSX.Element), {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
25
29
|
data: {
|
|
26
30
|
type: PropType<Paragraph>;
|
|
@@ -41,6 +45,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
41
45
|
type: StringConstructor;
|
|
42
46
|
default: string;
|
|
43
47
|
};
|
|
48
|
+
render: {
|
|
49
|
+
type: PropType<(text: string) => string>;
|
|
50
|
+
required: true;
|
|
51
|
+
};
|
|
44
52
|
}>> & Readonly<{}>, {
|
|
45
53
|
pause: boolean;
|
|
46
54
|
data: Paragraph;
|
|
@@ -3,6 +3,10 @@ import type { Ref } from 'vue';
|
|
|
3
3
|
import type { Paragraph } from './types';
|
|
4
4
|
import { ParagraphStatus } from './const';
|
|
5
5
|
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
6
|
+
render: {
|
|
7
|
+
type: import("vue").PropType<(text: string) => string>;
|
|
8
|
+
default: typeof import("./const").defaultRender;
|
|
9
|
+
};
|
|
6
10
|
data: {
|
|
7
11
|
type: {
|
|
8
12
|
(arrayLength: number): Paragraph[];
|
|
@@ -74,6 +78,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
74
78
|
'update:completed': (_: boolean) => boolean;
|
|
75
79
|
'update:error': (_: boolean) => boolean;
|
|
76
80
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
81
|
+
render: {
|
|
82
|
+
type: import("vue").PropType<(text: string) => string>;
|
|
83
|
+
default: typeof import("./const").defaultRender;
|
|
84
|
+
};
|
|
77
85
|
data: {
|
|
78
86
|
type: {
|
|
79
87
|
(arrayLength: number): Paragraph[];
|
|
@@ -141,6 +149,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
141
149
|
source: string;
|
|
142
150
|
delay: number;
|
|
143
151
|
pause: boolean;
|
|
152
|
+
render: (text: string) => string;
|
|
144
153
|
data: Paragraph[];
|
|
145
154
|
separators: string[];
|
|
146
155
|
keepRead: boolean;
|
|
@@ -293,6 +302,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
293
302
|
type: BooleanConstructor;
|
|
294
303
|
default: boolean;
|
|
295
304
|
};
|
|
305
|
+
render: {
|
|
306
|
+
type: import("vue").PropType<(text: string) => string>;
|
|
307
|
+
required: true;
|
|
308
|
+
};
|
|
296
309
|
}>, (() => null) | (() => false | JSX.Element), {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
297
310
|
voice: {
|
|
298
311
|
type: import("vue").PropType<SpeechSynthesisVoice>;
|
|
@@ -310,6 +323,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
310
323
|
type: BooleanConstructor;
|
|
311
324
|
default: boolean;
|
|
312
325
|
};
|
|
326
|
+
render: {
|
|
327
|
+
type: import("vue").PropType<(text: string) => string>;
|
|
328
|
+
required: true;
|
|
329
|
+
};
|
|
313
330
|
}>> & Readonly<{}>, {
|
|
314
331
|
pause: boolean;
|
|
315
332
|
data: Paragraph;
|
|
@@ -391,6 +408,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
391
408
|
type: StringConstructor;
|
|
392
409
|
default: string;
|
|
393
410
|
};
|
|
411
|
+
render: {
|
|
412
|
+
type: import("vue").PropType<(text: string) => string>;
|
|
413
|
+
required: true;
|
|
414
|
+
};
|
|
394
415
|
}>, (() => null) | (() => JSX.Element), {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
395
416
|
data: {
|
|
396
417
|
type: import("vue").PropType<Paragraph>;
|
|
@@ -408,6 +429,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
408
429
|
type: StringConstructor;
|
|
409
430
|
default: string;
|
|
410
431
|
};
|
|
432
|
+
render: {
|
|
433
|
+
type: import("vue").PropType<(text: string) => string>;
|
|
434
|
+
required: true;
|
|
435
|
+
};
|
|
411
436
|
}>> & Readonly<{}>, {
|
|
412
437
|
pause: boolean;
|
|
413
438
|
data: Paragraph;
|
|
@@ -18,6 +18,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
18
18
|
type: BooleanConstructor;
|
|
19
19
|
default: boolean;
|
|
20
20
|
};
|
|
21
|
+
render: {
|
|
22
|
+
type: PropType<(text: string) => string>;
|
|
23
|
+
required: true;
|
|
24
|
+
};
|
|
21
25
|
}>, (() => null) | (() => false | JSX.Element), {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
22
26
|
voice: {
|
|
23
27
|
type: PropType<SpeechSynthesisVoice>;
|
|
@@ -35,6 +39,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
35
39
|
type: BooleanConstructor;
|
|
36
40
|
default: boolean;
|
|
37
41
|
};
|
|
42
|
+
render: {
|
|
43
|
+
type: PropType<(text: string) => string>;
|
|
44
|
+
required: true;
|
|
45
|
+
};
|
|
38
46
|
}>> & Readonly<{}>, {
|
|
39
47
|
pause: boolean;
|
|
40
48
|
data: Paragraph;
|
|
@@ -1,326 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defineComponent, createBlock, openBlock, unref, withCtx, createVNode, mergeProps } from 'vue';
|
|
2
2
|
import { VkBubbleTemplates } from '@vunk/plus/components/bubble-templates';
|
|
3
3
|
import { VkRenderer } from '@vunk/core/components/renderer';
|
|
4
4
|
import { VkRendererTemplateInstancesProvider } from '@vunk/core/components/renderer-template-instances-provider';
|
|
5
5
|
import { ElAutoResizer } from 'element-plus';
|
|
6
|
-
import {
|
|
6
|
+
import { BubbleList } from 'vue-element-plus-x';
|
|
7
7
|
import { noop } from '@vunk/shared/function';
|
|
8
8
|
export { Role } from '@vunk/plus/components/agent-chat-provider';
|
|
9
9
|
|
|
10
|
-
const _sfc_main$2 = {};
|
|
11
|
-
const _hoisted_1 = {
|
|
12
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
13
|
-
"xmlns:xlink": "http://www.w3.org/1999/xlink",
|
|
14
|
-
version: "1.1",
|
|
15
|
-
width: "704",
|
|
16
|
-
height: "704",
|
|
17
|
-
viewBox: "0 0 704 704"
|
|
18
|
-
};
|
|
19
|
-
function _sfc_render(_ctx, _cache) {
|
|
20
|
-
return openBlock(), createElementBlock("svg", _hoisted_1, _cache[0] || (_cache[0] = [createStaticVNode('<defs><filter id="master_svg0_62_10054" filterUnits="objectBoundingBox" color-interpolation-filters="sRGB" x="-0.030120481927710843" y="-0.030120481927710843" width="1.0602409638554218" height="1.0602409638554218"><feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood><feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"></feBlend><feGaussianBlur stdDeviation="5" result="effect1_foregroundBlur"></feGaussianBlur></filter><linearGradient id="master_svg1_62_10082" x1="0.5" y1="-0.13192443549633026" x2="0.42319029569625854" y2="1.368432641029358"><stop offset="9.145302325487137%" stop-color="currentColor" stop-opacity="1"></stop><stop offset="13.636428117752075%" stop-color="currentColor" stop-opacity="0.07539999485015869"></stop><stop offset="16.968481242656708%" stop-color="currentColor" stop-opacity="0"></stop></linearGradient></defs><g transform="matrix(0,1,-1,0,704,-664)" filter="url(#master_svg0_62_10054)"><path d="M1016,684C1199.359,684,1348,535.359,1348,352C1348,168.641,1199.359,20,1016,20C832.641,20,684,168.641,684,352C684,535.359,832.641,684,1016,684ZM1016,32C1192.731,32,1336,175.269,1336,352C1336,528.731,1192.731,672,1016,672C839.269,672,696,528.731,696,352C696,175.269,839.269,32,1016,32Z" fill-rule="evenodd" fill="url(#master_svg1_62_10082)" fill-opacity="1"></path></g>', 2)]));
|
|
21
|
-
}
|
|
22
|
-
const loadingBg = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render]]);
|
|
23
|
-
|
|
24
|
-
const useScrollDetector = (elementRef) => {
|
|
25
|
-
const hasVertical = ref(false);
|
|
26
|
-
const hasHorizontal = ref(false);
|
|
27
|
-
const check = () => {
|
|
28
|
-
const el = elementRef.value;
|
|
29
|
-
if (!el) return;
|
|
30
|
-
hasVertical.value = el.scrollHeight > el.clientHeight;
|
|
31
|
-
hasHorizontal.value = el.scrollWidth > el.clientWidth;
|
|
32
|
-
};
|
|
33
|
-
onMounted(() => {
|
|
34
|
-
check();
|
|
35
|
-
const observer = new ResizeObserver(check);
|
|
36
|
-
observer.observe(elementRef.value);
|
|
37
|
-
onBeforeUnmount(() => observer.disconnect());
|
|
38
|
-
});
|
|
39
|
-
return {
|
|
40
|
-
hasVertical,
|
|
41
|
-
// 是否有纵向滚动条
|
|
42
|
-
hasHorizontal,
|
|
43
|
-
// 是否有横向滚动条
|
|
44
|
-
check
|
|
45
|
-
// 检查滚动条状态
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
const threshold = 20;
|
|
49
|
-
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
50
|
-
__name: "index",
|
|
51
|
-
props: {
|
|
52
|
-
list: {
|
|
53
|
-
default: () => []
|
|
54
|
-
},
|
|
55
|
-
maxHeight: {
|
|
56
|
-
default: "500px"
|
|
57
|
-
},
|
|
58
|
-
triggerIndices: {
|
|
59
|
-
default: "only-last"
|
|
60
|
-
},
|
|
61
|
-
alwaysShowScrollbar: {
|
|
62
|
-
type: Boolean,
|
|
63
|
-
default: false
|
|
64
|
-
},
|
|
65
|
-
backButtonThreshold: {
|
|
66
|
-
default: 80
|
|
67
|
-
},
|
|
68
|
-
showBackButton: {
|
|
69
|
-
type: Boolean,
|
|
70
|
-
default: true
|
|
71
|
-
},
|
|
72
|
-
backButtonPosition: {
|
|
73
|
-
default: () => {
|
|
74
|
-
return {
|
|
75
|
-
bottom: "20px",
|
|
76
|
-
left: "calc(50% - 19px)"
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
btnLoading: {
|
|
81
|
-
type: Boolean,
|
|
82
|
-
default: true
|
|
83
|
-
},
|
|
84
|
-
btnColor: {
|
|
85
|
-
default: "#409EFF"
|
|
86
|
-
},
|
|
87
|
-
btnIconSize: {
|
|
88
|
-
default: 24
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
emits: ["complete"],
|
|
92
|
-
setup(__props, {
|
|
93
|
-
expose: __expose,
|
|
94
|
-
emit: __emit
|
|
95
|
-
}) {
|
|
96
|
-
const props = __props;
|
|
97
|
-
const emits = __emit;
|
|
98
|
-
const scrollContainer = ref(null);
|
|
99
|
-
const {
|
|
100
|
-
hasVertical
|
|
101
|
-
} = useScrollDetector(scrollContainer);
|
|
102
|
-
const stopAutoScrollToBottom = ref(false);
|
|
103
|
-
const lastScrollTop = ref(0);
|
|
104
|
-
const accumulatedScrollUpDistance = ref(0);
|
|
105
|
-
const resizeObserver = ref(null);
|
|
106
|
-
const showBackToBottom = ref(false);
|
|
107
|
-
const effectiveTriggerIndices = computed(() => {
|
|
108
|
-
if (props.triggerIndices === "only-last") {
|
|
109
|
-
const triggerIndices = props.list.filter((item) => item.typing).map((_, index) => index);
|
|
110
|
-
return triggerIndices.length > 0 ? [triggerIndices[triggerIndices.length - 1]] : [];
|
|
111
|
-
} else if (props.triggerIndices === "all") {
|
|
112
|
-
return props.list.map((_, index) => index);
|
|
113
|
-
} else if (Array.isArray(props.triggerIndices)) {
|
|
114
|
-
const validIndices = getValidIndices(props.list, props.triggerIndices);
|
|
115
|
-
return validIndices.length > 0 ? [validIndices[validIndices.length - 1]] : [];
|
|
116
|
-
}
|
|
117
|
-
return [];
|
|
118
|
-
});
|
|
119
|
-
function getValidIndices(list, indices) {
|
|
120
|
-
const validIndices = [];
|
|
121
|
-
for (let i = 0; i < indices.length; i++) {
|
|
122
|
-
const index = indices[i];
|
|
123
|
-
if (index < 0 || index >= list.length || !list[index].typing) ;
|
|
124
|
-
else {
|
|
125
|
-
validIndices.push(index);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
return validIndices;
|
|
129
|
-
}
|
|
130
|
-
watch(() => props.list.length, () => {
|
|
131
|
-
if (props.list && props.list.length > 0) {
|
|
132
|
-
nextTick(() => {
|
|
133
|
-
autoScroll();
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
}, {
|
|
137
|
-
immediate: true
|
|
138
|
-
});
|
|
139
|
-
function scrollToTop() {
|
|
140
|
-
stopAutoScrollToBottom.value = true;
|
|
141
|
-
nextTick(() => {
|
|
142
|
-
scrollContainer.value.scrollTop = 0;
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
function scrollToBottom() {
|
|
146
|
-
try {
|
|
147
|
-
if (scrollContainer.value && scrollContainer.value.scrollHeight) {
|
|
148
|
-
nextTick(() => {
|
|
149
|
-
scrollContainer.value.scrollTop = scrollContainer.value.scrollHeight;
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
} catch (error) {
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
function scrollToBubble(index) {
|
|
156
|
-
const container = scrollContainer.value;
|
|
157
|
-
if (!container) return;
|
|
158
|
-
const bubbles = container.querySelectorAll(".el-bubble");
|
|
159
|
-
if (index >= bubbles.length) return;
|
|
160
|
-
stopAutoScrollToBottom.value = true;
|
|
161
|
-
const targetBubble = bubbles[index];
|
|
162
|
-
const containerRect = container.getBoundingClientRect();
|
|
163
|
-
const bubbleRect = targetBubble.getBoundingClientRect();
|
|
164
|
-
const scrollPosition = bubbleRect.top - containerRect.top + container.scrollTop;
|
|
165
|
-
container.scrollTo({
|
|
166
|
-
top: scrollPosition,
|
|
167
|
-
behavior: "smooth"
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
function autoScroll() {
|
|
171
|
-
if (scrollContainer.value) {
|
|
172
|
-
const listBubbles = scrollContainer.value.querySelectorAll(".el-bubble-content-wrapper");
|
|
173
|
-
if (resizeObserver.value) {
|
|
174
|
-
resizeObserver.value.disconnect();
|
|
175
|
-
}
|
|
176
|
-
const lastItem = listBubbles[listBubbles.length - 1];
|
|
177
|
-
if (lastItem) {
|
|
178
|
-
resizeObserver.value = new ResizeObserver(() => {
|
|
179
|
-
if (!stopAutoScrollToBottom.value) {
|
|
180
|
-
scrollToBottom();
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
resizeObserver.value.observe(lastItem);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
function handleBubbleComplete(index, instance) {
|
|
188
|
-
if (effectiveTriggerIndices.value.includes(index)) {
|
|
189
|
-
emits("complete", instance, index);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
function handleScroll() {
|
|
193
|
-
if (scrollContainer.value) {
|
|
194
|
-
const {
|
|
195
|
-
scrollTop,
|
|
196
|
-
scrollHeight,
|
|
197
|
-
clientHeight
|
|
198
|
-
} = scrollContainer.value;
|
|
199
|
-
const distanceToBottom = scrollHeight - (scrollTop + clientHeight);
|
|
200
|
-
showBackToBottom.value = props.showBackButton && distanceToBottom > props.backButtonThreshold;
|
|
201
|
-
const isCloseToBottom = scrollTop + clientHeight >= scrollHeight - 30;
|
|
202
|
-
const isScrollingUp = lastScrollTop.value > scrollTop;
|
|
203
|
-
const isScrollingDown = lastScrollTop.value < scrollTop;
|
|
204
|
-
const scrollDelta = lastScrollTop.value - scrollTop;
|
|
205
|
-
lastScrollTop.value = scrollTop;
|
|
206
|
-
if (isScrollingUp) {
|
|
207
|
-
accumulatedScrollUpDistance.value += scrollDelta;
|
|
208
|
-
if (accumulatedScrollUpDistance.value >= threshold) {
|
|
209
|
-
if (!stopAutoScrollToBottom.value) {
|
|
210
|
-
stopAutoScrollToBottom.value = true;
|
|
211
|
-
}
|
|
212
|
-
accumulatedScrollUpDistance.value = 0;
|
|
213
|
-
}
|
|
214
|
-
} else {
|
|
215
|
-
accumulatedScrollUpDistance.value = 0;
|
|
216
|
-
}
|
|
217
|
-
if (isScrollingDown && isCloseToBottom) {
|
|
218
|
-
if (stopAutoScrollToBottom.value) {
|
|
219
|
-
stopAutoScrollToBottom.value = false;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
__expose({
|
|
225
|
-
scrollToTop,
|
|
226
|
-
scrollToBottom,
|
|
227
|
-
scrollToBubble
|
|
228
|
-
});
|
|
229
|
-
return (_ctx, _cache) => {
|
|
230
|
-
const _component_el_icon = ElIcon;
|
|
231
|
-
return openBlock(), createElementBlock("div", {
|
|
232
|
-
ref_key: "scrollContainer",
|
|
233
|
-
ref: scrollContainer,
|
|
234
|
-
class: normalizeClass(["el-bubble-list", {
|
|
235
|
-
"always-scrollbar": props.alwaysShowScrollbar
|
|
236
|
-
}]),
|
|
237
|
-
style: normalizeStyle({
|
|
238
|
-
"--el-bubble-list-max-height": `${_ctx.maxHeight}`,
|
|
239
|
-
"--el-bubble-list-btn-size": `${props.btnIconSize}px`
|
|
240
|
-
}),
|
|
241
|
-
onScroll: handleScroll
|
|
242
|
-
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.list, (item, index) => {
|
|
243
|
-
return openBlock(), createBlock(Bubble, {
|
|
244
|
-
key: index,
|
|
245
|
-
content: item.content,
|
|
246
|
-
placement: item.placement,
|
|
247
|
-
loading: item.loading,
|
|
248
|
-
shape: item.shape,
|
|
249
|
-
variant: item.variant,
|
|
250
|
-
"is-markdown": item.isMarkdown,
|
|
251
|
-
"is-fog": item.isFog,
|
|
252
|
-
typing: item.typing,
|
|
253
|
-
"max-width": item.maxWidth,
|
|
254
|
-
avatar: item.avatar,
|
|
255
|
-
"avatar-size": item.avatarSize,
|
|
256
|
-
"avatar-gap": item.avatarGap,
|
|
257
|
-
"avatar-shape": item.avatarShape,
|
|
258
|
-
"avatar-icon": item.avatarIcon,
|
|
259
|
-
"avatar-src-set": item.avatarSrcSet,
|
|
260
|
-
"avatar-alt": item.avatarAlt,
|
|
261
|
-
"avatar-fit": item.avatarFit,
|
|
262
|
-
"no-style": item.noStyle,
|
|
263
|
-
onFinish: (instance) => handleBubbleComplete(index, instance)
|
|
264
|
-
}, createSlots({
|
|
265
|
-
_: 2
|
|
266
|
-
}, [_ctx.$slots.avatar ? {
|
|
267
|
-
name: "avatar",
|
|
268
|
-
fn: withCtx(() => [renderSlot(_ctx.$slots, "avatar", {
|
|
269
|
-
item
|
|
270
|
-
}, void 0, true)]),
|
|
271
|
-
key: "0"
|
|
272
|
-
} : void 0, _ctx.$slots.header ? {
|
|
273
|
-
name: "header",
|
|
274
|
-
fn: withCtx(() => [renderSlot(_ctx.$slots, "header", {
|
|
275
|
-
item
|
|
276
|
-
}, void 0, true)]),
|
|
277
|
-
key: "1"
|
|
278
|
-
} : void 0, _ctx.$slots.content ? {
|
|
279
|
-
name: "content",
|
|
280
|
-
fn: withCtx(() => [renderSlot(_ctx.$slots, "content", {
|
|
281
|
-
item
|
|
282
|
-
}, void 0, true)]),
|
|
283
|
-
key: "2"
|
|
284
|
-
} : void 0, _ctx.$slots.footer ? {
|
|
285
|
-
name: "footer",
|
|
286
|
-
fn: withCtx(() => [renderSlot(_ctx.$slots, "footer", {
|
|
287
|
-
item
|
|
288
|
-
}, void 0, true)]),
|
|
289
|
-
key: "3"
|
|
290
|
-
} : void 0, _ctx.$slots.loading ? {
|
|
291
|
-
name: "loading",
|
|
292
|
-
fn: withCtx(() => [renderSlot(_ctx.$slots, "loading", {
|
|
293
|
-
item
|
|
294
|
-
}, void 0, true)]),
|
|
295
|
-
key: "4"
|
|
296
|
-
} : void 0]), 1032, ["content", "placement", "loading", "shape", "variant", "is-markdown", "is-fog", "typing", "max-width", "avatar", "avatar-size", "avatar-gap", "avatar-shape", "avatar-icon", "avatar-src-set", "avatar-alt", "avatar-fit", "no-style", "onFinish"]);
|
|
297
|
-
}), 128)), unref(showBackToBottom) && unref(hasVertical) ? (openBlock(), createElementBlock("div", {
|
|
298
|
-
key: 0,
|
|
299
|
-
class: normalizeClass(["el-bubble-list-default-back-button", {
|
|
300
|
-
"el-bubble-list-back-to-bottom-solt": _ctx.$slots.backToBottom
|
|
301
|
-
}]),
|
|
302
|
-
style: normalizeStyle({
|
|
303
|
-
bottom: _ctx.backButtonPosition.bottom,
|
|
304
|
-
left: _ctx.backButtonPosition.left
|
|
305
|
-
}),
|
|
306
|
-
onClick: scrollToBottom
|
|
307
|
-
}, [renderSlot(_ctx.$slots, "backToBottom", {}, () => [createVNode(_component_el_icon, {
|
|
308
|
-
class: "el-bubble-list-back-to-bottom-icon",
|
|
309
|
-
style: normalizeStyle({
|
|
310
|
-
color: props.btnColor
|
|
311
|
-
})
|
|
312
|
-
}, {
|
|
313
|
-
default: withCtx(() => [createVNode(unref(arrow_down_bold_default)), props.btnLoading ? (openBlock(), createBlock(loadingBg, {
|
|
314
|
-
key: 0,
|
|
315
|
-
class: "back-to-bottom-loading-svg-bg"
|
|
316
|
-
})) : createCommentVNode("", true)]),
|
|
317
|
-
_: 1
|
|
318
|
-
}, 8, ["style"])], true)], 6)) : createCommentVNode("", true)], 38);
|
|
319
|
-
};
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
const BubbleList = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-a7a18fd5"]]);
|
|
323
|
-
|
|
324
10
|
const props = {
|
|
325
11
|
items: {
|
|
326
12
|
type: Array,
|
|
@@ -36,6 +36,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
36
36
|
initRenderData: (emitSetData: any, props: any) => void;
|
|
37
37
|
typed: (e: import("./types").Item) => import("./types").Item;
|
|
38
38
|
readonly VkBroadcastingMarkdown: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
39
|
+
render: {
|
|
40
|
+
type: import("vue").PropType<(text: string) => string>;
|
|
41
|
+
default: typeof import("../../broadcasting-markdown").defaultRender;
|
|
42
|
+
};
|
|
39
43
|
data: {
|
|
40
44
|
type: {
|
|
41
45
|
(arrayLength: number): import("../../broadcasting-markdown/src/types").Paragraph[];
|
|
@@ -107,6 +111,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
107
111
|
'update:completed': (_: boolean) => boolean;
|
|
108
112
|
'update:error': (_: boolean) => boolean;
|
|
109
113
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
114
|
+
render: {
|
|
115
|
+
type: import("vue").PropType<(text: string) => string>;
|
|
116
|
+
default: typeof import("../../broadcasting-markdown").defaultRender;
|
|
117
|
+
};
|
|
110
118
|
data: {
|
|
111
119
|
type: {
|
|
112
120
|
(arrayLength: number): import("../../broadcasting-markdown/src/types").Paragraph[];
|
|
@@ -174,6 +182,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
174
182
|
source: string;
|
|
175
183
|
delay: number;
|
|
176
184
|
pause: boolean;
|
|
185
|
+
render: (text: string) => string;
|
|
177
186
|
data: import("../../broadcasting-markdown/src/types").Paragraph[];
|
|
178
187
|
separators: string[];
|
|
179
188
|
keepRead: boolean;
|
|
@@ -326,6 +335,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
326
335
|
type: BooleanConstructor;
|
|
327
336
|
default: boolean;
|
|
328
337
|
};
|
|
338
|
+
render: {
|
|
339
|
+
type: import("vue").PropType<(text: string) => string>;
|
|
340
|
+
required: true;
|
|
341
|
+
};
|
|
329
342
|
}>, (() => null) | (() => false | JSX.Element), {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
330
343
|
voice: {
|
|
331
344
|
type: import("vue").PropType<SpeechSynthesisVoice>;
|
|
@@ -343,6 +356,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
343
356
|
type: BooleanConstructor;
|
|
344
357
|
default: boolean;
|
|
345
358
|
};
|
|
359
|
+
render: {
|
|
360
|
+
type: import("vue").PropType<(text: string) => string>;
|
|
361
|
+
required: true;
|
|
362
|
+
};
|
|
346
363
|
}>> & Readonly<{}>, {
|
|
347
364
|
pause: boolean;
|
|
348
365
|
data: import("../../broadcasting-markdown/src/types").Paragraph;
|
|
@@ -424,6 +441,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
424
441
|
type: StringConstructor;
|
|
425
442
|
default: string;
|
|
426
443
|
};
|
|
444
|
+
render: {
|
|
445
|
+
type: import("vue").PropType<(text: string) => string>;
|
|
446
|
+
required: true;
|
|
447
|
+
};
|
|
427
448
|
}>, (() => null) | (() => JSX.Element), {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
428
449
|
data: {
|
|
429
450
|
type: import("vue").PropType<import("../../broadcasting-markdown/src/types").Paragraph>;
|
|
@@ -441,6 +462,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
441
462
|
type: StringConstructor;
|
|
442
463
|
default: string;
|
|
443
464
|
};
|
|
465
|
+
render: {
|
|
466
|
+
type: import("vue").PropType<(text: string) => string>;
|
|
467
|
+
required: true;
|
|
468
|
+
};
|
|
444
469
|
}>> & Readonly<{}>, {
|
|
445
470
|
pause: boolean;
|
|
446
471
|
data: import("../../broadcasting-markdown/src/types").Paragraph;
|