yt-chat-components 1.7.5 → 1.7.6

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": "1.7.5",
3
+ "version": "1.7.6",
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",
@@ -52,7 +52,6 @@ export class AudioPlayer {
52
52
 
53
53
  connect(token : string) {
54
54
  // cosyvoice 流式语言合成 2元、万字
55
- console.log('token = ', token)
56
55
  const socketUrl = `wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1?token=${token}`;
57
56
  // 普通语言合成 1元、万字
58
57
  // const socketUrl = `wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1?token=${this.token}`;
@@ -377,7 +377,7 @@ const CallInterface: React.FC<CallInterfaceProps> = ({
377
377
  } else if (message.type === 'connected') {
378
378
  setCallStatus('connected');
379
379
  if (message.audioData) {
380
- handleAudioData(message.audioData);
380
+ handleAudioChunkData(message.audioData)
381
381
  }
382
382
  } else if (message.type === 'complete-audio') {
383
383
  // 处理从后端返回的完整音频响应
@@ -1,5 +1,5 @@
1
1
  // @ts-nocheck
2
- import {extractMessageFromOutput} from './utils';
2
+ import {checkAndRequestMicrophonePermission, extractMessageFromOutput} from './utils';
3
3
  import React, {Context, forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState} from 'react';
4
4
  import {ChatMessageType, embedAppExtend, InputValueType, MessageItem, MessageType} from './types/chatWidget';
5
5
  import ChatMessage from './chatMessage';
@@ -661,7 +661,11 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({
661
661
 
662
662
  // 处理打电话按钮点击
663
663
  const handleCallButtonClick = () => {
664
- setShowCallInterface(true);
664
+ checkAndRequestMicrophonePermission().then((isGranted) => {
665
+ if (isGranted) {
666
+ setShowCallInterface(true);
667
+ }
668
+ });
665
669
  };
666
670
 
667
671
  // 处理挂断电话
@@ -1374,7 +1378,13 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({
1374
1378
  <div
1375
1379
  className="w_send_voice_box"
1376
1380
  style={receivingMessage ? {cursor: 'not-allowed'} : {}}
1377
- onClick={startConnectAndRecord}
1381
+ onClick={() => {
1382
+ checkAndRequestMicrophonePermission().then(isGranted => {
1383
+ if (isGranted){
1384
+ startConnectAndRecord();
1385
+ }
1386
+ })
1387
+ }}
1378
1388
  >
1379
1389
  <img src={recordState ? soundWavePng : (speakUrl || luyinPng)} style={{width: 35}}
1380
1390
  className={recordState ? "w_recordIng" : ''}></img>
@@ -1,6 +1,7 @@
1
1
  import React from "react";// 音波动画组件
2
2
  import styles from "./index.module.css";
3
3
  import {Input, message} from "antd";
4
+ import {checkAndRequestMicrophonePermission} from "../utils";
4
5
 
5
6
  class InputMobile extends React.Component {
6
7
  constructor(props) {
@@ -54,13 +55,26 @@ class InputMobile extends React.Component {
54
55
  handleRecordClick = () => {
55
56
  const {onStartRecordClick} = this.props;
56
57
  if (this.state.isVoice && !this.state.isRecording) {
57
- this.startRecording();
58
- onStartRecordClick()
58
+ checkAndRequestMicrophonePermission().then(isGranted => {
59
+ if (isGranted) {
60
+ this.startRecording();
61
+ onStartRecordClick();
62
+ }
63
+ })
59
64
  } else {
60
65
  this.stopRecording();
61
66
  }
62
67
  }
63
68
 
69
+ handleSwitchVoice = () => {
70
+ // 如果正在录音,则停止录音
71
+ if (this.state.isRecording) {
72
+ this.stopRecording();
73
+ }else {
74
+ this.setState({isVoice: !this.state.isVoice})
75
+ }
76
+ }
77
+
64
78
  render() {
65
79
  const {isShowVoiceButton, disabled, placeholder, onSendClick, inputRef, onSmartRobotClick = () => {}, isInH5Page } = this.props;
66
80
  return (
@@ -75,7 +89,7 @@ class InputMobile extends React.Component {
75
89
  {
76
90
  isShowVoiceButton &&
77
91
  <div
78
- onClick={() => this.setState({isVoice: !this.state.isVoice})}
92
+ onClick={this.handleSwitchVoice}
79
93
  className={styles.m_voiceToggle}
80
94
  >
81
95
  <img
@@ -1,75 +1,127 @@
1
- export function getChatPosition(
2
- triggerPosition: DOMRect,
3
- Cwidth:number,
4
- Cheight:number,
5
- position?: string,
6
- ): { top: string; left: string;
7
- position?: string, } {
8
- if (!triggerPosition) {
9
- return { top: "0px", left: "0px" }; // Return empty string if trigger position is not available
10
- }
11
-
12
- const { top, left, width, height } = triggerPosition;
13
-
14
- const distance = 5; // Adjust this value to set the desired distance from the trigger
15
- if(!position) return { top: distance + height+ "px", left: width + "px" };
16
-
17
- switch (position) {
18
- case "top-left":
19
- return { top: - distance - Cheight + "px", left: -Cwidth + "px" };
20
- case "top-center":
21
- return { top: - distance - Cheight + "px", left: width/2-Cwidth / 2 + "px" };
22
- case "top-right":
23
- return { top: - distance - Cheight + "px", left: width+ "px" };
24
- case "center-left":
25
- return { top: width/2-Cheight/2 + "px", left: -Cwidth - distance + "px" };
26
- case "center-right":
27
- return {
28
- top: width/2-Cheight/2 + "px",
29
- left: width + distance + "px",
30
- };
31
- case "bottom-right":
32
- return { top: distance + height+ "px", left: width + "px" };
33
- case "bottom-center":
34
- return {
35
- top: distance + height+ "px",
36
- left: width/2-Cwidth / 2 + "px",
37
- };
38
- case "bottom-left":
39
- return { top: distance + height+ "px", left: -Cwidth + "px"};
40
- default:
41
- return { top: distance + height+ "px", left: width + "px" };
42
- }
43
- }
44
-
45
- export function getAnimationOrigin(position?:string) {
46
- if(!position) return "origin-top-left";
47
- switch (position) {
48
- case "top-left":
49
- return 'origin-bottom-right'
50
- case "top-center":
51
- return "origin-bottom";
52
- case "top-right":
53
- return "origin-bottom-left";
54
- case "center-left":
55
- return "origin-center";
56
- case "center-right":
57
- return "origin-center";
58
- case "bottom-right":
59
- return "origin-top-left";
60
- case "bottom-center":
61
- return "origin-top";
62
- case "bottom-left":
63
- return "origin-top-right"
64
- default:
65
- return "origin-top-left"
66
- }
67
- }
68
-
69
- export function extractMessageFromOutput(output:{type:string, message:any}){
70
- const {type, message} = output;
71
- if(type === "text") return message;
72
- if (type ==="message") return message.text;
73
- if(type==="object") return message.text;
74
- return "Unknown message structure"
75
- }
1
+ import {message} from "antd";
2
+
3
+
4
+ export function getChatPosition(
5
+ triggerPosition: DOMRect,
6
+ Cwidth:number,
7
+ Cheight:number,
8
+ position?: string,
9
+ ): { top: string; left: string;
10
+ position?: string, } {
11
+ if (!triggerPosition) {
12
+ return { top: "0px", left: "0px" }; // Return empty string if trigger position is not available
13
+ }
14
+
15
+ const { top, left, width, height } = triggerPosition;
16
+
17
+ const distance = 5; // Adjust this value to set the desired distance from the trigger
18
+ if(!position) return { top: distance + height+ "px", left: width + "px" };
19
+
20
+ switch (position) {
21
+ case "top-left":
22
+ return { top: - distance - Cheight + "px", left: -Cwidth + "px" };
23
+ case "top-center":
24
+ return { top: - distance - Cheight + "px", left: width/2-Cwidth / 2 + "px" };
25
+ case "top-right":
26
+ return { top: - distance - Cheight + "px", left: width+ "px" };
27
+ case "center-left":
28
+ return { top: width/2-Cheight/2 + "px", left: -Cwidth - distance + "px" };
29
+ case "center-right":
30
+ return {
31
+ top: width/2-Cheight/2 + "px",
32
+ left: width + distance + "px",
33
+ };
34
+ case "bottom-right":
35
+ return { top: distance + height+ "px", left: width + "px" };
36
+ case "bottom-center":
37
+ return {
38
+ top: distance + height+ "px",
39
+ left: width/2-Cwidth / 2 + "px",
40
+ };
41
+ case "bottom-left":
42
+ return { top: distance + height+ "px", left: -Cwidth + "px"};
43
+ default:
44
+ return { top: distance + height+ "px", left: width + "px" };
45
+ }
46
+ }
47
+
48
+ export function getAnimationOrigin(position?:string) {
49
+ if(!position) return "origin-top-left";
50
+ switch (position) {
51
+ case "top-left":
52
+ return 'origin-bottom-right'
53
+ case "top-center":
54
+ return "origin-bottom";
55
+ case "top-right":
56
+ return "origin-bottom-left";
57
+ case "center-left":
58
+ return "origin-center";
59
+ case "center-right":
60
+ return "origin-center";
61
+ case "bottom-right":
62
+ return "origin-top-left";
63
+ case "bottom-center":
64
+ return "origin-top";
65
+ case "bottom-left":
66
+ return "origin-top-right"
67
+ default:
68
+ return "origin-top-left"
69
+ }
70
+ }
71
+
72
+ export function extractMessageFromOutput(output:{type:string, message:any}){
73
+ const {type, message} = output;
74
+ if(type === "text") return message;
75
+ if (type ==="message") return message.text;
76
+ if(type==="object") return message.text;
77
+ return "Unknown message structure"
78
+ }
79
+
80
+ /**
81
+ * 麦克风权限检查及请求
82
+ */
83
+ export async function checkAndRequestMicrophonePermission() {
84
+ // 检查是否支持 navigator.mediaDevices 和 getUserMedia
85
+ if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
86
+ console.error('您的浏览器不支持麦克风访问');
87
+ alert('您的浏览器不支持麦克风访问,请使用最新版本的浏览器尝试。');
88
+ return false;
89
+ }
90
+
91
+ try {
92
+ // 尝试获取麦克风权限
93
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
94
+ console.log('麦克风权限已授予');
95
+
96
+ // 如果成功获取权限,关闭音频流以释放麦克风资源
97
+ stream.getTracks().forEach(track => track.stop());
98
+ return true;
99
+ } catch (err) {
100
+ let alertMessage = '获取麦克风失败:';
101
+ // @ts-ignore
102
+ switch(err.name) {
103
+ case 'NotAllowedError':
104
+ case 'PermissionDeniedError': // 部分浏览器可能使用 PermissionDeniedError
105
+ alertMessage += '您已拒绝麦克风访问权限。请在浏览器设置中允许此网站访问麦克风。';
106
+ break;
107
+ case 'NotFoundError':
108
+ alertMessage += '未找到可用的麦克风设备。';
109
+ break;
110
+ case 'NotReadableError':
111
+ alertMessage += '麦克风设备正在被占用或无法访问。';
112
+ break;
113
+ case 'SecurityError':
114
+ alertMessage += '安全错误,可能是由于页面不是通过HTTPS提供服务。';
115
+ break;
116
+ default:
117
+ alertMessage += err;
118
+ break;
119
+ }
120
+ console.error(alertMessage);
121
+
122
+ // 提供用户友好的提示信息
123
+ message.warning (alertMessage + '\n如果您希望使用录音功能,请按照提示调整设置。');
124
+
125
+ return false;
126
+ }
127
+ }
@@ -114,7 +114,6 @@ const TabSelector = ({
114
114
  borderBottom: 'transparent !important',
115
115
  }}
116
116
  renderTabBar={(props, DefaultTabBar) => {
117
- console.log(" " , activeKey , props.activeKey)
118
117
  return (
119
118
  <div className={props.activeKey === activeKey ? styles.tabBarActive : styles.tabBar}>
120
119
  <DefaultTabBar {...props} style={{ marginBottom: '0px' }}/>
@@ -403,10 +403,8 @@ export class MobileChatPage extends React.Component {
403
403
  userInfo.code = sessionId;
404
404
  }
405
405
  const operationId = userInfo['code'] || '';
406
- console.log('getCurrentFlowHistory', flowId, operationId)
407
406
  getHistoryList(this.props.hostUrl, flowId, operationId).then((res) => {
408
407
  if(res.status === 200){
409
- console.log('getCurrentFlowHistory', res.data)
410
408
  this.setState({ historyList: res.data });
411
409
  }
412
410
  });
@@ -429,7 +427,6 @@ export class MobileChatPage extends React.Component {
429
427
  }else{
430
428
  const currentScene = sceneData||this.state.sceneInfo;
431
429
  const currentFlow = currentScene.flows[0];
432
- console.log('getHistoryList', sceneData, currentFlow)
433
430
  const dropDownList = this.getDropDownList(currentFlow.welcome_words);
434
431
  if(!isEmpty(sceneData)){
435
432
  this.setState({ currentFlow, dropDownList })
@@ -674,8 +674,6 @@ export class MobileChatPageV2 extends React.Component {
674
674
  <img src={"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/kai_yuan/common/call.png"}
675
675
  alt="call"
676
676
  onClick={() => {
677
- console.log(this.chatWindowRef);
678
-
679
677
  this.chatWindowRef.current.handleCallButtonClick()
680
678
  }}
681
679
  />