@fv-ui/ai-chat 0.1.1 → 0.3.0
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/README.md +756 -741
- package/dist/index.d.ts +45 -12
- package/dist/style.css +1 -1
- package/es/index.mjs +527 -225
- package/lib/index.js +527 -225
- package/package.json +1 -1
package/es/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { defineComponent, computed, openBlock, createElementBlock, ref, watch, onBeforeUnmount, normalizeClass, createCommentVNode, createBlock, createTextVNode, toDisplayString, normalizeStyle, renderSlot, unref, createElementVNode, Fragment, renderList, createVNode, isRef, nextTick, onMounted, mergeProps, createSlots, withCtx, Transition, useSlots, normalizeProps, guardReactiveProps, reactive, resolveDynamicComponent, markRaw, withModifiers
|
|
1
|
+
import { defineComponent, computed, openBlock, createElementBlock, ref, watch, onBeforeUnmount, normalizeClass, createCommentVNode, createBlock, createTextVNode, toDisplayString, normalizeStyle, renderSlot, unref, createElementVNode, Fragment, renderList, createVNode, isRef, nextTick, onMounted, mergeProps, createSlots, withCtx, Transition, getCurrentInstance, useSlots, normalizeProps, guardReactiveProps, reactive, resolveDynamicComponent, markRaw, withModifiers } from 'vue';
|
|
2
2
|
import MarkdownIt from 'markdown-it';
|
|
3
3
|
import mdKatex from '@vscode/markdown-it-katex';
|
|
4
4
|
import DOMPurify from 'dompurify';
|
|
5
5
|
import Prism$1 from 'prismjs';
|
|
6
|
-
import { ElAvatar, ElButton, ElPopover,
|
|
6
|
+
import { ElAvatar, ElButton, ElIcon, ElPopover, ElMessage, ElDialog, ElDropdown, ElDropdownMenu, ElDropdownItem, ElMessageBox, ElTooltip, ElSelect, ElOption } from 'element-plus';
|
|
7
7
|
import * as ElementPlusIconsVue from '@element-plus/icons-vue';
|
|
8
|
-
import { ArrowDown, Delete, Microphone,
|
|
8
|
+
import { ArrowDown, Close, Check, Delete, Microphone, Promotion, VideoPause, Loading, SuccessFilled, CircleCloseFilled, ChatDotRound, Cpu, Cellphone, Link, Folder, Headset, Film, Monitor, DataAnalysis, Document, Notebook, Picture, Paperclip, RefreshRight, MoreFilled, User, DocumentCopy, ArrowUp, CopyDocument, Download, FullScreen } from '@element-plus/icons-vue';
|
|
9
9
|
|
|
10
10
|
function unwrapPlugin(plugin) {
|
|
11
11
|
const candidate = plugin && typeof plugin === "object" && "default" in plugin ? plugin.default : plugin;
|
|
@@ -1526,8 +1526,8 @@ function prismHighlight(str, lang) {
|
|
|
1526
1526
|
}
|
|
1527
1527
|
}
|
|
1528
1528
|
|
|
1529
|
-
const _hoisted_1$
|
|
1530
|
-
var _sfc_main$
|
|
1529
|
+
const _hoisted_1$i = ["innerHTML"];
|
|
1530
|
+
var _sfc_main$i = /* @__PURE__ */ defineComponent({
|
|
1531
1531
|
...{ name: "FvMarkdown" },
|
|
1532
1532
|
__name: "index",
|
|
1533
1533
|
props: {
|
|
@@ -1550,12 +1550,12 @@ var _sfc_main$h = /* @__PURE__ */ defineComponent({
|
|
|
1550
1550
|
return openBlock(), createElementBlock("div", {
|
|
1551
1551
|
class: "fv-xmarkdown markdown-body",
|
|
1552
1552
|
innerHTML: html.value
|
|
1553
|
-
}, null, 8, _hoisted_1$
|
|
1553
|
+
}, null, 8, _hoisted_1$i);
|
|
1554
1554
|
};
|
|
1555
1555
|
}
|
|
1556
1556
|
});
|
|
1557
1557
|
|
|
1558
|
-
const _hoisted_1$
|
|
1558
|
+
const _hoisted_1$h = {
|
|
1559
1559
|
key: 1,
|
|
1560
1560
|
class: "fv-typewriter-text"
|
|
1561
1561
|
};
|
|
@@ -1563,7 +1563,7 @@ const _hoisted_2$f = {
|
|
|
1563
1563
|
key: 0,
|
|
1564
1564
|
class: "fv-typewriter-suffix"
|
|
1565
1565
|
};
|
|
1566
|
-
var _sfc_main$
|
|
1566
|
+
var _sfc_main$h = /* @__PURE__ */ defineComponent({
|
|
1567
1567
|
...{ name: "FvTypewriter" },
|
|
1568
1568
|
__name: "index",
|
|
1569
1569
|
props: {
|
|
@@ -1653,11 +1653,11 @@ var _sfc_main$g = /* @__PURE__ */ defineComponent({
|
|
|
1653
1653
|
},
|
|
1654
1654
|
[
|
|
1655
1655
|
createCommentVNode(" markdown \u6A21\u5F0F:suffix \u4E0D\u8FFD\u52A0(element-plus-x \u884C\u4E3A),isTyping \u900F\u4F20\u7ED9 XMarkdown \u4F5C\u6837\u5F0F\u94A9\u5B50 "),
|
|
1656
|
-
__props.isMarkdown ? (openBlock(), createBlock(_sfc_main$
|
|
1656
|
+
__props.isMarkdown ? (openBlock(), createBlock(_sfc_main$i, {
|
|
1657
1657
|
key: 0,
|
|
1658
1658
|
content: renderedContent.value,
|
|
1659
1659
|
"is-typing": isTyping.value
|
|
1660
|
-
}, null, 8, ["content", "is-typing"])) : (openBlock(), createElementBlock("span", _hoisted_1$
|
|
1660
|
+
}, null, 8, ["content", "is-typing"])) : (openBlock(), createElementBlock("span", _hoisted_1$h, [
|
|
1661
1661
|
createTextVNode(
|
|
1662
1662
|
toDisplayString(renderedContent.value),
|
|
1663
1663
|
1
|
|
@@ -1692,12 +1692,12 @@ var _sfc_main$g = /* @__PURE__ */ defineComponent({
|
|
|
1692
1692
|
}
|
|
1693
1693
|
});
|
|
1694
1694
|
|
|
1695
|
-
const _hoisted_1$
|
|
1695
|
+
const _hoisted_1$g = {
|
|
1696
1696
|
key: 0,
|
|
1697
1697
|
class: "fv-bubble-avatar"
|
|
1698
1698
|
};
|
|
1699
1699
|
const _hoisted_2$e = { class: "fv-bubble-main" };
|
|
1700
|
-
const _hoisted_3$
|
|
1700
|
+
const _hoisted_3$e = {
|
|
1701
1701
|
key: 0,
|
|
1702
1702
|
class: "fv-bubble-header"
|
|
1703
1703
|
};
|
|
@@ -1713,7 +1713,7 @@ const _hoisted_6$6 = {
|
|
|
1713
1713
|
key: 1,
|
|
1714
1714
|
class: "fv-bubble-footer"
|
|
1715
1715
|
};
|
|
1716
|
-
var _sfc_main$
|
|
1716
|
+
var _sfc_main$g = /* @__PURE__ */ defineComponent({
|
|
1717
1717
|
...{ name: "FvBubble" },
|
|
1718
1718
|
__name: "index",
|
|
1719
1719
|
props: {
|
|
@@ -1780,7 +1780,7 @@ var _sfc_main$f = /* @__PURE__ */ defineComponent({
|
|
|
1780
1780
|
},
|
|
1781
1781
|
[
|
|
1782
1782
|
createCommentVNode(" \u5934\u50CF:placement \u540C\u7F18\u6392\u5217(end \u7ECF row-reverse \u7FFB\u8F6C\u5230\u53F3\u4FA7),#avatar \u63D2\u69FD\u4F18\u5148 "),
|
|
1783
|
-
_ctx.$slots.avatar || __props.avatar || __props.avatarIcon ? (openBlock(), createElementBlock("div", _hoisted_1$
|
|
1783
|
+
_ctx.$slots.avatar || __props.avatar || __props.avatarIcon ? (openBlock(), createElementBlock("div", _hoisted_1$g, [
|
|
1784
1784
|
_ctx.$slots.avatar ? renderSlot(_ctx.$slots, "avatar", {}, void 0, void 0, 0) : (openBlock(), createBlock(unref(ElAvatar), {
|
|
1785
1785
|
key: 1,
|
|
1786
1786
|
size: __props.avatarSize || void 0,
|
|
@@ -1794,7 +1794,7 @@ var _sfc_main$f = /* @__PURE__ */ defineComponent({
|
|
|
1794
1794
|
}, null, 8, ["size", "shape", "icon", "src", "src-set", "alt", "fit"]))
|
|
1795
1795
|
])) : createCommentVNode("v-if", true),
|
|
1796
1796
|
createElementVNode("div", _hoisted_2$e, [
|
|
1797
|
-
_ctx.$slots.header ? (openBlock(), createElementBlock("div", _hoisted_3$
|
|
1797
|
+
_ctx.$slots.header ? (openBlock(), createElementBlock("div", _hoisted_3$e, [
|
|
1798
1798
|
renderSlot(_ctx.$slots, "header")
|
|
1799
1799
|
])) : createCommentVNode("v-if", true),
|
|
1800
1800
|
createElementVNode(
|
|
@@ -1838,7 +1838,7 @@ var _sfc_main$f = /* @__PURE__ */ defineComponent({
|
|
|
1838
1838
|
{ key: 2 },
|
|
1839
1839
|
[
|
|
1840
1840
|
createCommentVNode(" typing \u900F\u4F20 Typewriter;\u975E typing:isMarkdown \u2192 XMarkdown,\u5426\u5219\u7EAF\u6587\u672C "),
|
|
1841
|
-
createVNode(_sfc_main$
|
|
1841
|
+
createVNode(_sfc_main$h, {
|
|
1842
1842
|
ref_key: "twRef",
|
|
1843
1843
|
ref: twRef,
|
|
1844
1844
|
content: __props.content,
|
|
@@ -1852,7 +1852,7 @@ var _sfc_main$f = /* @__PURE__ */ defineComponent({
|
|
|
1852
1852
|
],
|
|
1853
1853
|
2112
|
|
1854
1854
|
/* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
|
|
1855
|
-
)) : __props.isMarkdown ? (openBlock(), createBlock(_sfc_main$
|
|
1855
|
+
)) : __props.isMarkdown ? (openBlock(), createBlock(_sfc_main$i, {
|
|
1856
1856
|
key: 3,
|
|
1857
1857
|
content: __props.content
|
|
1858
1858
|
}, null, 8, ["content"])) : (openBlock(), createElementBlock(
|
|
@@ -1878,8 +1878,8 @@ var _sfc_main$f = /* @__PURE__ */ defineComponent({
|
|
|
1878
1878
|
}
|
|
1879
1879
|
});
|
|
1880
1880
|
|
|
1881
|
-
const _hoisted_1$
|
|
1882
|
-
var _sfc_main$
|
|
1881
|
+
const _hoisted_1$f = { class: "fv-bubble-list" };
|
|
1882
|
+
var _sfc_main$f = /* @__PURE__ */ defineComponent({
|
|
1883
1883
|
...{ name: "FvBubbleList" },
|
|
1884
1884
|
__name: "index",
|
|
1885
1885
|
props: {
|
|
@@ -1979,7 +1979,7 @@ var _sfc_main$e = /* @__PURE__ */ defineComponent({
|
|
|
1979
1979
|
}));
|
|
1980
1980
|
__expose({ scrollToTop, scrollToBottom, scrollToBubble });
|
|
1981
1981
|
return (_ctx, _cache) => {
|
|
1982
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
1982
|
+
return openBlock(), createElementBlock("div", _hoisted_1$f, [
|
|
1983
1983
|
createElementVNode(
|
|
1984
1984
|
"div",
|
|
1985
1985
|
{
|
|
@@ -1994,7 +1994,7 @@ var _sfc_main$e = /* @__PURE__ */ defineComponent({
|
|
|
1994
1994
|
Fragment,
|
|
1995
1995
|
null,
|
|
1996
1996
|
renderList(__props.list, (item, index) => {
|
|
1997
|
-
return openBlock(), createBlock(_sfc_main$
|
|
1997
|
+
return openBlock(), createBlock(_sfc_main$g, mergeProps({
|
|
1998
1998
|
key: item.key,
|
|
1999
1999
|
ref_for: true,
|
|
2000
2000
|
ref: (el) => setBubbleRef(el, index)
|
|
@@ -2102,12 +2102,145 @@ var _sfc_main$e = /* @__PURE__ */ defineComponent({
|
|
|
2102
2102
|
}
|
|
2103
2103
|
});
|
|
2104
2104
|
|
|
2105
|
+
const _hoisted_1$e = {
|
|
2106
|
+
class: "fv-stop-icon",
|
|
2107
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2108
|
+
viewBox: "0 0 24 24",
|
|
2109
|
+
width: "1em",
|
|
2110
|
+
height: "1em",
|
|
2111
|
+
"aria-hidden": "true",
|
|
2112
|
+
focusable: "false"
|
|
2113
|
+
};
|
|
2114
|
+
var _sfc_main$e = /* @__PURE__ */ defineComponent({
|
|
2115
|
+
...{ name: "FvStopIcon" },
|
|
2116
|
+
__name: "StopIcon",
|
|
2117
|
+
setup(__props) {
|
|
2118
|
+
return (_ctx, _cache) => {
|
|
2119
|
+
return openBlock(), createElementBlock("svg", _hoisted_1$e, [..._cache[0] || (_cache[0] = [
|
|
2120
|
+
createElementVNode(
|
|
2121
|
+
"rect",
|
|
2122
|
+
{
|
|
2123
|
+
x: "5.5",
|
|
2124
|
+
y: "5.5",
|
|
2125
|
+
width: "13",
|
|
2126
|
+
height: "13",
|
|
2127
|
+
rx: "2.5",
|
|
2128
|
+
fill: "currentColor"
|
|
2129
|
+
},
|
|
2130
|
+
null,
|
|
2131
|
+
-1
|
|
2132
|
+
/* CACHED */
|
|
2133
|
+
)
|
|
2134
|
+
])]);
|
|
2135
|
+
};
|
|
2136
|
+
}
|
|
2137
|
+
});
|
|
2138
|
+
|
|
2139
|
+
function getSpeechRecognitionCtor() {
|
|
2140
|
+
if (typeof window === "undefined") return void 0;
|
|
2141
|
+
const w = window;
|
|
2142
|
+
const ctor = w.SpeechRecognition ?? w.webkitSpeechRecognition;
|
|
2143
|
+
return typeof ctor === "function" ? ctor : void 0;
|
|
2144
|
+
}
|
|
2145
|
+
function useRecord() {
|
|
2146
|
+
const isRecording = ref(false);
|
|
2147
|
+
const text = ref("");
|
|
2148
|
+
const audioUrl = ref(null);
|
|
2149
|
+
const error = ref(null);
|
|
2150
|
+
let mediaStream = null;
|
|
2151
|
+
let mediaRecorder = null;
|
|
2152
|
+
let chunks = [];
|
|
2153
|
+
let recognition = null;
|
|
2154
|
+
let finalText = "";
|
|
2155
|
+
function revokeAudioUrl() {
|
|
2156
|
+
if (audioUrl.value) {
|
|
2157
|
+
URL.revokeObjectURL(audioUrl.value);
|
|
2158
|
+
audioUrl.value = null;
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
async function start() {
|
|
2162
|
+
if (isRecording.value) return;
|
|
2163
|
+
error.value = null;
|
|
2164
|
+
text.value = "";
|
|
2165
|
+
finalText = "";
|
|
2166
|
+
chunks = [];
|
|
2167
|
+
revokeAudioUrl();
|
|
2168
|
+
if (typeof MediaRecorder === "undefined" || !navigator.mediaDevices?.getUserMedia) {
|
|
2169
|
+
error.value = new Error("\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301\u97F3\u9891\u5F55\u5236");
|
|
2170
|
+
return;
|
|
2171
|
+
}
|
|
2172
|
+
try {
|
|
2173
|
+
mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
2174
|
+
} catch (e) {
|
|
2175
|
+
error.value = e instanceof Error ? e : new Error(String(e));
|
|
2176
|
+
return;
|
|
2177
|
+
}
|
|
2178
|
+
mediaRecorder = new MediaRecorder(mediaStream);
|
|
2179
|
+
mediaRecorder.ondataavailable = (e) => {
|
|
2180
|
+
if (e.data && e.data.size > 0) chunks.push(e.data);
|
|
2181
|
+
};
|
|
2182
|
+
mediaRecorder.onstop = () => {
|
|
2183
|
+
if (chunks.length > 0) {
|
|
2184
|
+
const blob = new Blob(chunks, { type: mediaRecorder?.mimeType || "audio/webm" });
|
|
2185
|
+
audioUrl.value = URL.createObjectURL(blob);
|
|
2186
|
+
}
|
|
2187
|
+
mediaStream?.getTracks().forEach((t) => t.stop());
|
|
2188
|
+
mediaStream = null;
|
|
2189
|
+
};
|
|
2190
|
+
const SRCtor = getSpeechRecognitionCtor();
|
|
2191
|
+
if (SRCtor) {
|
|
2192
|
+
try {
|
|
2193
|
+
recognition = new SRCtor();
|
|
2194
|
+
recognition.continuous = true;
|
|
2195
|
+
recognition.interimResults = true;
|
|
2196
|
+
recognition.onresult = (event) => {
|
|
2197
|
+
let interim = "";
|
|
2198
|
+
for (let i = event.resultIndex; i < event.results.length; i++) {
|
|
2199
|
+
const r = event.results[i];
|
|
2200
|
+
if (r.isFinal) finalText += r[0].transcript;
|
|
2201
|
+
else interim += r[0].transcript;
|
|
2202
|
+
}
|
|
2203
|
+
text.value = finalText + interim;
|
|
2204
|
+
};
|
|
2205
|
+
recognition.onerror = (ev) => {
|
|
2206
|
+
error.value = new Error(`\u8BED\u97F3\u8BC6\u522B\u9519\u8BEF: ${ev?.error ?? "unknown"}`);
|
|
2207
|
+
};
|
|
2208
|
+
recognition.start();
|
|
2209
|
+
} catch {
|
|
2210
|
+
recognition = null;
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
mediaRecorder.start();
|
|
2214
|
+
isRecording.value = true;
|
|
2215
|
+
}
|
|
2216
|
+
function stop() {
|
|
2217
|
+
if (!isRecording.value) return;
|
|
2218
|
+
isRecording.value = false;
|
|
2219
|
+
try {
|
|
2220
|
+
recognition?.stop();
|
|
2221
|
+
} catch {
|
|
2222
|
+
}
|
|
2223
|
+
recognition = null;
|
|
2224
|
+
try {
|
|
2225
|
+
if (mediaRecorder && mediaRecorder.state !== "inactive") mediaRecorder.stop();
|
|
2226
|
+
} catch {
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
if (getCurrentInstance()) {
|
|
2230
|
+
onBeforeUnmount(() => {
|
|
2231
|
+
stop();
|
|
2232
|
+
revokeAudioUrl();
|
|
2233
|
+
});
|
|
2234
|
+
}
|
|
2235
|
+
return { start, stop, isRecording, text, audioUrl, error };
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2105
2238
|
const _hoisted_1$d = {
|
|
2106
2239
|
key: 0,
|
|
2107
2240
|
class: "fv-sender-header"
|
|
2108
2241
|
};
|
|
2109
2242
|
const _hoisted_2$d = { class: "fv-sender-body" };
|
|
2110
|
-
const _hoisted_3$
|
|
2243
|
+
const _hoisted_3$d = {
|
|
2111
2244
|
key: 0,
|
|
2112
2245
|
class: "fv-sender-body-top"
|
|
2113
2246
|
};
|
|
@@ -2116,24 +2249,38 @@ const _hoisted_5$7 = {
|
|
|
2116
2249
|
key: 0,
|
|
2117
2250
|
class: "fv-sender-prefix"
|
|
2118
2251
|
};
|
|
2119
|
-
const _hoisted_6$5 =
|
|
2120
|
-
|
|
2121
|
-
|
|
2252
|
+
const _hoisted_6$5 = {
|
|
2253
|
+
class: "fv-sender-recording-wave",
|
|
2254
|
+
"aria-hidden": "true"
|
|
2255
|
+
};
|
|
2256
|
+
const _hoisted_7$4 = { class: "fv-sender-recording-duration" };
|
|
2257
|
+
const _hoisted_8$3 = ["value", "placeholder", "disabled", "readonly"];
|
|
2258
|
+
const _hoisted_9$2 = {
|
|
2259
|
+
key: 3,
|
|
2122
2260
|
class: "fv-sender-actions"
|
|
2123
2261
|
};
|
|
2124
|
-
const
|
|
2125
|
-
key:
|
|
2262
|
+
const _hoisted_10$2 = {
|
|
2263
|
+
key: 4,
|
|
2126
2264
|
class: "fv-sender-actions"
|
|
2127
2265
|
};
|
|
2128
|
-
const
|
|
2266
|
+
const _hoisted_11$2 = {
|
|
2129
2267
|
key: 0,
|
|
2130
2268
|
class: "fv-sender-action-left"
|
|
2131
2269
|
};
|
|
2132
|
-
const
|
|
2270
|
+
const _hoisted_12$2 = {
|
|
2271
|
+
class: "fv-sender-stop-ring",
|
|
2272
|
+
"aria-hidden": "true"
|
|
2273
|
+
};
|
|
2274
|
+
const _hoisted_13$2 = ["rx"];
|
|
2275
|
+
const _hoisted_14$2 = {
|
|
2133
2276
|
key: 1,
|
|
2134
2277
|
class: "fv-sender-footer"
|
|
2135
2278
|
};
|
|
2136
2279
|
const ROW_HEIGHT = 22;
|
|
2280
|
+
const WAVE_BARS = 48;
|
|
2281
|
+
const RING_HEAD = 10;
|
|
2282
|
+
const RING_TAIL = 40;
|
|
2283
|
+
const RING_LAYERS = 6;
|
|
2137
2284
|
var _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
2138
2285
|
...{ name: "FvSender" },
|
|
2139
2286
|
__name: "index",
|
|
@@ -2147,6 +2294,8 @@ var _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
|
2147
2294
|
disabled: { type: Boolean, required: false, default: false },
|
|
2148
2295
|
readOnly: { type: Boolean, required: false, default: false },
|
|
2149
2296
|
clearable: { type: Boolean, required: false, default: false },
|
|
2297
|
+
round: { type: Boolean, required: false, default: true },
|
|
2298
|
+
shadow: { type: Boolean, required: false, default: false },
|
|
2150
2299
|
inputWidth: { type: String, required: false, default: "" },
|
|
2151
2300
|
variant: { type: String, required: false, default: "default" },
|
|
2152
2301
|
submitBtnDisabled: { type: Boolean, required: false, default: false },
|
|
@@ -2319,11 +2468,136 @@ var _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
|
2319
2468
|
for (const f of Array.from(files)) emit("paste-file", f);
|
|
2320
2469
|
}
|
|
2321
2470
|
}
|
|
2322
|
-
|
|
2323
|
-
|
|
2471
|
+
const { start: startRecord, stop: stopRecord, isRecording, text: recordText, error: recordError } = useRecord();
|
|
2472
|
+
async function exitRecordingFocusInput() {
|
|
2473
|
+
await nextTick();
|
|
2474
|
+
focus("end");
|
|
2324
2475
|
}
|
|
2476
|
+
function insertTextAtCursor(insert) {
|
|
2477
|
+
if (!insert) return;
|
|
2478
|
+
const el = textareaRef.value;
|
|
2479
|
+
const pos = el?.selectionStart ?? value.value.length;
|
|
2480
|
+
const next = value.value.slice(0, pos) + insert + value.value.slice(el?.selectionEnd ?? pos);
|
|
2481
|
+
setValue(next);
|
|
2482
|
+
nextTick(() => {
|
|
2483
|
+
const t = textareaRef.value;
|
|
2484
|
+
if (t) t.setSelectionRange(pos + insert.length, pos + insert.length);
|
|
2485
|
+
});
|
|
2486
|
+
}
|
|
2487
|
+
async function onSpeechClick() {
|
|
2488
|
+
if (isRecording.value) return;
|
|
2489
|
+
await startRecord();
|
|
2490
|
+
if (recordError.value) {
|
|
2491
|
+
ElMessage.error(recordError.value.message || "\u65E0\u6CD5\u8BBF\u95EE\u9EA6\u514B\u98CE");
|
|
2492
|
+
return;
|
|
2493
|
+
}
|
|
2494
|
+
emit("recording-change", true);
|
|
2495
|
+
}
|
|
2496
|
+
async function onRecordConfirm() {
|
|
2497
|
+
stopRecord();
|
|
2498
|
+
emit("recording-change", false);
|
|
2499
|
+
insertTextAtCursor(recordText.value);
|
|
2500
|
+
await exitRecordingFocusInput();
|
|
2501
|
+
}
|
|
2502
|
+
async function onRecordCancel() {
|
|
2503
|
+
stopRecord();
|
|
2504
|
+
emit("recording-change", false);
|
|
2505
|
+
await exitRecordingFocusInput();
|
|
2506
|
+
}
|
|
2507
|
+
function onRecordingKeydown(e) {
|
|
2508
|
+
if (e.key === "Escape") {
|
|
2509
|
+
e.preventDefault();
|
|
2510
|
+
onRecordCancel();
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
const waveLevels = ref(Array(WAVE_BARS).fill(0.04));
|
|
2514
|
+
let audioCtx = null;
|
|
2515
|
+
let analyserSource = null;
|
|
2516
|
+
let waveRafId = 0;
|
|
2517
|
+
function normalizeRms(rms) {
|
|
2518
|
+
const scaled = Math.pow(rms * 10, 1.5);
|
|
2519
|
+
return Math.min(1, Math.max(0.04, scaled));
|
|
2520
|
+
}
|
|
2521
|
+
async function startWaveVisualizer() {
|
|
2522
|
+
if (typeof AudioContext === "undefined" || !navigator.mediaDevices?.getUserMedia) return;
|
|
2523
|
+
try {
|
|
2524
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
2525
|
+
audioCtx = new AudioContext();
|
|
2526
|
+
analyserSource = audioCtx.createMediaStreamSource(stream);
|
|
2527
|
+
const analyser = audioCtx.createAnalyser();
|
|
2528
|
+
analyser.minDecibels = -45;
|
|
2529
|
+
analyserSource.connect(analyser);
|
|
2530
|
+
const timeData = new Uint8Array(analyser.fftSize);
|
|
2531
|
+
const processFrame = () => {
|
|
2532
|
+
analyser.getByteTimeDomainData(timeData);
|
|
2533
|
+
let sumSquares = 0;
|
|
2534
|
+
for (let i = 0; i < timeData.length; i++) {
|
|
2535
|
+
const v = (timeData[i] - 128) / 128;
|
|
2536
|
+
sumSquares += v * v;
|
|
2537
|
+
}
|
|
2538
|
+
const level = normalizeRms(Math.sqrt(sumSquares / timeData.length));
|
|
2539
|
+
waveLevels.value = [...waveLevels.value.slice(1), level];
|
|
2540
|
+
waveRafId = requestAnimationFrame(processFrame);
|
|
2541
|
+
};
|
|
2542
|
+
waveRafId = requestAnimationFrame(processFrame);
|
|
2543
|
+
stream.getTracks().forEach((t) => t.addEventListener("ended", () => stopWaveVisualizer()));
|
|
2544
|
+
analyserSourceStream = stream;
|
|
2545
|
+
} catch {
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
let analyserSourceStream = null;
|
|
2549
|
+
function stopWaveVisualizer() {
|
|
2550
|
+
cancelAnimationFrame(waveRafId);
|
|
2551
|
+
waveRafId = 0;
|
|
2552
|
+
analyserSource?.disconnect();
|
|
2553
|
+
analyserSource = null;
|
|
2554
|
+
analyserSourceStream?.getTracks().forEach((t) => t.stop());
|
|
2555
|
+
analyserSourceStream = null;
|
|
2556
|
+
audioCtx?.close().catch(() => {
|
|
2557
|
+
});
|
|
2558
|
+
audioCtx = null;
|
|
2559
|
+
waveLevels.value = Array(WAVE_BARS).fill(0.04);
|
|
2560
|
+
}
|
|
2561
|
+
watch(isRecording, (rec) => {
|
|
2562
|
+
if (rec) startWaveVisualizer();
|
|
2563
|
+
else stopWaveVisualizer();
|
|
2564
|
+
});
|
|
2565
|
+
const recordSeconds = ref(0);
|
|
2566
|
+
let recordTimer = null;
|
|
2567
|
+
watch(isRecording, (rec) => {
|
|
2568
|
+
if (rec) {
|
|
2569
|
+
recordSeconds.value = 0;
|
|
2570
|
+
recordTimer = setInterval(() => {
|
|
2571
|
+
recordSeconds.value++;
|
|
2572
|
+
}, 1e3);
|
|
2573
|
+
} else if (recordTimer) {
|
|
2574
|
+
clearInterval(recordTimer);
|
|
2575
|
+
recordTimer = null;
|
|
2576
|
+
}
|
|
2577
|
+
});
|
|
2578
|
+
const recordDuration = computed(() => {
|
|
2579
|
+
const m = Math.floor(recordSeconds.value / 60);
|
|
2580
|
+
const s = recordSeconds.value % 60;
|
|
2581
|
+
return `${m}:${String(s).padStart(2, "0")}`;
|
|
2582
|
+
});
|
|
2583
|
+
onBeforeUnmount(() => {
|
|
2584
|
+
stopWaveVisualizer();
|
|
2585
|
+
if (recordTimer) clearInterval(recordTimer);
|
|
2586
|
+
});
|
|
2325
2587
|
const inputDisabled = computed(() => props.disabled || props.loading);
|
|
2326
2588
|
const inputReadonly = computed(() => props.readOnly);
|
|
2589
|
+
const ringLayers = computed(
|
|
2590
|
+
() => Array.from({ length: RING_LAYERS }, (_, i) => {
|
|
2591
|
+
const len = RING_HEAD + RING_TAIL * i / (RING_LAYERS - 1);
|
|
2592
|
+
const alpha = 0.9 * Math.pow(0.72, i);
|
|
2593
|
+
return {
|
|
2594
|
+
style: {
|
|
2595
|
+
"--ring-len": len.toFixed(2),
|
|
2596
|
+
"--ring-alpha": alpha.toFixed(3)
|
|
2597
|
+
}
|
|
2598
|
+
};
|
|
2599
|
+
})
|
|
2600
|
+
);
|
|
2327
2601
|
const slots = useSlots();
|
|
2328
2602
|
const hasActionListSlot = computed(() => !!slots["action-list"]);
|
|
2329
2603
|
__expose({ submit, cancel, clear, focus, blur, openHeader, closeHeader });
|
|
@@ -2331,7 +2605,7 @@ var _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
|
2331
2605
|
return openBlock(), createElementBlock(
|
|
2332
2606
|
"div",
|
|
2333
2607
|
{
|
|
2334
|
-
class: normalizeClass(["fv-sender", [`variant-${__props.variant}`, { "is-disabled": __props.disabled, "is-loading": __props.loading, "is-focused": isFocused.value }]])
|
|
2608
|
+
class: normalizeClass(["fv-sender", [`variant-${__props.variant}`, { "is-disabled": __props.disabled, "is-loading": __props.loading, "is-focused": isFocused.value, "has-shadow": __props.shadow }]])
|
|
2335
2609
|
},
|
|
2336
2610
|
[
|
|
2337
2611
|
createCommentVNode(" \u5934\u90E8:#header \u63D2\u69FD,openHeader/closeHeader \u63A7\u5236 "),
|
|
@@ -2340,7 +2614,7 @@ var _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
|
2340
2614
|
])) : createCommentVNode("v-if", true),
|
|
2341
2615
|
createElementVNode("div", _hoisted_2$d, [
|
|
2342
2616
|
createCommentVNode(" body \u9876\u90E8\u533A:\u5728\u8F93\u5165\u6846\u4E0A\u65B9\u3001body \u8FB9\u6846\u5185(\u5982\u9644\u4EF6\u5217\u8868) "),
|
|
2343
|
-
_ctx.$slots["body-top"] ? (openBlock(), createElementBlock("div", _hoisted_3$
|
|
2617
|
+
_ctx.$slots["body-top"] ? (openBlock(), createElementBlock("div", _hoisted_3$d, [
|
|
2344
2618
|
renderSlot(_ctx.$slots, "body-top")
|
|
2345
2619
|
])) : createCommentVNode("v-if", true),
|
|
2346
2620
|
createCommentVNode(" \u4E3B\u4F53\u884C:\u524D\u7F00 + \u8F93\u5165 + \u64CD\u4F5C "),
|
|
@@ -2349,9 +2623,89 @@ var _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
|
2349
2623
|
_ctx.$slots.prefix ? (openBlock(), createElementBlock("div", _hoisted_5$7, [
|
|
2350
2624
|
renderSlot(_ctx.$slots, "prefix")
|
|
2351
2625
|
])) : createCommentVNode("v-if", true),
|
|
2352
|
-
|
|
2626
|
+
createCommentVNode(" \u8BED\u97F3\u5F55\u97F3\u4E2D:\u8F93\u5165\u533A\u539F\u4F4D\u66FF\u6362\u4E3A\u5F55\u97F3\u6761(\u53D6\u6D88/\u6CE2\u5F62+\u65F6\u957F/\u786E\u8BA4);Esc \u53D6\u6D88 "),
|
|
2627
|
+
unref(isRecording) ? (openBlock(), createElementBlock(
|
|
2353
2628
|
"div",
|
|
2354
2629
|
{
|
|
2630
|
+
key: 1,
|
|
2631
|
+
class: "fv-sender-recording",
|
|
2632
|
+
tabindex: "-1",
|
|
2633
|
+
onKeydown: onRecordingKeydown
|
|
2634
|
+
},
|
|
2635
|
+
[
|
|
2636
|
+
createVNode(unref(ElButton), {
|
|
2637
|
+
class: "fv-sender-recording-cancel",
|
|
2638
|
+
text: "",
|
|
2639
|
+
circle: "",
|
|
2640
|
+
"aria-label": "\u53D6\u6D88\u5F55\u97F3",
|
|
2641
|
+
onClick: onRecordCancel
|
|
2642
|
+
}, {
|
|
2643
|
+
default: withCtx(() => [
|
|
2644
|
+
createVNode(unref(ElIcon), null, {
|
|
2645
|
+
default: withCtx(() => [
|
|
2646
|
+
createVNode(unref(Close))
|
|
2647
|
+
]),
|
|
2648
|
+
_: 1
|
|
2649
|
+
/* STABLE */
|
|
2650
|
+
})
|
|
2651
|
+
]),
|
|
2652
|
+
_: 1
|
|
2653
|
+
/* STABLE */
|
|
2654
|
+
}),
|
|
2655
|
+
createElementVNode("div", _hoisted_6$5, [
|
|
2656
|
+
(openBlock(true), createElementBlock(
|
|
2657
|
+
Fragment,
|
|
2658
|
+
null,
|
|
2659
|
+
renderList(waveLevels.value, (lv, i) => {
|
|
2660
|
+
return openBlock(), createElementBlock(
|
|
2661
|
+
"span",
|
|
2662
|
+
{
|
|
2663
|
+
key: i,
|
|
2664
|
+
class: "fv-sender-recording-bar",
|
|
2665
|
+
style: normalizeStyle({ height: `${Math.round(lv * 100)}%` })
|
|
2666
|
+
},
|
|
2667
|
+
null,
|
|
2668
|
+
4
|
|
2669
|
+
/* STYLE */
|
|
2670
|
+
);
|
|
2671
|
+
}),
|
|
2672
|
+
128
|
|
2673
|
+
/* KEYED_FRAGMENT */
|
|
2674
|
+
))
|
|
2675
|
+
]),
|
|
2676
|
+
createElementVNode(
|
|
2677
|
+
"span",
|
|
2678
|
+
_hoisted_7$4,
|
|
2679
|
+
toDisplayString(recordDuration.value),
|
|
2680
|
+
1
|
|
2681
|
+
/* TEXT */
|
|
2682
|
+
),
|
|
2683
|
+
createVNode(unref(ElButton), {
|
|
2684
|
+
class: "fv-sender-recording-confirm",
|
|
2685
|
+
type: "primary",
|
|
2686
|
+
circle: "",
|
|
2687
|
+
"aria-label": "\u786E\u8BA4\u5F55\u97F3",
|
|
2688
|
+
onClick: onRecordConfirm
|
|
2689
|
+
}, {
|
|
2690
|
+
default: withCtx(() => [
|
|
2691
|
+
createVNode(unref(ElIcon), null, {
|
|
2692
|
+
default: withCtx(() => [
|
|
2693
|
+
createVNode(unref(Check))
|
|
2694
|
+
]),
|
|
2695
|
+
_: 1
|
|
2696
|
+
/* STABLE */
|
|
2697
|
+
})
|
|
2698
|
+
]),
|
|
2699
|
+
_: 1
|
|
2700
|
+
/* STABLE */
|
|
2701
|
+
})
|
|
2702
|
+
],
|
|
2703
|
+
32
|
|
2704
|
+
/* NEED_HYDRATION */
|
|
2705
|
+
)) : (openBlock(), createElementBlock(
|
|
2706
|
+
"div",
|
|
2707
|
+
{
|
|
2708
|
+
key: 2,
|
|
2355
2709
|
class: "fv-sender-input",
|
|
2356
2710
|
style: normalizeStyle(__props.inputWidth && __props.variant === "default" ? { width: __props.inputWidth } : void 0)
|
|
2357
2711
|
},
|
|
@@ -2371,7 +2725,7 @@ var _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
|
2371
2725
|
onPaste,
|
|
2372
2726
|
onFocus: _cache[0] || (_cache[0] = ($event) => isFocused.value = true),
|
|
2373
2727
|
onBlur: onTextareaBlur
|
|
2374
|
-
}, null, 40,
|
|
2728
|
+
}, null, 40, _hoisted_8$3),
|
|
2375
2729
|
createCommentVNode(" \u6307\u4EE4\u5F39\u6846:\u5185\u7F6E el-popover,\u5B9A\u4F4D\u6309 triggerPopover* \u7CFB\u5217 "),
|
|
2376
2730
|
createVNode(unref(ElPopover), {
|
|
2377
2731
|
visible: triggerVisible.value && __props.triggerStrings.length > 0,
|
|
@@ -2402,12 +2756,12 @@ var _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
|
2402
2756
|
],
|
|
2403
2757
|
4
|
|
2404
2758
|
/* STYLE */
|
|
2405
|
-
),
|
|
2759
|
+
)),
|
|
2406
2760
|
createCommentVNode(" \u64CD\u4F5C\u533A:#action-list \u5B58\u5728\u65F6\u5168\u81EA\u5B9A\u4E49,\u9690\u85CF\u5185\u7F6E\u6309\u94AE;#action-left \u7F6E\u4E8E\u64CD\u4F5C\u680F\u5DE6\u4FA7(\u4E0E\u63D0\u4EA4\u6309\u94AE\u540C\u884C) "),
|
|
2407
|
-
hasActionListSlot.value ? (openBlock(), createElementBlock("div",
|
|
2761
|
+
hasActionListSlot.value ? (openBlock(), createElementBlock("div", _hoisted_9$2, [
|
|
2408
2762
|
renderSlot(_ctx.$slots, "action-list")
|
|
2409
|
-
])) : (openBlock(), createElementBlock("div",
|
|
2410
|
-
_ctx.$slots["action-left"] ? (openBlock(), createElementBlock("div",
|
|
2763
|
+
])) : (openBlock(), createElementBlock("div", _hoisted_10$2, [
|
|
2764
|
+
_ctx.$slots["action-left"] ? (openBlock(), createElementBlock("div", _hoisted_11$2, [
|
|
2411
2765
|
renderSlot(_ctx.$slots, "action-left")
|
|
2412
2766
|
])) : createCommentVNode("v-if", true),
|
|
2413
2767
|
__props.clearable && value.value ? (openBlock(), createBlock(unref(ElButton), {
|
|
@@ -2430,7 +2784,7 @@ var _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
|
2430
2784
|
_: 1
|
|
2431
2785
|
/* STABLE */
|
|
2432
2786
|
}, 8, ["disabled"])) : createCommentVNode("v-if", true),
|
|
2433
|
-
__props.allowSpeech ? (openBlock(), createBlock(unref(ElButton), {
|
|
2787
|
+
__props.allowSpeech && !unref(isRecording) ? (openBlock(), createBlock(unref(ElButton), {
|
|
2434
2788
|
key: 2,
|
|
2435
2789
|
class: "fv-sender-speech",
|
|
2436
2790
|
text: "",
|
|
@@ -2450,29 +2804,49 @@ var _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
|
2450
2804
|
_: 1
|
|
2451
2805
|
/* STABLE */
|
|
2452
2806
|
}, 8, ["disabled"])) : createCommentVNode("v-if", true),
|
|
2453
|
-
createCommentVNode(" loading \u2192 \u505C\u6B62\u6309\u94AE
|
|
2807
|
+
createCommentVNode(" loading \u2192 \u505C\u6B62\u6309\u94AE:SVG \u5149\u5E26\u6CBF\u8FB9\u6846\u5300\u901F\u6D41\u8F6C,\u65B9/\u5706\u6309\u94AE\u5747\u9002\u7528 "),
|
|
2454
2808
|
__props.loading ? (openBlock(), createBlock(unref(ElButton), {
|
|
2455
2809
|
key: 3,
|
|
2456
2810
|
class: "fv-sender-stop",
|
|
2457
2811
|
type: "primary",
|
|
2812
|
+
circle: __props.round,
|
|
2458
2813
|
"aria-label": "\u505C\u6B62",
|
|
2459
2814
|
onClick: cancel
|
|
2460
2815
|
}, {
|
|
2461
2816
|
default: withCtx(() => [
|
|
2462
2817
|
createVNode(unref(ElIcon), null, {
|
|
2463
2818
|
default: withCtx(() => [
|
|
2464
|
-
createVNode(
|
|
2819
|
+
createVNode(_sfc_main$e)
|
|
2465
2820
|
]),
|
|
2466
2821
|
_: 1
|
|
2467
2822
|
/* STABLE */
|
|
2468
|
-
})
|
|
2823
|
+
}),
|
|
2824
|
+
createCommentVNode('\r\n \u6CBF\u8FB9\u6846\u6D41\u8F6C\u7684\u6E10\u53D8\u5149\u5E26(\u8682\u8681\u7EBF\u539F\u7406,pathLength=100 \u5F52\u4E00\u5468\u957F,dashoffset \u5300\u901F\u5E73\u79FB)\u3002\r\n \u6E10\u53D8\u96BE\u70B9:linearGradient \u6CBF\u76F4\u7EBF\u8DEF\u5F84\u5B9A\u4E49,\u65E0\u6CD5\u6CBF\u95ED\u5408\u6298\u7EBF\u5468\u957F\u6E10\u53D8 \u2014\u2014\r\n \u6545\u7528 6 \u5C42\u957F\u77ED/\u900F\u660E\u5EA6\u53CC\u9012\u51CF\u7684\u540C\u76F8\u4F4D dash \u53E0\u52A0,\u79BB\u6563\u9636\u68AF\u903C\u8FD1\u8FDE\u7EED\u6E10\u53D8:\r\n \u6BCF\u5C42\u957F\u5EA6\u4F9D\u6B21\u9012\u589E(\u5E26\u5934\u6700\u77ED\u6700\u5B9E,\u5E26\u5C3E\u6700\u957F\u6700\u865A),\u900F\u660E\u5EA6\u4F9D\u6B21\u9012\u51CF,\r\n \u53E0\u52A0\u540E\u7684\u900F\u660E\u5EA6\u5256\u9762\u4E3A\u591A\u7EA7\u53F0\u9636 \u2192 \u8FD0\u52A8\u4E2D\u8BFB\u4F5C"\u5934\u4EAE\u5C3E\u9690"\u7684\u8FDE\u7EED\u62D6\u5F71\u3002\r\n \u5C42\u6570\u7531 RING_LAYERS \u5E38\u91CF\u9A71\u52A8,\u900F\u660E\u5EA6\u63D2\u503C\u5728 CSS \u91CC\u6309 --ring-alpha \u53D8\u91CF\u7B97\u3002\r\n '),
|
|
2825
|
+
(openBlock(), createElementBlock("svg", _hoisted_12$2, [
|
|
2826
|
+
(openBlock(true), createElementBlock(
|
|
2827
|
+
Fragment,
|
|
2828
|
+
null,
|
|
2829
|
+
renderList(ringLayers.value, (layer, i) => {
|
|
2830
|
+
return openBlock(), createElementBlock("rect", {
|
|
2831
|
+
key: i,
|
|
2832
|
+
class: "fv-sender-stop-ring-rect",
|
|
2833
|
+
style: normalizeStyle(layer.style),
|
|
2834
|
+
rx: __props.round ? "50%" : 2.5,
|
|
2835
|
+
pathLength: "100"
|
|
2836
|
+
}, null, 12, _hoisted_13$2);
|
|
2837
|
+
}),
|
|
2838
|
+
128
|
|
2839
|
+
/* KEYED_FRAGMENT */
|
|
2840
|
+
))
|
|
2841
|
+
]))
|
|
2469
2842
|
]),
|
|
2470
2843
|
_: 1
|
|
2471
2844
|
/* STABLE */
|
|
2472
|
-
})) : (openBlock(), createBlock(unref(ElButton), {
|
|
2845
|
+
}, 8, ["circle"])) : (openBlock(), createBlock(unref(ElButton), {
|
|
2473
2846
|
key: 4,
|
|
2474
2847
|
class: "fv-sender-submit",
|
|
2475
2848
|
type: "primary",
|
|
2849
|
+
circle: __props.round,
|
|
2476
2850
|
disabled: !submitable(),
|
|
2477
2851
|
"aria-label": "\u53D1\u9001",
|
|
2478
2852
|
onClick: doSubmit
|
|
@@ -2488,13 +2862,13 @@ var _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
|
2488
2862
|
]),
|
|
2489
2863
|
_: 1
|
|
2490
2864
|
/* STABLE */
|
|
2491
|
-
}, 8, ["disabled"]))
|
|
2865
|
+
}, 8, ["circle", "disabled"]))
|
|
2492
2866
|
]))
|
|
2493
2867
|
]),
|
|
2494
2868
|
createCommentVNode(" /fv-sender-row ")
|
|
2495
2869
|
]),
|
|
2496
2870
|
createCommentVNode(" \u5E95\u90E8 "),
|
|
2497
|
-
_ctx.$slots.footer ? (openBlock(), createElementBlock("div",
|
|
2871
|
+
_ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_14$2, [
|
|
2498
2872
|
renderSlot(_ctx.$slots, "footer")
|
|
2499
2873
|
])) : createCommentVNode("v-if", true)
|
|
2500
2874
|
],
|
|
@@ -2510,7 +2884,7 @@ const _hoisted_2$c = {
|
|
|
2510
2884
|
key: 0,
|
|
2511
2885
|
class: "fv-mention-title"
|
|
2512
2886
|
};
|
|
2513
|
-
const _hoisted_3$
|
|
2887
|
+
const _hoisted_3$c = {
|
|
2514
2888
|
key: 1,
|
|
2515
2889
|
class: "fv-mention-loading"
|
|
2516
2890
|
};
|
|
@@ -2878,7 +3252,7 @@ var _sfc_main$c = /* @__PURE__ */ defineComponent({
|
|
|
2878
3252
|
1
|
|
2879
3253
|
/* TEXT */
|
|
2880
3254
|
)) : createCommentVNode("v-if", true),
|
|
2881
|
-
asyncLoading.value ? (openBlock(), createElementBlock("div", _hoisted_3$
|
|
3255
|
+
asyncLoading.value ? (openBlock(), createElementBlock("div", _hoisted_3$c, "\u52A0\u8F7D\u4E2D\u2026")) : (openBlock(true), createElementBlock(
|
|
2882
3256
|
Fragment,
|
|
2883
3257
|
{ key: 2 },
|
|
2884
3258
|
renderList(candidates.value, (item, index) => {
|
|
@@ -2937,7 +3311,7 @@ const _hoisted_1$b = {
|
|
|
2937
3311
|
class: "fv-editor-header"
|
|
2938
3312
|
};
|
|
2939
3313
|
const _hoisted_2$b = { class: "fv-editor-body" };
|
|
2940
|
-
const _hoisted_3$
|
|
3314
|
+
const _hoisted_3$b = {
|
|
2941
3315
|
key: 0,
|
|
2942
3316
|
class: "fv-editor-prefix"
|
|
2943
3317
|
};
|
|
@@ -3715,7 +4089,7 @@ var _sfc_main$b = /* @__PURE__ */ defineComponent({
|
|
|
3715
4089
|
])) : createCommentVNode("v-if", true),
|
|
3716
4090
|
createElementVNode("div", _hoisted_2$b, [
|
|
3717
4091
|
createCommentVNode(" \u524D\u7F00\u533A "),
|
|
3718
|
-
_ctx.$slots.prefix ? (openBlock(), createElementBlock("div", _hoisted_3$
|
|
4092
|
+
_ctx.$slots.prefix ? (openBlock(), createElementBlock("div", _hoisted_3$b, [
|
|
3719
4093
|
renderSlot(_ctx.$slots, "prefix")
|
|
3720
4094
|
])) : createCommentVNode("v-if", true),
|
|
3721
4095
|
createElementVNode("div", _hoisted_4$a, [
|
|
@@ -4000,7 +4374,7 @@ const _hoisted_2$a = {
|
|
|
4000
4374
|
key: 0,
|
|
4001
4375
|
class: "fv-thinking-dot"
|
|
4002
4376
|
};
|
|
4003
|
-
const _hoisted_3$
|
|
4377
|
+
const _hoisted_3$a = { class: "fv-thinking-label" };
|
|
4004
4378
|
const _hoisted_4$9 = ["hidden"];
|
|
4005
4379
|
var _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
4006
4380
|
...{ name: "FvThinking" },
|
|
@@ -4096,7 +4470,7 @@ var _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
|
4096
4470
|
}))
|
|
4097
4471
|
])
|
|
4098
4472
|
]),
|
|
4099
|
-
createElementVNode("span", _hoisted_3$
|
|
4473
|
+
createElementVNode("span", _hoisted_3$a, [
|
|
4100
4474
|
renderSlot(_ctx.$slots, "label", {}, () => [
|
|
4101
4475
|
createTextVNode(
|
|
4102
4476
|
toDisplayString(statusText.value),
|
|
@@ -4156,7 +4530,7 @@ const _hoisted_2$9 = {
|
|
|
4156
4530
|
key: 4,
|
|
4157
4531
|
class: "fv-chain-dot"
|
|
4158
4532
|
};
|
|
4159
|
-
const _hoisted_3$
|
|
4533
|
+
const _hoisted_3$9 = { class: "fv-chain-main" };
|
|
4160
4534
|
const _hoisted_4$8 = { class: "fv-chain-title" };
|
|
4161
4535
|
const _hoisted_5$4 = {
|
|
4162
4536
|
key: 0,
|
|
@@ -4231,7 +4605,7 @@ var _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
|
4231
4605
|
})) : (openBlock(), createElementBlock("span", _hoisted_2$9))
|
|
4232
4606
|
]),
|
|
4233
4607
|
createCommentVNode(" \u5185\u5BB9:#content \u4F5C\u7528\u57DF\u63D2\u69FD\u8986\u76D6\u9ED8\u8BA4 title/description "),
|
|
4234
|
-
createElementVNode("div", _hoisted_3$
|
|
4608
|
+
createElementVNode("div", _hoisted_3$9, [
|
|
4235
4609
|
renderSlot(_ctx.$slots, "content", {
|
|
4236
4610
|
item,
|
|
4237
4611
|
index
|
|
@@ -4270,7 +4644,7 @@ var _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
|
4270
4644
|
|
|
4271
4645
|
const _hoisted_1$8 = { class: "fv-welcome" };
|
|
4272
4646
|
const _hoisted_2$8 = { class: "fv-welcome-icon" };
|
|
4273
|
-
const _hoisted_3$
|
|
4647
|
+
const _hoisted_3$8 = {
|
|
4274
4648
|
key: 0,
|
|
4275
4649
|
class: "fv-welcome-name"
|
|
4276
4650
|
};
|
|
@@ -4317,7 +4691,7 @@ var _sfc_main$8 = /* @__PURE__ */ defineComponent({
|
|
|
4317
4691
|
])
|
|
4318
4692
|
]),
|
|
4319
4693
|
createCommentVNode(" #name \u63D2\u69FD\u8986\u76D6\u540D\u79F0 "),
|
|
4320
|
-
_ctx.$slots.name || __props.name ? (openBlock(), createElementBlock("h2", _hoisted_3$
|
|
4694
|
+
_ctx.$slots.name || __props.name ? (openBlock(), createElementBlock("h2", _hoisted_3$8, [
|
|
4321
4695
|
renderSlot(_ctx.$slots, "name", {}, () => [
|
|
4322
4696
|
createTextVNode(
|
|
4323
4697
|
toDisplayString(__props.name),
|
|
@@ -4346,7 +4720,7 @@ const _hoisted_2$7 = {
|
|
|
4346
4720
|
key: 0,
|
|
4347
4721
|
class: "fv-prompts-title"
|
|
4348
4722
|
};
|
|
4349
|
-
const _hoisted_3$
|
|
4723
|
+
const _hoisted_3$7 = { class: "fv-prompts-list" };
|
|
4350
4724
|
const _hoisted_4$6 = ["role", "tabindex", "onClick"];
|
|
4351
4725
|
const _hoisted_5$3 = { class: "fv-prompt-item-main" };
|
|
4352
4726
|
const _hoisted_6$2 = { class: "fv-prompt-item-text" };
|
|
@@ -4389,7 +4763,7 @@ var _sfc_main$7 = /* @__PURE__ */ defineComponent({
|
|
|
4389
4763
|
1
|
|
4390
4764
|
/* TEXT */
|
|
4391
4765
|
)) : createCommentVNode("v-if", true),
|
|
4392
|
-
createElementVNode("div", _hoisted_3$
|
|
4766
|
+
createElementVNode("div", _hoisted_3$7, [
|
|
4393
4767
|
(openBlock(true), createElementBlock(
|
|
4394
4768
|
Fragment,
|
|
4395
4769
|
null,
|
|
@@ -4454,7 +4828,7 @@ var _sfc_main$7 = /* @__PURE__ */ defineComponent({
|
|
|
4454
4828
|
|
|
4455
4829
|
const _hoisted_1$6 = ["src", "alt"];
|
|
4456
4830
|
const _hoisted_2$6 = { class: "fv-files-card-info" };
|
|
4457
|
-
const _hoisted_3$
|
|
4831
|
+
const _hoisted_3$6 = ["title"];
|
|
4458
4832
|
const _hoisted_4$5 = {
|
|
4459
4833
|
key: 0,
|
|
4460
4834
|
class: "fv-files-card-size"
|
|
@@ -4596,7 +4970,7 @@ var _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
|
4596
4970
|
createElementVNode("div", {
|
|
4597
4971
|
class: "fv-files-card-name",
|
|
4598
4972
|
title: __props.name
|
|
4599
|
-
}, toDisplayString(__props.name), 9, _hoisted_3$
|
|
4973
|
+
}, toDisplayString(__props.name), 9, _hoisted_3$6),
|
|
4600
4974
|
sizeText.value ? (openBlock(), createElementBlock(
|
|
4601
4975
|
"div",
|
|
4602
4976
|
_hoisted_4$5,
|
|
@@ -4640,7 +5014,7 @@ var _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
|
4640
5014
|
|
|
4641
5015
|
const _hoisted_1$5 = { class: "fv-attachments" };
|
|
4642
5016
|
const _hoisted_2$5 = ["accept"];
|
|
4643
|
-
const _hoisted_3$
|
|
5017
|
+
const _hoisted_3$5 = ["disabled"];
|
|
4644
5018
|
const _hoisted_4$4 = {
|
|
4645
5019
|
key: 1,
|
|
4646
5020
|
class: "fv-attachments-list"
|
|
@@ -4782,7 +5156,7 @@ var _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
|
4782
5156
|
_: 1
|
|
4783
5157
|
/* STABLE */
|
|
4784
5158
|
})
|
|
4785
|
-
], 10, _hoisted_3$
|
|
5159
|
+
], 10, _hoisted_3$5)) : createCommentVNode("v-if", true),
|
|
4786
5160
|
createCommentVNode(" \u6587\u4EF6\u5217\u8868:FilesCard;#list-thumb/#list-item \u8986\u76D6\u9879\u6E32\u67D3(triggerOnly \u5E03\u5C40\u4E0D\u6E32\u67D3) "),
|
|
4787
5161
|
list.value.length && __props.layout !== "triggerOnly" ? (openBlock(), createElementBlock("div", _hoisted_4$4, [
|
|
4788
5162
|
(openBlock(true), createElementBlock(
|
|
@@ -4860,7 +5234,7 @@ const _hoisted_1$4 = {
|
|
|
4860
5234
|
class: "fv-conversations-group-title"
|
|
4861
5235
|
};
|
|
4862
5236
|
const _hoisted_2$4 = ["onClick"];
|
|
4863
|
-
const _hoisted_3$
|
|
5237
|
+
const _hoisted_3$4 = { class: "fv-conversations-item-content" };
|
|
4864
5238
|
const _hoisted_4$3 = ["title"];
|
|
4865
5239
|
var _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
4866
5240
|
...{ name: "FvConversations" },
|
|
@@ -4992,7 +5366,7 @@ var _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
|
4992
5366
|
onClick: ($event) => onItemClick(item)
|
|
4993
5367
|
}, [
|
|
4994
5368
|
createCommentVNode(" \u884C\u5185\u5BB9:#item \u8986\u76D6\u6574\u884C(\u9ED8\u8BA4\u6E32\u67D3 label) "),
|
|
4995
|
-
createElementVNode("div", _hoisted_3$
|
|
5369
|
+
createElementVNode("div", _hoisted_3$4, [
|
|
4996
5370
|
renderSlot(_ctx.$slots, "item", {
|
|
4997
5371
|
item,
|
|
4998
5372
|
active: isActive(item)
|
|
@@ -5630,16 +6004,22 @@ ${fileParts.join("\n")}` });
|
|
|
5630
6004
|
}
|
|
5631
6005
|
|
|
5632
6006
|
const _hoisted_1$3 = ["data-message-id"];
|
|
5633
|
-
const _hoisted_2$3 = {
|
|
5634
|
-
|
|
5635
|
-
|
|
6007
|
+
const _hoisted_2$3 = {
|
|
6008
|
+
key: 0,
|
|
6009
|
+
class: "fv-msg-avatar"
|
|
6010
|
+
};
|
|
6011
|
+
const _hoisted_3$3 = { class: "fv-msg-main" };
|
|
6012
|
+
const _hoisted_4$2 = {
|
|
6013
|
+
key: 0,
|
|
6014
|
+
class: "fv-msg-header"
|
|
6015
|
+
};
|
|
5636
6016
|
const _hoisted_5 = { class: "fv-msg-role" };
|
|
5637
6017
|
const _hoisted_6 = {
|
|
5638
6018
|
key: 0,
|
|
5639
6019
|
class: "fv-msg-model"
|
|
5640
6020
|
};
|
|
5641
6021
|
const _hoisted_7 = {
|
|
5642
|
-
key:
|
|
6022
|
+
key: 1,
|
|
5643
6023
|
class: "fv-msg-files"
|
|
5644
6024
|
};
|
|
5645
6025
|
const _hoisted_8 = ["src", "alt"];
|
|
@@ -5648,7 +6028,7 @@ const _hoisted_9 = {
|
|
|
5648
6028
|
class: "fv-msg-file-name"
|
|
5649
6029
|
};
|
|
5650
6030
|
const _hoisted_10 = {
|
|
5651
|
-
key:
|
|
6031
|
+
key: 3,
|
|
5652
6032
|
class: "fv-msg-content"
|
|
5653
6033
|
};
|
|
5654
6034
|
const _hoisted_11 = {
|
|
@@ -5660,11 +6040,11 @@ const _hoisted_12 = {
|
|
|
5660
6040
|
class: "fv-msg-pending"
|
|
5661
6041
|
};
|
|
5662
6042
|
const _hoisted_13 = {
|
|
5663
|
-
key:
|
|
6043
|
+
key: 4,
|
|
5664
6044
|
class: "fv-msg-content fv-msg-content-user"
|
|
5665
6045
|
};
|
|
5666
6046
|
const _hoisted_14 = {
|
|
5667
|
-
key:
|
|
6047
|
+
key: 5,
|
|
5668
6048
|
class: "fv-msg-actions"
|
|
5669
6049
|
};
|
|
5670
6050
|
const _hoisted_15 = {
|
|
@@ -5680,6 +6060,8 @@ var _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
5680
6060
|
branch: { type: Object, required: false, default: void 0 },
|
|
5681
6061
|
showActions: { type: Boolean, required: false, default: true },
|
|
5682
6062
|
showBranchSwitch: { type: Boolean, required: false, default: true },
|
|
6063
|
+
showUserAvatar: { type: Boolean, required: false, default: true },
|
|
6064
|
+
showUserName: { type: Boolean, required: false, default: true },
|
|
5683
6065
|
autoCollapse: { type: Boolean, required: false, default: true }
|
|
5684
6066
|
},
|
|
5685
6067
|
emits: ["copy", "regenerate", "branch-change"],
|
|
@@ -5710,8 +6092,8 @@ var _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
5710
6092
|
class: normalizeClass(["fv-msg", [`is-${__props.message.role}`, { "is-error": __props.message.status === "error", "is-user": isUser.value }]]),
|
|
5711
6093
|
"data-message-id": __props.message.id
|
|
5712
6094
|
}, [
|
|
5713
|
-
createCommentVNode(" \u5934\u50CF:user \u53F3\u4FA7(\u81EA\u8EAB)
|
|
5714
|
-
|
|
6095
|
+
createCommentVNode(" \u5934\u50CF:user \u53F3\u4FA7(\u81EA\u8EAB),assistant \u5DE6\u4FA7;showUserAvatar=false \u65F6\u7528\u6237\u6D88\u606F\u4E0D\u6E32\u67D3 "),
|
|
6096
|
+
!isUser.value || __props.showUserAvatar ? (openBlock(), createElementBlock("div", _hoisted_2$3, [
|
|
5715
6097
|
renderSlot(_ctx.$slots, "message-avatar", { message: __props.message }, () => [
|
|
5716
6098
|
isUser.value ? (openBlock(), createBlock(unref(ElIcon), {
|
|
5717
6099
|
key: 0,
|
|
@@ -5733,10 +6115,10 @@ var _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
5733
6115
|
/* STABLE */
|
|
5734
6116
|
}))
|
|
5735
6117
|
])
|
|
5736
|
-
]),
|
|
5737
|
-
createElementVNode("div", _hoisted_3$
|
|
5738
|
-
createCommentVNode(" \u5934\u90E8:\u89D2\u8272\u540D + \u6A21\u578B\u6807\u8BB0 "),
|
|
5739
|
-
|
|
6118
|
+
])) : createCommentVNode("v-if", true),
|
|
6119
|
+
createElementVNode("div", _hoisted_3$3, [
|
|
6120
|
+
createCommentVNode(" \u5934\u90E8:\u89D2\u8272\u540D + \u6A21\u578B\u6807\u8BB0;showUserName=false \u65F6\u7528\u6237\u6D88\u606F\u4E0D\u6E32\u67D3 "),
|
|
6121
|
+
!isUser.value || __props.showUserName ? (openBlock(), createElementBlock("div", _hoisted_4$2, [
|
|
5740
6122
|
createElementVNode(
|
|
5741
6123
|
"span",
|
|
5742
6124
|
_hoisted_5,
|
|
@@ -5751,7 +6133,7 @@ var _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
5751
6133
|
1
|
|
5752
6134
|
/* TEXT */
|
|
5753
6135
|
)) : createCommentVNode("v-if", true)
|
|
5754
|
-
]),
|
|
6136
|
+
])) : createCommentVNode("v-if", true),
|
|
5755
6137
|
createCommentVNode(" \u9644\u4EF6:user \u6D88\u606F files \u4EE5 FilesCard \u5E73\u94FA "),
|
|
5756
6138
|
__props.message.files?.length ? (openBlock(), createElementBlock("div", _hoisted_7, [
|
|
5757
6139
|
renderSlot(_ctx.$slots, "message-files", {
|
|
@@ -5793,13 +6175,13 @@ var _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
5793
6175
|
])) : createCommentVNode("v-if", true),
|
|
5794
6176
|
createCommentVNode(" \u601D\u8003\u94FE\u6298\u53E0(assistant \u542B reasoning \u65F6) "),
|
|
5795
6177
|
!isUser.value && hasReasoning.value ? (openBlock(), createBlock(_sfc_main$a, {
|
|
5796
|
-
key:
|
|
6178
|
+
key: 2,
|
|
5797
6179
|
content: __props.message.reasoning,
|
|
5798
6180
|
status: thinkingStatus.value,
|
|
5799
6181
|
"auto-collapse": __props.autoCollapse
|
|
5800
6182
|
}, {
|
|
5801
6183
|
content: withCtx(() => [
|
|
5802
|
-
createVNode(_sfc_main$
|
|
6184
|
+
createVNode(_sfc_main$i, {
|
|
5803
6185
|
content: __props.message.reasoning ?? ""
|
|
5804
6186
|
}, null, 8, ["content"])
|
|
5805
6187
|
]),
|
|
@@ -5814,7 +6196,7 @@ var _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
5814
6196
|
toDisplayString(__props.message.error || "\u751F\u6210\u5931\u8D25"),
|
|
5815
6197
|
1
|
|
5816
6198
|
/* TEXT */
|
|
5817
|
-
)) : __props.message.content ? (openBlock(), createBlock(_sfc_main$
|
|
6199
|
+
)) : __props.message.content ? (openBlock(), createBlock(_sfc_main$i, {
|
|
5818
6200
|
key: 1,
|
|
5819
6201
|
content: __props.message.content
|
|
5820
6202
|
}, null, 8, ["content"])) : __props.message.status === "pending" || __props.message.status === "streaming" ? (openBlock(), createElementBlock("span", _hoisted_12, [
|
|
@@ -5969,6 +6351,7 @@ const _hoisted_2$2 = {
|
|
|
5969
6351
|
key: 0,
|
|
5970
6352
|
class: "fv-messages-empty"
|
|
5971
6353
|
};
|
|
6354
|
+
const _hoisted_3$2 = { class: "fv-messages-inner" };
|
|
5972
6355
|
var _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
5973
6356
|
...{ name: "FvAiMessages" },
|
|
5974
6357
|
__name: "index",
|
|
@@ -5982,7 +6365,9 @@ var _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
5982
6365
|
suggestionsTitle: { type: String, required: false, default: "" },
|
|
5983
6366
|
scrollThreshold: { type: Number, required: false, default: 40 },
|
|
5984
6367
|
showActions: { type: Boolean, required: false, default: true },
|
|
5985
|
-
showBranchSwitch: { type: Boolean, required: false, default: true }
|
|
6368
|
+
showBranchSwitch: { type: Boolean, required: false, default: true },
|
|
6369
|
+
showUserAvatar: { type: Boolean, required: false, default: true },
|
|
6370
|
+
showUserName: { type: Boolean, required: false, default: true }
|
|
5986
6371
|
},
|
|
5987
6372
|
emits: ["select", "copy", "regenerate", "branch-change"],
|
|
5988
6373
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
@@ -6073,7 +6458,7 @@ var _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
6073
6458
|
Fragment,
|
|
6074
6459
|
{ key: 1 },
|
|
6075
6460
|
[
|
|
6076
|
-
createCommentVNode(" \u6D88\u606F\u5217\u8868 "),
|
|
6461
|
+
createCommentVNode(" \u6D88\u606F\u5217\u8868:\u5185\u5C42 fv-messages-inner \u63A7\u5236\u6EDA\u52A8\u5185\u5BB9\u6700\u5927\u5BBD\u5EA6\u5E76\u5DE6\u53F3\u5C45\u4E2D(--fv-messages-max-width \u53EF\u8986\u76D6) "),
|
|
6077
6462
|
createElementVNode(
|
|
6078
6463
|
"div",
|
|
6079
6464
|
{
|
|
@@ -6082,42 +6467,46 @@ var _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
6082
6467
|
class: "fv-messages-scroll"
|
|
6083
6468
|
},
|
|
6084
6469
|
[
|
|
6085
|
-
(
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6470
|
+
createElementVNode("div", _hoisted_3$2, [
|
|
6471
|
+
(openBlock(true), createElementBlock(
|
|
6472
|
+
Fragment,
|
|
6473
|
+
null,
|
|
6474
|
+
renderList(__props.messages, (m) => {
|
|
6475
|
+
return openBlock(), createBlock(_sfc_main$3, {
|
|
6476
|
+
key: m.id,
|
|
6477
|
+
message: m,
|
|
6478
|
+
branch: branchInfo(m),
|
|
6479
|
+
"show-actions": __props.showActions,
|
|
6480
|
+
"show-branch-switch": __props.showBranchSwitch,
|
|
6481
|
+
"show-user-avatar": __props.showUserAvatar,
|
|
6482
|
+
"show-user-name": __props.showUserName,
|
|
6483
|
+
onCopy,
|
|
6484
|
+
onRegenerate,
|
|
6485
|
+
onBranchChange: onBranch
|
|
6486
|
+
}, createSlots({
|
|
6487
|
+
_: 2
|
|
6488
|
+
/* DYNAMIC */
|
|
6489
|
+
}, [
|
|
6490
|
+
_ctx.$slots["message-avatar"] ? {
|
|
6491
|
+
name: "message-avatar",
|
|
6492
|
+
fn: withCtx((scope) => [
|
|
6493
|
+
renderSlot(_ctx.$slots, "message-avatar", mergeProps({ ref_for: true }, scope))
|
|
6494
|
+
]),
|
|
6495
|
+
key: "0"
|
|
6496
|
+
} : void 0,
|
|
6497
|
+
_ctx.$slots["message-actions"] ? {
|
|
6498
|
+
name: "message-actions",
|
|
6499
|
+
fn: withCtx((scope) => [
|
|
6500
|
+
renderSlot(_ctx.$slots, "message-actions", mergeProps({ ref_for: true }, scope))
|
|
6501
|
+
]),
|
|
6502
|
+
key: "1"
|
|
6503
|
+
} : void 0
|
|
6504
|
+
]), 1032, ["message", "branch", "show-actions", "show-branch-switch", "show-user-avatar", "show-user-name"]);
|
|
6505
|
+
}),
|
|
6506
|
+
128
|
|
6507
|
+
/* KEYED_FRAGMENT */
|
|
6508
|
+
))
|
|
6509
|
+
])
|
|
6121
6510
|
],
|
|
6122
6511
|
512
|
|
6123
6512
|
/* NEED_PATCH */
|
|
@@ -6385,7 +6774,10 @@ var _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
6385
6774
|
}
|
|
6386
6775
|
});
|
|
6387
6776
|
|
|
6388
|
-
const _hoisted_1 = {
|
|
6777
|
+
const _hoisted_1 = {
|
|
6778
|
+
key: 0,
|
|
6779
|
+
class: "fv-ai-chat-header"
|
|
6780
|
+
};
|
|
6389
6781
|
const _hoisted_2 = { class: "fv-ai-chat-title" };
|
|
6390
6782
|
const _hoisted_3 = { class: "fv-ai-chat-body" };
|
|
6391
6783
|
const _hoisted_4 = { class: "fv-ai-chat-footer" };
|
|
@@ -6400,7 +6792,12 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
6400
6792
|
adapter: { type: Object, required: false, default: void 0 },
|
|
6401
6793
|
messages: { type: Array, required: false, default: void 0 },
|
|
6402
6794
|
title: { type: String, required: false, default: "" },
|
|
6795
|
+
showHeader: { type: Boolean, required: false, default: false },
|
|
6796
|
+
centerWelcome: { type: Boolean, required: false, default: true },
|
|
6797
|
+
showUserAvatar: { type: Boolean, required: false, default: true },
|
|
6798
|
+
showUserName: { type: Boolean, required: false, default: true },
|
|
6403
6799
|
placeholder: { type: String, required: false, default: "" },
|
|
6800
|
+
senderShadow: { type: Boolean, required: false, default: true },
|
|
6404
6801
|
suggestions: { type: Array, required: false, default: () => [] },
|
|
6405
6802
|
features: { type: Object, required: false, default: () => ({}) },
|
|
6406
6803
|
allowAttachments: { type: Boolean, required: false, default: false },
|
|
@@ -6448,6 +6845,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
6448
6845
|
const { send, stop: stopChat, regenerate: regenerateChat, msgs, isLoading } = chat;
|
|
6449
6846
|
const nodeTable = chat.messages;
|
|
6450
6847
|
const chain = chat.chain;
|
|
6848
|
+
const isCenterWelcome = computed(() => props.centerWelcome && chain.value.length === 0);
|
|
6451
6849
|
let flushTimer = null;
|
|
6452
6850
|
watch(chain, (c) => {
|
|
6453
6851
|
if (flushTimer) clearTimeout(flushTimer);
|
|
@@ -6613,11 +7011,11 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
6613
7011
|
return openBlock(), createElementBlock(
|
|
6614
7012
|
"div",
|
|
6615
7013
|
{
|
|
6616
|
-
class: normalizeClass(["fv-ai-chat", { "is-dark": isDark.value }])
|
|
7014
|
+
class: normalizeClass(["fv-ai-chat", { "is-dark": isDark.value, "is-center-welcome": isCenterWelcome.value }])
|
|
6617
7015
|
},
|
|
6618
7016
|
[
|
|
6619
7017
|
createCommentVNode(" \u9876\u680F:\u6807\u9898 + \u6A21\u578B\u9009\u62E9\u5668(models \u6709\u503C\u65F6 multiple) "),
|
|
6620
|
-
|
|
7018
|
+
__props.showHeader ? (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
6621
7019
|
createElementVNode(
|
|
6622
7020
|
"div",
|
|
6623
7021
|
_hoisted_2,
|
|
@@ -6653,7 +7051,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
6653
7051
|
_: 1
|
|
6654
7052
|
/* STABLE */
|
|
6655
7053
|
}, 8, ["modelValue"])) : createCommentVNode("v-if", true)
|
|
6656
|
-
]),
|
|
7054
|
+
])) : createCommentVNode("v-if", true),
|
|
6657
7055
|
createCommentVNode(" \u6D88\u606F\u533A:\u7A7A\u65F6 Welcome + Prompts(AiMessages \u5185\u7F6E);\u5F00\u542F artifacts \u65F6\u53F3\u4FA7\u62FC\u9884\u89C8\u9762\u677F "),
|
|
6658
7056
|
createElementVNode("div", _hoisted_3, [
|
|
6659
7057
|
createVNode(_sfc_main$2, {
|
|
@@ -6661,6 +7059,8 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
6661
7059
|
nodes: unref(nodeTable),
|
|
6662
7060
|
name: __props.title,
|
|
6663
7061
|
suggestions: __props.suggestions,
|
|
7062
|
+
"show-user-avatar": __props.showUserAvatar,
|
|
7063
|
+
"show-user-name": __props.showUserName,
|
|
6664
7064
|
onSelect: onSelectSuggestion,
|
|
6665
7065
|
onCopy,
|
|
6666
7066
|
onRegenerate,
|
|
@@ -6690,7 +7090,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
6690
7090
|
]),
|
|
6691
7091
|
key: "2"
|
|
6692
7092
|
} : void 0
|
|
6693
|
-
]), 1032, ["messages", "nodes", "name", "suggestions"]),
|
|
7093
|
+
]), 1032, ["messages", "nodes", "name", "suggestions", "show-user-avatar", "show-user-name"]),
|
|
6694
7094
|
__props.features?.artifacts && artifacts.value.length ? (openBlock(), createBlock(_sfc_main$1, {
|
|
6695
7095
|
key: 0,
|
|
6696
7096
|
artifacts: artifacts.value,
|
|
@@ -6704,6 +7104,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
6704
7104
|
createVNode(_sfc_main$d, {
|
|
6705
7105
|
placeholder: __props.placeholder,
|
|
6706
7106
|
loading: unref(isLoading),
|
|
7107
|
+
shadow: __props.senderShadow,
|
|
6707
7108
|
variant: "updown",
|
|
6708
7109
|
maxlength: 8e3,
|
|
6709
7110
|
"allow-empty-submit": __props.allowAttachments && !!pendingFiles.value.length,
|
|
@@ -6748,7 +7149,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
6748
7149
|
]),
|
|
6749
7150
|
key: "2"
|
|
6750
7151
|
} : void 0
|
|
6751
|
-
]), 1032, ["placeholder", "loading", "allow-empty-submit"])
|
|
7152
|
+
]), 1032, ["placeholder", "loading", "shadow", "allow-empty-submit"])
|
|
6752
7153
|
])
|
|
6753
7154
|
],
|
|
6754
7155
|
2
|
|
@@ -6879,105 +7280,6 @@ function XRequest(url, options = {}) {
|
|
|
6879
7280
|
});
|
|
6880
7281
|
}
|
|
6881
7282
|
|
|
6882
|
-
function getSpeechRecognitionCtor() {
|
|
6883
|
-
if (typeof window === "undefined") return void 0;
|
|
6884
|
-
const w = window;
|
|
6885
|
-
const ctor = w.SpeechRecognition ?? w.webkitSpeechRecognition;
|
|
6886
|
-
return typeof ctor === "function" ? ctor : void 0;
|
|
6887
|
-
}
|
|
6888
|
-
function useRecord() {
|
|
6889
|
-
const isRecording = ref(false);
|
|
6890
|
-
const text = ref("");
|
|
6891
|
-
const audioUrl = ref(null);
|
|
6892
|
-
const error = ref(null);
|
|
6893
|
-
let mediaStream = null;
|
|
6894
|
-
let mediaRecorder = null;
|
|
6895
|
-
let chunks = [];
|
|
6896
|
-
let recognition = null;
|
|
6897
|
-
let finalText = "";
|
|
6898
|
-
function revokeAudioUrl() {
|
|
6899
|
-
if (audioUrl.value) {
|
|
6900
|
-
URL.revokeObjectURL(audioUrl.value);
|
|
6901
|
-
audioUrl.value = null;
|
|
6902
|
-
}
|
|
6903
|
-
}
|
|
6904
|
-
async function start() {
|
|
6905
|
-
if (isRecording.value) return;
|
|
6906
|
-
error.value = null;
|
|
6907
|
-
text.value = "";
|
|
6908
|
-
finalText = "";
|
|
6909
|
-
chunks = [];
|
|
6910
|
-
revokeAudioUrl();
|
|
6911
|
-
if (typeof MediaRecorder === "undefined" || !navigator.mediaDevices?.getUserMedia) {
|
|
6912
|
-
error.value = new Error("\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301\u97F3\u9891\u5F55\u5236");
|
|
6913
|
-
return;
|
|
6914
|
-
}
|
|
6915
|
-
try {
|
|
6916
|
-
mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
6917
|
-
} catch (e) {
|
|
6918
|
-
error.value = e instanceof Error ? e : new Error(String(e));
|
|
6919
|
-
return;
|
|
6920
|
-
}
|
|
6921
|
-
mediaRecorder = new MediaRecorder(mediaStream);
|
|
6922
|
-
mediaRecorder.ondataavailable = (e) => {
|
|
6923
|
-
if (e.data && e.data.size > 0) chunks.push(e.data);
|
|
6924
|
-
};
|
|
6925
|
-
mediaRecorder.onstop = () => {
|
|
6926
|
-
if (chunks.length > 0) {
|
|
6927
|
-
const blob = new Blob(chunks, { type: mediaRecorder?.mimeType || "audio/webm" });
|
|
6928
|
-
audioUrl.value = URL.createObjectURL(blob);
|
|
6929
|
-
}
|
|
6930
|
-
mediaStream?.getTracks().forEach((t) => t.stop());
|
|
6931
|
-
mediaStream = null;
|
|
6932
|
-
};
|
|
6933
|
-
const SRCtor = getSpeechRecognitionCtor();
|
|
6934
|
-
if (SRCtor) {
|
|
6935
|
-
try {
|
|
6936
|
-
recognition = new SRCtor();
|
|
6937
|
-
recognition.continuous = true;
|
|
6938
|
-
recognition.interimResults = true;
|
|
6939
|
-
recognition.onresult = (event) => {
|
|
6940
|
-
let interim = "";
|
|
6941
|
-
for (let i = event.resultIndex; i < event.results.length; i++) {
|
|
6942
|
-
const r = event.results[i];
|
|
6943
|
-
if (r.isFinal) finalText += r[0].transcript;
|
|
6944
|
-
else interim += r[0].transcript;
|
|
6945
|
-
}
|
|
6946
|
-
text.value = finalText + interim;
|
|
6947
|
-
};
|
|
6948
|
-
recognition.onerror = (ev) => {
|
|
6949
|
-
error.value = new Error(`\u8BED\u97F3\u8BC6\u522B\u9519\u8BEF: ${ev?.error ?? "unknown"}`);
|
|
6950
|
-
};
|
|
6951
|
-
recognition.start();
|
|
6952
|
-
} catch {
|
|
6953
|
-
recognition = null;
|
|
6954
|
-
}
|
|
6955
|
-
}
|
|
6956
|
-
mediaRecorder.start();
|
|
6957
|
-
isRecording.value = true;
|
|
6958
|
-
}
|
|
6959
|
-
function stop() {
|
|
6960
|
-
if (!isRecording.value) return;
|
|
6961
|
-
isRecording.value = false;
|
|
6962
|
-
try {
|
|
6963
|
-
recognition?.stop();
|
|
6964
|
-
} catch {
|
|
6965
|
-
}
|
|
6966
|
-
recognition = null;
|
|
6967
|
-
try {
|
|
6968
|
-
if (mediaRecorder && mediaRecorder.state !== "inactive") mediaRecorder.stop();
|
|
6969
|
-
} catch {
|
|
6970
|
-
}
|
|
6971
|
-
}
|
|
6972
|
-
if (getCurrentInstance()) {
|
|
6973
|
-
onBeforeUnmount(() => {
|
|
6974
|
-
stop();
|
|
6975
|
-
revokeAudioUrl();
|
|
6976
|
-
});
|
|
6977
|
-
}
|
|
6978
|
-
return { start, stop, isRecording, text, audioUrl, error };
|
|
6979
|
-
}
|
|
6980
|
-
|
|
6981
7283
|
class DetOmsError extends Error {
|
|
6982
7284
|
constructor(message, code) {
|
|
6983
7285
|
super(message);
|
|
@@ -7173,4 +7475,4 @@ function createMemoryAdapter() {
|
|
|
7173
7475
|
|
|
7174
7476
|
const version = "0.1.0";
|
|
7175
7477
|
|
|
7176
|
-
export { DetOmsChatAdapter, DetOmsError, _sfc_main$1 as FvAiArtifacts, _sfc_main as FvAiChat, _sfc_main$3 as FvAiMessage, _sfc_main$2 as FvAiMessages, _sfc_main$5 as FvAttachments, _sfc_main$
|
|
7478
|
+
export { DetOmsChatAdapter, DetOmsError, _sfc_main$1 as FvAiArtifacts, _sfc_main as FvAiChat, _sfc_main$3 as FvAiMessage, _sfc_main$2 as FvAiMessages, _sfc_main$5 as FvAttachments, _sfc_main$g as FvBubble, _sfc_main$f as FvBubbleList, _sfc_main$4 as FvConversations, _sfc_main$b as FvEditorSender, _sfc_main$6 as FvFilesCard, _sfc_main$i as FvMarkdown, _sfc_main$c as FvMentionSender, _sfc_main$7 as FvPrompts, _sfc_main$d as FvSender, _sfc_main$a as FvThinking, _sfc_main$9 as FvThoughtChain, _sfc_main$h as FvTypewriter, _sfc_main$8 as FvWelcome, OpenAIAdapter, XRequest, createLocalStorageAdapter, createMemoryAdapter, createMessageTree, createSSEParser, useChat, useMessages, useRecord, useSend, useXStream, version };
|