inl-ui 0.1.3 → 0.1.4

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.
@@ -11231,6 +11231,105 @@ const SszComment = vue.defineComponent({
11231
11231
  });
11232
11232
  var index = installComponent(SszComment, "ssz-comment");
11233
11233
 
11234
+ function formatDataString(str) {
11235
+ const lines = str.split("\n");
11236
+ const result = lines.filter(line => !!line.trim()).map(line => {
11237
+ const data = JSON.parse(line.replace("data: ", ""));
11238
+ return data.text;
11239
+ }).filter(line => line !== void 0).join("");
11240
+ return result;
11241
+ }
11242
+ function request(question, streamCallback, doneCallback) {
11243
+ fetch("/mt_cpp_gpt/chat", {
11244
+ method: "POST",
11245
+ headers: {
11246
+ "Content-Type": "application/json"
11247
+ },
11248
+ body: JSON.stringify({
11249
+ query: question,
11250
+ conversation_id: ""
11251
+ })
11252
+ }).then(res => res.body).then(stream => {
11253
+ const decoder = new TextDecoder();
11254
+ const reader = stream.getReader();
11255
+ let result = "";
11256
+ function processText() {
11257
+ return reader.read().then(({
11258
+ done,
11259
+ value
11260
+ }) => {
11261
+ if (done) {
11262
+ doneCallback();
11263
+ return;
11264
+ }
11265
+ const dataString = decoder.decode(value, {
11266
+ stream: true
11267
+ });
11268
+ const str = formatDataString(dataString);
11269
+ result += str;
11270
+ streamCallback(result);
11271
+ return processText();
11272
+ });
11273
+ }
11274
+ return processText();
11275
+ });
11276
+ }
11277
+ function useQA() {
11278
+ const context = vue.ref([]);
11279
+ const answerLoading = vue.ref(false);
11280
+ const answer = vue.ref("");
11281
+ setTimeout(() => {
11282
+ const questionItem = {
11283
+ type: "answer",
11284
+ content: "",
11285
+ id: /* @__PURE__ */new Date().getTime(),
11286
+ timestamp: /* @__PURE__ */new Date().getTime(),
11287
+ answers: [{
11288
+ content: "\u4F60\u597D\uFF0C\u6211\u662F\u4F60\u7684\u5DE5\u4F5C\u4F19\u4F34 \u7F8E\u5C0F\u817E! \u6211\u53EF\u4EE5\u8F85\u52A9\u4F60\u5FEB\u901F\u83B7\u53D6\u4FE1\u606F\uFF0C\u76D1\u63A7\u3001\u67E5\u770B\u751F\u4EA7\u6307\u6807\uFF0C\u56DE\u7B54\u60A8\u7684\u9009\u7164\u4E13\u4E1A\u95EE\u9898\uFF0C\u5FEB\u8BD5\u8BD5\u4E0B\u9762\u5BF9\u8BDD\u5427\u3002",
11289
+ timestamp: /* @__PURE__ */new Date().getTime(),
11290
+ hideOperates: true,
11291
+ id: /* @__PURE__ */new Date().getTime()
11292
+ }]
11293
+ };
11294
+ context.value.push(questionItem);
11295
+ }, 1e3);
11296
+ function sendQuestion(question, questionId) {
11297
+ if (answerLoading.value) return;
11298
+ answerLoading.value = true;
11299
+ let questionItem = context.value.find(item => item.id === questionId);
11300
+ question = questionItem?.content || question;
11301
+ if (!questionId) {
11302
+ questionItem = {
11303
+ id: /* @__PURE__ */new Date().getTime(),
11304
+ timestamp: /* @__PURE__ */new Date().getTime(),
11305
+ content: question,
11306
+ answers: []
11307
+ };
11308
+ context.value.push(questionItem);
11309
+ }
11310
+ const answerItem = vue.ref({
11311
+ content: "\u6B63\u5728\u601D\u8003\u4E2D...",
11312
+ timestamp: /* @__PURE__ */new Date().getTime(),
11313
+ parentId: questionItem.id,
11314
+ id: /* @__PURE__ */new Date().getTime()
11315
+ });
11316
+ questionItem.answers.push(answerItem.value);
11317
+ request(question, data => {
11318
+ answer.value = data;
11319
+ answerItem.value.content = data;
11320
+ }, () => {
11321
+ answerLoading.value = false;
11322
+ answerItem.value.loadEnd = true;
11323
+ });
11324
+ }
11325
+ return {
11326
+ context,
11327
+ answerLoading,
11328
+ answer,
11329
+ sendQuestion
11330
+ };
11331
+ }
11332
+
11234
11333
  const Input = vue.defineComponent({
11235
11334
  emits: ["send"],
11236
11335
  setup(props, {
@@ -11239,7 +11338,13 @@ const Input = vue.defineComponent({
11239
11338
  }) {
11240
11339
  const value = vue.ref("");
11241
11340
  const isFocus = vue.ref(false);
11341
+ const loading = vue.inject("answerLoading");
11242
11342
  const send = () => {
11343
+ if (loading.value) return;
11344
+ if (value.value.length === 0) {
11345
+ antDesignVue.message.warn("\u8BF7\u8F93\u5165\u95EE\u9898");
11346
+ return;
11347
+ }
11243
11348
  emit("send", value.value);
11244
11349
  value.value = "";
11245
11350
  };
@@ -11251,14 +11356,24 @@ const Input = vue.defineComponent({
11251
11356
  "class": ["chat-box-input", {
11252
11357
  focus: isFocus.value
11253
11358
  }]
11254
- }, [vue.createVNode(iconsVue.AudioFilled, null, null), vue.createVNode(vue.resolveComponent("a-input"), {
11359
+ }, [vue.createVNode("img", {
11360
+ "class": "img img-mic",
11361
+ "src": "/micro-assets/largeLanguageModel/mic.png",
11362
+ "alt": ""
11363
+ }, null), vue.createVNode(vue.resolveComponent("a-input"), {
11255
11364
  "value": value.value,
11256
11365
  "onUpdate:value": $event => value.value = $event,
11257
11366
  "bordered": false,
11258
11367
  "placeholder": "\u5982: \u67E5\u770BXXX\u76AE\u5E26\u673A\u5934\u7535\u6D41\u7B49",
11259
11368
  "onFocus": () => isFocus.value = true,
11260
- "onBlur": () => isFocus.value = false
11261
- }, null), vue.createVNode(iconsVue.SendOutlined, {
11369
+ "onBlur": () => isFocus.value = false,
11370
+ "onPressEnter": send
11371
+ }, null), loading.value ? vue.createVNode(iconsVue.BorderOutlined, {
11372
+ "class": "btn-abord",
11373
+ "title": "\u4E2D\u6B62\u56DE\u7B54"
11374
+ }, null) : vue.createVNode("img", {
11375
+ "class": "img img-send",
11376
+ "src": "/micro-assets/largeLanguageModel/send.png",
11262
11377
  "onClick": send
11263
11378
  }, null)]);
11264
11379
  }
@@ -11266,15 +11381,19 @@ const Input = vue.defineComponent({
11266
11381
 
11267
11382
  const tips = ["\u8BBE\u5907\u5DE5\u4F5C\u539F\u7406", "\u8BBE\u5907\u7EF4\u4FDD\u624B\u518C"];
11268
11383
  const Bottom = vue.defineComponent({
11269
- setup() {
11384
+ emits: ["send"],
11385
+ setup(props, {
11386
+ emit
11387
+ }) {
11270
11388
  const inputRef = vue.ref();
11271
11389
  const handleSend = msg => {
11272
11390
  inputRef.value.clear();
11391
+ emit("send", msg);
11273
11392
  };
11274
11393
  return () => {
11275
11394
  const tipsDom = tips.map(tip => vue.createVNode("div", {
11276
11395
  "class": "tip",
11277
- "onClick": () => handleSend()
11396
+ "onClick": () => handleSend(tip)
11278
11397
  }, [tip]));
11279
11398
  return vue.createVNode("div", {
11280
11399
  "class": "bottom"
@@ -11319,6 +11438,28 @@ const Avatar = vue.defineComponent({
11319
11438
  }
11320
11439
  });
11321
11440
 
11441
+ const QuestionBubble = vue.defineComponent({
11442
+ props: {
11443
+ content: {
11444
+ type: String,
11445
+ default: ""
11446
+ }
11447
+ },
11448
+ setup(props) {
11449
+ return () => vue.createVNode("div", {
11450
+ "class": "question-bubble chat-bubble"
11451
+ }, [vue.createVNode(Avatar, {
11452
+ "reverse": true,
11453
+ "avatar": "/micro-assets/platform_app/avatar.png",
11454
+ "name": "\u5F20\u660E\u5FD7"
11455
+ }, null), vue.createVNode("div", {
11456
+ "class": "bubble question"
11457
+ }, [props.content]), vue.createVNode("div", {
11458
+ "class": "operates"
11459
+ }, null)]);
11460
+ }
11461
+ });
11462
+
11322
11463
  const styleDark = `
11323
11464
  <style>
11324
11465
  :host > p {
@@ -11346,25 +11487,26 @@ const styleLight = `
11346
11487
 
11347
11488
  const suggestionList = ["\u7F8E\u5C0F\u817E\u80FD\u5E2E\u6211\u505A\u4EC0\u4E48\uFF1F", "\u8FD1\u4E00\u4E2A\u6708\u7684\u4ECB\u8017\u60C5\u51B5\u5982\u4F55\uFF1F", "\u5C3E\u77FF\u8DD1\u7C97\u7684\u6392\u67E5\u5904\u7406\u65B9\u6CD5\u6709\u54EA\u4E9B\uFF1F\u5C3E\u77FF\u8DD1\u7C97\u7684\u6392\u67E5\u5904\u7406\u65B9\u6CD5\u6709\u54EA\u4E9B\u5C3E\u77FF\u8DD1\u7C97\u7684\u6392\u67E5\u5904\u7406\u65B9\u6CD5\u6709\u54EA\u4E9B\u5C3E\u77FF\u8DD1\u7C97\u7684\u6392\u67E5\u5904\u7406\u65B9\u6CD5\u6709\u54EA\u4E9B"];
11348
11489
  const AnswerBubble = vue.defineComponent({
11490
+ emits: ["send", "render", "delete"],
11491
+ props: {
11492
+ content: {
11493
+ type: Array,
11494
+ default: () => []
11495
+ }
11496
+ },
11349
11497
  setup(props, {
11350
11498
  emit
11351
11499
  }) {
11352
11500
  const chatTheme = vue.inject("chat-theme");
11501
+ const {
11502
+ copy
11503
+ } = core.useClipboard({
11504
+ legacy: true
11505
+ });
11353
11506
  const bubbleRef = vue.ref();
11507
+ const activeAnswerIndex = vue.ref(0);
11508
+ const activeAnswer = vue.computed(() => props.content[activeAnswerIndex.value]);
11354
11509
  let shadowRoot;
11355
- const mdText = vue.ref(`\u4ECA\u5929\u7684\u7CBE\u7164\u4EA7\u91CF**18830.0**\u5428\uFF0C\u672B\u7164\u4EA7\u91CF**15900.0**\u5428\uFF0C\u7164\u6CE5**539.0**\u5428
11356
-
11357
- #### \u4F60\u597D\u554A
11358
-
11359
- 1. \u4F60\u597D\u554A
11360
-
11361
- 2. \u4E09\u5929\u4E4B\u5185\u6740\u4E86\u4F60
11362
-
11363
- 3. \u4F60\u662F\u771F\u6CA1\u89C1\u8FC7\u9ED1\u793E\u4F1A\u554A
11364
-
11365
- 4. \u6562\u4E0D\u6562\u8DDF\u6211\u6BD4\u5212\u6BD4\u5212
11366
-
11367
- 5. \u8BA9\u4F60\u89C1\u8BC6\u89C1\u8BC6\u4EC0\u4E48\u53EB\u9ED1\u624B`);
11368
11510
  const trasformMd = mdString => {
11369
11511
  return marked.marked(mdString);
11370
11512
  };
@@ -11372,49 +11514,177 @@ const AnswerBubble = vue.defineComponent({
11372
11514
  shadowRoot = bubbleRef.value.attachShadow({
11373
11515
  mode: "open"
11374
11516
  });
11517
+ renderText();
11518
+ });
11519
+ const renderText = () => {
11520
+ if (!shadowRoot) return;
11521
+ emit("render", activeAnswer.value.content);
11375
11522
  const themeStyle = chatTheme === "dark" ? styleDark : styleLight;
11376
11523
  const html = `
11377
- ${trasformMd(mdText.value)}
11524
+ ${trasformMd(activeAnswer.value.content)}
11378
11525
 
11379
11526
  ${themeStyle}
11380
11527
  `;
11381
11528
  shadowRoot.innerHTML = html;
11529
+ };
11530
+ vue.watch([() => props.content, activeAnswerIndex], renderText, {
11531
+ deep: true
11382
11532
  });
11533
+ const operateList = vue.reactive([{
11534
+ title: "\u590D\u5236",
11535
+ key: "copy",
11536
+ isActive: false
11537
+ }, {
11538
+ title: "\u6709\u7528",
11539
+ key: "like",
11540
+ isActive: vue.computed(() => activeAnswer.value.isLike)
11541
+ }, {
11542
+ title: "\u65E0\u7528",
11543
+ key: "dislike",
11544
+ isActive: vue.computed(() => activeAnswer.value.isDislike)
11545
+ }, {
11546
+ title: "\u8BC4\u8BBA",
11547
+ key: "comment",
11548
+ isActive: false
11549
+ }, {
11550
+ title: "\u91CD\u65B0\u751F\u6210",
11551
+ key: "regenerate",
11552
+ isActive: false
11553
+ }, {
11554
+ ttile: "\u5220\u9664",
11555
+ key: "delete",
11556
+ isActive: false
11557
+ }]);
11558
+ const handleOperate = key => {
11559
+ switch (key) {
11560
+ case "like":
11561
+ if (!activeAnswer.value.isDislike && !activeAnswer.value.isDislike) {
11562
+ activeAnswer.value.isLike = !activeAnswer.value.isLike;
11563
+ }
11564
+ break;
11565
+ case "dislike":
11566
+ if (!activeAnswer.value.isLike && !activeAnswer.value.isDislike) {
11567
+ activeAnswer.value.isDislike = !activeAnswer.value.isDislike;
11568
+ }
11569
+ break;
11570
+ case "copy":
11571
+ copy(activeAnswer.value.content);
11572
+ antDesignVue.message.success("\u590D\u5236\u6210\u529F");
11573
+ break;
11574
+ case "delete":
11575
+ antDesignVue.Modal.confirm({
11576
+ title: "\u786E\u5B9A\u5220\u9664\u8FD9\u4E2A\u56DE\u7B54\u5417\uFF1F",
11577
+ onOk: () => {
11578
+ emit("delete", activeAnswer.value.id);
11579
+ }
11580
+ });
11581
+ break;
11582
+ case "comment":
11583
+ antDesignVue.message.info("\u6682\u672A\u5F00\u653E");
11584
+ break;
11585
+ }
11586
+ };
11383
11587
  return () => {
11384
- const suggestionListDom = suggestionList.map(item => vue.createVNode("div", {
11588
+ suggestionList.map(item => vue.createVNode("div", {
11385
11589
  "class": "suggestion-item",
11386
11590
  "onClick": () => emit("send", item)
11387
11591
  }, [item]));
11592
+ const showOperates = !activeAnswer.value.hideOperates && activeAnswer.value.loadEnd;
11593
+ const operateDom = operateList.map(item => {
11594
+ return vue.createVNode(vue.resolveComponent("a-tooltip"), {
11595
+ "title": item.title
11596
+ }, {
11597
+ default: () => [vue.createVNode("div", {
11598
+ "class": ["operate-item", item.key, {
11599
+ active: item.isActive
11600
+ }],
11601
+ "onClick": () => handleOperate(item.key)
11602
+ }, null)]
11603
+ });
11604
+ });
11605
+ const prevDisabled = activeAnswerIndex.value === 0;
11606
+ const nextDisabled = activeAnswerIndex.value === props.content.length - 1;
11607
+ const answerNav = vue.createVNode("div", {
11608
+ "class": "operate-item"
11609
+ }, [vue.createVNode("span", {
11610
+ "class": ["nav", {
11611
+ disalbed: prevDisabled
11612
+ }]
11613
+ }, ["<"]), activeAnswerIndex.value + 1, "/ ", props.content.length, vue.createVNode("span", {
11614
+ "class": ["nav", {
11615
+ disalbed: nextDisabled
11616
+ }]
11617
+ }, [">"])]);
11388
11618
  return vue.createVNode("div", {
11389
11619
  "class": "answer-bubble chat-bubble"
11390
11620
  }, [vue.createVNode(Avatar, {
11391
- "avatar": "",
11621
+ "avatar": "/micro-assets/largeLanguageModel/robot-avatar.png",
11392
11622
  "name": "\u7F8E\u5C0F\u817E"
11393
11623
  }, null), vue.createVNode("div", {
11394
11624
  "ref": bubbleRef,
11395
11625
  "class": "bubble answer"
11396
- }, null), vue.createVNode("div", {
11626
+ }, null), showOperates && vue.createVNode("div", {
11397
11627
  "class": "operates"
11398
- }, null), vue.createVNode("div", {
11399
- "class": "suggestion-list"
11400
- }, [suggestionListDom])]);
11628
+ }, [props.content.length > 1 && answerNav, operateDom])]);
11401
11629
  };
11402
11630
  }
11403
11631
  });
11404
11632
 
11405
- const QuestionBubble = vue.defineComponent({
11406
- setup() {
11407
- return () => vue.createVNode("div", {
11408
- "class": "question-bubble chat-bubble"
11409
- }, [vue.createVNode(Avatar, {
11410
- "reverse": true,
11411
- "avatar": "",
11412
- "name": "\u5F20\u660E\u5FD7"
11413
- }, null), vue.createVNode("div", {
11414
- "class": "bubble question"
11415
- }, ["\u6562\u4E0D\u6562\u8DDF\u6211\u6BD4\u5212\u6BD4\u5212"]), vue.createVNode("div", {
11416
- "class": "operates"
11417
- }, null)]);
11633
+ const QaContext = vue.defineComponent({
11634
+ props: {
11635
+ list: {
11636
+ type: Array,
11637
+ default: () => []
11638
+ }
11639
+ },
11640
+ setup(props) {
11641
+ const containerRef = vue.ref();
11642
+ const onAnswerRender = text => {
11643
+ containerRef.value.scrollTo({
11644
+ top: containerRef.value.scrollHeight,
11645
+ behavior: "smooth"
11646
+ });
11647
+ };
11648
+ const handleDeleteAnswer = (questionId, answerId) => {
11649
+ const question = props.list.find(item => item.id === questionId);
11650
+ if (question) {
11651
+ question.answers = question.answers.filter(item => item.id !== answerId);
11652
+ }
11653
+ };
11654
+ return () => {
11655
+ const contextList = [];
11656
+ for (let i = 0; i < props.list.length; i++) {
11657
+ const questionItem = props.list[i];
11658
+ const prevItem = props.list[i - 1];
11659
+ const currentTime = questionItem.timestamp;
11660
+ let timeDiff = 0;
11661
+ if (prevItem) {
11662
+ const prevTime = prevItem.timestamp;
11663
+ timeDiff = currentTime - prevTime;
11664
+ }
11665
+ if (!prevItem || timeDiff > 1e3 * 60 * 5) {
11666
+ contextList.push(vue.createVNode("div", {
11667
+ "class": "time-line"
11668
+ }, [dayjs__default["default"](currentTime).format("MM/DD HH:mm")]));
11669
+ }
11670
+ if (questionItem.content) {
11671
+ contextList.push(vue.createVNode(QuestionBubble, {
11672
+ "content": questionItem.content
11673
+ }, null));
11674
+ }
11675
+ if (questionItem.answers.length > 0) {
11676
+ contextList.push(vue.createVNode(AnswerBubble, {
11677
+ "onRender": onAnswerRender,
11678
+ "content": questionItem.answers,
11679
+ "onDelete": answerId => handleDeleteAnswer(questionItem.id, answerId)
11680
+ }, null));
11681
+ }
11682
+ }
11683
+ return vue.createVNode("div", {
11684
+ "class": "qa-context",
11685
+ "ref": containerRef
11686
+ }, [contextList]);
11687
+ };
11418
11688
  }
11419
11689
  });
11420
11690
 
@@ -11434,11 +11704,24 @@ const ChatBox = vue.defineComponent({
11434
11704
  emit
11435
11705
  }) {
11436
11706
  vue.provide("chat-theme", props.theme);
11437
- vue.ref();
11707
+ const {
11708
+ context,
11709
+ answerLoading,
11710
+ sendQuestion,
11711
+ answer
11712
+ } = useQA();
11713
+ vue.provide("answerLoading", answerLoading);
11714
+ const handleSend = msg => {
11715
+ sendQuestion(msg);
11716
+ };
11438
11717
  return () => {
11439
11718
  return vue.createVNode("div", {
11440
11719
  "class": ["inl-chat-box", `inl-chat-box-${props.theme}`]
11441
- }, [vue.createVNode(AnswerBubble, null, null), vue.createVNode(QuestionBubble, null, null), vue.createVNode(Bottom, null, null)]);
11720
+ }, [vue.createVNode(QaContext, {
11721
+ "list": context.value
11722
+ }, null), vue.createVNode(Bottom, {
11723
+ "onSend": handleSend
11724
+ }, null)]);
11442
11725
  };
11443
11726
  }
11444
11727
  });