stream-chat-react-native-core 9.1.0 → 9.1.1-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.
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
  [![NPM](https://img.shields.io/npm/v/stream-chat-react-native.svg)](https://www.npmjs.com/package/stream-chat-react-native)
11
11
  [![Build Status](https://github.com/GetStream/stream-chat-react-native/actions/workflows/release.yml/badge.svg)](https://github.com/GetStream/stream-chat-react-native/actions)
12
12
  [![Component Reference](https://img.shields.io/badge/docs-component%20reference-blue.svg)](https://getstream.io/chat/docs/sdk/reactnative)
13
- ![JS Bundle Size](https://img.shields.io/badge/js_bundle_size-353%20KB-blue)
13
+ ![JS Bundle Size](https://img.shields.io/badge/js_bundle_size-360%20KB-blue)
14
14
 
15
15
  <img align="right" src="https://getstream.imgix.net/images/ios-chat-tutorial/iphone_chat_art@3x.png?auto=format,enhance" width="50%" />
16
16
 
@@ -21,14 +21,22 @@ var _this = this,
21
21
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
22
22
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
23
23
  var END_ANCHOR_THRESHOLD = 16;
24
- var END_SHRINK_COMPENSATION_DURATION = 200;
24
+ var ATTACHMENT_PREVIEW_ANIMATION_DURATION = 200;
25
+ var TRAILING_SPACER_RELEASE_DELAY = ATTACHMENT_PREVIEW_ANIMATION_DURATION + 80;
25
26
  var MAX_AUDIO_ATTACHMENTS_CONTAINER_WIDTH = 560;
27
+ var attachmentPreviewEntering = _reactNativeReanimated.ZoomIn.duration(ATTACHMENT_PREVIEW_ANIMATION_DURATION);
28
+ var attachmentPreviewExiting = _reactNativeReanimated.ZoomOut.duration(ATTACHMENT_PREVIEW_ANIMATION_DURATION);
29
+ var attachmentPreviewLayout = _reactNativeReanimated.LinearTransition.duration(ATTACHMENT_PREVIEW_ANIMATION_DURATION);
26
30
  var AttachmentPreviewCell = function AttachmentPreviewCell(_ref) {
27
- var children = _ref.children;
31
+ var children = _ref.children,
32
+ onLayout = _ref.onLayout,
33
+ style = _ref.style;
28
34
  return (0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
29
- entering: _reactNativeReanimated.ZoomIn.duration(200),
30
- exiting: _reactNativeReanimated.ZoomOut.duration(200),
31
- layout: _reactNativeReanimated.LinearTransition.duration(200),
35
+ entering: attachmentPreviewEntering,
36
+ exiting: attachmentPreviewExiting,
37
+ layout: attachmentPreviewLayout,
38
+ onLayout: onLayout,
39
+ style: style,
32
40
  children: children
33
41
  });
34
42
  };
@@ -39,6 +47,13 @@ var ItemSeparatorComponent = function ItemSeparatorComponent() {
39
47
  style: [styles.itemSeparator, itemSeparator]
40
48
  });
41
49
  };
50
+ var useLazyRef = function useLazyRef(getInitialValue) {
51
+ var ref = (0, _react.useRef)(null);
52
+ if (ref.current === null) {
53
+ ref.current = getInitialValue();
54
+ }
55
+ return ref;
56
+ };
42
57
  var getIsAudioAttachmentPreview = function getIsAudioAttachmentPreview(soundPackageAvailable) {
43
58
  return function (attachment) {
44
59
  return (0, _streamChat.isLocalVoiceRecordingAttachment)(attachment) || soundPackageAvailable && (0, _streamChat.isLocalAudioAttachment)(attachment);
@@ -58,146 +73,280 @@ var UnMemoizedAttachmentUploadPreviewList = function UnMemoizedAttachmentUploadP
58
73
  attachments = _useAttachmentManager.attachments;
59
74
  var isRTL = _reactNative.I18nManager.isRTL;
60
75
  var attachmentListRef = (0, _react.useRef)(null);
61
- var soundPackageAvailable = (0, _native.isSoundPackageAvailable)();
62
- var isAudioAttachmentPreview = getIsAudioAttachmentPreview(soundPackageAvailable);
76
+ var soundPackageAvailable = (0, _react.useMemo)(function () {
77
+ return (0, _native.isSoundPackageAvailable)();
78
+ }, []);
79
+ var isAudioAttachmentPreview = (0, _react.useMemo)(function () {
80
+ return getIsAudioAttachmentPreview(soundPackageAvailable);
81
+ }, [soundPackageAvailable]);
82
+ var dataRef = useLazyRef(function () {
83
+ return [];
84
+ });
85
+ var previousDataRef = useLazyRef(function () {
86
+ return [];
87
+ });
63
88
  var previousNonAudioAttachmentsLengthRef = (0, _react.useRef)(0);
64
89
  var contentWidthRef = (0, _react.useRef)(0);
65
90
  var itemsContentWidthRef = (0, _react.useRef)(0);
66
91
  var viewportWidthRef = (0, _react.useRef)(0);
67
92
  var scrollOffsetXRef = (0, _react.useRef)(0);
68
- var rtlLeadingSpacerWidthRef = (0, _react.useRef)(0);
69
- var endShrinkCompensationX = (0, _reactNativeReanimated.useSharedValue)(0);
70
- var _useState = (0, _react.useState)(0),
71
- _useState2 = (0, _slicedToArray2.default)(_useState, 2),
72
- rtlLeadingSpacerWidth = _useState2[0],
73
- setRtlLeadingSpacerWidth = _useState2[1];
74
- var previewAttachments = attachments.filter(function (attachment) {
75
- return !(audioRecordingSendOnComplete && (0, _streamChat.isLocalVoiceRecordingAttachment)(attachment));
93
+ var attachmentCellWidthsRef = useLazyRef(function () {
94
+ return {};
95
+ });
96
+ var preparedRemovalIdsRef = useLazyRef(function () {
97
+ return new Set();
76
98
  });
77
- var audioAttachments = previewAttachments.filter(isAudioAttachmentPreview);
78
- var nonAudioAttachments = previewAttachments.filter(function (attachment) {
79
- return !isAudioAttachmentPreview(attachment);
99
+ var spacerReleaseFramesRef = useLazyRef(function () {
100
+ return new Set();
80
101
  });
81
- var data = isRTL ? nonAudioAttachments.toReversed() : nonAudioAttachments;
102
+ var spacerReleaseTimeoutsRef = useLazyRef(function () {
103
+ return new Set();
104
+ });
105
+ var shouldScrollToEndOnContentSizeChangeRef = (0, _react.useRef)(false);
106
+ var trailingSpacerWidthRef = (0, _react.useRef)(0);
107
+ var _useState = (0, _react.useState)(0),
108
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
109
+ trailingSpacerWidth = _useState2[0],
110
+ setTrailingSpacerWidth = _useState2[1];
111
+ var previewAttachments = (0, _react.useMemo)(function () {
112
+ return attachments.filter(function (attachment) {
113
+ return !(audioRecordingSendOnComplete && (0, _streamChat.isLocalVoiceRecordingAttachment)(attachment));
114
+ });
115
+ }, [attachments, audioRecordingSendOnComplete]);
116
+ var audioAttachments = (0, _react.useMemo)(function () {
117
+ return previewAttachments.filter(isAudioAttachmentPreview);
118
+ }, [isAudioAttachmentPreview, previewAttachments]);
119
+ var nonAudioAttachments = (0, _react.useMemo)(function () {
120
+ return previewAttachments.filter(function (attachment) {
121
+ return !isAudioAttachmentPreview(attachment);
122
+ });
123
+ }, [isAudioAttachmentPreview, previewAttachments]);
124
+ var data = (0, _react.useMemo)(function () {
125
+ return isRTL ? nonAudioAttachments.toReversed() : nonAudioAttachments;
126
+ }, [isRTL, nonAudioAttachments]);
82
127
  var _useTheme2 = (0, _ThemeContext.useTheme)(),
83
128
  _useTheme2$theme$mess = _useTheme2.theme.messageComposer.attachmentUploadPreviewList,
84
129
  audioAttachmentsContainer = _useTheme2$theme$mess.audioAttachmentsContainer,
85
130
  flatList = _useTheme2$theme$mess.flatList;
86
- var updateRtlLeadingSpacerWidth = (0, _react.useCallback)(function (itemsWidth, viewportWidth) {
87
- if (!isRTL || !viewportWidth) {
88
- if (rtlLeadingSpacerWidthRef.current !== 0) {
89
- rtlLeadingSpacerWidthRef.current = 0;
90
- setRtlLeadingSpacerWidth(0);
131
+ var scrollToOffset = (0, _react.useCallback)(function (offset) {
132
+ var _attachmentListRef$cu;
133
+ var animated = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
134
+ var nextOffset = Math.max(0, offset);
135
+ (_attachmentListRef$cu = attachmentListRef.current) == null || _attachmentListRef$cu.scrollTo({
136
+ animated: animated,
137
+ x: nextOffset
138
+ });
139
+ scrollOffsetXRef.current = nextOffset;
140
+ }, []);
141
+ var setTrailingSpacerLayoutWidth = (0, _react.useCallback)(function (width) {
142
+ var nextWidth = Math.max(0, width);
143
+ trailingSpacerWidthRef.current = nextWidth;
144
+ setTrailingSpacerWidth(nextWidth);
145
+ }, []);
146
+ var prepareTrailingSpacer = (0, _react.useCallback)(function (width) {
147
+ if (width <= 0) {
148
+ return;
149
+ }
150
+ var nextWidth = trailingSpacerWidthRef.current + width;
151
+ setTrailingSpacerLayoutWidth(nextWidth);
152
+ }, [setTrailingSpacerLayoutWidth]);
153
+ var scheduleTrailingSpacerRelease = (0, _react.useCallback)(function (width) {
154
+ if (width <= 0) {
155
+ return;
156
+ }
157
+ var timeout = setTimeout(function () {
158
+ spacerReleaseTimeoutsRef.current.delete(timeout);
159
+ var firstFrame = requestAnimationFrame(function () {
160
+ spacerReleaseFramesRef.current.delete(firstFrame);
161
+ var secondFrame = requestAnimationFrame(function () {
162
+ spacerReleaseFramesRef.current.delete(secondFrame);
163
+ setTrailingSpacerLayoutWidth(trailingSpacerWidthRef.current - width);
164
+ });
165
+ spacerReleaseFramesRef.current.add(secondFrame);
166
+ });
167
+ spacerReleaseFramesRef.current.add(firstFrame);
168
+ }, TRAILING_SPACER_RELEASE_DELAY);
169
+ spacerReleaseTimeoutsRef.current.add(timeout);
170
+ }, [setTrailingSpacerLayoutWidth, spacerReleaseFramesRef, spacerReleaseTimeoutsRef]);
171
+ var getRemovalMetrics = (0, _react.useCallback)(function (ids, baseData) {
172
+ var removedIds = new Set(ids);
173
+ var fallbackCellWidth = baseData.length ? itemsContentWidthRef.current / baseData.length : 0;
174
+ var offsetBefore = scrollOffsetXRef.current;
175
+ var oldMaxOffset = Math.max(0, itemsContentWidthRef.current - viewportWidthRef.current);
176
+ var wasNearEnd = oldMaxOffset - offsetBefore <= END_ANCHOR_THRESHOLD;
177
+ var contentOffset = 0;
178
+ var removedContentWidth = 0;
179
+ var anchorCorrectionWidth = 0;
180
+ baseData.forEach(function (attachment) {
181
+ var _attachmentCellWidths;
182
+ var attachmentId = attachment.localMetadata.id;
183
+ var cellWidth = (_attachmentCellWidths = attachmentCellWidthsRef.current[attachmentId]) != null ? _attachmentCellWidths : fallbackCellWidth;
184
+ if (removedIds.has(attachmentId)) {
185
+ removedContentWidth += cellWidth;
186
+ if (contentOffset <= offsetBefore) {
187
+ anchorCorrectionWidth += cellWidth;
188
+ }
91
189
  }
190
+ contentOffset += cellWidth;
191
+ });
192
+ if (!removedContentWidth) {
193
+ return {
194
+ removedContentWidth: 0,
195
+ scrollCorrectionWidth: 0
196
+ };
197
+ }
198
+ return {
199
+ removedContentWidth: removedContentWidth,
200
+ scrollCorrectionWidth: wasNearEnd ? removedContentWidth : Math.min(anchorCorrectionWidth, removedContentWidth)
201
+ };
202
+ }, [attachmentCellWidthsRef]);
203
+ var applyRemovalScrollCorrection = (0, _react.useCallback)(function (removedContentWidth, scrollCorrectionWidth) {
204
+ if (removedContentWidth <= 0 || isRTL) {
92
205
  return;
93
206
  }
94
- var nextSpacerWidth = Math.max(0, viewportWidth - itemsWidth);
95
- if (rtlLeadingSpacerWidthRef.current === nextSpacerWidth) {
207
+ var offsetBefore = scrollOffsetXRef.current;
208
+ var nextContentWidth = Math.max(0, itemsContentWidthRef.current - removedContentWidth);
209
+ var nextMaxOffset = Math.max(0, nextContentWidth - viewportWidthRef.current);
210
+ var nextOffset = Math.min(nextMaxOffset, Math.max(0, offsetBefore - scrollCorrectionWidth));
211
+ if (nextOffset !== offsetBefore) {
212
+ scrollToOffset(nextOffset, true);
213
+ }
214
+ }, [isRTL, scrollToOffset]);
215
+ var prepareForRemoval = (0, _react.useCallback)(function (ids, baseData) {
216
+ var _getRemovalMetrics = getRemovalMetrics(ids, baseData),
217
+ removedContentWidth = _getRemovalMetrics.removedContentWidth,
218
+ scrollCorrectionWidth = _getRemovalMetrics.scrollCorrectionWidth;
219
+ if (!removedContentWidth) {
96
220
  return;
97
221
  }
98
- rtlLeadingSpacerWidthRef.current = nextSpacerWidth;
99
- setRtlLeadingSpacerWidth(nextSpacerWidth);
100
- }, [isRTL]);
101
- var renderItem = (0, _react.useCallback)(function (_ref2) {
102
- var item = _ref2.item;
103
- if ((0, _streamChat.isLocalImageAttachment)(item)) {
104
- return (0, _jsxRuntime.jsx)(AttachmentPreviewCell, {
105
- children: (0, _jsxRuntime.jsx)(ImageAttachmentUploadPreview, {
106
- attachment: item,
107
- handleRetry: attachmentManager.uploadAttachment,
108
- removeAttachments: attachmentManager.removeAttachments
109
- })
222
+ if (!isRTL) {
223
+ prepareTrailingSpacer(removedContentWidth);
224
+ }
225
+ applyRemovalScrollCorrection(removedContentWidth, scrollCorrectionWidth);
226
+ ids.forEach(function (id) {
227
+ return preparedRemovalIdsRef.current.add(id);
228
+ });
229
+ }, [applyRemovalScrollCorrection, getRemovalMetrics, isRTL, preparedRemovalIdsRef, prepareTrailingSpacer]);
230
+ var removeAttachments = (0, _react.useCallback)(function (ids) {
231
+ prepareForRemoval(ids, dataRef.current);
232
+ attachmentManager.removeAttachments(ids);
233
+ }, [attachmentManager, dataRef, prepareForRemoval]);
234
+ (0, _react.useLayoutEffect)(function () {
235
+ var previousData = previousDataRef.current;
236
+ var nextIds = new Set(data.map(function (attachment) {
237
+ return attachment.localMetadata.id;
238
+ }));
239
+ var removedIds = previousData.map(function (attachment) {
240
+ return attachment.localMetadata.id;
241
+ }).filter(function (id) {
242
+ return !nextIds.has(id);
243
+ });
244
+ if (removedIds.length) {
245
+ var _getRemovalMetrics2 = getRemovalMetrics(removedIds, previousData),
246
+ removedContentWidth = _getRemovalMetrics2.removedContentWidth;
247
+ var unpreparedRemovedIds = removedIds.filter(function (id) {
248
+ return !preparedRemovalIdsRef.current.has(id);
110
249
  });
111
- } else if ((0, _streamChat.isLocalVoiceRecordingAttachment)(item)) {
112
- return (0, _jsxRuntime.jsx)(AttachmentPreviewCell, {
113
- children: (0, _jsxRuntime.jsx)(AudioAttachmentUploadPreview, {
114
- attachment: item,
115
- handleRetry: attachmentManager.uploadAttachment,
116
- removeAttachments: attachmentManager.removeAttachments
117
- })
250
+ var didPrepareAfterRemovalCommit = unpreparedRemovedIds.length > 0;
251
+ if (didPrepareAfterRemovalCommit) {
252
+ prepareForRemoval(unpreparedRemovedIds, previousData);
253
+ }
254
+ removedIds.forEach(function (id) {
255
+ return preparedRemovalIdsRef.current.delete(id);
118
256
  });
119
- } else if ((0, _streamChat.isLocalAudioAttachment)(item)) {
120
- if ((0, _native.isSoundPackageAvailable)()) {
121
- return (0, _jsxRuntime.jsx)(AttachmentPreviewCell, {
122
- children: (0, _jsxRuntime.jsx)(AudioAttachmentUploadPreview, {
123
- attachment: item,
124
- handleRetry: attachmentManager.uploadAttachment,
125
- removeAttachments: attachmentManager.removeAttachments
126
- })
257
+ if (!isRTL) {
258
+ scheduleTrailingSpacerRelease(removedContentWidth);
259
+ }
260
+ }
261
+ previousDataRef.current = data;
262
+ dataRef.current = data;
263
+ }, [data, dataRef, getRemovalMetrics, isRTL, preparedRemovalIdsRef, prepareForRemoval, previousDataRef, scheduleTrailingSpacerRelease]);
264
+ (0, _react.useEffect)(function () {
265
+ return function () {
266
+ spacerReleaseFramesRef.current.forEach(cancelAnimationFrame);
267
+ spacerReleaseFramesRef.current.clear();
268
+ spacerReleaseTimeoutsRef.current.forEach(clearTimeout);
269
+ spacerReleaseTimeoutsRef.current.clear();
270
+ };
271
+ }, [spacerReleaseFramesRef, spacerReleaseTimeoutsRef]);
272
+ var renderAttachmentPreview = (0, _react.useCallback)(function (attachment) {
273
+ if ((0, _streamChat.isLocalImageAttachment)(attachment)) {
274
+ return (0, _jsxRuntime.jsx)(ImageAttachmentUploadPreview, {
275
+ attachment: attachment,
276
+ handleRetry: attachmentManager.uploadAttachment,
277
+ removeAttachments: removeAttachments
278
+ });
279
+ } else if ((0, _streamChat.isLocalVoiceRecordingAttachment)(attachment)) {
280
+ return (0, _jsxRuntime.jsx)(AudioAttachmentUploadPreview, {
281
+ attachment: attachment,
282
+ handleRetry: attachmentManager.uploadAttachment,
283
+ removeAttachments: removeAttachments
284
+ });
285
+ } else if ((0, _streamChat.isLocalAudioAttachment)(attachment)) {
286
+ if (soundPackageAvailable) {
287
+ return (0, _jsxRuntime.jsx)(AudioAttachmentUploadPreview, {
288
+ attachment: attachment,
289
+ handleRetry: attachmentManager.uploadAttachment,
290
+ removeAttachments: removeAttachments
127
291
  });
128
292
  } else {
129
- return (0, _jsxRuntime.jsx)(AttachmentPreviewCell, {
130
- children: (0, _jsxRuntime.jsx)(FileAttachmentUploadPreview, {
131
- attachment: item,
132
- handleRetry: attachmentManager.uploadAttachment,
133
- removeAttachments: attachmentManager.removeAttachments
134
- })
293
+ return (0, _jsxRuntime.jsx)(FileAttachmentUploadPreview, {
294
+ attachment: attachment,
295
+ handleRetry: attachmentManager.uploadAttachment,
296
+ removeAttachments: removeAttachments
135
297
  });
136
298
  }
137
- } else if ((0, _streamChat.isVideoAttachment)(item)) {
138
- return (0, _jsxRuntime.jsx)(AttachmentPreviewCell, {
139
- children: (0, _jsxRuntime.jsx)(VideoAttachmentUploadPreview, {
140
- attachment: item,
141
- handleRetry: attachmentManager.uploadAttachment,
142
- removeAttachments: attachmentManager.removeAttachments
143
- })
299
+ } else if ((0, _streamChat.isVideoAttachment)(attachment)) {
300
+ return (0, _jsxRuntime.jsx)(VideoAttachmentUploadPreview, {
301
+ attachment: attachment,
302
+ handleRetry: attachmentManager.uploadAttachment,
303
+ removeAttachments: removeAttachments
144
304
  });
145
- } else if ((0, _streamChat.isLocalFileAttachment)(item)) {
146
- return (0, _jsxRuntime.jsx)(AttachmentPreviewCell, {
147
- children: (0, _jsxRuntime.jsx)(FileAttachmentUploadPreview, {
148
- attachment: item,
149
- handleRetry: attachmentManager.uploadAttachment,
150
- removeAttachments: attachmentManager.removeAttachments
151
- })
305
+ } else if ((0, _streamChat.isLocalFileAttachment)(attachment)) {
306
+ return (0, _jsxRuntime.jsx)(FileAttachmentUploadPreview, {
307
+ attachment: attachment,
308
+ handleRetry: attachmentManager.uploadAttachment,
309
+ removeAttachments: removeAttachments
152
310
  });
153
311
  } else return null;
154
- }, [AudioAttachmentUploadPreview, FileAttachmentUploadPreview, ImageAttachmentUploadPreview, VideoAttachmentUploadPreview, attachmentManager.removeAttachments, attachmentManager.uploadAttachment]);
312
+ }, [AudioAttachmentUploadPreview, FileAttachmentUploadPreview, ImageAttachmentUploadPreview, VideoAttachmentUploadPreview, attachmentManager.uploadAttachment, removeAttachments, soundPackageAvailable]);
155
313
  var onScrollHandler = (0, _react.useCallback)(function (event) {
156
314
  scrollOffsetXRef.current = event.nativeEvent.contentOffset.x;
157
315
  }, []);
316
+ var scrollToEndOffset = (0, _react.useCallback)(function (contentWidth) {
317
+ var animated = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
318
+ if (isRTL) {
319
+ return;
320
+ }
321
+ scrollToOffset(Math.max(0, contentWidth - viewportWidthRef.current), animated);
322
+ }, [isRTL, scrollToOffset]);
158
323
  var onLayoutHandler = (0, _react.useCallback)(function (event) {
159
- var viewportWidth = event.nativeEvent.layout.width;
160
- viewportWidthRef.current = viewportWidth;
161
- updateRtlLeadingSpacerWidth(itemsContentWidthRef.current, viewportWidth);
162
- }, [updateRtlLeadingSpacerWidth]);
324
+ viewportWidthRef.current = event.nativeEvent.layout.width;
325
+ }, []);
326
+ var onAttachmentCellLayout = (0, _react.useCallback)(function (id, event) {
327
+ attachmentCellWidthsRef.current[id] = event.nativeEvent.layout.width;
328
+ }, [attachmentCellWidthsRef]);
163
329
  var onContentSizeChangeHandler = (0, _react.useCallback)(function (width) {
164
- var itemsContentWidth = isRTL ? Math.max(0, width - rtlLeadingSpacerWidthRef.current) : width;
330
+ var scrollableContentWidth = width;
331
+ var itemsContentWidth = Math.max(0, scrollableContentWidth - trailingSpacerWidthRef.current);
165
332
  var previousContentWidth = contentWidthRef.current;
166
333
  contentWidthRef.current = itemsContentWidth;
167
334
  itemsContentWidthRef.current = itemsContentWidth;
168
- updateRtlLeadingSpacerWidth(itemsContentWidth, viewportWidthRef.current);
169
- if (!previousContentWidth || itemsContentWidth >= previousContentWidth) {
335
+ if (shouldScrollToEndOnContentSizeChangeRef.current && itemsContentWidth > previousContentWidth) {
336
+ shouldScrollToEndOnContentSizeChangeRef.current = false;
337
+ scrollToEndOffset(scrollableContentWidth);
170
338
  return;
171
339
  }
172
- var oldMaxOffset = Math.max(0, previousContentWidth - viewportWidthRef.current);
173
- var newMaxOffset = Math.max(0, itemsContentWidth - viewportWidthRef.current);
174
- var offsetBefore = scrollOffsetXRef.current;
175
- var wasNearEnd = oldMaxOffset - offsetBefore <= END_ANCHOR_THRESHOLD;
176
- var overshoot = Math.max(0, offsetBefore - newMaxOffset);
177
- var shouldAnchorEnd = wasNearEnd || overshoot > 0;
178
- if (!shouldAnchorEnd) {
179
- return;
180
- }
181
- if (overshoot > 0) {
182
- var _attachmentListRef$cu;
183
- (_attachmentListRef$cu = attachmentListRef.current) == null || _attachmentListRef$cu.scrollToOffset({
184
- animated: false,
185
- offset: newMaxOffset
186
- });
187
- scrollOffsetXRef.current = newMaxOffset;
188
- }
189
- if (isRTL) {
340
+ if (!previousContentWidth || itemsContentWidth >= previousContentWidth) {
190
341
  return;
191
342
  }
192
- var compensation = newMaxOffset - oldMaxOffset;
193
- if (compensation !== 0) {
194
- (0, _reactNativeReanimated.cancelAnimation)(endShrinkCompensationX);
195
- endShrinkCompensationX.value = compensation;
196
- endShrinkCompensationX.value = (0, _reactNativeReanimated.withSpring)(0, {
197
- duration: END_SHRINK_COMPENSATION_DURATION
198
- });
343
+ var actualMaxOffset = Math.max(0, scrollableContentWidth - viewportWidthRef.current);
344
+ var offsetBefore = scrollOffsetXRef.current;
345
+ var overshoot = Math.max(0, offsetBefore - actualMaxOffset);
346
+ if (overshoot > END_ANCHOR_THRESHOLD) {
347
+ scrollToOffset(actualMaxOffset);
199
348
  }
200
- }, [endShrinkCompensationX, isRTL, updateRtlLeadingSpacerWidth]);
349
+ }, [scrollToEndOffset, scrollToOffset]);
201
350
  (0, _react.useEffect)(function () {
202
351
  var previousLength = previousNonAudioAttachmentsLengthRef.current;
203
352
  var nextLength = nonAudioAttachments.length;
@@ -206,72 +355,61 @@ var UnMemoizedAttachmentUploadPreviewList = function UnMemoizedAttachmentUploadP
206
355
  if (!didAddAttachment) {
207
356
  return;
208
357
  }
209
- (0, _reactNativeReanimated.cancelAnimation)(endShrinkCompensationX);
210
- endShrinkCompensationX.value = 0;
211
- requestAnimationFrame(function () {
212
- var _attachmentListRef$cu2;
213
- if (isRTL) {
214
- return;
215
- }
216
- (_attachmentListRef$cu2 = attachmentListRef.current) == null || _attachmentListRef$cu2.scrollToEnd({
217
- animated: true
218
- });
219
- });
220
- }, [endShrinkCompensationX, isRTL, nonAudioAttachments.length]);
221
- var animatedListWrapperStyle = (0, _reactNativeReanimated.useAnimatedStyle)(function () {
222
- return {
223
- transform: [{
224
- translateX: endShrinkCompensationX.value
225
- }]
226
- };
227
- });
358
+ shouldScrollToEndOnContentSizeChangeRef.current = true;
359
+ }, [nonAudioAttachments.length]);
228
360
  if (!previewAttachments.length) {
229
361
  return null;
230
362
  }
231
363
  return (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
232
364
  children: [audioAttachments.length ? (0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
233
- entering: _reactNativeReanimated.ZoomIn.duration(200),
234
- exiting: _reactNativeReanimated.ZoomOut.duration(200),
235
- layout: _reactNativeReanimated.LinearTransition.duration(200),
365
+ entering: attachmentPreviewEntering,
366
+ exiting: attachmentPreviewExiting,
367
+ layout: attachmentPreviewLayout,
236
368
  style: [styles.audioAttachmentsContainer, audioAttachmentsContainer],
237
369
  children: audioAttachments.map(function (attachment) {
238
370
  return (0, _jsxRuntime.jsx)(AttachmentPreviewCell, {
239
371
  children: (0, _jsxRuntime.jsx)(AudioAttachmentUploadPreview, {
240
372
  attachment: attachment,
241
373
  handleRetry: attachmentManager.uploadAttachment,
242
- removeAttachments: attachmentManager.removeAttachments
374
+ removeAttachments: removeAttachments
243
375
  })
244
376
  }, attachment.localMetadata.id);
245
377
  })
246
378
  }) : null, data.length ? (0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
247
- entering: _reactNativeReanimated.ZoomIn.duration(200),
248
- exiting: _reactNativeReanimated.ZoomOut.duration(200),
249
- layout: _reactNativeReanimated.LinearTransition.duration(200),
250
- children: (0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
251
- style: animatedListWrapperStyle,
252
- children: (0, _jsxRuntime.jsx)(_reactNative.FlatList, {
253
- data: data,
254
- horizontal: true,
255
- ItemSeparatorComponent: ItemSeparatorComponent,
256
- keyExtractor: function keyExtractor(item) {
257
- return item.localMetadata.id;
258
- },
259
- ListHeaderComponent: isRTL && rtlLeadingSpacerWidth > 0 ? (0, _jsxRuntime.jsx)(_reactNative.View, {
260
- style: {
261
- width: rtlLeadingSpacerWidth
262
- }
263
- }) : null,
264
- onContentSizeChange: onContentSizeChangeHandler,
265
- onLayout: onLayoutHandler,
266
- onScroll: onScrollHandler,
267
- removeClippedSubviews: false,
268
- ref: attachmentListRef,
269
- renderItem: renderItem,
270
- scrollEventThrottle: 16,
271
- showsHorizontalScrollIndicator: false,
272
- style: [styles.flatList, flatList],
273
- testID: 'attachment-upload-preview-list'
274
- })
379
+ entering: attachmentPreviewEntering,
380
+ exiting: attachmentPreviewExiting,
381
+ layout: attachmentPreviewLayout,
382
+ style: styles.flatListContainer,
383
+ children: (0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
384
+ contentContainerStyle: styles.flatListContentContainer,
385
+ horizontal: true,
386
+ onContentSizeChange: onContentSizeChangeHandler,
387
+ onLayout: onLayoutHandler,
388
+ onScroll: onScrollHandler,
389
+ ref: attachmentListRef,
390
+ scrollEventThrottle: 16,
391
+ showsHorizontalScrollIndicator: false,
392
+ style: [styles.flatList, flatList],
393
+ testID: 'attachment-upload-preview-list',
394
+ children: [data.map(function (attachment, index) {
395
+ var attachmentId = attachment.localMetadata.id;
396
+ return (0, _jsxRuntime.jsxs)(AttachmentPreviewCell, {
397
+ onLayout: function onLayout(event) {
398
+ return onAttachmentCellLayout(attachmentId, event);
399
+ },
400
+ style: styles.attachmentPreviewCell,
401
+ children: [index > 0 ? (0, _jsxRuntime.jsx)(ItemSeparatorComponent, {}) : null, (0, _jsxRuntime.jsx)(_reactNative.View, {
402
+ collapsable: false,
403
+ style: styles.attachmentPreviewContent,
404
+ children: renderAttachmentPreview(attachment)
405
+ })]
406
+ }, attachmentId);
407
+ }), !isRTL ? (0, _jsxRuntime.jsx)(_reactNative.View, {
408
+ pointerEvents: 'none',
409
+ style: [styles.trailingSpacer, {
410
+ width: trailingSpacerWidth
411
+ }]
412
+ }) : null]
275
413
  })
276
414
  }) : null]
277
415
  });
@@ -281,16 +419,36 @@ var AttachmentUploadPreviewList = exports.AttachmentUploadPreviewList = function
281
419
  return (0, _jsxRuntime.jsx)(MemoizedAttachmentUploadPreviewListWithContext, {});
282
420
  };
283
421
  var styles = _reactNative.StyleSheet.create({
422
+ attachmentPreviewCell: {
423
+ alignItems: 'flex-start',
424
+ flexDirection: 'row',
425
+ flexShrink: 0
426
+ },
427
+ attachmentPreviewContent: {
428
+ flexShrink: 0
429
+ },
284
430
  audioAttachmentsContainer: {
285
431
  maxWidth: MAX_AUDIO_ATTACHMENTS_CONTAINER_WIDTH,
286
432
  width: '100%'
287
433
  },
288
434
  flatList: {
289
- overflow: 'visible',
290
- direction: 'ltr'
435
+ direction: 'ltr',
436
+ flexGrow: 0,
437
+ overflow: 'visible'
438
+ },
439
+ flatListContentContainer: {
440
+ alignItems: 'flex-start'
441
+ },
442
+ flatListContainer: {
443
+ alignSelf: 'flex-start',
444
+ flexShrink: 1,
445
+ maxWidth: '100%'
291
446
  },
292
447
  itemSeparator: {
293
448
  width: _theme.primitives.spacingXs
449
+ },
450
+ trailingSpacer: {
451
+ flexShrink: 0
294
452
  }
295
453
  });
296
454
  AttachmentUploadPreviewList.displayName = 'AttachmentUploadPreviewList{messageComposer{attachmentUploadPreviewList}}';