@ray-js/t-agent-ui-ray 0.2.0-beta-2 → 0.2.0-beta-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.
- package/dist/ChatContainer/index.js +30 -1
- package/dist/MessageInput/MessageInputAIStream/AsrInput.d.ts +4 -5
- package/dist/MessageInput/MessageInputAIStream/AsrInput.js +57 -89
- package/dist/MessageInput/MessageInputAIStream/WaveformVisualizer.d.ts +4 -0
- package/dist/MessageInput/MessageInputAIStream/WaveformVisualizer.js +47 -0
- package/dist/MessageInput/MessageInputAIStream/index.js +27 -19
- package/dist/MessageInput/index.less +46 -15
- package/dist/MessageList/index.d.ts +0 -5
- package/dist/MessageList/index.js +4 -4
- package/dist/MessageRender/index.d.ts +2 -6
- package/dist/MessageRender/index.js +27 -12
- package/dist/MessageRender/index.less +5 -5
- package/dist/hooks/context.d.ts +2 -0
- package/dist/hooks/context.js +24 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/useLongPress.d.ts +2 -2
- package/dist/hooks/useLongPress.js +54 -37
- package/dist/hooks/{useMultSelect.d.ts → useMultiSelect.d.ts} +1 -1
- package/dist/hooks/{useMultSelect.js → useMultiSelect.js} +1 -1
- package/dist/i18n/strings.d.ts +4 -2
- package/dist/i18n/strings.js +6 -4
- package/dist/tiles/BubbleTile/index.js +5 -36
- package/dist/tiles/WorkflowTile/RollBack/index.d.ts +1 -1
- package/dist/tiles/WorkflowTile/RollBack/index.js +9 -15
- package/package.json +2 -2
|
@@ -12,6 +12,13 @@ import { defaultRenderOptions } from '../renderOption';
|
|
|
12
12
|
import logger from '../logger';
|
|
13
13
|
export default function ChatContainer(props) {
|
|
14
14
|
const [keyboardHeight, setKeyboardHeight] = useState(0);
|
|
15
|
+
const [windowSize, setWindowSize] = useState(() => {
|
|
16
|
+
const info = ty.getSystemInfoSync();
|
|
17
|
+
return {
|
|
18
|
+
width: info.windowWidth,
|
|
19
|
+
height: info.windowHeight
|
|
20
|
+
};
|
|
21
|
+
});
|
|
15
22
|
const {
|
|
16
23
|
createAgent,
|
|
17
24
|
renderOptions = defaultRenderOptions,
|
|
@@ -25,6 +32,13 @@ export default function ChatContainer(props) {
|
|
|
25
32
|
if (!agent.plugins.ui) {
|
|
26
33
|
throw new Error('UI plugin not found');
|
|
27
34
|
}
|
|
35
|
+
agent.session.initValue('UIRay.multiSelect.show', false);
|
|
36
|
+
agent.session.initValue('UIRay.multiSelect.selected', []);
|
|
37
|
+
agent.session.onChange((key, value) => {
|
|
38
|
+
if (key === 'UIRay.multiSelect.show' && !value) {
|
|
39
|
+
agent.session.set('UIRay.multiSelect.selected', []);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
28
42
|
return agent;
|
|
29
43
|
});
|
|
30
44
|
if (props.agentRef) {
|
|
@@ -135,6 +149,17 @@ export default function ChatContainer(props) {
|
|
|
135
149
|
const hide = () => {
|
|
136
150
|
setKeyboardHeight(0);
|
|
137
151
|
};
|
|
152
|
+
const resize = _ref4 => {
|
|
153
|
+
let {
|
|
154
|
+
size
|
|
155
|
+
} = _ref4;
|
|
156
|
+
setWindowSize({
|
|
157
|
+
width: size.windowWidth,
|
|
158
|
+
height: size.windowHeight
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
// @ts-ignore
|
|
162
|
+
ty.onWindowResize(resize);
|
|
138
163
|
ty.onKeyboardWillShow(show);
|
|
139
164
|
ty.onKeyboardWillHide(hide);
|
|
140
165
|
ty.onKeyboardHeightChange(show);
|
|
@@ -142,12 +167,16 @@ export default function ChatContainer(props) {
|
|
|
142
167
|
ty.offKeyboardWillShow(show);
|
|
143
168
|
ty.offKeyboardWillHide(hide);
|
|
144
169
|
ty.offKeyboardHeightChange(show);
|
|
170
|
+
// @ts-ignore
|
|
171
|
+
ty.offWindowResize(resize);
|
|
145
172
|
};
|
|
146
173
|
}, []);
|
|
147
174
|
return /*#__PURE__*/React.createElement(View, {
|
|
148
175
|
style: _objectSpread({
|
|
149
176
|
// @ts-ignore
|
|
150
|
-
'--t-agent-chat-container-keyboard-height': "".concat(keyboardHeight, "px")
|
|
177
|
+
'--t-agent-chat-container-keyboard-height': "".concat(keyboardHeight, "px"),
|
|
178
|
+
'--t-agent-chat-container-window-height': "".concat(windowSize.height, "px"),
|
|
179
|
+
'--t-agent-chat-container-window-width': "".concat(windowSize.width, "px")
|
|
151
180
|
}, style),
|
|
152
181
|
className: cx('t-agent-chat-container', className, {
|
|
153
182
|
't-agent-chat-container-keyboard-show': keyboardHeight > 0
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
3
|
-
amplitudeCount: number;
|
|
4
|
-
}) => React.JSX.Element;
|
|
5
|
-
interface IProps {
|
|
2
|
+
interface Props {
|
|
6
3
|
amplitudeCount: number;
|
|
4
|
+
responding: boolean;
|
|
7
5
|
recording: boolean;
|
|
8
6
|
disabled?: boolean;
|
|
9
7
|
onConfirm: () => void;
|
|
10
8
|
onRecord: () => void;
|
|
11
9
|
onCancel: () => void;
|
|
12
10
|
onBack: () => void;
|
|
11
|
+
onAbort: () => void;
|
|
13
12
|
}
|
|
14
|
-
declare const AsrInput: (props:
|
|
13
|
+
declare const AsrInput: (props: Props) => React.JSX.Element;
|
|
15
14
|
export default AsrInput;
|
|
@@ -1,112 +1,80 @@
|
|
|
1
|
-
import "core-js/modules/es.regexp.exec.js";
|
|
2
|
-
import "core-js/modules/esnext.iterator.constructor.js";
|
|
3
|
-
import "core-js/modules/esnext.iterator.map.js";
|
|
4
1
|
import "core-js/modules/web.dom-collections.iterator.js";
|
|
5
|
-
import React, { useState } from 'react';
|
|
2
|
+
import React, { useRef, useState } from 'react';
|
|
6
3
|
import { Button, View } from '@ray-js/ray';
|
|
7
4
|
import cx from 'clsx';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
let {
|
|
11
|
-
amplitudeCount
|
|
12
|
-
} = _ref;
|
|
13
|
-
const [bars, setBars] = useState(() => Array.from({
|
|
14
|
-
length: amplitudeCount
|
|
15
|
-
}, (_, index) => /*#__PURE__*/React.createElement(View
|
|
16
|
-
// eslint-disable-next-line react/no-array-index-key
|
|
17
|
-
, {
|
|
18
|
-
key: "asr_wave_".concat(index),
|
|
19
|
-
className: "t-agent-message-input-waveform-bar",
|
|
20
|
-
style: {
|
|
21
|
-
height: 0,
|
|
22
|
-
// 添加渐变色偏移效果
|
|
23
|
-
animationDelay: "".concat(index * 10, "ms")
|
|
24
|
-
}
|
|
25
|
-
})));
|
|
26
|
-
useOnEvent('amplitudes', val => {
|
|
27
|
-
const waveBase = val.body.amplitudes || [];
|
|
28
|
-
const bars = waveBase.map((item, index) => {
|
|
29
|
-
const value = item > 1 ? 1 : item * 100;
|
|
30
|
-
// 将数值映射到高度范围(0-100 → 2px-20px)
|
|
31
|
-
// const height = 2 + (value / 100) * 18;
|
|
32
|
-
return /*#__PURE__*/React.createElement(View
|
|
33
|
-
// eslint-disable-next-line react/no-array-index-key
|
|
34
|
-
, {
|
|
35
|
-
key: "asr_wave_".concat(index),
|
|
36
|
-
className: "t-agent-message-input-waveform-bar t-agent-item",
|
|
37
|
-
style: {
|
|
38
|
-
height: "".concat(value, "%"),
|
|
39
|
-
// 添加渐变色偏移效果
|
|
40
|
-
animationDelay: "".concat(index * 10, "ms")
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
setBars(bars);
|
|
45
|
-
});
|
|
46
|
-
return /*#__PURE__*/React.createElement(View, {
|
|
47
|
-
className: "t-agent-message-input-waveform-container"
|
|
48
|
-
}, bars);
|
|
49
|
-
};
|
|
5
|
+
import { useTranslate } from '../../hooks';
|
|
6
|
+
import { WaveformVisualizer } from './WaveformVisualizer';
|
|
50
7
|
const AsrInput = props => {
|
|
51
|
-
const
|
|
8
|
+
const touchRef = useRef({
|
|
9
|
+
startAt: 0,
|
|
10
|
+
y: 0
|
|
11
|
+
});
|
|
52
12
|
const t = useTranslate();
|
|
53
|
-
const [
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
const touchY =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
13
|
+
const [active, setActive] = useState(false);
|
|
14
|
+
const [cancel, setCancel] = useState(false);
|
|
15
|
+
const onVoiceTouchEnd = event => {
|
|
16
|
+
const touchY = event.changedTouches[0].pageY;
|
|
17
|
+
setCancel(false);
|
|
18
|
+
setActive(false);
|
|
19
|
+
if (touchRef.current.y - touchY > 100) {
|
|
20
|
+
touchRef.current = {
|
|
21
|
+
startAt: 0,
|
|
22
|
+
y: 0
|
|
23
|
+
};
|
|
24
|
+
props.onCancel();
|
|
64
25
|
return;
|
|
65
26
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
27
|
+
if (Date.now() - touchRef.current.startAt < 500) {
|
|
28
|
+
// 这种情况是误触,直接取消
|
|
29
|
+
touchRef.current = {
|
|
30
|
+
startAt: 0,
|
|
31
|
+
y: 0
|
|
32
|
+
};
|
|
33
|
+
props.onCancel();
|
|
72
34
|
return;
|
|
73
35
|
}
|
|
74
|
-
|
|
75
|
-
props.onConfirm();
|
|
76
|
-
}, 200);
|
|
77
|
-
setAsrElementBounds(null);
|
|
36
|
+
props.onConfirm();
|
|
78
37
|
};
|
|
79
|
-
return /*#__PURE__*/React.createElement(
|
|
38
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
39
|
+
className: "t-agent-message-input-ptt-bar"
|
|
40
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
80
41
|
className: cx('t-agent-message-input-ptt', {
|
|
81
|
-
't-agent-message-input-ptt-
|
|
42
|
+
't-agent-message-input-ptt-active': active,
|
|
43
|
+
't-agent-message-input-ptt-cancel': cancel
|
|
82
44
|
}),
|
|
83
|
-
onTouchStart:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
45
|
+
onTouchStart: async event => {
|
|
46
|
+
var _event$touches$;
|
|
47
|
+
touchRef.current = {
|
|
48
|
+
startAt: Date.now(),
|
|
49
|
+
y: (_event$touches$ = event.touches[0]) === null || _event$touches$ === void 0 ? void 0 : _event$touches$.pageY
|
|
50
|
+
};
|
|
51
|
+
setActive(true);
|
|
52
|
+
props.onRecord();
|
|
53
|
+
},
|
|
54
|
+
onTouchMove: event => {
|
|
55
|
+
const touch = event.touches[0];
|
|
56
|
+
const touchY = touch.pageY;
|
|
57
|
+
setCancel(touchRef.current.y - touchY > 100);
|
|
93
58
|
},
|
|
94
59
|
onTouchCancel: onVoiceTouchEnd,
|
|
95
60
|
onTouchEnd: onVoiceTouchEnd
|
|
96
|
-
}, props.recording ? /*#__PURE__*/React.createElement(View, {
|
|
97
|
-
className: "t-agent-message-input-oninput"
|
|
98
61
|
}, /*#__PURE__*/React.createElement(View, {
|
|
99
|
-
className: "t-agent-message-input-
|
|
62
|
+
className: "t-agent-message-input-ptt-text"
|
|
63
|
+
}, " ", t('t-agent.input.asr.ptt')), /*#__PURE__*/React.createElement(View, {
|
|
64
|
+
className: cx('t-agent-message-input-ptt-overlay', {
|
|
65
|
+
't-agent-message-input-ptt-overlay-active': active,
|
|
66
|
+
't-agent-message-input-ptt-overlay-cancel': cancel
|
|
67
|
+
})
|
|
68
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
69
|
+
className: "t-agent-message-input-ptt-active-text-top"
|
|
100
70
|
}, t('t-agent.input.asr.oninput.text.top')), /*#__PURE__*/React.createElement(View, {
|
|
101
|
-
className: "t-agent-message-input-
|
|
71
|
+
className: "t-agent-message-input-ptt-active-text-center"
|
|
102
72
|
}, t('t-agent.input.asr.oninput.text.center')), /*#__PURE__*/React.createElement(WaveformVisualizer, {
|
|
103
73
|
amplitudeCount: props.amplitudeCount
|
|
104
|
-
}))
|
|
105
|
-
className:
|
|
106
|
-
}, " ", t('t-agent.input.asr.ptt'))), !props.recording && /*#__PURE__*/React.createElement(Button, {
|
|
107
|
-
className: "t-agent-message-input-button t-agent-message-input-button-keyboard",
|
|
74
|
+
}))), !props.recording && /*#__PURE__*/React.createElement(Button, {
|
|
75
|
+
className: cx('t-agent-message-input-button', 't-agent-message-input-ptt-action-button', props.responding ? 't-agent-message-input-button-stop' : 't-agent-message-input-button-keyboard'),
|
|
108
76
|
"data-testid": "t-agent-message-input-button-asr",
|
|
109
|
-
onClick: props.onBack
|
|
77
|
+
onClick: props.responding ? props.onAbort : props.onBack
|
|
110
78
|
}));
|
|
111
79
|
};
|
|
112
80
|
export default AsrInput;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
2
|
+
import "core-js/modules/esnext.iterator.map.js";
|
|
3
|
+
import "core-js/modules/web.dom-collections.iterator.js";
|
|
4
|
+
import React, { useState } from 'react';
|
|
5
|
+
import { View } from '@ray-js/ray';
|
|
6
|
+
import { useOnEvent } from '../../hooks';
|
|
7
|
+
export const WaveformVisualizer = _ref => {
|
|
8
|
+
let {
|
|
9
|
+
amplitudeCount
|
|
10
|
+
} = _ref;
|
|
11
|
+
const [bars, setBars] = useState(() => Array.from({
|
|
12
|
+
length: amplitudeCount
|
|
13
|
+
}, (_, index) => /*#__PURE__*/React.createElement(View
|
|
14
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
15
|
+
, {
|
|
16
|
+
key: "asr_wave_".concat(index),
|
|
17
|
+
className: "t-agent-message-input-waveform-bar",
|
|
18
|
+
style: {
|
|
19
|
+
height: 0,
|
|
20
|
+
// 添加渐变色偏移效果
|
|
21
|
+
animationDelay: "".concat(index * 10, "ms")
|
|
22
|
+
}
|
|
23
|
+
})));
|
|
24
|
+
useOnEvent('amplitudes', val => {
|
|
25
|
+
const waveBase = val.body.amplitudes || [];
|
|
26
|
+
const bars = waveBase.map((item, index) => {
|
|
27
|
+
const value = item > 1 ? 1 : item * 100;
|
|
28
|
+
// 将数值映射到高度范围(0-100 → 2px-20px)
|
|
29
|
+
// const height = 2 + (value / 100) * 18;
|
|
30
|
+
return /*#__PURE__*/React.createElement(View
|
|
31
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
32
|
+
, {
|
|
33
|
+
key: "asr_wave_".concat(index),
|
|
34
|
+
className: "t-agent-message-input-waveform-bar",
|
|
35
|
+
style: {
|
|
36
|
+
height: "".concat(value, "%"),
|
|
37
|
+
// 添加渐变色偏移效果
|
|
38
|
+
animationDelay: "".concat(index * 10, "ms")
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
setBars(bars);
|
|
43
|
+
});
|
|
44
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
45
|
+
className: "t-agent-message-input-waveform-container"
|
|
46
|
+
}, bars);
|
|
47
|
+
};
|
|
@@ -14,8 +14,9 @@ import imageSvg from '../icons/image.svg';
|
|
|
14
14
|
import videoSvg from '../icons/video.svg';
|
|
15
15
|
import loadingSvg from '../icons/loading.svg';
|
|
16
16
|
import closeCircleSvg from '../icons/close-circle.svg';
|
|
17
|
-
import { useAttachmentInput, useChatAgent, useEmitEvent, useIsUnmounted, useOnEvent, useTranslate } from '../../hooks';
|
|
17
|
+
import { useAgentSessionValue, useAttachmentInput, useChatAgent, useEmitEvent, useIsUnmounted, useOnEvent, useTranslate } from '../../hooks';
|
|
18
18
|
import AsrInput from './AsrInput';
|
|
19
|
+
import { useSleep } from '../../hooks/useSleep';
|
|
19
20
|
const AMPLITUDE_COUNT = 60;
|
|
20
21
|
export default function MessageInputAIStream(props) {
|
|
21
22
|
const [moreOpen, setMoreOpen] = useState(false);
|
|
@@ -50,9 +51,10 @@ export default function MessageInputAIStream(props) {
|
|
|
50
51
|
setResponding(false);
|
|
51
52
|
}
|
|
52
53
|
});
|
|
53
|
-
const
|
|
54
|
+
const [hasMore] = useAgentSessionValue('multiModal');
|
|
55
|
+
const isMore = !text.trim().length && hasMore;
|
|
54
56
|
const send = async inputBlocks => {
|
|
55
|
-
if (!(inputBlocks !== null && inputBlocks !== void 0 && inputBlocks.length)
|
|
57
|
+
if (!(inputBlocks !== null && inputBlocks !== void 0 && inputBlocks.length)) {
|
|
56
58
|
return;
|
|
57
59
|
}
|
|
58
60
|
setUploaded([]);
|
|
@@ -63,8 +65,8 @@ export default function MessageInputAIStream(props) {
|
|
|
63
65
|
ac.signal.addEventListener('abort', () => {
|
|
64
66
|
if (acRef.current === ac) {
|
|
65
67
|
acRef.current = null;
|
|
68
|
+
setResponding(false);
|
|
66
69
|
}
|
|
67
|
-
setResponding(false);
|
|
68
70
|
});
|
|
69
71
|
try {
|
|
70
72
|
await agent.pushInputBlocks(inputBlocks, ac.signal);
|
|
@@ -131,7 +133,9 @@ export default function MessageInputAIStream(props) {
|
|
|
131
133
|
});
|
|
132
134
|
}
|
|
133
135
|
};
|
|
136
|
+
const sleep = useSleep();
|
|
134
137
|
let container;
|
|
138
|
+
const canSend = text.trim().length && !responding && !attachmentInput.uploading;
|
|
135
139
|
if (mode === 'text') {
|
|
136
140
|
container = /*#__PURE__*/React.createElement(View, {
|
|
137
141
|
className: "t-agent-message-input-text-bar"
|
|
@@ -145,7 +149,7 @@ export default function MessageInputAIStream(props) {
|
|
|
145
149
|
"data-testid": "t-agent-message-input-text-inner",
|
|
146
150
|
className: "t-agent-message-input-text-inner",
|
|
147
151
|
onConfirm: () => {
|
|
148
|
-
if (
|
|
152
|
+
if (canSend) {
|
|
149
153
|
send([...attachmentInput.blocks, {
|
|
150
154
|
type: 'text',
|
|
151
155
|
text
|
|
@@ -193,7 +197,7 @@ export default function MessageInputAIStream(props) {
|
|
|
193
197
|
}
|
|
194
198
|
} else if (isMore) {
|
|
195
199
|
openMoreClick();
|
|
196
|
-
} else if (
|
|
200
|
+
} else if (canSend) {
|
|
197
201
|
await send([...attachmentInput.blocks, {
|
|
198
202
|
type: 'text',
|
|
199
203
|
text
|
|
@@ -202,21 +206,25 @@ export default function MessageInputAIStream(props) {
|
|
|
202
206
|
}
|
|
203
207
|
}));
|
|
204
208
|
} else {
|
|
205
|
-
container = /*#__PURE__*/React.createElement(
|
|
206
|
-
|
|
207
|
-
}, /*#__PURE__*/React.createElement(View, {
|
|
208
|
-
className: "t-agent-message-input-text-group"
|
|
209
|
-
}, /*#__PURE__*/React.createElement(AsrInput, {
|
|
209
|
+
container = /*#__PURE__*/React.createElement(AsrInput, {
|
|
210
|
+
responding: responding,
|
|
210
211
|
disabled: responding,
|
|
211
212
|
amplitudeCount: AMPLITUDE_COUNT,
|
|
212
213
|
recording: record.recording,
|
|
213
214
|
onRecord: async () => {
|
|
215
|
+
if (attachmentInput.uploading) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (responding && acRef.current) {
|
|
219
|
+
acRef.current.abort('User abort');
|
|
220
|
+
// 中断后等待一会再开始
|
|
221
|
+
await sleep(50);
|
|
222
|
+
}
|
|
214
223
|
const emitter = new Emitter();
|
|
215
224
|
setRecord({
|
|
216
225
|
startAt: Date.now(),
|
|
217
226
|
recording: true,
|
|
218
227
|
confirm: () => {
|
|
219
|
-
console.log('setRecord confirm');
|
|
220
228
|
emitter.dispatchEvent(new EmitterEvent('confirm'));
|
|
221
229
|
setRecord({
|
|
222
230
|
startAt: 0,
|
|
@@ -226,7 +234,6 @@ export default function MessageInputAIStream(props) {
|
|
|
226
234
|
});
|
|
227
235
|
},
|
|
228
236
|
cancel: () => {
|
|
229
|
-
console.log('setRecord cancel');
|
|
230
237
|
emitter.dispatchEvent(new EmitterEvent('cancel'));
|
|
231
238
|
setRecord({
|
|
232
239
|
startAt: 0,
|
|
@@ -237,7 +244,6 @@ export default function MessageInputAIStream(props) {
|
|
|
237
244
|
}
|
|
238
245
|
});
|
|
239
246
|
emitter.addEventListener('error', event => {
|
|
240
|
-
console.log('setRecord error');
|
|
241
247
|
ty.showToast({
|
|
242
248
|
icon: 'error',
|
|
243
249
|
title: t('t-agent.input.voice.recording-failed')
|
|
@@ -250,7 +256,6 @@ export default function MessageInputAIStream(props) {
|
|
|
250
256
|
cancel: null
|
|
251
257
|
});
|
|
252
258
|
});
|
|
253
|
-
console.log('setRecord send');
|
|
254
259
|
await send([...attachmentInput.blocks, {
|
|
255
260
|
type: 'audio',
|
|
256
261
|
audio_emitter: emitter,
|
|
@@ -259,16 +264,19 @@ export default function MessageInputAIStream(props) {
|
|
|
259
264
|
},
|
|
260
265
|
onConfirm: () => {
|
|
261
266
|
var _record$confirm;
|
|
262
|
-
console.log('test onConfirm');
|
|
263
267
|
(_record$confirm = record.confirm) === null || _record$confirm === void 0 || _record$confirm.call(record);
|
|
264
268
|
},
|
|
265
269
|
onCancel: () => {
|
|
266
270
|
var _record$cancel;
|
|
267
|
-
console.log('test onCancel');
|
|
268
271
|
(_record$cancel = record.cancel) === null || _record$cancel === void 0 || _record$cancel.call(record);
|
|
269
272
|
},
|
|
270
|
-
onBack: () => setMode('text')
|
|
271
|
-
|
|
273
|
+
onBack: () => setMode('text'),
|
|
274
|
+
onAbort: () => {
|
|
275
|
+
if (responding && acRef.current) {
|
|
276
|
+
acRef.current.abort('User abort');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
});
|
|
272
280
|
}
|
|
273
281
|
return /*#__PURE__*/React.createElement(View, {
|
|
274
282
|
className: "".concat(props.className || '', " t-agent-message-input"),
|
|
@@ -146,12 +146,16 @@
|
|
|
146
146
|
right: 10rpx;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
.t-agent-message-input-button
|
|
150
|
-
background: transparent url('icons/keyboard.svg') no-repeat center;
|
|
149
|
+
.t-agent-message-input-ptt-action-button {
|
|
151
150
|
position: absolute;
|
|
152
151
|
top: 50%;
|
|
153
152
|
transform: translateY(-50%);
|
|
154
|
-
right:
|
|
153
|
+
right: 32rpx;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.t-agent-message-input-button-keyboard {
|
|
157
|
+
border: 2rpx solid var(--t-agent-input-border-color);
|
|
158
|
+
background: transparent url('icons/text.svg') no-repeat center;
|
|
155
159
|
}
|
|
156
160
|
|
|
157
161
|
.t-agent-message-input-button-stop {
|
|
@@ -314,37 +318,64 @@
|
|
|
314
318
|
min-height: 56rpx;
|
|
315
319
|
}
|
|
316
320
|
|
|
317
|
-
|
|
321
|
+
.t-agent-message-input-ptt-bar {
|
|
322
|
+
padding: 16rpx 32rpx;
|
|
323
|
+
position: relative;
|
|
324
|
+
}
|
|
318
325
|
|
|
319
326
|
.t-agent-message-input-ptt {
|
|
320
327
|
background: transparent;
|
|
321
328
|
padding: 0;
|
|
322
329
|
border: none;
|
|
323
|
-
height:
|
|
330
|
+
height: 72rpx;
|
|
324
331
|
display: flex;
|
|
325
332
|
justify-content: center;
|
|
326
333
|
align-items: center;
|
|
327
|
-
transition: height
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
.t-agent-message-input-ptt-handle {
|
|
331
|
-
height: 224rpx;
|
|
334
|
+
transition: height 0.3s ease-in-out; // 定义高度变化的过渡效果
|
|
332
335
|
}
|
|
333
336
|
|
|
334
337
|
.t-agent-message-input-ptt-text {
|
|
335
338
|
font-size: 32rpx;
|
|
336
339
|
line-height: 56rpx;
|
|
337
|
-
color: var(--app-
|
|
340
|
+
color: var(--app-B1-N1);
|
|
338
341
|
text-align: center;
|
|
339
342
|
}
|
|
340
343
|
|
|
341
|
-
.t-agent-message-input-
|
|
344
|
+
.t-agent-message-input-ptt-overlay-cancel {
|
|
345
|
+
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.t-agent-message-input-ptt-overlay {
|
|
349
|
+
position: absolute;
|
|
350
|
+
height: 100%;
|
|
351
|
+
left: 0;
|
|
352
|
+
right: 0;
|
|
353
|
+
bottom: 0;
|
|
354
|
+
background-color: var(--app-B1);
|
|
355
|
+
pointer-events: none;
|
|
356
|
+
opacity: 0;
|
|
357
|
+
display: flex;
|
|
358
|
+
flex-direction: column;
|
|
359
|
+
justify-content: center;
|
|
360
|
+
border-top: 2rpx solid var(--t-agent-input-border-color);
|
|
361
|
+
z-index: 2;
|
|
362
|
+
transition: opacity 0s ease 0.1s, height 0.3s ease;
|
|
363
|
+
|
|
364
|
+
&.t-agent-message-input-ptt-overlay-active {
|
|
365
|
+
transition: opacity 0s ease 0s, height 0.3s ease;
|
|
366
|
+
opacity: 1;
|
|
367
|
+
height: calc(100% + 150rpx);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
.t-agent-message-input-ptt-active-text-top {
|
|
342
372
|
font-size: 32rpx;
|
|
343
373
|
line-height: 56rpx;
|
|
344
374
|
color: var(--app-M1-B1);
|
|
345
375
|
text-align: center;
|
|
346
376
|
}
|
|
347
|
-
|
|
377
|
+
|
|
378
|
+
.t-agent-message-input-ptt-active-text-center {
|
|
348
379
|
font-size: 20rpx;
|
|
349
380
|
color: var(--app-M1-B1);
|
|
350
381
|
text-align: center;
|
|
@@ -365,7 +396,7 @@
|
|
|
365
396
|
background-color: var(--app-M4);
|
|
366
397
|
border-radius: 2rpx;
|
|
367
398
|
transition: height 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s ease;
|
|
368
|
-
animation:
|
|
399
|
+
animation: t-agent-message-input-waveform-bar-color-pulse 2s infinite;
|
|
369
400
|
margin-right: 4rpx;
|
|
370
401
|
opacity: 1;
|
|
371
402
|
|
|
@@ -374,7 +405,7 @@
|
|
|
374
405
|
}
|
|
375
406
|
}
|
|
376
407
|
|
|
377
|
-
@keyframes
|
|
408
|
+
@keyframes t-agent-message-input-waveform-bar-color-pulse {
|
|
378
409
|
0% {
|
|
379
410
|
opacity: 1;
|
|
380
411
|
}
|
|
@@ -10,11 +10,6 @@ interface Props {
|
|
|
10
10
|
assistant?: 'start' | 'end' | string;
|
|
11
11
|
[key: string]: 'start' | 'end' | string;
|
|
12
12
|
};
|
|
13
|
-
multSelect?: {
|
|
14
|
-
show: boolean;
|
|
15
|
-
select: string[];
|
|
16
|
-
onSelect: (msgs: string[]) => void;
|
|
17
|
-
};
|
|
18
13
|
historyLimit?: {
|
|
19
14
|
/** 历史消息数量限制 */
|
|
20
15
|
count: number;
|
|
@@ -10,7 +10,7 @@ import { ScrollView } from '@ray-js/ray';
|
|
|
10
10
|
import { generateId } from '@ray-js/t-agent';
|
|
11
11
|
import { isVersionMatch } from '@ray-js/t-agent-plugin-aistream';
|
|
12
12
|
import MessageRender from '../MessageRender';
|
|
13
|
-
import { useAgentMessage, useOnEvent } from '../hooks';
|
|
13
|
+
import { useAgentMessage, useAgentSessionValue, useOnEvent } from '../hooks';
|
|
14
14
|
import { useDebouncedFn } from '../hooks/useDebouncedFn';
|
|
15
15
|
import { useSleep } from '../hooks/useSleep';
|
|
16
16
|
export default function MessageList(props) {
|
|
@@ -20,8 +20,7 @@ export default function MessageList(props) {
|
|
|
20
20
|
style,
|
|
21
21
|
wrapperClassName,
|
|
22
22
|
wrapperStyle,
|
|
23
|
-
historyLimit
|
|
24
|
-
multSelect
|
|
23
|
+
historyLimit
|
|
25
24
|
} = props;
|
|
26
25
|
const {
|
|
27
26
|
messages
|
|
@@ -32,6 +31,7 @@ export default function MessageList(props) {
|
|
|
32
31
|
const [scrollTop, setScrollTop] = useState(() => 1000000000000000 + Math.floor(Date.now() / 10));
|
|
33
32
|
const followNewMessageRef = useRef(true);
|
|
34
33
|
const sleep = useSleep();
|
|
34
|
+
const [showSelect] = useAgentSessionValue('UIRay.multiSelect.show');
|
|
35
35
|
const canIUse = useMemo(() => {
|
|
36
36
|
// @ts-ignore
|
|
37
37
|
const {
|
|
@@ -104,7 +104,7 @@ export default function MessageList(props) {
|
|
|
104
104
|
side = msg.role === 'user' ? 'end' : 'start';
|
|
105
105
|
}
|
|
106
106
|
return /*#__PURE__*/React.createElement(MessageRender, {
|
|
107
|
-
|
|
107
|
+
showSelect: showSelect,
|
|
108
108
|
key: msg.id,
|
|
109
109
|
message: msg,
|
|
110
110
|
isLatestMessage: index === 0,
|
|
@@ -5,11 +5,7 @@ interface Props {
|
|
|
5
5
|
message: ChatMessageObject;
|
|
6
6
|
isLatestMessage: boolean;
|
|
7
7
|
side: 'start' | 'end' | string;
|
|
8
|
-
|
|
9
|
-
show: boolean;
|
|
10
|
-
select: string[];
|
|
11
|
-
onSelect: (msgs: string[]) => void;
|
|
12
|
-
};
|
|
8
|
+
showSelect?: boolean;
|
|
13
9
|
}
|
|
14
|
-
export default function MessageRender({ message, isLatestMessage, side,
|
|
10
|
+
export default function MessageRender({ message, isLatestMessage, side, showSelect }: Props): React.JSX.Element;
|
|
15
11
|
export {};
|
|
@@ -4,24 +4,34 @@ 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 from 'react';
|
|
7
|
+
import React, { useState } from 'react';
|
|
8
8
|
import TileRender from '../TileRender';
|
|
9
|
+
import { useChatAgent, useOnEvent } from '../hooks';
|
|
9
10
|
export default function MessageRender(_ref) {
|
|
10
11
|
let {
|
|
11
12
|
message,
|
|
12
13
|
isLatestMessage,
|
|
13
14
|
side,
|
|
14
|
-
|
|
15
|
+
showSelect
|
|
15
16
|
} = _ref;
|
|
16
17
|
const {
|
|
17
18
|
id,
|
|
18
19
|
tiles
|
|
19
20
|
} = message;
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
21
|
+
const agent = useChatAgent();
|
|
22
|
+
const [isSelected, setIsSelected] = useState(() => {
|
|
23
|
+
var _agent$session$get;
|
|
24
|
+
return !!((_agent$session$get = agent.session.get("UIRay.multiSelect.selected")) !== null && _agent$session$get !== void 0 && _agent$session$get.includes(id));
|
|
25
|
+
});
|
|
26
|
+
useOnEvent('sessionChange', _ref2 => {
|
|
27
|
+
let {
|
|
28
|
+
key,
|
|
29
|
+
value
|
|
30
|
+
} = _ref2;
|
|
31
|
+
if (key === 'UIRay.multiSelect.selected') {
|
|
32
|
+
setIsSelected(!!(value !== null && value !== void 0 && value.includes(id)));
|
|
33
|
+
}
|
|
34
|
+
});
|
|
25
35
|
if (tiles.length === 0) {
|
|
26
36
|
return /*#__PURE__*/React.createElement(View, {
|
|
27
37
|
key: id,
|
|
@@ -30,14 +40,19 @@ export default function MessageRender(_ref) {
|
|
|
30
40
|
}
|
|
31
41
|
return /*#__PURE__*/React.createElement(View, {
|
|
32
42
|
key: id,
|
|
33
|
-
className: "t-agent-message-list-row-container
|
|
34
|
-
|
|
43
|
+
className: "t-agent-message-list-row-container",
|
|
44
|
+
onClick: () => {
|
|
45
|
+
if (showSelect) {
|
|
46
|
+
const prev = agent.session.get("UIRay.multiSelect.selected") || [];
|
|
47
|
+
isSelected ? agent.session.set("UIRay.multiSelect.selected", prev.filter(i => i !== id)) : agent.session.set("UIRay.multiSelect.selected", [...prev, id]);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, showSelect && /*#__PURE__*/React.createElement(View, {
|
|
35
51
|
className: "t-agent-message-list-row-check"
|
|
36
52
|
}, /*#__PURE__*/React.createElement(View, {
|
|
37
|
-
className: "checkbox-container ".concat(
|
|
38
|
-
onClick: () => select.includes(id) ? onSelect([...select.filter(v => v !== id)]) : onSelect([...select, id])
|
|
53
|
+
className: "t-agent-message-list-checkbox-container ".concat(isSelected ? 't-agent-message-list-checkbox-selected' : '')
|
|
39
54
|
}, /*#__PURE__*/React.createElement(View, {
|
|
40
|
-
className: "checkbox-check"
|
|
55
|
+
className: "t-agent-message-list-checkbox-check"
|
|
41
56
|
}))), /*#__PURE__*/React.createElement(View, {
|
|
42
57
|
className: "t-agent-message-list-row t-agent-message-list-row-".concat(side)
|
|
43
58
|
}, tiles.map(tile => {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
@border-color: rgba(0, 0, 0, 0.3);
|
|
29
29
|
@active-color: #3678E3;
|
|
30
30
|
|
|
31
|
-
.checkbox-container {
|
|
31
|
+
.t-agent-message-list-checkbox-container {
|
|
32
32
|
position: relative;
|
|
33
33
|
width: @checkbox-size;
|
|
34
34
|
height: @checkbox-size;
|
|
@@ -38,17 +38,17 @@
|
|
|
38
38
|
cursor: pointer;
|
|
39
39
|
transition: all 0.2s ease-in-out;
|
|
40
40
|
|
|
41
|
-
&.selected {
|
|
41
|
+
&.t-agent-message-list-checkbox-selected {
|
|
42
42
|
background: @active-color;
|
|
43
43
|
border-color: transparent;
|
|
44
44
|
|
|
45
|
-
.checkbox-check {
|
|
45
|
+
.t-agent-message-list-checkbox-check {
|
|
46
46
|
opacity: 1;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
.checkbox-check {
|
|
51
|
+
.t-agent-message-list-checkbox-check {
|
|
52
52
|
position: absolute;
|
|
53
53
|
top: 50%;
|
|
54
54
|
left: 50%;
|
|
@@ -58,4 +58,4 @@
|
|
|
58
58
|
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSI5IiB2aWV3Qm94PSIwIDAgMTIgOSI+PHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRkZGIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik0xIDRsMy43NSA0TDEwLjMgMSIvPjwvc3ZnPg==");
|
|
59
59
|
opacity: 0;
|
|
60
60
|
transition: opacity 0.2s ease-in-out;
|
|
61
|
-
}
|
|
61
|
+
}
|
package/dist/hooks/context.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from 'react';
|
|
1
2
|
import { TTTAction } from '../types';
|
|
2
3
|
export declare const useChatAgent: () => import("../contexts").UIChatAgent;
|
|
3
4
|
export declare const useAgentMessage: () => {
|
|
@@ -9,3 +10,4 @@ export declare const useOnEvent: (eventName: string, callback: (details: any) =>
|
|
|
9
10
|
export declare const useEmitEvent: () => <T extends keyof import("@ray-js/t-agent").UIEventMap>(eventName: T, detail: import("@ray-js/t-agent").UIEventMap[T]) => void;
|
|
10
11
|
export declare const useTileProps: () => import("../types").TileProps<any, any>;
|
|
11
12
|
export declare const useSendAction: () => (action: TTTAction) => void;
|
|
13
|
+
export declare const useAgentSessionValue: <S = any>(key: string) => readonly [S, Dispatch<SetStateAction<S>>];
|
package/dist/hooks/context.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "core-js/modules/web.dom-collections.iterator.js";
|
|
2
|
+
import { useEffect, useContext, useCallback, useRef, useState } from 'react';
|
|
2
3
|
import { TilePropsContext, ChatAgentContext, MessageContext, RenderContext } from '../contexts';
|
|
3
4
|
export const useChatAgent = () => {
|
|
4
5
|
return useContext(ChatAgentContext);
|
|
@@ -42,4 +43,26 @@ export const useSendAction = () => {
|
|
|
42
43
|
agent.plugins.ui.emitEvent('runTTTAction', action);
|
|
43
44
|
}, [agent]);
|
|
44
45
|
return emitTileEvent ? tileSendAction : uiSendAction;
|
|
46
|
+
};
|
|
47
|
+
export const useAgentSessionValue = key => {
|
|
48
|
+
const agent = useChatAgent();
|
|
49
|
+
const [value, setValue] = useState(() => agent.session.get(key));
|
|
50
|
+
const set = useCallback(value => {
|
|
51
|
+
if (typeof value === 'function') {
|
|
52
|
+
const prev = agent.session.get(key);
|
|
53
|
+
value = value(prev);
|
|
54
|
+
}
|
|
55
|
+
agent.session.set(key, value);
|
|
56
|
+
setValue(value);
|
|
57
|
+
}, []);
|
|
58
|
+
useOnEvent('sessionChange', _ref => {
|
|
59
|
+
let {
|
|
60
|
+
key: k,
|
|
61
|
+
value
|
|
62
|
+
} = _ref;
|
|
63
|
+
if (k === key) {
|
|
64
|
+
setValue(value);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return [value, set];
|
|
45
68
|
};
|
package/dist/hooks/index.d.ts
CHANGED
package/dist/hooks/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { ChatMessageObject } from '@ray-js/t-agent';
|
|
|
2
2
|
/**
|
|
3
3
|
* 预定义动作类型
|
|
4
4
|
*/
|
|
5
|
-
export type ActionType = 'copy' | 'delete' | 'like' | 'unlike' | 'deleteByChannel' | '
|
|
5
|
+
export type ActionType = 'copy' | 'delete' | 'like' | 'unlike' | 'deleteByChannel' | 'multiSelect';
|
|
6
6
|
export interface ActionMenuItem {
|
|
7
7
|
key: string;
|
|
8
8
|
label: string;
|
|
@@ -23,7 +23,7 @@ export interface LongPressActionMenuProps {
|
|
|
23
23
|
}
|
|
24
24
|
export interface UseLongPressOptions {
|
|
25
25
|
message?: ChatMessageObject;
|
|
26
|
-
actions?: ActionType | ActionType[];
|
|
26
|
+
actions?: ActionType | ActionType[] | string[];
|
|
27
27
|
getMessageContent?: () => string;
|
|
28
28
|
customActions?: ActionMenuItem[];
|
|
29
29
|
disabled?: boolean;
|
|
@@ -20,7 +20,7 @@ export function useLongPress() {
|
|
|
20
20
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
21
21
|
const {
|
|
22
22
|
message,
|
|
23
|
-
actions = ['copy', '
|
|
23
|
+
actions = ['copy', 'multiSelect', 'delete'],
|
|
24
24
|
getMessageContent = () => '',
|
|
25
25
|
customActions = [],
|
|
26
26
|
disabled = false
|
|
@@ -79,12 +79,12 @@ export function useLongPress() {
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
break;
|
|
82
|
-
case '
|
|
82
|
+
case 'multiSelect':
|
|
83
83
|
menuItems.push({
|
|
84
|
-
key: '
|
|
85
|
-
label: t('t-agent.message.action.
|
|
84
|
+
key: 'multiSelect',
|
|
85
|
+
label: t('t-agent.message.action.multiSelect'),
|
|
86
86
|
action: () => {
|
|
87
|
-
|
|
87
|
+
agent.session.set('UIRay.multiSelect.show', !agent.session.get('UIRay.multiSelect.show'));
|
|
88
88
|
}
|
|
89
89
|
});
|
|
90
90
|
break;
|
|
@@ -115,32 +115,33 @@ export function useLongPress() {
|
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
break;
|
|
118
|
-
case 'deleteByChannel':
|
|
119
|
-
menuItems.push({
|
|
120
|
-
key: 'deleteByChannel',
|
|
121
|
-
label: t('t-agent.message.action.deleteByChannel'),
|
|
122
|
-
action: () => {
|
|
123
|
-
// const channel = agent.session.get('AIAssistant.channel');
|
|
124
|
-
// const { removeMessageByChannel } = agent.plugins.assistant;
|
|
125
|
-
// if (typeof removeMessageByChannel === 'function') {
|
|
126
|
-
// removeMessageByChannel(channel);
|
|
127
|
-
// }
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
break;
|
|
131
118
|
case 'like':
|
|
132
119
|
menuItems.push({
|
|
133
120
|
key: 'like',
|
|
134
121
|
label: t('t-agent.message.action.like'),
|
|
135
122
|
action: async () => {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
123
|
+
try {
|
|
124
|
+
const result = await agent.plugins.ui.callHook('onMessageFeedback', {
|
|
125
|
+
messageId: message.id,
|
|
126
|
+
rate: 'like'
|
|
127
|
+
});
|
|
128
|
+
if (result !== null && result !== void 0 && result.success) {
|
|
129
|
+
ty.showToast({
|
|
130
|
+
title: t('t-agent.message.like.success'),
|
|
131
|
+
icon: 'none'
|
|
132
|
+
});
|
|
133
|
+
} else {
|
|
134
|
+
ty.showToast({
|
|
135
|
+
title: t('t-agent.unknown-error'),
|
|
136
|
+
icon: 'none'
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
} catch (error) {
|
|
140
|
+
ty.showToast({
|
|
141
|
+
title: (error === null || error === void 0 ? void 0 : error.message) || t('t-agent.unknown-error'),
|
|
142
|
+
icon: 'none'
|
|
143
|
+
});
|
|
144
|
+
}
|
|
144
145
|
}
|
|
145
146
|
});
|
|
146
147
|
break;
|
|
@@ -149,14 +150,28 @@ export function useLongPress() {
|
|
|
149
150
|
key: 'unlike',
|
|
150
151
|
label: t('t-agent.message.action.unlike'),
|
|
151
152
|
action: async () => {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
153
|
+
try {
|
|
154
|
+
const result = await agent.plugins.ui.callHook('onMessageFeedback', {
|
|
155
|
+
messageId: message.id,
|
|
156
|
+
rate: 'unlike'
|
|
157
|
+
});
|
|
158
|
+
if (result !== null && result !== void 0 && result.success) {
|
|
159
|
+
ty.showToast({
|
|
160
|
+
title: t('t-agent.message.unlike.success'),
|
|
161
|
+
icon: 'none'
|
|
162
|
+
});
|
|
163
|
+
} else {
|
|
164
|
+
ty.showToast({
|
|
165
|
+
title: t('t-agent.unknown-error'),
|
|
166
|
+
icon: 'none'
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
ty.showToast({
|
|
171
|
+
title: (error === null || error === void 0 ? void 0 : error.message) || t('t-agent.unknown-error'),
|
|
172
|
+
icon: 'none'
|
|
173
|
+
});
|
|
174
|
+
}
|
|
160
175
|
}
|
|
161
176
|
});
|
|
162
177
|
break;
|
|
@@ -217,9 +232,11 @@ export function useLongPress() {
|
|
|
217
232
|
isClosing: false,
|
|
218
233
|
menuPosition: adjustedPosition
|
|
219
234
|
});
|
|
220
|
-
ty.
|
|
221
|
-
|
|
222
|
-
|
|
235
|
+
if (ty.getSystemInfoSync().brand !== 'devtools') {
|
|
236
|
+
ty.vibrateShort({
|
|
237
|
+
type: 'light'
|
|
238
|
+
});
|
|
239
|
+
}
|
|
223
240
|
if (e.origin && e.origin.stopPropagation) {
|
|
224
241
|
e.origin.stopPropagation();
|
|
225
242
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "core-js/modules/web.dom-collections.iterator.js";
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
-
export const
|
|
3
|
+
export const useMultiSelectMessage = () => {
|
|
4
4
|
const [select, setSelect] = useState([]);
|
|
5
5
|
const [show, setShow] = useState(false);
|
|
6
6
|
return {
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ declare const _default: {
|
|
|
25
25
|
't-agent.message.action.copy': string;
|
|
26
26
|
't-agent.message.action.delete': string;
|
|
27
27
|
't-agent.message.action.deleteByChannel': string;
|
|
28
|
-
't-agent.message.action.
|
|
28
|
+
't-agent.message.action.multiSelect': string;
|
|
29
29
|
't-agent.message.like.success': string;
|
|
30
30
|
't-agent.message.unlike.success': string;
|
|
31
31
|
't-agent.message.action.like': string;
|
|
@@ -66,6 +66,7 @@ declare const _default: {
|
|
|
66
66
|
't-agent.expand.scene.one-click': string;
|
|
67
67
|
't-agent.expand.scene.auto': string;
|
|
68
68
|
't-agent.expand.no.details': string;
|
|
69
|
+
't-agent.unknown-error': string;
|
|
69
70
|
};
|
|
70
71
|
'zh-Hant': {
|
|
71
72
|
't-agent.build-in.button.create_scene_manually': string;
|
|
@@ -157,7 +158,7 @@ declare const _default: {
|
|
|
157
158
|
't-agent.message.action.copy': string;
|
|
158
159
|
't-agent.message.action.delete': string;
|
|
159
160
|
't-agent.message.action.deleteByChannel': string;
|
|
160
|
-
't-agent.message.action.
|
|
161
|
+
't-agent.message.action.multiSelect': string;
|
|
161
162
|
't-agent.message.like.success': string;
|
|
162
163
|
't-agent.message.unlike.success': string;
|
|
163
164
|
't-agent.message.action.like': string;
|
|
@@ -198,6 +199,7 @@ declare const _default: {
|
|
|
198
199
|
't-agent.expand.scene.one-click': string;
|
|
199
200
|
't-agent.expand.scene.auto': string;
|
|
200
201
|
't-agent.expand.no.details': string;
|
|
202
|
+
't-agent.unknown-error': string;
|
|
201
203
|
};
|
|
202
204
|
ja: {
|
|
203
205
|
't-agent.build-in.button.create_scene_manually': string;
|
package/dist/i18n/strings.js
CHANGED
|
@@ -25,7 +25,7 @@ export default {
|
|
|
25
25
|
't-agent.message.action.copy': '复制消息',
|
|
26
26
|
't-agent.message.action.delete': '删除消息',
|
|
27
27
|
't-agent.message.action.deleteByChannel': '删除所有渠道消息',
|
|
28
|
-
't-agent.message.action.
|
|
28
|
+
't-agent.message.action.multiSelect': '多选',
|
|
29
29
|
't-agent.message.like.success': '点赞成功',
|
|
30
30
|
't-agent.message.unlike.success': '取消点赞成功',
|
|
31
31
|
't-agent.message.action.like': '喜欢消息',
|
|
@@ -65,7 +65,8 @@ export default {
|
|
|
65
65
|
't-agent.expand.scene.rename': '{oldName}改名成{newName}',
|
|
66
66
|
't-agent.expand.scene.one-click': '一键执行',
|
|
67
67
|
't-agent.expand.scene.auto': '自动执行',
|
|
68
|
-
't-agent.expand.no.details': '没有可显示的详情内容'
|
|
68
|
+
't-agent.expand.no.details': '没有可显示的详情内容',
|
|
69
|
+
't-agent.unknown-error': '未知错误'
|
|
69
70
|
},
|
|
70
71
|
'zh-Hant': {
|
|
71
72
|
't-agent.build-in.button.create_scene_manually': '手動創建場景',
|
|
@@ -160,7 +161,7 @@ export default {
|
|
|
160
161
|
't-agent.message.action.copy': 'Copy Message',
|
|
161
162
|
't-agent.message.action.delete': 'Delete Message',
|
|
162
163
|
't-agent.message.action.deleteByChannel': 'Delete All Channel Messages',
|
|
163
|
-
't-agent.message.action.
|
|
164
|
+
't-agent.message.action.multiSelect': 'Multiple Selection',
|
|
164
165
|
't-agent.message.like.success': 'Like Successful',
|
|
165
166
|
't-agent.message.unlike.success': 'Unlike Successful',
|
|
166
167
|
't-agent.message.action.like': 'Like Message',
|
|
@@ -200,7 +201,8 @@ export default {
|
|
|
200
201
|
't-agent.expand.scene.rename': '{oldName} renamed to {newName}',
|
|
201
202
|
't-agent.expand.scene.one-click': 'One-click Execution',
|
|
202
203
|
't-agent.expand.scene.auto': 'Automatic Execution',
|
|
203
|
-
't-agent.expand.no.details': 'No details available'
|
|
204
|
+
't-agent.expand.no.details': 'No details available',
|
|
205
|
+
't-agent.unknown-error': 'Unknown Error'
|
|
204
206
|
},
|
|
205
207
|
ja: {
|
|
206
208
|
't-agent.build-in.button.create_scene_manually': 'シーンを手動で作成',
|
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
-
import "core-js/modules/es.json.stringify.js";
|
|
3
2
|
import "core-js/modules/esnext.iterator.constructor.js";
|
|
4
3
|
import "core-js/modules/esnext.iterator.find.js";
|
|
5
4
|
import "core-js/modules/esnext.iterator.map.js";
|
|
6
5
|
import "core-js/modules/esnext.iterator.some.js";
|
|
7
|
-
import "core-js/modules/web.dom-collections.iterator.js";
|
|
8
6
|
import './index.less';
|
|
9
7
|
import { View } from '@ray-js/components';
|
|
10
|
-
import React, {
|
|
8
|
+
import React, { useCallback, memo } from 'react';
|
|
11
9
|
import { Image } from '@ray-js/ray';
|
|
12
|
-
import { BubbleTileStatus, ChatMessageStatus
|
|
10
|
+
import { BubbleTileStatus, ChatMessageStatus } from '@ray-js/t-agent';
|
|
13
11
|
import TileRender from '../../TileRender';
|
|
14
12
|
import noticeSvg from './notice.svg';
|
|
15
13
|
import noticeWarnSvg from './notice-warn.svg';
|
|
16
14
|
import { useChatAgent, useTranslate, useLongPress, useRenderOptions } from '../../hooks';
|
|
17
15
|
import RollBack from '../WorkflowTile/RollBack';
|
|
18
16
|
const BubbleTile = props => {
|
|
19
|
-
var
|
|
20
|
-
|
|
17
|
+
var _workflowTile$data;
|
|
18
|
+
useChatAgent();
|
|
21
19
|
const {
|
|
22
20
|
renderLongPressAs
|
|
23
21
|
} = useRenderOptions();
|
|
@@ -38,30 +36,6 @@ const BubbleTile = props => {
|
|
|
38
36
|
const bubbleStatus = data.status || BubbleTileStatus.NORMAL;
|
|
39
37
|
const t = useTranslate();
|
|
40
38
|
const loading = status === ChatMessageStatus.START || status === ChatMessageStatus.UPDATING;
|
|
41
|
-
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;
|
|
42
|
-
const [feedbackLoaded, setFeedbackLoaded] = useState(false);
|
|
43
|
-
const [feedbackValue, setFeedbackValue] = useState(null);
|
|
44
|
-
useEffect(() => {
|
|
45
|
-
ty.getStorage({
|
|
46
|
-
key: 'latestMessageFeedbackValue',
|
|
47
|
-
success: res => {
|
|
48
|
-
if (res.data) {
|
|
49
|
-
try {
|
|
50
|
-
const {
|
|
51
|
-
requestId,
|
|
52
|
-
value
|
|
53
|
-
} = safeParseJSON(res.data);
|
|
54
|
-
if (requestId === message.meta.requestId) {
|
|
55
|
-
setFeedbackValue(value);
|
|
56
|
-
}
|
|
57
|
-
} catch (e) {
|
|
58
|
-
// noop
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
setFeedbackLoaded(true);
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
}, []);
|
|
65
39
|
const showInfo = () => {
|
|
66
40
|
if (data.info) {
|
|
67
41
|
ty.showToast({
|
|
@@ -90,12 +64,7 @@ const BubbleTile = props => {
|
|
|
90
64
|
}, [tile]);
|
|
91
65
|
const longPressRes = useLongPress({
|
|
92
66
|
message,
|
|
93
|
-
|
|
94
|
-
// 'copy',
|
|
95
|
-
// 'delete',
|
|
96
|
-
// ...(isAssistantMessage ? ['like', 'unlike', 'deleteByChannel'] : []),
|
|
97
|
-
// ] as ActionType[],
|
|
98
|
-
actions: ['copy', 'multSelect', 'delete'],
|
|
67
|
+
actions: ['copy', 'multiSelect', 'delete', 'like', 'unlike'],
|
|
99
68
|
getMessageContent,
|
|
100
69
|
disabled: loading
|
|
101
70
|
});
|
|
@@ -1,28 +1,22 @@
|
|
|
1
|
+
import './index.less';
|
|
1
2
|
import { Image, View } from '@ray-js/ray';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import rollback from './workflow-rollback.png';
|
|
4
|
-
import {
|
|
5
|
-
import './index.less';
|
|
5
|
+
import { useTileProps } from '../../../hooks';
|
|
6
6
|
export default function RollBack(props) {
|
|
7
7
|
const {
|
|
8
8
|
nodeId
|
|
9
9
|
} = props;
|
|
10
|
-
const
|
|
10
|
+
const {
|
|
11
|
+
emitTileEvent
|
|
12
|
+
} = useTileProps();
|
|
11
13
|
return /*#__PURE__*/React.createElement(View, {
|
|
12
14
|
className: "t-agent-workflow-rollback-tile",
|
|
13
15
|
onClick: async () => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
// domain: 'control',
|
|
19
|
-
// intent: 'backNode',
|
|
20
|
-
// lang,
|
|
21
|
-
// 'back.node.id': nodeId,
|
|
22
|
-
// device_id: undefined,
|
|
23
|
-
// 'text.stream': 'true',
|
|
24
|
-
// 'tts.disable': 'true',
|
|
25
|
-
// });
|
|
16
|
+
emitTileEvent({
|
|
17
|
+
type: 'rollback',
|
|
18
|
+
nodeId
|
|
19
|
+
});
|
|
26
20
|
}
|
|
27
21
|
}, /*#__PURE__*/React.createElement(Image, {
|
|
28
22
|
src: rollback,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ray-js/t-agent-ui-ray",
|
|
3
|
-
"version": "0.2.0-beta-
|
|
3
|
+
"version": "0.2.0-beta-4",
|
|
4
4
|
"author": "Tuya.inc",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"@types/echarts": "^4.9.22",
|
|
41
41
|
"@types/markdown-it": "^14.1.1"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "1728f8a1cac6b2ca53e506e06171808fbf38efdc"
|
|
44
44
|
}
|