Skip to content

Commit 678cceb

Browse files
committed
fix: animation stutter on editing
1 parent 4a66852 commit 678cceb

File tree

2 files changed

+48
-10
lines changed

2 files changed

+48
-10
lines changed

package/src/components/Message/hooks/useMessageActionHandlers.ts

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { useMemo } from 'react';
2-
import { Alert } from 'react-native';
1+
import { useEffect, useMemo, useRef } from 'react';
2+
import { Alert, EventSubscription, Keyboard, Platform } from 'react-native';
33

44
import { UserResponse } from 'stream-chat';
55

@@ -9,12 +9,15 @@ import type { ChannelContextValue } from '../../../contexts/channelContext/Chann
99
import type { ChatContextValue } from '../../../contexts/chatContext/ChatContext';
1010
import { MessageComposerAPIContextValue } from '../../../contexts/messageComposerContext/MessageComposerAPIContext';
1111
import type { MessageContextValue } from '../../../contexts/messageContext/MessageContext';
12+
import { useMessageInputContext } from '../../../contexts/messageInputContext/MessageInputContext';
1213
import type { MessagesContextValue } from '../../../contexts/messagesContext/MessagesContext';
1314

1415
import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext';
1516
import { useStableCallback } from '../../../hooks';
17+
import { useKeyboardVisibility } from '../../../hooks/useKeyboardVisibility';
1618
import { useTranslatedMessage } from '../../../hooks/useTranslatedMessage';
1719
import { NativeHandlers } from '../../../native';
20+
import { KeyboardControllerPackage } from '../../KeyboardCompatibleView/KeyboardControllerAvoidingView';
1821

1922
export const useMessageActionHandlers = ({
2023
channel,
@@ -37,9 +40,19 @@ export const useMessageActionHandlers = ({
3740
const { t } = useTranslationContext();
3841
const handleResendMessage = useStableCallback(() => retrySendMessage(message));
3942
const translatedMessage = useTranslatedMessage(message);
43+
const { inputBoxRef } = useMessageInputContext();
44+
const isKeyboardVisible = useKeyboardVisibility();
45+
const keyboardDidShowSubscriptionRef = useRef<EventSubscription | undefined>(undefined);
4046

4147
const isMuted = useUserMuteActive(message.user);
4248

49+
const clearKeyboardDidShowSubscription = useStableCallback(() => {
50+
keyboardDidShowSubscriptionRef.current?.remove();
51+
keyboardDidShowSubscriptionRef.current = undefined;
52+
});
53+
54+
useEffect(() => clearKeyboardDidShowSubscription, [clearKeyboardDidShowSubscription]);
55+
4356
const handleQuotedReplyMessage = useStableCallback(() => {
4457
setQuotedMessage(message);
4558
});
@@ -115,7 +128,38 @@ export const useMessageActionHandlers = ({
115128
});
116129

117130
const handleEditMessage = useStableCallback(() => {
118-
setEditingState(message);
131+
requestAnimationFrame(() =>
132+
requestAnimationFrame(() => {
133+
clearKeyboardDidShowSubscription();
134+
135+
const openEditingState = () => {
136+
clearKeyboardDidShowSubscription();
137+
setEditingState(message);
138+
};
139+
140+
if (!inputBoxRef.current) {
141+
openEditingState();
142+
return;
143+
}
144+
145+
if (isKeyboardVisible) {
146+
inputBoxRef.current?.focus();
147+
openEditingState();
148+
return;
149+
}
150+
151+
const event = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
152+
153+
keyboardDidShowSubscriptionRef.current = KeyboardControllerPackage?.KeyboardEvents
154+
? KeyboardControllerPackage.KeyboardEvents.addListener(
155+
'keyboardDidShow',
156+
openEditingState,
157+
)
158+
: Keyboard.addListener(event, openEditingState);
159+
160+
inputBoxRef.current?.focus();
161+
}),
162+
);
119163
});
120164

121165
const handleFlagMessage = useStableCallback(() => {

package/src/components/MessageInput/MessageComposer.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ const MessageComposerWithContext = (props: MessageComposerPropsWithContext) => {
219219
closePollCreationDialog,
220220
CreatePollContent,
221221
createPollOptionGap,
222-
editing,
223222
InputView,
224223
MessageComposerLeadingView,
225224
MessageComposerTrailingView,
@@ -272,12 +271,6 @@ const MessageComposerWithContext = (props: MessageComposerPropsWithContext) => {
272271
[closeAttachmentPicker],
273272
);
274273

275-
useEffect(() => {
276-
if (editing && inputBoxRef.current) {
277-
inputBoxRef.current.focus();
278-
}
279-
}, [editing, inputBoxRef]);
280-
281274
/**
282275
* Effect to get the draft data for legacy thread composer and set it to message composer.
283276
* TODO: This can be removed once we remove legacy thread composer.
@@ -746,6 +739,7 @@ export const MessageComposer = (props: MessageComposerProps) => {
746739
closePollCreationDialog,
747740
compressImageQuality,
748741
CreatePollContent,
742+
// TODO: probably not needed anymore, please check
749743
editing,
750744
Input,
751745
InputView,

0 commit comments

Comments
 (0)