Skip to content

Commit 9f40531

Browse files
authored
Merge pull request #1995 from GetStream/develop
v10.7.5
2 parents 7819196 + fad794b commit 9f40531

File tree

3 files changed

+104
-4
lines changed

3 files changed

+104
-4
lines changed

src/components/Channel/Channel.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ const ChannelInner = <
438438
const oldestID = channel.state?.messages?.[0]?.id;
439439

440440
/**
441-
* As the channel state is not normalized we re-fetch the channel data. Thus we avoid having to search for user references in the channel state.
441+
* As the channel state is not normalized we re-fetch the channel data. Thus, we avoid having to search for user references in the channel state.
442442
*/
443443
await channel.query({
444444
messages: { id_lt: oldestID, limit: DEFAULT_NEXT_CHANNEL_PAGE_SIZE },
@@ -682,8 +682,26 @@ const ChannelInner = <
682682
messageResponse = await channel.sendMessage(messageData);
683683
}
684684

685-
// replace it after send is completed
686-
if (messageResponse?.message) {
685+
let existingMessage;
686+
for (let i = channel.state.messages.length - 1; i >= 0; i--) {
687+
const msg = channel.state.messages[i];
688+
if (msg.id === messageData.id) {
689+
existingMessage = msg;
690+
break;
691+
}
692+
}
693+
694+
const responseTimestamp = new Date(messageResponse?.message?.updated_at || 0).getTime();
695+
const existingMessageTimestamp = existingMessage?.updated_at?.getTime() || 0;
696+
const responseIsTheNewest = responseTimestamp > existingMessageTimestamp;
697+
698+
// Replace the message payload after send is completed
699+
// We need to check for the newest message payload, because on slow network, the response can arrive later than WS events message.new, message.updated.
700+
// Always override existing message in status "sending"
701+
if (
702+
messageResponse?.message &&
703+
(responseIsTheNewest || existingMessage?.status === 'sending')
704+
) {
687705
updateMessage({
688706
...messageResponse.message,
689707
status: 'received',

src/components/Channel/__tests__/Channel.test.js

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,87 @@ describe('Channel', () => {
826826
expect(await findByText(message.text)).toBeInTheDocument();
827827
});
828828

829+
it('should not overwrite the message with send response, if already updated by WS events', async () => {
830+
let oldText;
831+
const newText = 'new text';
832+
const creationDate = new Date();
833+
const created_at = creationDate.toISOString();
834+
const updated_at = new Date(creationDate.getTime() + 1).toISOString();
835+
let hasSent = false;
836+
837+
jest.spyOn(channel, 'sendMessage').mockImplementationOnce((message) => {
838+
oldText = message.text;
839+
const finalMessage = { ...message, created_at, updated_at: created_at };
840+
useMockedApis(chatClient, [sendMessageApi(finalMessage)]);
841+
// both effects have to be emitted, otherwise the original message in status "sending" will not be filtered out (done when message.new is emitted) => and the message.updated event would add the updated message as a new message.
842+
createChannelEventDispatcher({
843+
created_at,
844+
message: {
845+
...finalMessage,
846+
text: newText,
847+
},
848+
user,
849+
})();
850+
createChannelEventDispatcher({
851+
created_at: updated_at,
852+
message: {
853+
...finalMessage,
854+
text: newText,
855+
updated_at,
856+
user,
857+
},
858+
type: 'message.updated',
859+
})();
860+
return channel.sendMessage(message);
861+
});
862+
863+
const { queryByText } = renderComponent(
864+
{ children: <MockMessageList /> },
865+
({ sendMessage }) => {
866+
if (!hasSent) {
867+
sendMessage(generateMessage());
868+
hasSent = true;
869+
}
870+
},
871+
);
872+
873+
await waitFor(async () => {
874+
expect(await queryByText(oldText, undefined, { timeout: 100 })).not.toBeInTheDocument();
875+
expect(await queryByText(newText, undefined, { timeout: 100 })).toBeInTheDocument();
876+
});
877+
});
878+
879+
it('should overwrite the message of status "sending" regardless of updated_at timestamp', async () => {
880+
let oldText;
881+
const newText = 'new text';
882+
const creationDate = new Date();
883+
const created_at = creationDate.toISOString();
884+
const updated_at = new Date(creationDate.getTime() - 1).toISOString();
885+
let hasSent = false;
886+
887+
jest.spyOn(channel, 'sendMessage').mockImplementationOnce((message) => {
888+
oldText = message.text;
889+
const finalMessage = { ...message, created_at, text: newText, updated_at };
890+
useMockedApis(chatClient, [sendMessageApi(finalMessage)]);
891+
return channel.sendMessage(message);
892+
});
893+
894+
const { queryByText } = renderComponent(
895+
{ children: <MockMessageList /> },
896+
({ sendMessage }) => {
897+
if (!hasSent) {
898+
sendMessage(generateMessage());
899+
hasSent = true;
900+
}
901+
},
902+
);
903+
904+
await waitFor(async () => {
905+
expect(await queryByText(oldText, undefined, { timeout: 100 })).not.toBeInTheDocument();
906+
expect(await queryByText(newText, undefined, { timeout: 100 })).toBeInTheDocument();
907+
});
908+
});
909+
829910
it('should mark the channel as read if a new message from another user comes in and the user is looking at the page', async () => {
830911
const markReadSpy = jest.spyOn(channel, 'markRead');
831912

@@ -862,7 +943,7 @@ describe('Channel', () => {
862943
const updatedThreadMessage = { ...threadMessage, text: newText };
863944
const dispatchUpdateMessageEvent = createChannelEventDispatcher(
864945
{ message: updatedThreadMessage },
865-
'message.update',
946+
'message.updated',
866947
);
867948
let threadStarterHasUpdatedText = false;
868949
renderComponent({}, ({ openThread, thread }) => {

src/components/MessageInput/hooks/useCreateMessageInputContext.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ export const useCreateMessageInputContext = <
157157
showCommandsList,
158158
showMentionsList,
159159
text,
160+
handleSubmit,
160161
],
161162
);
162163

0 commit comments

Comments
 (0)