@ray-js/t-agent-ui-ray 0.2.2-beta-1 → 0.2.3-beta-1
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 +1 -9
- package/dist/EchartsBlockRender/index.js +8 -10
- package/dist/LazyScrollView/LazyItem/index.d.ts +18 -0
- package/dist/LazyScrollView/LazyItem/index.js +51 -0
- package/dist/LazyScrollView/LazyItem/index.json +3 -0
- package/dist/LazyScrollView/LazyItem/index.tyml +16 -0
- package/dist/LazyScrollView/index.d.ts +26 -0
- package/dist/LazyScrollView/index.js +27 -0
- package/dist/LazyScrollView/index.json +3 -0
- package/dist/LazyScrollView/index.tyml +15 -0
- package/dist/LazyScrollView/lazy-scroll-view.sjs +317 -0
- package/dist/LazyScrollView/weak-ref.sjs +45 -0
- package/dist/MessageInput/MessageInputAIStream/AsrInput.js +2 -2
- package/dist/MessageInput/MessageInputAIStream/Waveform/index.d.ts +9 -0
- package/dist/MessageInput/MessageInputAIStream/Waveform/index.js +52 -0
- package/dist/MessageInput/MessageInputAIStream/Waveform/index.json +3 -0
- package/dist/MessageInput/MessageInputAIStream/Waveform/index.tyml +9 -0
- package/dist/MessageInput/MessageInputAIStream/index.d.ts +1 -0
- package/dist/MessageInput/MessageInputAIStream/index.js +2 -4
- package/dist/MessageList/ScrollBottomView.d.ts +21 -20
- package/dist/MessageList/ScrollBottomView.js +59 -135
- package/dist/MessageList/index.d.ts +6 -8
- package/dist/MessageList/index.js +91 -11
- package/dist/MessageList/index.less +1 -2
- package/dist/MessageRender/index.d.ts +6 -1
- package/dist/MessageRender/index.js +49 -17
- package/dist/MessageRender/index.less +5 -3
- package/dist/TileRender/index.d.ts +2 -1
- package/dist/TileRender/index.js +3 -3
- package/dist/contexts.d.ts +1 -5
- package/dist/hooks/context.d.ts +0 -2
- package/dist/hooks/context.js +0 -6
- package/dist/tiles/BubbleTile/index.js +2 -1
- package/dist/tiles/CardTile/index.less +1 -1
- package/dist/tiles/ExecuteCardTile/index.d.ts +1 -8
- package/dist/tiles/ExecuteCardTile/index.js +8 -15
- package/dist/tiles/ExecuteCardTile/index.less +177 -151
- package/dist/tiles/OperateCardTile/Expand.d.ts +2 -1
- package/dist/tiles/OperateCardTile/Expand.js +4 -2
- package/dist/tiles/OperateCardTile/index.d.ts +2 -6
- package/dist/tiles/OperateCardTile/index.js +6 -9
- package/dist/tiles/types.d.ts +31 -0
- package/dist/tiles/types.js +5 -0
- package/dist/utils/index.js +1 -1
- package/dist/utils/object.d.ts +8 -0
- package/dist/utils/object.js +57 -0
- package/package.json +2 -2
- package/dist/MessageInput/MessageInputAIStream/WaveformVisualizer.d.ts +0 -4
- package/dist/MessageInput/MessageInputAIStream/WaveformVisualizer.js +0 -54
- package/dist/MessageList/LazyView.d.ts +0 -9
- package/dist/MessageList/LazyView.js +0 -57
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
2
|
+
import "core-js/modules/esnext.iterator.map.js";
|
|
3
|
+
import { systemInfo } from '../../../utils';
|
|
4
|
+
|
|
5
|
+
// eslint-disable-next-line no-undef
|
|
6
|
+
Component({
|
|
7
|
+
options: {
|
|
8
|
+
styleIsolation: 'shared'
|
|
9
|
+
},
|
|
10
|
+
properties: {
|
|
11
|
+
amplitudeCount: {
|
|
12
|
+
type: Number,
|
|
13
|
+
value: 60
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
data: {
|
|
17
|
+
values: []
|
|
18
|
+
},
|
|
19
|
+
lifetimes: {
|
|
20
|
+
attached() {
|
|
21
|
+
// eslint-disable-next-line no-undef
|
|
22
|
+
ty.aistream.onRecordAmplitudes(this.update);
|
|
23
|
+
},
|
|
24
|
+
detached() {
|
|
25
|
+
// eslint-disable-next-line no-undef
|
|
26
|
+
ty.aistream.offRecordAmplitudes(this.update);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
methods: {
|
|
30
|
+
update(body) {
|
|
31
|
+
this.setData({
|
|
32
|
+
// 将数值映射到高度范围(0-1)
|
|
33
|
+
values: body.amplitudes.map(item => item > 1 ? 1 : item * 100)
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
observers: {
|
|
38
|
+
amplitudeCount(value) {
|
|
39
|
+
if (systemInfo.brand !== 'devtools') {
|
|
40
|
+
// eslint-disable-next-line no-undef
|
|
41
|
+
ty.aistream.registerRecordAmplitudes({
|
|
42
|
+
count: value
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
this.setData({
|
|
46
|
+
values: Array.from({
|
|
47
|
+
length: value
|
|
48
|
+
}, () => 0)
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
@@ -19,7 +19,6 @@ import logger from '../../logger';
|
|
|
19
19
|
import { systemInfo } from '../../utils';
|
|
20
20
|
import { useSleep } from '../../hooks/useSleep';
|
|
21
21
|
import { useStableCallback } from '../../hooks/useStableCallback';
|
|
22
|
-
const AMPLITUDE_COUNT = 60;
|
|
23
22
|
export let MessageInputState = /*#__PURE__*/function (MessageInputState) {
|
|
24
23
|
MessageInputState["PENDING"] = "pending";
|
|
25
24
|
MessageInputState["RECORDING"] = "recording";
|
|
@@ -320,7 +319,7 @@ export default function MessageInputAIStream(props) {
|
|
|
320
319
|
container = /*#__PURE__*/React.createElement(AsrInput, {
|
|
321
320
|
responding: canAbort,
|
|
322
321
|
disabled: state.current === MessageInputState.ABORTING,
|
|
323
|
-
amplitudeCount:
|
|
322
|
+
amplitudeCount: props.amplitudeCount || 60,
|
|
324
323
|
recording: state.current === MessageInputState.RECORDING,
|
|
325
324
|
onRecord: async () => {
|
|
326
325
|
logger.debug('MessageInputAIStream', 'AsrInput onRecord');
|
|
@@ -406,8 +405,7 @@ export default function MessageInputAIStream(props) {
|
|
|
406
405
|
setText('');
|
|
407
406
|
const inputBlocks = [...attachmentInput.blocks, {
|
|
408
407
|
type: 'audio',
|
|
409
|
-
audio_emitter: emitter
|
|
410
|
-
amplitude_count: AMPLITUDE_COUNT
|
|
408
|
+
audio_emitter: emitter
|
|
411
409
|
}];
|
|
412
410
|
try {
|
|
413
411
|
logger.debug('MessageInputAIStream', 'pushInputBlocks start');
|
|
@@ -1,46 +1,47 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { ScrollEventDetail } from '../LazyScrollView';
|
|
3
|
+
interface ScrollBottomViewOptions {
|
|
4
|
+
scrollViewId?: string;
|
|
5
|
+
onScroll?: (event: {
|
|
6
|
+
detail: ScrollEventDetail;
|
|
7
|
+
}) => void;
|
|
8
|
+
tick: string;
|
|
9
|
+
loadedPromise?: Promise<void>;
|
|
4
10
|
}
|
|
5
|
-
export declare function useScrollBottomView(
|
|
11
|
+
export declare function useScrollBottomView(options: ScrollBottomViewOptions): {
|
|
6
12
|
scrollToBottom: ({ animation, follow }: {
|
|
7
13
|
animation?: boolean | undefined;
|
|
8
14
|
follow?: boolean | undefined;
|
|
9
|
-
}) =>
|
|
15
|
+
}) => Promise<boolean>;
|
|
10
16
|
scrollViewLoading: boolean;
|
|
11
17
|
scrollIntoViewId: string;
|
|
12
|
-
contentViewProps: {
|
|
13
|
-
contentViewId: string;
|
|
14
|
-
};
|
|
15
18
|
scrollViewProps: {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
scrollViewId: string;
|
|
20
|
+
bindscroll: (event: {
|
|
21
|
+
detail: ScrollEventDetail;
|
|
22
|
+
}) => void;
|
|
23
|
+
binddone: (event: {
|
|
20
24
|
detail: {
|
|
21
|
-
|
|
22
|
-
scrollHeight: number;
|
|
23
|
-
deltaY: number;
|
|
25
|
+
scrollIntoView: string;
|
|
24
26
|
};
|
|
25
|
-
currentTarget: any;
|
|
26
|
-
timeStamp: number;
|
|
27
27
|
}) => void;
|
|
28
28
|
scrollWithAnimation: boolean;
|
|
29
29
|
scrollIntoView: string;
|
|
30
30
|
};
|
|
31
31
|
};
|
|
32
|
-
interface Props {
|
|
32
|
+
interface Props extends ScrollBottomViewOptions {
|
|
33
|
+
scrollViewId?: string;
|
|
33
34
|
className?: string;
|
|
34
35
|
contentClassName?: string;
|
|
35
36
|
children: React.ReactNode;
|
|
36
37
|
style?: React.CSSProperties;
|
|
37
|
-
|
|
38
|
+
hideScrollbar?: boolean;
|
|
38
39
|
}
|
|
39
|
-
interface
|
|
40
|
+
export interface ScrollBottomViewRef {
|
|
40
41
|
scrollToBottom: (options?: {
|
|
41
42
|
animation?: boolean;
|
|
42
43
|
follow?: boolean;
|
|
43
44
|
}) => void;
|
|
44
45
|
}
|
|
45
|
-
declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<Props & React.RefAttributes<
|
|
46
|
+
declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<Props & React.RefAttributes<ScrollBottomViewRef>>>;
|
|
46
47
|
export default _default;
|
|
@@ -1,178 +1,95 @@
|
|
|
1
|
-
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
-
import "core-js/modules/es.regexp.exec.js";
|
|
3
1
|
import "core-js/modules/web.dom-collections.iterator.js";
|
|
4
2
|
import React, { useCallback, useEffect, useRef, useState, forwardRef, useImperativeHandle } from 'react';
|
|
5
3
|
import { useSleep } from '../hooks/useSleep';
|
|
6
4
|
import { generateId } from '@ray-js/t-agent';
|
|
7
|
-
import { useOnEvent, useTick } from '../hooks';
|
|
8
|
-
import { ScrollView } from '@ray-js/ray';
|
|
9
5
|
import { View } from '@ray-js/components';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
6
|
+
import LazyScrollView from '../LazyScrollView';
|
|
7
|
+
import { createResolvable } from '../utils/object';
|
|
8
|
+
export function useScrollBottomView(options) {
|
|
9
|
+
const [scrollViewId] = useState(() => options.scrollViewId || "ScrollView-".concat(generateId()));
|
|
10
|
+
const {
|
|
11
|
+
tick,
|
|
12
|
+
loadedPromise
|
|
13
|
+
} = options;
|
|
14
14
|
const [ready, setReady] = useState(false);
|
|
15
15
|
const [scrollIntoViewFlag, setScrollIntoViewIdFlag] = useState(() => "".concat(Date.now()));
|
|
16
16
|
const [scrollWithAnimation, setScrollWithAnimation] = useState(false);
|
|
17
|
+
const prefix = "".concat(scrollViewId, "-toView-").concat(tick, "-");
|
|
18
|
+
const scrollIntoViewId = "".concat(prefix).concat(scrollIntoViewFlag);
|
|
17
19
|
const ref = useRef({
|
|
18
|
-
clientHeight: 0,
|
|
19
20
|
needFollow: true,
|
|
20
21
|
following: false,
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
resolvableMap: {},
|
|
23
|
+
prefix
|
|
23
24
|
});
|
|
25
|
+
ref.current.prefix = prefix;
|
|
24
26
|
const sleep = useSleep();
|
|
25
|
-
const makeScrollBottomEvent = useCallback(() => {
|
|
26
|
-
if (ref.current.lastScrollEvent) {
|
|
27
|
-
const {
|
|
28
|
-
detail,
|
|
29
|
-
currentTarget,
|
|
30
|
-
target
|
|
31
|
-
} = ref.current.lastScrollEvent;
|
|
32
|
-
const {
|
|
33
|
-
scrollTop,
|
|
34
|
-
scrollHeight
|
|
35
|
-
} = detail;
|
|
36
|
-
const newDetail = {
|
|
37
|
-
deltaX: 0,
|
|
38
|
-
scrollLeft: 0,
|
|
39
|
-
scrollTop: scrollHeight - ref.current.clientHeight,
|
|
40
|
-
scrollWidth: detail.scrollWidth,
|
|
41
|
-
scrollHeight,
|
|
42
|
-
deltaY: scrollTop - (scrollHeight - ref.current.clientHeight)
|
|
43
|
-
};
|
|
44
|
-
if (scrollTop === newDetail.scrollTop) {
|
|
45
|
-
// 如果滚动位置没有变化,则不触发事件
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
type: 'scroll',
|
|
50
|
-
timeStamp: Date.now() - ref.current.startTimestamp,
|
|
51
|
-
currentTarget,
|
|
52
|
-
target,
|
|
53
|
-
stopPropagation: () => {},
|
|
54
|
-
detail: newDetail
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
return null;
|
|
58
|
-
}, []);
|
|
59
27
|
const scrollToBottom = useCallback(_ref => {
|
|
60
28
|
let {
|
|
61
29
|
animation,
|
|
62
30
|
follow
|
|
63
31
|
} = _ref;
|
|
32
|
+
let promise = Promise.resolve(false);
|
|
33
|
+
const scroll = () => {
|
|
34
|
+
const flag = "".concat(Date.now());
|
|
35
|
+
const id = "".concat(ref.current.prefix).concat(flag);
|
|
36
|
+
setScrollIntoViewIdFlag(flag);
|
|
37
|
+
const r = createResolvable();
|
|
38
|
+
ref.current.resolvableMap[id] = r;
|
|
39
|
+
ref.current.needFollow = true;
|
|
40
|
+
promise = r.promise.then(() => true);
|
|
41
|
+
};
|
|
64
42
|
if (follow) {
|
|
65
43
|
if (ref.current.needFollow) {
|
|
66
|
-
|
|
67
|
-
ref.current.needFollow = true;
|
|
68
|
-
const event = makeScrollBottomEvent();
|
|
69
|
-
if (event) {
|
|
70
|
-
sleep(10).then(() => {
|
|
71
|
-
var _params$onScroll;
|
|
72
|
-
params === null || params === void 0 || (_params$onScroll = params.onScroll) === null || _params$onScroll === void 0 || _params$onScroll.call(params, event);
|
|
73
|
-
});
|
|
74
|
-
}
|
|
44
|
+
scroll();
|
|
75
45
|
}
|
|
76
46
|
} else {
|
|
77
47
|
if (animation) {
|
|
78
48
|
setScrollWithAnimation(true);
|
|
79
49
|
}
|
|
80
|
-
|
|
81
|
-
setScrollIntoViewIdFlag("".concat(Date.now()));
|
|
82
|
-
const event = makeScrollBottomEvent();
|
|
83
|
-
if (event) {
|
|
84
|
-
sleep(100).then(() => {
|
|
85
|
-
var _params$onScroll2;
|
|
86
|
-
params === null || params === void 0 || (_params$onScroll2 = params.onScroll) === null || _params$onScroll2 === void 0 || _params$onScroll2.call(params, event);
|
|
87
|
-
});
|
|
88
|
-
}
|
|
50
|
+
scroll();
|
|
89
51
|
if (animation) {
|
|
90
52
|
sleep(10).then(() => {
|
|
91
53
|
setScrollWithAnimation(false);
|
|
92
54
|
});
|
|
93
55
|
}
|
|
94
56
|
}
|
|
57
|
+
return promise;
|
|
58
|
+
}, []);
|
|
59
|
+
const onDone = useCallback(event => {
|
|
60
|
+
const id = event.detail.scrollIntoView;
|
|
61
|
+
if (id && ref.current.resolvableMap[id]) {
|
|
62
|
+
ref.current.resolvableMap[id].resolve();
|
|
63
|
+
delete ref.current.resolvableMap[id];
|
|
64
|
+
}
|
|
95
65
|
}, []);
|
|
96
66
|
useEffect(() => {
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
// @ts-ignore
|
|
100
|
-
const query = ty.createSelectorQuery();
|
|
101
|
-
query.select("#".concat(scrollViewId)).fields({
|
|
102
|
-
dataset: true
|
|
103
|
-
}, res => {
|
|
104
|
-
resolve(res.dataset.renderTick);
|
|
105
|
-
}).exec();
|
|
106
|
-
});
|
|
107
|
-
};
|
|
108
|
-
const getClientHeight = () => {
|
|
109
|
-
return new Promise(resolve => {
|
|
110
|
-
// @ts-ignore
|
|
111
|
-
const query = ty.createSelectorQuery();
|
|
112
|
-
query.select("#".concat(scrollViewId)).fields({
|
|
113
|
-
size: true
|
|
114
|
-
}, res => {
|
|
115
|
-
resolve(res.height);
|
|
116
|
-
}).exec();
|
|
117
|
-
});
|
|
118
|
-
};
|
|
119
|
-
const scrollViewInterval = setInterval(() => {
|
|
120
|
-
// 外部容器高度变化不频繁,1 秒查一次
|
|
121
|
-
getClientHeight().then(height => {
|
|
122
|
-
ref.current.clientHeight = height;
|
|
123
|
-
});
|
|
124
|
-
}, 1000);
|
|
125
|
-
|
|
126
|
-
// 初始化好 clientHeight
|
|
127
|
-
(async () => {
|
|
128
|
-
let tick = await getDomTick();
|
|
129
|
-
while (tick <= 0) {
|
|
130
|
-
await sleep(1);
|
|
131
|
-
tick = await getDomTick();
|
|
132
|
-
}
|
|
133
|
-
return tick;
|
|
134
|
-
})().then(() => getClientHeight()).then(height => {
|
|
135
|
-
console.log('scrollView clientHeight', height);
|
|
136
|
-
ref.current.clientHeight = height;
|
|
137
|
-
})
|
|
67
|
+
const promise = loadedPromise || Promise.resolve();
|
|
68
|
+
promise
|
|
138
69
|
// 渲染完毕后,开始滚动到最底部
|
|
139
70
|
.then(() => scrollToBottom({}))
|
|
140
71
|
// 展示列表
|
|
141
72
|
.then(() => setReady(true));
|
|
142
|
-
return () => {
|
|
143
|
-
clearInterval(scrollViewInterval);
|
|
144
|
-
};
|
|
145
73
|
}, [scrollViewId]);
|
|
146
|
-
let scrollIntoViewId = "".concat(scrollViewId, "-toView-").concat(tickValue, "-").concat(scrollIntoViewFlag);
|
|
147
|
-
if (!ref.current.needFollow) {
|
|
148
|
-
scrollIntoViewId = null;
|
|
149
|
-
}
|
|
150
74
|
return {
|
|
151
75
|
scrollToBottom,
|
|
152
76
|
scrollViewLoading: !ready,
|
|
153
77
|
scrollIntoViewId,
|
|
154
|
-
contentViewProps: {
|
|
155
|
-
contentViewId
|
|
156
|
-
},
|
|
157
78
|
scrollViewProps: {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
onScroll: event => {
|
|
162
|
-
var _params$onScroll3;
|
|
163
|
-
ref.current.lastScrollEvent = event;
|
|
79
|
+
scrollViewId,
|
|
80
|
+
bindscroll: event => {
|
|
81
|
+
var _options$onScroll;
|
|
164
82
|
const {
|
|
165
83
|
scrollTop,
|
|
166
|
-
scrollHeight
|
|
84
|
+
scrollHeight,
|
|
85
|
+
clientHeight
|
|
167
86
|
} = event.detail;
|
|
168
|
-
ref.current.needFollow = scrollHeight - scrollTop <=
|
|
169
|
-
|
|
170
|
-
if (!ref.current.startTimestamp) {
|
|
171
|
-
ref.current.startTimestamp = Date.now() - event.timeStamp;
|
|
172
|
-
}
|
|
87
|
+
ref.current.needFollow = scrollHeight - scrollTop <= clientHeight + 25;
|
|
88
|
+
options === null || options === void 0 || (_options$onScroll = options.onScroll) === null || _options$onScroll === void 0 || _options$onScroll.call(options, event);
|
|
173
89
|
},
|
|
90
|
+
binddone: onDone,
|
|
174
91
|
scrollWithAnimation,
|
|
175
|
-
scrollIntoView: scrollIntoViewId
|
|
92
|
+
scrollIntoView: ref.current.needFollow ? scrollIntoViewId : ''
|
|
176
93
|
}
|
|
177
94
|
};
|
|
178
95
|
}
|
|
@@ -181,21 +98,28 @@ const ScrollBottomView = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
181
98
|
scrollToBottom,
|
|
182
99
|
scrollViewProps,
|
|
183
100
|
scrollIntoViewId,
|
|
184
|
-
contentViewProps,
|
|
185
101
|
scrollViewLoading
|
|
186
102
|
} = useScrollBottomView({
|
|
187
|
-
|
|
103
|
+
scrollViewId: props.scrollViewId,
|
|
104
|
+
onScroll: props.onScroll,
|
|
105
|
+
tick: props.tick,
|
|
106
|
+
loadedPromise: props.loadedPromise
|
|
188
107
|
});
|
|
189
|
-
useOnEvent('scrollToBottom', scrollToBottom);
|
|
190
108
|
useImperativeHandle(ref, () => ({
|
|
191
109
|
scrollToBottom
|
|
192
110
|
}), [scrollToBottom]);
|
|
193
|
-
return /*#__PURE__*/React.createElement(
|
|
194
|
-
className: "".concat(props.className || '', " ").concat(scrollViewLoading ? 't-agent-message-list-
|
|
195
|
-
style: props.style
|
|
196
|
-
|
|
111
|
+
return /*#__PURE__*/React.createElement(LazyScrollView, {
|
|
112
|
+
className: "".concat(props.className || '', " ").concat(scrollViewLoading ? 't-agent-message-list-loading' : ''),
|
|
113
|
+
style: props.style,
|
|
114
|
+
hideScrollbar: props.hideScrollbar || false,
|
|
115
|
+
bindscroll: scrollViewProps.bindscroll,
|
|
116
|
+
binddone: scrollViewProps.binddone,
|
|
117
|
+
scrollViewId: scrollViewProps.scrollViewId,
|
|
118
|
+
scrollWithAnimation: scrollViewProps.scrollWithAnimation,
|
|
119
|
+
scrollIntoView: scrollViewProps.scrollIntoView
|
|
120
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
197
121
|
className: "".concat(props.contentClassName || '')
|
|
198
|
-
}
|
|
122
|
+
}, props.children, /*#__PURE__*/React.createElement(View, {
|
|
199
123
|
id: scrollIntoViewId
|
|
200
124
|
})));
|
|
201
125
|
});
|
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
import './index.less';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
interface RenderPartOptions {
|
|
4
|
+
notifyHeightChanged: () => void;
|
|
5
|
+
}
|
|
3
6
|
interface Props {
|
|
4
7
|
className?: string;
|
|
5
8
|
style?: React.CSSProperties;
|
|
6
9
|
wrapperClassName?: string;
|
|
7
10
|
wrapperStyle?: React.CSSProperties;
|
|
8
|
-
renderTop?: React.ReactNode;
|
|
9
|
-
renderBottom?: React.ReactNode;
|
|
11
|
+
renderTop?: React.ReactNode | ((options: RenderPartOptions) => React.ReactNode);
|
|
12
|
+
renderBottom?: React.ReactNode | ((options: RenderPartOptions) => React.ReactNode);
|
|
10
13
|
onScroll?: (event: any) => void;
|
|
14
|
+
hideScrollbar?: boolean;
|
|
11
15
|
roleSide?: {
|
|
12
16
|
user?: 'start' | 'end' | string;
|
|
13
17
|
assistant?: 'start' | 'end' | string;
|
|
14
18
|
[key: string]: 'start' | 'end' | string;
|
|
15
19
|
};
|
|
16
|
-
historyLimit?: {
|
|
17
|
-
/** 历史消息数量限制 */
|
|
18
|
-
count: number;
|
|
19
|
-
/** 超过限制时显示的提示文本 */
|
|
20
|
-
tipText: string;
|
|
21
|
-
};
|
|
22
20
|
}
|
|
23
21
|
declare const MessageList: (props: Props) => React.JSX.Element;
|
|
24
22
|
export default MessageList;
|
|
@@ -3,11 +3,15 @@ import "core-js/modules/esnext.iterator.map.js";
|
|
|
3
3
|
import "core-js/modules/web.dom-collections.iterator.js";
|
|
4
4
|
import './index.less';
|
|
5
5
|
import { View } from '@ray-js/components';
|
|
6
|
-
import React from 'react';
|
|
6
|
+
import React, { useRef, useState } from 'react';
|
|
7
7
|
import MessageRender from '../MessageRender';
|
|
8
|
-
import { useAgentMessage, useAgentSessionValue } from '../hooks';
|
|
8
|
+
import { useAgentMessage, useAgentSessionValue, useKeyboardHeight, useOnEvent } from '../hooks';
|
|
9
9
|
import ScrollBottomView from './ScrollBottomView';
|
|
10
10
|
import { useStableCallback } from '../hooks/useStableCallback';
|
|
11
|
+
import { createResolvable, objectsId } from '../utils/object';
|
|
12
|
+
import { generateId } from '@ray-js/t-agent';
|
|
13
|
+
import LazyItem from '../LazyScrollView/LazyItem';
|
|
14
|
+
import { useSleep } from '../hooks/useSleep';
|
|
11
15
|
const MessageList = props => {
|
|
12
16
|
const {
|
|
13
17
|
className,
|
|
@@ -15,26 +19,80 @@ const MessageList = props => {
|
|
|
15
19
|
style,
|
|
16
20
|
wrapperClassName,
|
|
17
21
|
wrapperStyle,
|
|
18
|
-
|
|
22
|
+
hideScrollbar
|
|
19
23
|
} = props;
|
|
24
|
+
const [scrollViewId] = useState(() => "message-list-scroll-".concat(generateId()));
|
|
20
25
|
const messages = useAgentMessage();
|
|
21
26
|
const onScroll = useStableCallback(props.onScroll);
|
|
22
27
|
const [showSelect] = useAgentSessionValue('UIRay.multiSelect.show');
|
|
28
|
+
const keyboardHeight = useKeyboardHeight();
|
|
29
|
+
const ref = useRef();
|
|
30
|
+
if (!ref.current) {
|
|
31
|
+
ref.current = {
|
|
32
|
+
loaded: createResolvable()
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const scrollRef = useRef(null);
|
|
36
|
+
useOnEvent('scrollToBottom', payload => {
|
|
37
|
+
if (scrollRef.current) {
|
|
38
|
+
scrollRef.current.scrollToBottom(payload);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
useOnEvent('messageListInit', () => {
|
|
42
|
+
ref.current.loaded.resolve();
|
|
43
|
+
});
|
|
44
|
+
const [_tick, setTick] = useState(() => "".concat(Math.random()));
|
|
45
|
+
const tick = objectsId(messages, _tick, keyboardHeight);
|
|
46
|
+
const notifyHeightChanged = useStableCallback(() => {
|
|
47
|
+
setTick("".concat(Math.random()));
|
|
48
|
+
});
|
|
49
|
+
const [tickTop, setTickTop] = useState(() => "".concat(Math.random()));
|
|
50
|
+
const notifyHeightChangedTop = useStableCallback(() => {
|
|
51
|
+
notifyHeightChanged();
|
|
52
|
+
setTickTop("".concat(Math.random()));
|
|
53
|
+
});
|
|
54
|
+
const [tickBottom, setTickBottom] = useState(() => "".concat(Math.random()));
|
|
55
|
+
const notifyHeightChangedEnd = useStableCallback(() => {
|
|
56
|
+
notifyHeightChanged();
|
|
57
|
+
setTickBottom("".concat(Math.random()));
|
|
58
|
+
});
|
|
59
|
+
const showMapRef = useRef({
|
|
60
|
+
map: {},
|
|
61
|
+
pending: false
|
|
62
|
+
});
|
|
63
|
+
const [, forceUpdate] = useState(0);
|
|
64
|
+
const sleep = useSleep();
|
|
65
|
+
const top = typeof props.renderTop === 'function' ? props.renderTop({
|
|
66
|
+
notifyHeightChanged: notifyHeightChangedTop
|
|
67
|
+
}) : props.renderTop;
|
|
68
|
+
const bottom = typeof props.renderBottom === 'function' ? props.renderBottom({
|
|
69
|
+
notifyHeightChanged: notifyHeightChangedEnd
|
|
70
|
+
}) : props.renderBottom;
|
|
23
71
|
return /*#__PURE__*/React.createElement(View, {
|
|
24
72
|
className: "t-agent-message-list ".concat(wrapperClassName || ''),
|
|
25
73
|
"data-testid": "t-agent-message-list",
|
|
26
74
|
style: wrapperStyle,
|
|
27
75
|
id: "message-list"
|
|
28
76
|
}, /*#__PURE__*/React.createElement(ScrollBottomView, {
|
|
77
|
+
tick: tick,
|
|
78
|
+
scrollViewId: scrollViewId,
|
|
79
|
+
ref: scrollRef,
|
|
29
80
|
className: "".concat(className || '', " t-agent-message-list-scroll"),
|
|
30
81
|
contentClassName: "t-agent-message-list-scroll-content",
|
|
31
82
|
style: style,
|
|
32
|
-
onScroll: onScroll
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
},
|
|
83
|
+
onScroll: onScroll,
|
|
84
|
+
hideScrollbar: hideScrollbar,
|
|
85
|
+
loadedPromise: ref.current.loaded.promise
|
|
86
|
+
}, /*#__PURE__*/React.createElement(LazyItem, {
|
|
87
|
+
scrollViewId: scrollViewId,
|
|
88
|
+
itemId: "".concat(scrollViewId, "-top"),
|
|
89
|
+
key: "".concat(scrollViewId, "-top"),
|
|
90
|
+
update: tickTop,
|
|
91
|
+
ready: true,
|
|
92
|
+
index: 0
|
|
93
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
36
94
|
className: "t-agent-message-list-padding-start"
|
|
37
|
-
}),
|
|
95
|
+
}), top), messages.map((msg, index) => {
|
|
38
96
|
let side = roleSide === null || roleSide === void 0 ? void 0 : roleSide[msg.role];
|
|
39
97
|
if (!side) {
|
|
40
98
|
side = msg.role === 'user' ? 'end' : 'start';
|
|
@@ -45,10 +103,32 @@ const MessageList = props => {
|
|
|
45
103
|
key: msg.id,
|
|
46
104
|
message: msg,
|
|
47
105
|
isLatestMessage: isLatestMessage,
|
|
48
|
-
side: side
|
|
106
|
+
side: side,
|
|
107
|
+
notifyHeightChanged: notifyHeightChanged,
|
|
108
|
+
scrollViewId: scrollViewId,
|
|
109
|
+
index: index + 1,
|
|
110
|
+
show: showMapRef.current.map[msg.id] == null ? true : showMapRef.current.map[msg.id],
|
|
111
|
+
onShowChange: show => {
|
|
112
|
+
showMapRef.current.map[msg.id] = show;
|
|
113
|
+
if (showMapRef.current.pending) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
showMapRef.current.pending = true;
|
|
117
|
+
sleep(100).then(() => {
|
|
118
|
+
showMapRef.current.pending = false;
|
|
119
|
+
forceUpdate(Math.random());
|
|
120
|
+
});
|
|
121
|
+
}
|
|
49
122
|
});
|
|
50
|
-
}),
|
|
123
|
+
}), /*#__PURE__*/React.createElement(LazyItem, {
|
|
124
|
+
scrollViewId: scrollViewId,
|
|
125
|
+
itemId: "".concat(scrollViewId, "-bottom"),
|
|
126
|
+
key: "".concat(scrollViewId, "-bottom"),
|
|
127
|
+
update: tickBottom,
|
|
128
|
+
ready: true,
|
|
129
|
+
index: messages.length + 1
|
|
130
|
+
}, bottom, /*#__PURE__*/React.createElement(View, {
|
|
51
131
|
className: "t-agent-message-list-padding"
|
|
52
|
-
})));
|
|
132
|
+
}))));
|
|
53
133
|
};
|
|
54
134
|
export default MessageList;
|
|
@@ -6,6 +6,11 @@ interface Props {
|
|
|
6
6
|
isLatestMessage: boolean;
|
|
7
7
|
side: 'start' | 'end' | string;
|
|
8
8
|
showSelect?: boolean;
|
|
9
|
+
notifyHeightChanged: () => void;
|
|
10
|
+
scrollViewId?: string;
|
|
11
|
+
index: number;
|
|
12
|
+
onShowChange?: (show: boolean) => void;
|
|
13
|
+
show?: boolean;
|
|
9
14
|
}
|
|
10
|
-
export default function MessageRender({ message, isLatestMessage, side, showSelect }: Props): React.JSX.Element;
|
|
15
|
+
export default function MessageRender({ message, isLatestMessage, side, showSelect, notifyHeightChanged, scrollViewId, index, onShowChange, show, }: Props): React.JSX.Element;
|
|
11
16
|
export {};
|