@ray-js/t-agent-ui-ray 0.0.8-beta-1 → 0.0.8-beta-3
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-zh_CN.md +0 -2
- package/README.md +0 -2
- package/dist/ChatContainer/index.js +37 -14
- package/dist/MessageInput/AsrInput.d.ts +1 -0
- package/dist/MessageInput/AsrInput.js +6 -4
- package/dist/MessageInput/index.js +18 -11
- package/dist/MessageInput/index.less +12 -1
- package/dist/MessageList/index.js +13 -3
- package/dist/contexts.d.ts +2 -2
- package/dist/contexts.js +1 -2
- package/dist/hooks/context.d.ts +1 -1
- package/dist/hooks/useAsrInput.js +36 -15
- package/dist/renderOption.js +2 -1
- package/dist/tiles/BubbleTile/index.js +6 -3
- package/dist/tiles/ButtonsTile/index.js +16 -6
- package/dist/types.d.ts +1 -0
- package/package.json +2 -2
package/README-zh_CN.md
CHANGED
package/README.md
CHANGED
|
@@ -5,25 +5,20 @@ import "core-js/modules/web.dom-collections.iterator.js";
|
|
|
5
5
|
import './index.less';
|
|
6
6
|
import React, { useEffect, useMemo, useState } from 'react';
|
|
7
7
|
import { View } from '@ray-js/components';
|
|
8
|
-
import {
|
|
8
|
+
import { SocketStatus } from '@ray-js/t-agent-plugin-assistant';
|
|
9
|
+
import cx from 'clsx';
|
|
9
10
|
import { ChatAgentContext, MessageContext, RenderContext } from '../contexts';
|
|
10
11
|
import { defaultRenderOptions } from '../renderOption';
|
|
11
12
|
import logger from '../logger';
|
|
12
13
|
export default function ChatContainer(props) {
|
|
14
|
+
const [keyboardHeight, setKeyboardHeight] = useState(0);
|
|
13
15
|
const {
|
|
14
16
|
createAgent,
|
|
15
17
|
renderOptions = defaultRenderOptions,
|
|
16
18
|
children,
|
|
17
|
-
className
|
|
19
|
+
className
|
|
18
20
|
} = props;
|
|
19
21
|
const [messages, setMessages] = useState([]);
|
|
20
|
-
const [socketStatus, setSocketStatus] = useState(() => {
|
|
21
|
-
try {
|
|
22
|
-
return getWebSocketStatusSync().status;
|
|
23
|
-
} catch (e) {
|
|
24
|
-
return SocketStatus.WAITING;
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
22
|
const [agent] = useState(() => {
|
|
28
23
|
const agent = createAgent();
|
|
29
24
|
if (!agent.plugins.ui) {
|
|
@@ -40,7 +35,9 @@ export default function ChatContainer(props) {
|
|
|
40
35
|
emitEvent
|
|
41
36
|
} = agent.plugins.ui;
|
|
42
37
|
const offSocketStatusChange = agent.plugins.assistant.onSocketStatusChange(status => {
|
|
43
|
-
|
|
38
|
+
emitEvent('networkChange', {
|
|
39
|
+
online: status === SocketStatus.SUCCESS
|
|
40
|
+
});
|
|
44
41
|
});
|
|
45
42
|
const offMessageListInit = onEvent('messageListInit', _ref => {
|
|
46
43
|
let {
|
|
@@ -71,7 +68,8 @@ export default function ChatContainer(props) {
|
|
|
71
68
|
if (((_prev = prev[prev.length - 1]) === null || _prev === void 0 ? void 0 : _prev.id) === message.id) {
|
|
72
69
|
// 是最后一条消息,滚动到最底部
|
|
73
70
|
emitEvent('scrollToBottom', {
|
|
74
|
-
animation: false
|
|
71
|
+
animation: false,
|
|
72
|
+
follow: true
|
|
75
73
|
});
|
|
76
74
|
}
|
|
77
75
|
}
|
|
@@ -98,9 +96,9 @@ export default function ChatContainer(props) {
|
|
|
98
96
|
const messageValue = useMemo(() => {
|
|
99
97
|
return {
|
|
100
98
|
messages,
|
|
101
|
-
|
|
99
|
+
keyboardHeight
|
|
102
100
|
};
|
|
103
|
-
}, [messages,
|
|
101
|
+
}, [messages, keyboardHeight]);
|
|
104
102
|
useEffect(() => {
|
|
105
103
|
logger.debug('ChatProvider agent.start');
|
|
106
104
|
agent.start().then(() => {
|
|
@@ -112,8 +110,33 @@ export default function ChatContainer(props) {
|
|
|
112
110
|
agent.dispose();
|
|
113
111
|
};
|
|
114
112
|
}, []);
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
const show = _ref3 => {
|
|
115
|
+
let {
|
|
116
|
+
height
|
|
117
|
+
} = _ref3;
|
|
118
|
+
setKeyboardHeight(height);
|
|
119
|
+
};
|
|
120
|
+
const hide = () => {
|
|
121
|
+
setKeyboardHeight(0);
|
|
122
|
+
};
|
|
123
|
+
ty.onKeyboardWillShow(show);
|
|
124
|
+
ty.onKeyboardWillHide(hide);
|
|
125
|
+
ty.onKeyboardHeightChange(show);
|
|
126
|
+
return () => {
|
|
127
|
+
ty.offKeyboardWillShow(show);
|
|
128
|
+
ty.offKeyboardWillHide(hide);
|
|
129
|
+
ty.offKeyboardHeightChange(show);
|
|
130
|
+
};
|
|
131
|
+
}, []);
|
|
115
132
|
return /*#__PURE__*/React.createElement(View, {
|
|
116
|
-
|
|
133
|
+
style: {
|
|
134
|
+
// @ts-ignore
|
|
135
|
+
'--t-agent-chat-container-keyboard-height': "".concat(keyboardHeight, "px")
|
|
136
|
+
},
|
|
137
|
+
className: cx('t-agent-chat-container', className, {
|
|
138
|
+
't-agent-chat-container-keyboard-show': keyboardHeight > 0
|
|
139
|
+
})
|
|
117
140
|
}, /*#__PURE__*/React.createElement(ChatAgentContext.Provider, {
|
|
118
141
|
value: agent
|
|
119
142
|
}, /*#__PURE__*/React.createElement(RenderContext.Provider, {
|
|
@@ -5,6 +5,7 @@ import cx from 'clsx';
|
|
|
5
5
|
import { useAsrInput } from '../hooks';
|
|
6
6
|
export default function AsrInput(props) {
|
|
7
7
|
const {
|
|
8
|
+
responding,
|
|
8
9
|
sendDisabled,
|
|
9
10
|
onMoreClick,
|
|
10
11
|
moreOpen,
|
|
@@ -28,11 +29,12 @@ export default function AsrInput(props) {
|
|
|
28
29
|
}), /*#__PURE__*/React.createElement(View, {
|
|
29
30
|
className: "t-agent-message-input-voice-bubble",
|
|
30
31
|
"data-testid": "t-agent-message-input-asr-bubble"
|
|
31
|
-
}, state === 'recording' ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, null, currentText), /*#__PURE__*/React.createElement(Text, {
|
|
32
|
+
}, state === 'recording' ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, null, currentText.endsWith(' ') ? /*#__PURE__*/React.createElement(React.Fragment, null, currentText, "\xA0") : currentText), /*#__PURE__*/React.createElement(Text, {
|
|
32
33
|
className: "t-agent-message-input-voice-bubble-predicted"
|
|
33
34
|
}, incomingText)) : /*#__PURE__*/React.createElement(Textarea, {
|
|
34
35
|
"data-testid": "t-agent-message-input-asr-bubble-input",
|
|
35
36
|
autoHeight: true,
|
|
37
|
+
maxLength: 2048,
|
|
36
38
|
className: "t-agent-message-input-voice-bubble-input",
|
|
37
39
|
value: text,
|
|
38
40
|
onInput: event => setText(event.value)
|
|
@@ -56,18 +58,18 @@ export default function AsrInput(props) {
|
|
|
56
58
|
className: "t-agent-message-input-button t-agent-message-input-button-voice-active",
|
|
57
59
|
disabled: sendDisabled,
|
|
58
60
|
onTouchStart: () => {
|
|
59
|
-
press();
|
|
60
61
|
closeMore();
|
|
62
|
+
press();
|
|
61
63
|
},
|
|
62
64
|
onClick: release,
|
|
63
65
|
onTouchCancel: release,
|
|
64
66
|
onTouchEnd: release
|
|
65
67
|
}), /*#__PURE__*/React.createElement(Button, {
|
|
66
|
-
disabled: sendDisabled,
|
|
68
|
+
disabled: sendDisabled || responding,
|
|
67
69
|
"data-testid": "t-agent-message-input-asr-button-right",
|
|
68
70
|
className: cx('t-agent-message-input-button', {
|
|
69
71
|
't-agent-message-input-button-voice-send': state === 'pending',
|
|
70
|
-
't-agent-message-input-button-hide': state === 'recording' || !hasMore,
|
|
72
|
+
't-agent-message-input-button-hide': state === 'recording' || !hasMore && state !== 'pending',
|
|
71
73
|
't-agent-message-input-button-more': state === 'init' && hasMore,
|
|
72
74
|
't-agent-message-input-button-more-open': state === 'init' && moreOpen
|
|
73
75
|
}),
|
|
@@ -6,7 +6,7 @@ import './index.less';
|
|
|
6
6
|
import { Button, View } from '@ray-js/components';
|
|
7
7
|
import React, { useState } from 'react';
|
|
8
8
|
import { Image, Input, ScrollView } from '@ray-js/ray';
|
|
9
|
-
import { Asr
|
|
9
|
+
import { Asr } from '@ray-js/t-agent-plugin-assistant';
|
|
10
10
|
import cx from 'clsx';
|
|
11
11
|
import PrivateImage from '../PrivateImage';
|
|
12
12
|
import imageSvg from './icons/image.svg';
|
|
@@ -17,6 +17,9 @@ import { useAttachmentInput, useChatAgent, useEmitEvent, useIsUnmounted, useOnEv
|
|
|
17
17
|
import AsrInput from './AsrInput';
|
|
18
18
|
export default function MessageInput(props) {
|
|
19
19
|
const [moreOpen, setMoreOpen] = useState(false);
|
|
20
|
+
const {
|
|
21
|
+
i18nTranslate: t
|
|
22
|
+
} = useRenderOptions();
|
|
20
23
|
const [text, setText] = useState('');
|
|
21
24
|
const [asrText, setAsrText] = useState('');
|
|
22
25
|
const attachmentInput = useAttachmentInput();
|
|
@@ -31,8 +34,11 @@ export default function MessageInput(props) {
|
|
|
31
34
|
const agent = useChatAgent();
|
|
32
35
|
const emitEvent = useEmitEvent();
|
|
33
36
|
const isUnmounted = useIsUnmounted();
|
|
34
|
-
useOnEvent('
|
|
35
|
-
|
|
37
|
+
useOnEvent('networkChange', _ref => {
|
|
38
|
+
let {
|
|
39
|
+
online
|
|
40
|
+
} = _ref;
|
|
41
|
+
if (!online && responding) {
|
|
36
42
|
setResponding(false);
|
|
37
43
|
}
|
|
38
44
|
});
|
|
@@ -53,10 +59,10 @@ export default function MessageInput(props) {
|
|
|
53
59
|
}
|
|
54
60
|
}
|
|
55
61
|
};
|
|
56
|
-
useOnEvent('sendMessage', async
|
|
62
|
+
useOnEvent('sendMessage', async _ref2 => {
|
|
57
63
|
let {
|
|
58
64
|
blocks
|
|
59
|
-
} =
|
|
65
|
+
} = _ref2;
|
|
60
66
|
if (uploading || responding) {
|
|
61
67
|
return;
|
|
62
68
|
}
|
|
@@ -72,10 +78,10 @@ export default function MessageInput(props) {
|
|
|
72
78
|
}
|
|
73
79
|
}
|
|
74
80
|
});
|
|
75
|
-
useOnEvent('setInputBlocks', async
|
|
81
|
+
useOnEvent('setInputBlocks', async _ref3 => {
|
|
76
82
|
let {
|
|
77
83
|
blocks
|
|
78
|
-
} =
|
|
84
|
+
} = _ref3;
|
|
79
85
|
if (uploading || responding) {
|
|
80
86
|
return;
|
|
81
87
|
}
|
|
@@ -139,7 +145,7 @@ export default function MessageInput(props) {
|
|
|
139
145
|
if (!auth) {
|
|
140
146
|
ty.showToast({
|
|
141
147
|
icon: 'none',
|
|
142
|
-
title:
|
|
148
|
+
title: t('t-agent.input.voice.require-permission')
|
|
143
149
|
});
|
|
144
150
|
return;
|
|
145
151
|
}
|
|
@@ -177,7 +183,8 @@ export default function MessageInput(props) {
|
|
|
177
183
|
moreOpen: moreOpen,
|
|
178
184
|
closeMore: () => setMoreOpen(false),
|
|
179
185
|
onMoreClick: openMoreClick,
|
|
180
|
-
|
|
186
|
+
responding: responding,
|
|
187
|
+
sendDisabled: uploading,
|
|
181
188
|
onSend: async () => {
|
|
182
189
|
if (asrText) {
|
|
183
190
|
await send([...attachmentInput.blocks, {
|
|
@@ -258,7 +265,7 @@ export default function MessageInput(props) {
|
|
|
258
265
|
} catch (e) {
|
|
259
266
|
ty.showToast({
|
|
260
267
|
icon: 'error',
|
|
261
|
-
title:
|
|
268
|
+
title: t('t-agent.input.upload.failed')
|
|
262
269
|
});
|
|
263
270
|
}
|
|
264
271
|
}
|
|
@@ -274,7 +281,7 @@ export default function MessageInput(props) {
|
|
|
274
281
|
} catch (e) {
|
|
275
282
|
ty.showToast({
|
|
276
283
|
icon: 'error',
|
|
277
|
-
title:
|
|
284
|
+
title: t('t-agent.input.upload.failed')
|
|
278
285
|
});
|
|
279
286
|
}
|
|
280
287
|
}
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
padding-bottom: var(--t-agent-safe-bottom);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
.t-agent-chat-container-keyboard-show .t-agent-message-input {
|
|
16
|
+
padding-bottom: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
15
19
|
.t-agent-message-input-container {
|
|
16
20
|
border-top: 2rpx solid var(--t-agent-input-border-color);
|
|
17
21
|
background: var(--app-B1);
|
|
@@ -261,7 +265,10 @@
|
|
|
261
265
|
color: var(--app-M1-N1);
|
|
262
266
|
font-size: 32rpx;
|
|
263
267
|
transition: height 0.2s ease-in-out;
|
|
264
|
-
|
|
268
|
+
|
|
269
|
+
text {
|
|
270
|
+
white-space: pre-wrap;
|
|
271
|
+
}
|
|
265
272
|
|
|
266
273
|
&::after {
|
|
267
274
|
content: '';
|
|
@@ -277,6 +284,10 @@
|
|
|
277
284
|
}
|
|
278
285
|
}
|
|
279
286
|
|
|
287
|
+
.t-agent-chat-container-keyboard-show .t-agent-message-input-voice-bubble {
|
|
288
|
+
bottom: 260rpx;
|
|
289
|
+
}
|
|
290
|
+
|
|
280
291
|
.t-agent-message-input-voice-bubble-predicted {
|
|
281
292
|
color: var(--app-M1-N3);
|
|
282
293
|
}
|
|
@@ -4,7 +4,7 @@ import "core-js/modules/esnext.iterator.map.js";
|
|
|
4
4
|
import "core-js/modules/web.dom-collections.iterator.js";
|
|
5
5
|
import './index.less';
|
|
6
6
|
import { View } from '@ray-js/components';
|
|
7
|
-
import React, { useMemo, useState } from 'react';
|
|
7
|
+
import React, { useMemo, useRef, useState } from 'react';
|
|
8
8
|
import { ScrollView } from '@ray-js/ray';
|
|
9
9
|
import MessageRender from '../MessageRender';
|
|
10
10
|
import { useAgentMessage, useOnEvent, useSleep } from '../hooks';
|
|
@@ -19,13 +19,19 @@ export default function MessageList(props) {
|
|
|
19
19
|
const [scrollAnimation, setScrollAnimation] = useState(false);
|
|
20
20
|
// 最大整数位数,用于强制滚动到底部,收到连续 scrollToBottom 时,每 10 毫秒更新一次
|
|
21
21
|
const [scrollTop, setScrollTop] = useState(() => 1000000000000000 + Math.floor(Date.now() / 10));
|
|
22
|
+
const followNewMessageRef = useRef(true);
|
|
22
23
|
const sleep = useSleep();
|
|
23
24
|
|
|
24
25
|
// 强制滚动到底部
|
|
25
26
|
useOnEvent('scrollToBottom', _ref => {
|
|
26
27
|
let {
|
|
27
|
-
animation
|
|
28
|
+
animation,
|
|
29
|
+
follow
|
|
28
30
|
} = _ref;
|
|
31
|
+
// 如果发送的跟随新消息的滚动,判断当前是不是滚动到了底部,如果没有滚动到底部,不执行滚动
|
|
32
|
+
if (follow && !followNewMessageRef.current) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
29
35
|
sleep(100).then(() => {
|
|
30
36
|
setScrollAnimation(!!animation);
|
|
31
37
|
const top = 1000000000000000 + Math.floor(Date.now() / 10);
|
|
@@ -46,7 +52,11 @@ export default function MessageList(props) {
|
|
|
46
52
|
scrollTop: scrollTop,
|
|
47
53
|
refresherTriggered: false,
|
|
48
54
|
enableFlex: true,
|
|
49
|
-
scrollY: true
|
|
55
|
+
scrollY: true,
|
|
56
|
+
onScroll: event => {
|
|
57
|
+
// 使用了 flex-direction: column-reverse,所以滚动到顶部时,scrollTop = 0
|
|
58
|
+
followNewMessageRef.current = event.detail.scrollTop > -10;
|
|
59
|
+
}
|
|
50
60
|
}, /*#__PURE__*/React.createElement(View, {
|
|
51
61
|
className: "t-agent-message-list-padding"
|
|
52
62
|
}), reversed.map((msg, index) => {
|
package/dist/contexts.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { ChatAgent, ChatMessageObject, UIPlugin } from '@ray-js/t-agent';
|
|
3
|
-
import { AssistantPlugin
|
|
3
|
+
import { AssistantPlugin } from '@ray-js/t-agent-plugin-assistant';
|
|
4
4
|
import { RenderOptions, TileProps } from './types';
|
|
5
5
|
export declare const MessageContext: import("react").Context<{
|
|
6
6
|
messages: ChatMessageObject[];
|
|
7
|
-
|
|
7
|
+
keyboardHeight: number;
|
|
8
8
|
}>;
|
|
9
9
|
export declare const RenderContext: import("react").Context<RenderOptions>;
|
|
10
10
|
export declare const ChatAgentContext: import("react").Context<ChatAgent<UIPlugin & AssistantPlugin>>;
|
package/dist/contexts.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { createContext } from 'react';
|
|
2
|
-
import { SocketStatus } from '@ray-js/t-agent-plugin-assistant';
|
|
3
2
|
export const MessageContext = /*#__PURE__*/createContext({
|
|
4
3
|
messages: [],
|
|
5
|
-
|
|
4
|
+
keyboardHeight: 0
|
|
6
5
|
});
|
|
7
6
|
export const RenderContext = /*#__PURE__*/createContext({
|
|
8
7
|
renderTileAs: () => null,
|
package/dist/hooks/context.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { TTTAction } from '@ray-js/t-agent-plugin-assistant';
|
|
|
2
2
|
export declare const useChatAgent: () => import("@ray-js/t-agent").ChatAgent<import("@ray-js/t-agent").UIPlugin & import("@ray-js/t-agent-plugin-assistant").AssistantPlugin>;
|
|
3
3
|
export declare const useAgentMessage: () => {
|
|
4
4
|
messages: import("@ray-js/t-agent").ChatMessageObject[];
|
|
5
|
-
|
|
5
|
+
keyboardHeight: number;
|
|
6
6
|
};
|
|
7
7
|
export declare const useRenderOptions: () => import("..").RenderOptions;
|
|
8
8
|
export declare const useOnEvent: (eventName: string, callback: (details: any) => void) => void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import "core-js/modules/web.dom-collections.iterator.js";
|
|
2
|
-
import { useRef, useState } from 'react';
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
3
|
import { Asr, AsrDetectResultState } from '@ray-js/t-agent-plugin-assistant';
|
|
4
|
+
import { useIsUnmounted } from './useIsUnmounted';
|
|
4
5
|
export let AsrErrorCode = /*#__PURE__*/function (AsrErrorCode) {
|
|
5
6
|
AsrErrorCode[AsrErrorCode["SHORT_TIME"] = 0] = "SHORT_TIME";
|
|
6
7
|
return AsrErrorCode;
|
|
@@ -47,8 +48,18 @@ export function useAsrInput(options) {
|
|
|
47
48
|
const asrRef = useRef(null);
|
|
48
49
|
const [currentText, setCurrentText] = useState('');
|
|
49
50
|
const [incomingText, setIncomingText] = useState('');
|
|
51
|
+
const isUnmounted = useIsUnmounted();
|
|
50
52
|
const [state, setState] = useState('init');
|
|
51
53
|
const startAt = useRef(0);
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
return () => {
|
|
56
|
+
if (asrRef.current) {
|
|
57
|
+
asrRef.current.stop();
|
|
58
|
+
asrRef.current = null;
|
|
59
|
+
Asr.dispose();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}, []);
|
|
52
63
|
return {
|
|
53
64
|
currentText,
|
|
54
65
|
incomingText,
|
|
@@ -61,21 +72,31 @@ export function useAsrInput(options) {
|
|
|
61
72
|
},
|
|
62
73
|
press: async () => {
|
|
63
74
|
setState('recording');
|
|
64
|
-
|
|
75
|
+
|
|
76
|
+
// 保存当前文本,用于恢复
|
|
65
77
|
const initial = text;
|
|
66
|
-
|
|
78
|
+
|
|
79
|
+
// 上次识别的结果
|
|
80
|
+
let last = '';
|
|
67
81
|
setCurrentText(initial);
|
|
68
82
|
setIncomingText('');
|
|
69
83
|
|
|
70
84
|
// 开始录音时
|
|
71
|
-
const asr = Asr.detect(
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
85
|
+
const asr = Asr.detect(res => {
|
|
86
|
+
if (isUnmounted()) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (res.state === AsrDetectResultState.MID || res.state === AsrDetectResultState.END) {
|
|
90
|
+
if (res.text.startsWith(last)) {
|
|
91
|
+
const incoming = res.text.slice(last.length);
|
|
92
|
+
setIncomingText(incoming);
|
|
93
|
+
setCurrentText(initial + last);
|
|
94
|
+
last = res.text;
|
|
95
|
+
} else {
|
|
96
|
+
setIncomingText(res.text);
|
|
97
|
+
setCurrentText(initial);
|
|
98
|
+
}
|
|
99
|
+
setText(initial + res.text);
|
|
79
100
|
}
|
|
80
101
|
if (res.state === AsrDetectResultState.ERROR) {
|
|
81
102
|
onError(new AsrError(res.errorCode));
|
|
@@ -83,6 +104,7 @@ export function useAsrInput(options) {
|
|
|
83
104
|
});
|
|
84
105
|
try {
|
|
85
106
|
await asr.start();
|
|
107
|
+
startAt.current = Date.now();
|
|
86
108
|
asrRef.current = asr;
|
|
87
109
|
} catch (error) {
|
|
88
110
|
onError(error);
|
|
@@ -92,15 +114,14 @@ export function useAsrInput(options) {
|
|
|
92
114
|
if (state !== 'recording') {
|
|
93
115
|
return;
|
|
94
116
|
}
|
|
117
|
+
if (!text && startAt.current - Date.now() < 400) {
|
|
118
|
+
onError(new AsrError(AsrErrorCode.SHORT_TIME));
|
|
119
|
+
}
|
|
95
120
|
if (text) {
|
|
96
121
|
setState('pending');
|
|
97
122
|
} else {
|
|
98
|
-
onError(new AsrError(AsrErrorCode.SHORT_TIME));
|
|
99
123
|
setState('init');
|
|
100
124
|
}
|
|
101
|
-
if (Date.now() - startAt.current < 500 && text.length === 0) {
|
|
102
|
-
onError(new AsrError(AsrErrorCode.SHORT_TIME));
|
|
103
|
-
}
|
|
104
125
|
if (asrRef.current) {
|
|
105
126
|
await asrRef.current.stop();
|
|
106
127
|
asrRef.current = null;
|
package/dist/renderOption.js
CHANGED
|
@@ -12,7 +12,7 @@ import TileRender from '../../TileRender';
|
|
|
12
12
|
import Feedback from './Feedback';
|
|
13
13
|
import noticeSvg from './notice.svg';
|
|
14
14
|
import noticeWarnSvg from './notice-warn.svg';
|
|
15
|
-
import { useChatAgent } from '../../hooks';
|
|
15
|
+
import { useChatAgent, useRenderOptions } from '../../hooks';
|
|
16
16
|
const BubbleTile = props => {
|
|
17
17
|
var _message$meta$request;
|
|
18
18
|
const agent = useChatAgent();
|
|
@@ -31,6 +31,9 @@ const BubbleTile = props => {
|
|
|
31
31
|
data
|
|
32
32
|
} = tile;
|
|
33
33
|
const bubbleStatus = data.status || BubbleTileStatus.NORMAL;
|
|
34
|
+
const {
|
|
35
|
+
i18nTranslate: t
|
|
36
|
+
} = useRenderOptions();
|
|
34
37
|
const loading = status === ChatMessageStatus.START || status === ChatMessageStatus.UPDATING;
|
|
35
38
|
const showFeedback = isLatestMessage && status === ChatMessageStatus.FINISH && role === 'assistant' && ((_message$meta$request = message.meta.requestId) === null || _message$meta$request === void 0 ? void 0 : _message$meta$request.startsWith('AIAssistant')) && bubbleStatus === BubbleTileStatus.NORMAL;
|
|
36
39
|
const [feedbackLoaded, setFeedbackLoaded] = useState(false);
|
|
@@ -77,7 +80,7 @@ const BubbleTile = props => {
|
|
|
77
80
|
onClick: showInfo,
|
|
78
81
|
src: noticeWarnSvg,
|
|
79
82
|
className: "t-agent-bubble-tile-error",
|
|
80
|
-
"data-testid": "t-agent-bubble-tile-
|
|
83
|
+
"data-testid": "t-agent-bubble-tile-warning"
|
|
81
84
|
});
|
|
82
85
|
}
|
|
83
86
|
return /*#__PURE__*/React.createElement(View, {
|
|
@@ -120,7 +123,7 @@ const BubbleTile = props => {
|
|
|
120
123
|
})
|
|
121
124
|
});
|
|
122
125
|
ty.showToast({
|
|
123
|
-
title:
|
|
126
|
+
title: t('t-agent.message.feedback.success'),
|
|
124
127
|
icon: 'none'
|
|
125
128
|
});
|
|
126
129
|
}
|
|
@@ -3,17 +3,27 @@ import "core-js/modules/esnext.iterator.map.js";
|
|
|
3
3
|
import { Button, View } from '@ray-js/components';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import './index.less';
|
|
6
|
+
import { useRenderOptions } from '../../hooks';
|
|
6
7
|
export default function ButtonsTile(props) {
|
|
8
|
+
const {
|
|
9
|
+
i18nTranslate
|
|
10
|
+
} = useRenderOptions();
|
|
7
11
|
if (props.tile.locked) {
|
|
8
12
|
return null;
|
|
9
13
|
}
|
|
10
14
|
return /*#__PURE__*/React.createElement(View, {
|
|
11
15
|
className: "t-agent-buttons-tile"
|
|
12
|
-
}, props.tile.data.buttons.map(item =>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
item.clickPayload && props.emitEvent(item.clickPayload);
|
|
16
|
+
}, props.tile.data.buttons.map(item => {
|
|
17
|
+
let text = item.text;
|
|
18
|
+
if (item.i18nKey) {
|
|
19
|
+
text = i18nTranslate(item.i18nKey);
|
|
17
20
|
}
|
|
18
|
-
|
|
21
|
+
return /*#__PURE__*/React.createElement(Button, {
|
|
22
|
+
key: "".concat(text, "-").concat(item.type || ''),
|
|
23
|
+
className: "t-agent-buttons-tile-button ".concat(item.type ? "t-agent-buttons-tile-button-".concat(item.type) : ''),
|
|
24
|
+
onClick: () => {
|
|
25
|
+
item.clickPayload && props.emitEvent(item.clickPayload);
|
|
26
|
+
}
|
|
27
|
+
}, text);
|
|
28
|
+
}));
|
|
19
29
|
}
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ray-js/t-agent-ui-ray",
|
|
3
|
-
"version": "0.0.8-beta-
|
|
3
|
+
"version": "0.0.8-beta-3",
|
|
4
4
|
"author": "Tuya.inc",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"@types/echarts": "^4.9.22",
|
|
42
42
|
"@types/markdown-it": "^14.1.1"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "686e9d17bd1a96074d3ac16ac2a3d73e1aa17f8f"
|
|
45
45
|
}
|