yt-chat-components 0.7.0 → 0.9.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yt-chat-components",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "main": "build/static/js/bundle.min.js",
5
5
  "module": "build/static/js/bundle.min.js",
6
6
  "types": "build/static/js/index.d.ts",
package/public/index.html CHANGED
@@ -19,14 +19,16 @@
19
19
  is-show-side-right=false
20
20
  is-show-side-left=false
21
21
  modal-index="9999999999"
22
- modal-width="1400"
22
+ modal-width="1200"
23
23
  dialog-index="999999999"
24
24
  agent-url="https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/ccit/user/xc//image/ebfaf4da-c1d9-46fb-a0b1-f159e95cffc2_AI招生咨询小助手.png"
25
25
  agent-name="医专智能助手"
26
26
  logo-width="42px"
27
27
  logo-font-size="26px"
28
28
  logo-position="fixed"
29
- is-title-side-icon=true
29
+ is-title-side-icon=false
30
+ is-show-upload-button=true
31
+ drop-man-url="https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/ai_man01.png"
30
32
  />
31
33
  </body>
32
34
 
@@ -46,6 +48,8 @@
46
48
  <!-- logo-width="42px"-->
47
49
  <!-- logo-font-size="26px"-->
48
50
  <!-- is-title-side-icon=true-->
51
+ <!-- is-show-upload-button=false-->
52
+ <!-- drop-man-url="https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/ai_man01.png"-->
49
53
  <!--/>-->
50
54
  <!--</body>-->
51
55
 
@@ -70,7 +74,9 @@
70
74
  <!-- logo-width="42px"-->
71
75
  <!-- logo-font-size="26px"-->
72
76
  <!-- logo-position="fixed"-->
73
- <!-- is-title-side-icon=true-->
77
+ <!-- is-title-side-icon=false-->
78
+ <!-- is-show-upload-button=false-->
79
+ <!-- drop-man-url="https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/ai_man01.png"-->
74
80
  <!--/>-->
75
81
  <!--</body>-->
76
82
  </html>
@@ -10,6 +10,7 @@ import closexPng from '../../../assets/aicenter/closex.png';
10
10
  import upFilePng from '../../../assets/aicenter/upfile.png';
11
11
  import fileuploadPng from '../../../assets/aicenter/fileupload.png';
12
12
  import sendmessagePng from '../../../assets/aicenter/sendmessage.png';
13
+ import stopmessagePng from '../../../assets/aicenter/stopmessage.png';
13
14
  import toRightPng from '../../../assets/aicenter/toRight.png';
14
15
  import toLeftPng from '../../../assets/aicenter/toLeft.png';
15
16
  import typePdfPng from '../../../assets/aicenter/type-pdf.png';
@@ -69,6 +70,8 @@ export default function ChatWindow({
69
70
  setDropDownList = () => {},
70
71
  dropDownList = [],
71
72
  baseConfig = {},
73
+ isShowUploadButton,
74
+ dropManUrl = '',
72
75
  }: {
73
76
  tags: [];
74
77
  getHistoryList: Function;
@@ -106,6 +109,8 @@ export default function ChatWindow({
106
109
  sessionId: string;
107
110
  additional_headers?: { [key: string]: string };
108
111
  baseConfig: object;
112
+ isShowUploadButton: boolean;
113
+ dropManUrl: string;
109
114
  }) {
110
115
  const [value, setValue] = useState<string>('');
111
116
  const ref = useRef<HTMLDivElement>(null);
@@ -126,6 +131,8 @@ export default function ChatWindow({
126
131
  const [recordState, setRecordState] = useState(false); // 录音状态。true为正在录音,false为停止录音
127
132
  const [tagList, setTagList] = useState([]); // 问题标签列表
128
133
  const {isTitleSideIcon, logoWidth, agentUrl} = baseConfig;
134
+ const inputContainerRef = useRef(null);
135
+ const [inputContainerHeight,setInputContainerHeight] = useState('50px')
129
136
 
130
137
  let voiceChunks = []; // 临时存储录制的语音片段
131
138
  // 滚动事件处理,选择文件时,文件内容超出显示框时,显示左右箭头
@@ -627,35 +634,69 @@ export default function ChatWindow({
627
634
  </div>
628
635
  <div className="cl-header-subtitle"/>
629
636
  {!isEmpty(dropDownList) && (
630
- <div className="cl-drop-down">
631
- <div className="drop-down-title">Hi,欢迎使用{window_title},您可以这样问我:</div>
632
- <div className="drop-down-list">
633
- {dropDownList.map(({ backgroundImg, title }) => (
634
- <div className="drop-down-item-card" key={title}>
635
- <Typography.Paragraph
636
- className="drop-down-item-title"
637
- ellipsis={{
638
- rows: 2,
639
- tooltip: `“${title}”`,
640
- }}>{'“'+title+'”'}
641
- </Typography.Paragraph>
642
- <div className="drop-down-item-bottom">
643
- <div
644
- className="drop-down-item-bottom-button"
645
- onClick={() => {
646
- setDropDownList(undefined);
647
- handleClick(title);
648
- }}
649
- >
650
- <img src={btn_answer}/>
651
- {/*<RightOutlined style={{ height: '0.8rem', width: '0.4rem' }} />*/}
637
+ isEmpty(dropManUrl) ?
638
+ <div className="cl-drop-down">
639
+ <div className="drop-down-title">Hi,欢迎使用{window_title},您可以这样问我:</div>
640
+ <div className="drop-down-list">
641
+ {dropDownList.slice(0,3).map(({backgroundImg, title}) => (
642
+ <div className="drop-down-item-card" key={title}>
643
+ <Typography.Paragraph
644
+ className="drop-down-item-title"
645
+ ellipsis={{
646
+ rows: 2,
647
+ tooltip: `“${title}”`,
648
+ }}>{'“' + title + '”'}
649
+ </Typography.Paragraph>
650
+ <div className="drop-down-item-bottom">
651
+ <div
652
+ className="drop-down-item-bottom-button"
653
+ onClick={() => {
654
+ setDropDownList(undefined);
655
+ handleClick(title);
656
+ }}
657
+ >
658
+ <img src={btn_answer}/>
659
+ {/*<RightOutlined style={{ height: '0.8rem', width: '0.4rem' }} />*/}
660
+ </div>
661
+ <img className="drop-down-item-bottom-img" src={backgroundImg}/>
662
+ </div>
652
663
  </div>
653
- <img className="drop-down-item-bottom-img" src={backgroundImg} />
654
- </div>
664
+ ))}
665
+ </div>
666
+ </div>
667
+ :
668
+ <div className="cl-drop-man">
669
+ <img className="drop-man-img" src={dropManUrl}/>
670
+ <div className="cl-drop-down">
671
+ <div className="drop-down-title">Hi,欢迎使用{window_title},您可以这样问我:</div>
672
+ <div className="drop-down-list">
673
+ {dropDownList.slice(0,4).map(({backgroundImg, title}) => (
674
+ <div className="drop-down-item-card" key={title}>
675
+ <Typography.Paragraph
676
+ className="drop-down-item-title"
677
+ ellipsis={{
678
+ rows: 2,
679
+ tooltip: `“${title}”`,
680
+ }}>{'“' + title + '”'}
681
+ </Typography.Paragraph>
682
+ <div className="drop-down-item-bottom">
683
+ <div
684
+ className="drop-down-item-bottom-button"
685
+ onClick={() => {
686
+ setDropDownList(undefined);
687
+ handleClick(title);
688
+ }}
689
+ >
690
+ <img src={btn_answer}/>
691
+ {/*<RightOutlined style={{ height: '0.8rem', width: '0.4rem' }} />*/}
692
+ </div>
693
+ <img className="drop-down-item-bottom-img" src={backgroundImg}/>
694
+ </div>
695
+ </div>
696
+ ))}
655
697
  </div>
656
- ))}
657
- </div>
658
- </div>
698
+ </div>
699
+ </div>
659
700
  )}
660
701
  </div>
661
702
  <div
@@ -717,14 +758,14 @@ export default function ChatWindow({
717
758
  </div>
718
759
  <div style={input_container_style} className="cl-input_container">
719
760
  <div className="w_file_preview" ref={scrollContainerRef} onScroll={handleScroll}>
720
- <div className="w_toLeftBox" style={{ display: showLeftArrow ? 'flex' : 'none' }}>
761
+ <div className="w_toLeftBox" style={{display: showLeftArrow ? 'flex' : 'none'}}>
721
762
  <div className="w_toLeft" onClick={() => handleScrollRight('left')}>
722
- <img src={toLeftPng} />
763
+ <img src={toLeftPng}/>
723
764
  </div>
724
765
  </div>
725
- <div className="w_toRightBox" style={{ display: showRightArrow ? 'flex' : 'none' }}>
766
+ <div className="w_toRightBox" style={{display: showRightArrow ? 'flex' : 'none'}}>
726
767
  <div className="w_toRight" onClick={() => handleScrollRight('right')}>
727
- <img src={toRightPng} />
768
+ <img src={toRightPng}/>
728
769
  </div>
729
770
  </div>
730
771
  {fileList.map((item, index) => {
@@ -742,28 +783,28 @@ export default function ChatWindow({
742
783
  />
743
784
  )}
744
785
  {getFileTypeByUrl(item.file.name) == 'pdf' && (
745
- <img style={{ width: 40, height: 40 }} src={typePdfPng} />
786
+ <img style={{width: 40, height: 40}} src={typePdfPng}/>
746
787
  )}
747
788
  {getFileTypeByUrl(item.file.name) == 'word' && (
748
- <img style={{ width: 40, height: 40 }} src={typeWordPng} />
789
+ <img style={{width: 40, height: 40}} src={typeWordPng}/>
749
790
  )}
750
791
  {getFileTypeByUrl(item.file.name) == 'excel' && (
751
- <img style={{ width: 40, height: 40 }} src={typeExcelPng} />
792
+ <img style={{width: 40, height: 40}} src={typeExcelPng}/>
752
793
  )}
753
794
  {getFileTypeByUrl(item.file.name) == 'markdown' && (
754
- <img style={{ width: 40, height: 40 }} src={typeMarkdownPng} />
795
+ <img style={{width: 40, height: 40}} src={typeMarkdownPng}/>
755
796
  )}
756
797
  {getFileTypeByUrl(item.file.name) == 'txt' && (
757
- <img style={{ width: 40, height: 40 }} src={typeTextPng} />
798
+ <img style={{width: 40, height: 40}} src={typeTextPng}/>
758
799
  )}
759
800
  {getFileTypeByUrl(item.file.name) == 'mobi' && (
760
- <img style={{ width: 40, height: 40 }} src={typeMobiPng} />
801
+ <img style={{width: 40, height: 40}} src={typeMobiPng}/>
761
802
  )}
762
803
  {getFileTypeByUrl(item.file.name) == 'rpub' && (
763
- <img style={{ width: 40, height: 40 }} src={typeRPubPng} />
804
+ <img style={{width: 40, height: 40}} src={typeRPubPng}/>
764
805
  )}
765
806
  {getFileTypeByUrl(item.file.name) == 'file' && (
766
- <img style={{ width: 40, height: 40 }} src={upFilePng} />
807
+ <img style={{width: 40, height: 40}} src={upFilePng}/>
767
808
  )}
768
809
  <div className="w_fileInfoBox">
769
810
  <div className="w_fileInfoFileName">{item.file.name}</div>
@@ -777,14 +818,16 @@ export default function ChatWindow({
777
818
  removeFile(item, index);
778
819
  }}
779
820
  >
780
- <img src={closexPng} />
821
+ <img src={closexPng}/>
781
822
  </div>
782
823
  </div>
783
824
  );
784
825
  })}
785
826
  </div>
786
- <div className="w_inputBox">
827
+ <div className="w_inputBox" style={{height: inputContainerHeight}}>
787
828
  <textarea
829
+ onFocus={()=>setInputContainerHeight('120px')}
830
+ onBlur={()=>setInputContainerHeight('50px')}
788
831
  value={value}
789
832
  onChange={(e) => setValue(e.target.value)}
790
833
  onKeyDown={(e) => {
@@ -810,24 +853,43 @@ export default function ChatWindow({
810
853
  </div>
811
854
  </Tooltip>
812
855
  {/*<Tooltip title="支持PDF / Word / Excel / Markdown / txt / mobi / rpub">*/}
813
- <Tooltip title="支持图片格式">
814
- <div
815
- className="w_send_file_box"
816
- style={sendingMessage ? { cursor: 'not-allowed' } : {}}
817
- onClick={uploadFile}
818
- >
819
- <img src={fileuploadPng} style={{ width: 23 }}></img>
820
- </div>
821
- </Tooltip>
856
+ {
857
+ isShowUploadButton &&
858
+ <Tooltip title="支持图片格式">
859
+ <div
860
+ className="w_send_file_box"
861
+ style={sendingMessage ? { cursor: 'not-allowed' } : {}}
862
+ onClick={uploadFile}
863
+ >
864
+ <img src={fileuploadPng} style={{ width: 23 }}></img>
865
+ </div>
866
+ </Tooltip>
867
+ }
868
+ <Tooltip title={sendingMessage?'点击暂停':'点击发送'}>
822
869
  <button
823
- disabled={sendingMessage}
824
- style={{ ...(sendingMessage ? { cursor: 'not-allowed' } : {}), padding: '0 13px', background:'transparent', display:'flex', alignItems:'center', justifyContent:'center' }}
870
+ style={{ ...(sendingMessage ? { cursor: 'pointer' } : {}), padding: '0 13px', background:'transparent', display:'flex', alignItems:'center', justifyContent:'center' }}
825
871
  onClick={() => {
826
- handleClick('');
872
+ if(sendingMessage){
873
+ const output = {
874
+ message:nowAIContent,
875
+ type:'text'
876
+ };
877
+ addMessage({
878
+ message: extractMessageFromOutput(output),
879
+ isSend: false,
880
+ rawInfo: output.message,
881
+ });
882
+ abortControllerRef.current.abort('disconnect');
883
+ abortControllerRef.current = new AbortController();
884
+ }else{
885
+
886
+ }
827
887
  }}
828
888
  >
829
- <img src={sendmessagePng} style={{ width: 55 }}></img>
889
+
890
+ <img src={sendingMessage ? stopmessagePng : sendmessagePng} style={{width: 55}}/>
830
891
  </button>
892
+ </Tooltip>
831
893
  </div>
832
894
  </div>
833
895
  </div>
@@ -36,7 +36,9 @@ export default function ChatWidget({
36
36
  start_open = false,
37
37
  setDropDownList,
38
38
  dropDownList,
39
- baseConfig
39
+ baseConfig,
40
+ isShowUploadButton,
41
+ dropManUrl
40
42
  }: {
41
43
  tags: [];
42
44
  getHistoryList: Function;
@@ -70,6 +72,8 @@ export default function ChatWidget({
70
72
  session_id?: string;
71
73
  start_open?: boolean;
72
74
  baseConfig:object;
75
+ isShowUploadButton:boolean;
76
+ dropManUrl: string;
73
77
  }) {
74
78
  const [open, setOpen] = useState(start_open);
75
79
  const [messages, setMessages] = useState<ChatMessageType[]>([]);
@@ -347,7 +351,7 @@ video {
347
351
 
348
352
  .cl-window {
349
353
  border-radius: 1rem;
350
- padding-top: 2.3rem;
354
+ padding-top: 1.8rem;
351
355
  padding-bottom: 1.2rem;
352
356
  }
353
357
 
@@ -470,10 +474,43 @@ video {
470
474
  border-radius: 3px;
471
475
  }
472
476
 
477
+ .cl-drop-man{
478
+ width:100%;
479
+ display:flex;
480
+ }
481
+ .cl-drop-man .drop-man-img{
482
+ height:340px;
483
+ margin-right: 4rem;
484
+ margin-left: 3rem;
485
+ }
486
+
487
+ .cl-drop-man .cl-drop-down .drop-down-item-card .drop-down-item-bottom-img{
488
+ height:3.4rem;
489
+ margin-right:20px;
490
+ }
491
+
492
+ .cl-drop-man .drop-down-list{
493
+ width:auto;
494
+ display:flex;
495
+ flex-direction:row;
496
+ flex-wrap:wrap;
497
+ }
498
+
499
+ .cl-drop-man .cl-drop-down .drop-down-item-card{
500
+ width:48%;
501
+ }
502
+
503
+ .cl-drop-man .cl-drop-down{
504
+ flex:1;
505
+ position:unset;
506
+ border-bottom-left-radius: 0;
507
+ }
508
+
509
+
473
510
  .cl-drop-down {
474
511
  background: #FFFFFF;
475
512
  border-radius: 10px;
476
- box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.1);
513
+ box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.05);
477
514
  z-index: 1;
478
515
  position: absolute;
479
516
  width: 100%;
@@ -633,7 +670,7 @@ margin-bottom:1rem;
633
670
  padding-top: 0.25rem;
634
671
  padding-bottom: 0.25rem;
635
672
  font-weight: 300;
636
- background-color: #00000000;
673
+ background-color: #FFFFFF;
637
674
  color: rgb(17 24 39);
638
675
  border-top-left-radius: 50px;
639
676
  border-bottom-left-radius: 50px;
@@ -646,7 +683,6 @@ margin-bottom:1rem;
646
683
  .cl-input-element:focus {
647
684
  outline: 2px solid transparent;
648
685
  outline-offset: 2px;
649
- height:120px;
650
686
  }
651
687
 
652
688
  .cl-input-element:focus::placeholder {
@@ -2252,7 +2288,7 @@ input::-ms-input-placeholder { /* Microsoft Edge */
2252
2288
  justify-content: center;
2253
2289
  width: fit-content;
2254
2290
  height: 30px;
2255
- background: #F9FAFB;
2291
+ background: #00000000;
2256
2292
  border-radius: 15px;
2257
2293
  border: 1px solid #4B4FFF;
2258
2294
  cursor: pointer;
@@ -2295,6 +2331,8 @@ input::-ms-input-placeholder { /* Microsoft Edge */
2295
2331
  align-items: center;
2296
2332
  box-shadow: 0px 2px 15px 0px rgba(0,48,187,0.1);
2297
2333
  border-radius: 30px;
2334
+ background: #FFFFFF;
2335
+ transition: height 0.2s ease;
2298
2336
  textarea {
2299
2337
  resize: none;
2300
2338
  min-height: 48px;
@@ -2303,7 +2341,6 @@ input::-ms-input-placeholder { /* Microsoft Edge */
2303
2341
  box-shadow: none !important;
2304
2342
  color: #333;
2305
2343
  outline: 0;
2306
- // padding: 5px 10px 0 10px;
2307
2344
  width: 100%;
2308
2345
 
2309
2346
  box-sizing: border-box;
@@ -2384,6 +2421,8 @@ input::-ms-input-placeholder { /* Microsoft Edge */
2384
2421
  setDropDownList={setDropDownList}
2385
2422
  dropDownList={dropDownList}
2386
2423
  baseConfig={baseConfig}
2424
+ isShowUploadButton={isShowUploadButton}
2425
+ dropManUrl={dropManUrl}
2387
2426
  />
2388
2427
  </div>
2389
2428
  );
@@ -33,7 +33,9 @@ export class LogoBtn extends React.Component {
33
33
  logoWidth,
34
34
  logoFontSize,
35
35
  logoPosition = 'absolute',
36
- isTitleSideIcon
36
+ isTitleSideIcon,
37
+ isShowUploadButton,
38
+ dropManUrl
37
39
  } = this.props;
38
40
  const iconConfig = {
39
41
  width: `${width || 100}px`,
@@ -87,6 +89,8 @@ export class LogoBtn extends React.Component {
87
89
  logoFontSize={logoFontSize}
88
90
  isTitleSideIcon={isTitleSideIcon}
89
91
  modalIndex={modalIndex}
92
+ isShowUploadButton={isShowUploadButton}
93
+ dropManUrl={dropManUrl}
90
94
  />
91
95
  </Modal>
92
96
  </div>
@@ -35,6 +35,8 @@ export class LogoSplitBtn extends React.Component {
35
35
  logoFontSize = '26px',
36
36
  logoPosition = 'absolute',
37
37
  isTitleSideIcon,
38
+ isShowUploadButton,
39
+ dropManUrl
38
40
  } = this.props;
39
41
  const iconConfig = {
40
42
  width: `${width || 100}px`,
@@ -89,6 +91,8 @@ export class LogoSplitBtn extends React.Component {
89
91
  logoFontSize={logoFontSize}
90
92
  isTitleSideIcon={isTitleSideIcon}
91
93
  modalIndex={modalIndex}
94
+ isShowUploadButton={isShowUploadButton}
95
+ dropManUrl={dropManUrl}
92
96
  />
93
97
  </Modal>
94
98
  </div>
@@ -37,7 +37,7 @@ const style=`
37
37
  align-items: center;
38
38
  width: 300px;
39
39
  // height: 100%;
40
- padding: 1.5rem 1.6rem 2rem 2.4rem;
40
+ padding: 1.7rem 1.6rem 1.7rem 1.6rem;
41
41
 
42
42
  border-top-left-radius: 8px;
43
43
  border-bottom-left-radius: 8px;
@@ -160,7 +160,7 @@ const style=`
160
160
  width:300px;
161
161
  display:flex;
162
162
  flex-direction:column;
163
- padding:2.5rem 1.6rem 1.8rem 1.6rem
163
+ padding:2rem 1.6rem 1.8rem 1.6rem
164
164
  }
165
165
  .rightInnerContainer{
166
166
  height:calc(100% - 80px);
@@ -190,13 +190,15 @@ const style=`
190
190
  min-height:40%;
191
191
  }
192
192
  .p_toolRightToRight .rightSkillContainer .rightSkillList{
193
- display: grid;
193
+ display: flex;
194
+ flex-wrap: wrap;
194
195
  grid-template-columns: repeat(3, 1fr);
195
196
  gap: 10px;
196
197
  }
197
198
  .p_toolRightToRight .rightSkillContainer .rightSkillList .rightSkillItem{
198
199
  text-align: center;
199
200
  cursor:pointer;
201
+ width:30%;
200
202
  }
201
203
  .p_toolRightToRight .rightSkillContainer .rightSkillList .rightSkillItem img{
202
204
  width: 40px;
@@ -209,11 +211,12 @@ const style=`
209
211
  overflow: hidden;
210
212
  text-overflow: ellipsis;
211
213
  white-space: nowrap;
212
- width:80px;
214
+ // width:80px;
213
215
  color: #333333;
214
216
  }
215
217
  .p_toolRightToRight .rightKnowledgeTitle{
216
- margin-bottom:1.4rem;
218
+ nargin-top: 2.2rem;
219
+ margin-bottom: 1.4rem;
217
220
  font-size:18px;
218
221
  font-weight:500;
219
222
  display:flex;
@@ -436,10 +439,12 @@ export class ToolDialog extends React.Component {
436
439
  logoWidth = '42px',
437
440
  logoFontSize = '26px',
438
441
  isTitleSideIcon = false,// 是否将左侧历史顶部icon移到中间顶部左侧蓝点位置
439
- modalIndex
442
+ modalIndex,
443
+ isShowUploadButton,
444
+ dropManUrl
440
445
  } = this.props;
441
446
  const { sceneInfo, currentFlow = {} } = this.state;
442
- const { flows=[], name: sceneName } = sceneInfo;
447
+ const { flows=[], name: sceneName, } = sceneInfo;
443
448
  return (
444
449
  <div style={boxStyle}>
445
450
  <style dangerouslySetInnerHTML={{ __html: style }}></style>
@@ -508,6 +513,8 @@ export class ToolDialog extends React.Component {
508
513
  setDropDownList={(list) => this.setState({ dropDownList: list })}
509
514
  dropDownList={this.state.dropDownList}
510
515
  baseConfig={{ isTitleSideIcon, logoWidth, agentUrl }}
516
+ isShowUploadButton={isShowUploadButton}
517
+ dropManUrl={dropManUrl}
511
518
  />
512
519
  </div>
513
520
  {