@ray-js/t-agent-ui-ray 0.2.2-beta-2 → 0.2.3-beta-2

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.
Files changed (45) hide show
  1. package/dist/ChatContainer/index.js +1 -9
  2. package/dist/EchartsBlockRender/index.js +8 -10
  3. package/dist/LazyScrollView/LazyItem/index.d.ts +18 -0
  4. package/dist/LazyScrollView/LazyItem/index.js +51 -0
  5. package/dist/LazyScrollView/LazyItem/index.json +3 -0
  6. package/dist/LazyScrollView/LazyItem/index.tyml +16 -0
  7. package/dist/LazyScrollView/index.d.ts +26 -0
  8. package/dist/LazyScrollView/index.js +27 -0
  9. package/dist/LazyScrollView/index.json +3 -0
  10. package/dist/LazyScrollView/index.tyml +15 -0
  11. package/dist/LazyScrollView/lazy-scroll-view.sjs +317 -0
  12. package/dist/LazyScrollView/weak-ref.sjs +45 -0
  13. package/dist/MessageInput/MessageInputAIStream/AsrInput.js +2 -2
  14. package/dist/MessageInput/MessageInputAIStream/Waveform/index.d.ts +9 -0
  15. package/dist/MessageInput/MessageInputAIStream/Waveform/index.js +52 -0
  16. package/dist/MessageInput/MessageInputAIStream/Waveform/index.json +3 -0
  17. package/dist/MessageInput/MessageInputAIStream/Waveform/index.tyml +9 -0
  18. package/dist/MessageInput/MessageInputAIStream/index.d.ts +1 -0
  19. package/dist/MessageInput/MessageInputAIStream/index.js +2 -4
  20. package/dist/MessageList/ScrollBottomView.d.ts +20 -20
  21. package/dist/MessageList/ScrollBottomView.js +59 -138
  22. package/dist/MessageList/index.d.ts +5 -8
  23. package/dist/MessageList/index.js +89 -11
  24. package/dist/MessageList/index.less +1 -2
  25. package/dist/MessageRender/index.d.ts +6 -1
  26. package/dist/MessageRender/index.js +49 -17
  27. package/dist/MessageRender/index.less +4 -3
  28. package/dist/TileRender/index.d.ts +2 -1
  29. package/dist/TileRender/index.js +3 -3
  30. package/dist/contexts.d.ts +1 -5
  31. package/dist/hooks/context.d.ts +0 -2
  32. package/dist/hooks/context.js +0 -6
  33. package/dist/tiles/BubbleTile/index.js +2 -1
  34. package/dist/tiles/CardTile/index.less +1 -1
  35. package/dist/tiles/ExecuteCardTile/index.js +2 -1
  36. package/dist/tiles/OperateCardTile/Expand.d.ts +2 -1
  37. package/dist/tiles/OperateCardTile/Expand.js +4 -2
  38. package/dist/tiles/OperateCardTile/index.js +5 -6
  39. package/dist/utils/object.d.ts +8 -0
  40. package/dist/utils/object.js +57 -0
  41. package/package.json +2 -2
  42. package/dist/MessageInput/MessageInputAIStream/WaveformVisualizer.d.ts +0 -4
  43. package/dist/MessageInput/MessageInputAIStream/WaveformVisualizer.js +0 -54
  44. package/dist/MessageList/LazyView.d.ts +0 -9
  45. 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
+ });
@@ -0,0 +1,3 @@
1
+ {
2
+ "component": true
3
+ }
@@ -0,0 +1,9 @@
1
+ <view
2
+ class="t-agent-message-input-waveform-container"
3
+ >
4
+ <view
5
+ ty:for="{{values}}"
6
+ class="t-agent-message-input-waveform-bar"
7
+ style="height: {{item}}%; animation-delay: {{index * 10}}ms;"
8
+ ></view>
9
+ </view>
@@ -15,6 +15,7 @@ interface Props {
15
15
  maxTextLength?: number;
16
16
  maxAudioMs?: number;
17
17
  onStateChange?: (state: MessageInputState) => void;
18
+ amplitudeCount?: number;
18
19
  }
19
20
  export declare const enum MessageInputState {
20
21
  PENDING = "pending",
@@ -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: AMPLITUDE_COUNT,
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,47 +1,47 @@
1
1
  import React from 'react';
2
- interface ScrollBottomViewParams {
3
- onScroll?: (event: any) => void;
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(params: ScrollBottomViewParams): {
11
+ export declare function useScrollBottomView(options: ScrollBottomViewOptions): {
6
12
  scrollToBottom: ({ animation, follow }: {
7
13
  animation?: boolean | undefined;
8
14
  follow?: boolean | undefined;
9
- }) => void;
15
+ }) => Promise<boolean>;
10
16
  scrollViewLoading: boolean;
11
17
  scrollIntoViewId: string;
12
- contentViewProps: {
13
- contentViewId: string;
14
- };
15
18
  scrollViewProps: {
16
- 'data-render-tick': number;
17
- id: string;
18
- scrollY: boolean;
19
- onScroll: (event: {
19
+ scrollViewId: string;
20
+ bindscroll: (event: {
21
+ detail: ScrollEventDetail;
22
+ }) => void;
23
+ binddone: (event: {
20
24
  detail: {
21
- scrollTop: number;
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
- onScroll?: (event: any) => void;
38
38
  hideScrollbar?: boolean;
39
39
  }
40
- interface Ref {
40
+ export interface ScrollBottomViewRef {
41
41
  scrollToBottom: (options?: {
42
42
  animation?: boolean;
43
43
  follow?: boolean;
44
44
  }) => void;
45
45
  }
46
- declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<Props & React.RefAttributes<Ref>>>;
46
+ declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<Props & React.RefAttributes<ScrollBottomViewRef>>>;
47
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
- export function useScrollBottomView(params) {
11
- const [scrollViewId] = useState(() => "ScrollView-".concat(generateId()));
12
- const contentViewId = "".concat(scrollViewId, "-content");
13
- const tickValue = useTick();
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
- lastScrollEvent: null,
22
- startTimestamp: 0
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
- setScrollIntoViewIdFlag("".concat(Date.now()));
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
- ref.current.needFollow = true;
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 getDomTick = () => {
98
- return new Promise(resolve => {
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
- 'data-render-tick': tickValue,
159
- id: scrollViewId,
160
- scrollY: true,
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 <= ref.current.clientHeight + 25;
169
- params === null || params === void 0 || (_params$onScroll3 = params.onScroll) === null || _params$onScroll3 === void 0 || _params$onScroll3.call(params, event);
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,24 +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
- onScroll: props.onScroll
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(ScrollView, _extends({
194
- className: "".concat(props.className || '', " ").concat(scrollViewLoading ? 't-agent-message-list-hide' : ''),
195
- style: props.style
196
- // @ts-ignore
197
- ,
198
- hideScrollbar: props.hideScrollbar
199
- }, scrollViewProps), /*#__PURE__*/React.createElement(View, _extends({}, contentViewProps, {
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, {
200
121
  className: "".concat(props.contentClassName || '')
201
- }), props.children, /*#__PURE__*/React.createElement(View, {
122
+ }, props.children, /*#__PURE__*/React.createElement(View, {
202
123
  id: scrollIntoViewId
203
124
  })));
204
125
  });
@@ -1,12 +1,15 @@
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;
11
14
  hideScrollbar?: boolean;
12
15
  roleSide?: {
@@ -14,12 +17,6 @@ interface Props {
14
17
  assistant?: 'start' | 'end' | string;
15
18
  [key: string]: 'start' | 'end' | string;
16
19
  };
17
- historyLimit?: {
18
- /** 历史消息数量限制 */
19
- count: number;
20
- /** 超过限制时显示的提示文本 */
21
- tipText: string;
22
- };
23
20
  }
24
21
  declare const MessageList: (props: Props) => React.JSX.Element;
25
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,28 +19,80 @@ const MessageList = props => {
15
19
  style,
16
20
  wrapperClassName,
17
21
  wrapperStyle,
18
- historyLimit,
19
22
  hideScrollbar
20
23
  } = props;
24
+ const [scrollViewId] = useState(() => "message-list-scroll-".concat(generateId()));
21
25
  const messages = useAgentMessage();
22
26
  const onScroll = useStableCallback(props.onScroll);
23
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;
24
71
  return /*#__PURE__*/React.createElement(View, {
25
72
  className: "t-agent-message-list ".concat(wrapperClassName || ''),
26
73
  "data-testid": "t-agent-message-list",
27
74
  style: wrapperStyle,
28
75
  id: "message-list"
29
76
  }, /*#__PURE__*/React.createElement(ScrollBottomView, {
77
+ tick: tick,
78
+ scrollViewId: scrollViewId,
79
+ ref: scrollRef,
30
80
  className: "".concat(className || '', " t-agent-message-list-scroll"),
31
81
  contentClassName: "t-agent-message-list-scroll-content",
32
82
  style: style,
33
83
  onScroll: onScroll,
34
- hideScrollbar: hideScrollbar
35
- }, historyLimit && historyLimit.count < messages.length && /*#__PURE__*/React.createElement(View, {
36
- className: "t-agent-message-list-history-tip"
37
- }, historyLimit.tipText), /*#__PURE__*/React.createElement(View, {
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, {
38
94
  className: "t-agent-message-list-padding-start"
39
- }), props.renderTop, messages.map((msg, index) => {
95
+ }), top), messages.map((msg, index) => {
40
96
  let side = roleSide === null || roleSide === void 0 ? void 0 : roleSide[msg.role];
41
97
  if (!side) {
42
98
  side = msg.role === 'user' ? 'end' : 'start';
@@ -47,10 +103,32 @@ const MessageList = props => {
47
103
  key: msg.id,
48
104
  message: msg,
49
105
  isLatestMessage: isLatestMessage,
50
- 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
+ }
51
122
  });
52
- }), props.renderBottom, /*#__PURE__*/React.createElement(View, {
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, {
53
131
  className: "t-agent-message-list-padding"
54
- })));
132
+ }))));
55
133
  };
56
134
  export default MessageList;
@@ -24,10 +24,9 @@
24
24
  }
25
25
 
26
26
  .t-agent-message-list-padding {
27
- flex: 1
28
27
  }
29
28
 
30
- .t-agent-message-list-hide {
29
+ .t-agent-message-list-loading {
31
30
  opacity: 0;
32
31
  }
33
32
 
@@ -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 {};