Skip to content

Commit bceb537

Browse files
committed
fix: avoid remounting stateful messages on swipe to reply
1 parent 857fb68 commit bceb537

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

package/src/components/Attachment/FileAttachmentGroup.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import React, { useEffect, useState } from 'react';
22
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
33

44
import type { Attachment } from 'stream-chat';
@@ -43,6 +43,12 @@ const FileAttachmentGroupWithContext = (props: FileAttachmentGroupPropsWithConte
4343
files.map((file) => ({ ...file, duration: file.duration || 0, paused: true, progress: 0 })),
4444
);
4545

46+
useEffect(() => {
47+
setFilesToDisplay(
48+
files.map((file) => ({ ...file, duration: file.duration || 0, paused: true, progress: 0 })),
49+
);
50+
}, [files]);
51+
4652
// Handler triggered when an audio is loaded in the message input. The initial state is defined for the audio here and the duration is set.
4753
const onLoad = (index: string, duration: number) => {
4854
setFilesToDisplay((prevFilesToDisplay) =>

package/src/components/Message/MessageSimple/MessageSimple.tsx

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export type MessageSimplePropsWithContext = Pick<
9090
| 'reactionListPosition'
9191
| 'ReactionListTop'
9292
| 'setQuotedMessageState'
93-
>;
93+
> & { shouldRenderSwipeableWrapper: boolean };
9494

9595
const MessageSimpleWithContext = (props: MessageSimplePropsWithContext) => {
9696
const [messageContentWidth, setMessageContentWidth] = useState(0);
@@ -123,6 +123,7 @@ const MessageSimpleWithContext = (props: MessageSimplePropsWithContext) => {
123123
ReactionListTop,
124124
setQuotedMessageState,
125125
showMessageStatus,
126+
shouldRenderSwipeableWrapper,
126127
} = props;
127128

128129
const {
@@ -202,7 +203,7 @@ const MessageSimpleWithContext = (props: MessageSimplePropsWithContext) => {
202203
const translateX = useSharedValue(0);
203204
const touchStart = useSharedValue<{ x: number; y: number } | null>(null);
204205
const isSwiping = useSharedValue<boolean>(false);
205-
const [isBeingSwiped, setIsBeingSwiped] = useState<boolean>(false);
206+
const [isBeingSwiped, setIsBeingSwiped] = useState<boolean>(shouldRenderSwipeableWrapper);
206207

207208
const onSwipeToReply = useCallback(() => {
208209
clearQuotedMessageState();
@@ -233,7 +234,9 @@ const MessageSimpleWithContext = (props: MessageSimplePropsWithContext) => {
233234
if (isHorizontalPanning) {
234235
state.activate();
235236
isSwiping.value = true;
236-
runOnJS(setIsBeingSwiped)(isSwiping.value);
237+
if (!shouldRenderSwipeableWrapper) {
238+
runOnJS(setIsBeingSwiped)(isSwiping.value);
239+
}
237240
} else {
238241
state.fail();
239242
}
@@ -263,11 +266,21 @@ const MessageSimpleWithContext = (props: MessageSimplePropsWithContext) => {
263266
stiffness: 1,
264267
},
265268
() => {
266-
runOnJS(setIsBeingSwiped)(isSwiping.value);
269+
if (!shouldRenderSwipeableWrapper) {
270+
runOnJS(setIsBeingSwiped)(isSwiping.value);
271+
}
267272
},
268273
);
269274
}),
270-
[isSwiping, messageSwipeToReplyHitSlop, onSwipeToReply, touchStart, translateX, triggerHaptic],
275+
[
276+
isSwiping,
277+
messageSwipeToReplyHitSlop,
278+
onSwipeToReply,
279+
touchStart,
280+
translateX,
281+
triggerHaptic,
282+
shouldRenderSwipeableWrapper,
283+
],
271284
);
272285

273286
const messageBubbleAnimatedStyle = useAnimatedStyle(
@@ -586,6 +599,7 @@ export const MessageSimple = (props: MessageSimpleProps) => {
586599
onlyEmojis,
587600
otherAttachments,
588601
showMessageStatus,
602+
isMessageAIGenerated,
589603
} = useMessageContext();
590604
const {
591605
clearQuotedMessageState,
@@ -607,6 +621,11 @@ export const MessageSimple = (props: MessageSimpleProps) => {
607621
ReactionListTop,
608622
setQuotedMessageState,
609623
} = useMessagesContext();
624+
const isAIGenerated = useMemo(
625+
() => isMessageAIGenerated(message),
626+
[message, isMessageAIGenerated],
627+
);
628+
const shouldRenderSwipeableWrapper = (message?.attachments || []).length > 0 || isAIGenerated;
610629

611630
return (
612631
<MemoizedMessageSimple
@@ -639,6 +658,7 @@ export const MessageSimple = (props: MessageSimpleProps) => {
639658
reactionListPosition,
640659
ReactionListTop,
641660
setQuotedMessageState,
661+
shouldRenderSwipeableWrapper,
642662
showMessageStatus,
643663
}}
644664
{...props}

0 commit comments

Comments
 (0)