Skip to content

Commit 7a85726

Browse files
danney-chunCopilot
andauthored
Fixed a bug where Failed message can't be send (#1369)
[fix]: Fixed RQA Issue Fixes [CLNP-7007](https://sendbird.atlassian.net/browse/CLNP-7007) Fixes [CLNP-7553](https://sendbird.atlassian.net/browse/CLNP-7553) ### Changelogs - Fixed a bug where failed message can't be resend - Fixed a bug where Reaction is not updated in Thread ### Checklist Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If unsure, ask the members. This is a reminder of what we look for before merging your code. - [x] **All tests pass locally with my changes** - [ ] **I have added tests that prove my fix is effective or that my feature works** - [ ] **Public components / utils / props are appropriately exported** - [ ] I have added necessary documentation (if appropriate) ## External Contributions This project is not yet set up to accept pull requests from external contributors. If you have a pull request that you believe should be accepted, please contact the Developer Relations team <[email protected]> with details and we'll evaluate if we can set up a [CLA](https://en.wikipedia.org/wiki/Contributor_License_Agreement) to allow for the contribution. [CLNP-7007]: https://sendbird.atlassian.net/browse/CLNP-7007?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [CLNP-7553]: https://sendbird.atlassian.net/browse/CLNP-7553?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --------- Co-authored-by: Copilot <[email protected]>
1 parent 8ba4329 commit 7a85726

File tree

10 files changed

+80
-45
lines changed

10 files changed

+80
-45
lines changed

apps/testing/src/pages/PlaygroundPage.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,11 @@ import { defaultProps } from '../libs/const.ts';
44

55
export function PlaygroundPage() {
66
const props = useConfigParams(defaultProps);
7-
return <GroupChannelApp {...props} breakpoint={/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)} config={{ logLevel: 'all' }} />;
7+
return <GroupChannelApp {...props} breakpoint={/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)} config={{ logLevel: 'all' }}
8+
uikitOptions={{
9+
groupChannel: {
10+
replyType: 'thread',
11+
}
12+
}}
13+
/>;
814
}

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@
7070
"react-dom": "^16.8.6 || ^17.0.0 || ^18.0.0 || ^19.0.0"
7171
},
7272
"dependencies": {
73-
"@sendbird/chat": "^4.18.0",
74-
"@sendbird/react-uikit-message-template-view": "^0.0.10",
75-
"@sendbird/uikit-tools": "^0.0.10",
73+
"@sendbird/chat": "^4.20.0",
74+
"@sendbird/react-uikit-message-template-view": "^0.0.18",
75+
"@sendbird/uikit-tools": "^0.0.18",
7676
"css-vars-ponyfill": "^2.3.2",
7777
"date-fns": "^2.16.1",
7878
"dompurify": "^3.2.4"

src/modules/Channel/context/hooks/useHandleChannelEvents.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ function useHandleChannelEvents({
121121
},
122122
onUserMarkedUnread: (channel, userIds) => {
123123
logger.info('Channel | useHandleChannelEvents: onUserMarkedUnread', channel, userIds);
124-
// TODO:: MADOKA 이 부분에 대해서 명확하게 확인해야 함.
125124
if (compareIds(channel?.url, channelUrl)) {
126125
messagesDispatcher({
127126
type: messageActions.MARK_AS_UNREAD,
@@ -169,11 +168,13 @@ function useHandleChannelEvents({
169168
});
170169
},
171170
onReactionUpdated: (channel, reactionEvent) => {
172-
logger.info('Channel | useHandleChannelEvents: onReactionUpdated', { channel, reactionEvent });
173-
messagesDispatcher({
174-
type: messageActions.ON_REACTION_UPDATED,
175-
payload: reactionEvent,
176-
});
171+
if (channel.isGroupChannel() && compareIds(channel?.url, channelUrl)) {
172+
logger.info('Channel | useHandleChannelEvents: onReactionUpdated', { channel, reactionEvent });
173+
messagesDispatcher({
174+
type: messageActions.ON_REACTION_UPDATED,
175+
payload: reactionEvent,
176+
});
177+
}
177178
},
178179
onChannelChanged: (channel) => {
179180
if (channel.isGroupChannel() && compareIds(channel?.url, channelUrl)) {

src/modules/GroupChannel/components/MessageList/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export const MessageList = (props: GroupChannelMessageListProps) => {
110110

111111
// Find the first unread message
112112
const firstUnreadMessage = useMemo(() => {
113-
if (!enableMarkAsUnread || !isInitializedRef.current || messages.length === 0 || readState === 'read') {
113+
if (!enableMarkAsUnread || !isInitializedRef.current || messages.length === 0 || readState === 'read' || !currentChannel?.myLastRead) {
114114
return undefined;
115115
}
116116

src/modules/Thread/components/ThreadList/ThreadListItemContent.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ export default function ThreadListItemContent(props: ThreadListItemContentProps)
332332
toggleReaction,
333333
isOpenedFromThread: true,
334334
deleteMessage,
335+
resendMessage,
335336
onDownloadClick: async (e) => {
336337
if (!onBeforeDownloadFileMessage) return;
337338

src/modules/Thread/context/hooks/useThreadFetchers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ function getThreadMessageListParams(params?: Partial<ThreadedMessageListParams>)
3030
prevResultSize: PREV_THREADS_FETCH_SIZE,
3131
nextResultSize: NEXT_THREADS_FETCH_SIZE,
3232
includeMetaArray: true,
33+
isInclusive: true,
3334
...params,
3435
};
3536
}

src/modules/Thread/context/useThread.ts

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
BaseMessage,
1111
MultipleFilesMessage,
1212
ReactionEvent,
13+
SendingStatus,
1314
UserMessage,
1415
} from '@sendbird/chat/message';
1516
import { NEXT_THREADS_FETCH_SIZE, PREV_THREADS_FETCH_SIZE } from '../consts';
@@ -26,6 +27,8 @@ import useUpdateMessageCallback from './hooks/useUpdateMessageCallback';
2627
import useDeleteMessageCallback from './hooks/useDeleteMessageCallback';
2728
import { useThreadFetchers } from './hooks/useThreadFetchers';
2829

30+
import { cloneDeep } from 'lodash';
31+
2932
function hasReqId<T extends object>(
3033
message: T,
3134
): message is T & { reqId: string } {
@@ -56,6 +59,10 @@ const useThread = () => {
5659

5760
const sendMessageStatusActions = {
5861
sendMessageStart: useCallback((message: SendableMessageType) => store.setState(state => {
62+
if ('sendingStatus' in message) {
63+
(message as SendableMessageType).sendingStatus = SendingStatus.PENDING;
64+
}
65+
5966
return {
6067
...state,
6168
localThreadMessages: [
@@ -66,6 +73,10 @@ const useThread = () => {
6673
}), [store]),
6774

6875
sendMessageSuccess: useCallback((message: SendableMessageType) => store.setState(state => {
76+
if ('sendingStatus' in message) {
77+
(message as SendableMessageType).sendingStatus = SendingStatus.SUCCEEDED;
78+
}
79+
6980
return {
7081
...state,
7182
allThreadMessages: [
@@ -81,6 +92,10 @@ const useThread = () => {
8192
}), [store]),
8293

8394
sendMessageFailure: useCallback((message: SendableMessageType) => store.setState(state => {
95+
if ('sendingStatus' in message) {
96+
(message as SendableMessageType).sendingStatus = SendingStatus.FAILED;
97+
}
98+
8499
return {
85100
...state,
86101
localThreadMessages: state.localThreadMessages.map((m) => (
@@ -92,6 +107,10 @@ const useThread = () => {
92107
}), [store]),
93108

94109
resendMessageStart: useCallback((message: SendableMessageType) => store.setState(state => {
110+
if ('sendingStatus' in message) {
111+
(message as SendableMessageType).sendingStatus = SendingStatus.PENDING;
112+
}
113+
95114
return {
96115
...state,
97116
localThreadMessages: state.localThreadMessages.map((m) => (
@@ -235,16 +254,16 @@ const useThread = () => {
235254

236255
initializeThreadListSuccess: useCallback((parentMessage: BaseMessage, anchorMessage: SendableMessageType, threadedMessages: BaseMessage[]) => store.setState(state => {
237256
const anchorMessageCreatedAt = (!anchorMessage?.messageId) ? parentMessage?.createdAt : anchorMessage?.createdAt;
238-
const anchorIndex = threadedMessages.findIndex((message) => message?.createdAt > anchorMessageCreatedAt);
257+
const anchorIndex = threadedMessages.findIndex((message) => message?.createdAt === anchorMessageCreatedAt);
239258
const prevThreadMessages = anchorIndex > -1 ? threadedMessages.slice(0, anchorIndex) : threadedMessages;
240-
const anchorThreadMessage = anchorMessage?.messageId ? [anchorMessage] : [];
241259
const nextThreadMessages = anchorIndex > -1 ? threadedMessages.slice(anchorIndex) : [];
260+
242261
return {
243262
...state,
244263
threadListState: ThreadListStateTypes.INITIALIZED,
245264
hasMorePrev: anchorIndex === -1 || anchorIndex === PREV_THREADS_FETCH_SIZE,
246265
hasMoreNext: threadedMessages.length - anchorIndex === NEXT_THREADS_FETCH_SIZE,
247-
allThreadMessages: [prevThreadMessages, anchorThreadMessage, nextThreadMessages].flat() as CoreMessageType[],
266+
allThreadMessages: [...prevThreadMessages, ...nextThreadMessages] as CoreMessageType[],
248267
};
249268
}), [store]),
250269

@@ -397,18 +416,25 @@ const useThread = () => {
397416
}), [store]),
398417

399418
onReactionUpdated: useCallback((reactionEvent: ReactionEvent) => store.setState(state => {
400-
if (state?.parentMessage?.messageId === reactionEvent?.messageId) {
401-
state.parentMessage?.applyReactionEvent?.(reactionEvent);
419+
let updatedParentMessage = state.parentMessage;
420+
if (state.parentMessage?.messageId === reactionEvent?.messageId) {
421+
updatedParentMessage = cloneDeep(state.parentMessage as SendableMessageType);
422+
updatedParentMessage.applyReactionEvent(reactionEvent);
402423
}
424+
425+
const updatedMessages = state.allThreadMessages.map((m) => {
426+
if (reactionEvent?.messageId === m?.messageId) {
427+
const updatedMessage = cloneDeep(m as CoreMessageType);
428+
updatedMessage.applyReactionEvent(reactionEvent);
429+
return updatedMessage;
430+
}
431+
return m;
432+
});
433+
403434
return {
404435
...state,
405-
allThreadMessages: state.allThreadMessages.map((m) => {
406-
if (reactionEvent?.messageId === m?.messageId) {
407-
m?.applyReactionEvent?.(reactionEvent);
408-
return m;
409-
}
410-
return m;
411-
}),
436+
parentMessage: updatedParentMessage,
437+
allThreadMessages: [...updatedMessages], // Create new array reference to trigger re-render
412438
};
413439
}), [store]),
414440

src/ui/Checkbox/index.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,4 @@
7979
transform: rotate(45deg);
8080
}
8181
}
82-
/**rtl:end:ignore**/
82+
/*rtl:end:ignore*/

src/utils/storeManager.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export function hasStateChanged<T>(prevState: T, updates: Partial<T>): boolean {
1818
*/
1919
return false;
2020
}
21+
2122
return !isEqual(prevState[key as keyof T], value);
2223
});
2324
}

yarn.lock

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2747,9 +2747,9 @@ __metadata:
27472747
languageName: node
27482748
linkType: hard
27492749

2750-
"@sendbird/chat@npm:^4.18.0":
2751-
version: 4.19.5
2752-
resolution: "@sendbird/chat@npm:4.19.5"
2750+
"@sendbird/chat@npm:^4.20.0":
2751+
version: 4.20.0
2752+
resolution: "@sendbird/chat@npm:4.20.0"
27532753
peerDependencies:
27542754
"@react-native-async-storage/async-storage": ^1.17.6
27552755
react-native-mmkv: ">=2.0.0"
@@ -2758,29 +2758,28 @@ __metadata:
27582758
optional: true
27592759
react-native-mmkv:
27602760
optional: true
2761-
checksum: b67d3b9413ae1b61c4261ef540f7b31b21fec925950a2805ac2cb0eac2c981ec001f8d066bce8fc294d6a104a4ad2a0481c1e907e59fa9bcc8a0081411b729c6
2761+
checksum: ad614ef86f382aab8c41b333e02f6eab87409650c44d3aad9fab8f67ff3b2ffb331b38c84b3d70cc95cc9cd5f47b0ee568fc50257fa6b3aecd118ac304d7c494
27622762
languageName: node
27632763
linkType: hard
27642764

2765-
"@sendbird/react-uikit-message-template-view@npm:^0.0.10":
2766-
version: 0.0.10
2767-
resolution: "@sendbird/react-uikit-message-template-view@npm:0.0.10"
2765+
"@sendbird/react-uikit-message-template-view@npm:^0.0.18":
2766+
version: 0.0.18
2767+
resolution: "@sendbird/react-uikit-message-template-view@npm:0.0.18"
27682768
dependencies:
2769-
"@sendbird/uikit-message-template": ^0.0.10
2769+
"@sendbird/uikit-message-template": ^0.0.18
27702770
peerDependencies:
2771-
"@sendbird/chat": ">=4.3.0 <5"
27722771
react: ">=16.8.6"
27732772
react-dom: ">=16.8.6"
2774-
checksum: aac92fb0b963c4ee3f31eea05839cd49c5ad8561c427b5778731fdf61bcbc18076b329ab2866f12b776e77e9b2a9bfbba12263bcf25d4949a34ab80120548d2f
2773+
checksum: 1ce96ee2ff96934aa2d3ce092b2b8799701c5b782e84c04d45fe4dc4cfd3755499de013520edf0f599ce356c941ae1793e5a461d550ecadd14ed5f689f395531
27752774
languageName: node
27762775
linkType: hard
27772776

2778-
"@sendbird/uikit-message-template@npm:^0.0.10":
2779-
version: 0.0.10
2780-
resolution: "@sendbird/uikit-message-template@npm:0.0.10"
2777+
"@sendbird/uikit-message-template@npm:^0.0.18":
2778+
version: 0.0.18
2779+
resolution: "@sendbird/uikit-message-template@npm:0.0.18"
27812780
peerDependencies:
27822781
react: ">=16.8.6"
2783-
checksum: 18dfce8f7c83d37a94bc3cbca0f561d7ed10c4367bcb2d2bf9c9192fce8fa06cfd87e8f968c6f3ae6d464a5119338ee5167b1a055b777bd906664a225c7e486f
2782+
checksum: c732c8effe55c3cc1f659a41f372e934891828281b03aefc504930bbccfb1ac7c5f7f989217ffeb2dadca98b872aa8bde7fb2c8c92506ce99aba23cf1b89d969
27842783
languageName: node
27852784
linkType: hard
27862785

@@ -2803,9 +2802,9 @@ __metadata:
28032802
"@rollup/plugin-node-resolve": ^15.2.3
28042803
"@rollup/plugin-replace": ^5.0.4
28052804
"@rollup/plugin-typescript": ^11.1.5
2806-
"@sendbird/chat": ^4.18.0
2807-
"@sendbird/react-uikit-message-template-view": ^0.0.10
2808-
"@sendbird/uikit-tools": ^0.0.10
2805+
"@sendbird/chat": ^4.20.0
2806+
"@sendbird/react-uikit-message-template-view": ^0.0.18
2807+
"@sendbird/uikit-tools": ^0.0.18
28092808
"@storybook/addon-essentials": ^8.5.0
28102809
"@storybook/manager-api": ^8.5.0
28112810
"@storybook/react-vite": ^8.5.0
@@ -2870,13 +2869,13 @@ __metadata:
28702869
languageName: unknown
28712870
linkType: soft
28722871

2873-
"@sendbird/uikit-tools@npm:^0.0.10":
2874-
version: 0.0.10
2875-
resolution: "@sendbird/uikit-tools@npm:0.0.10"
2872+
"@sendbird/uikit-tools@npm:^0.0.18":
2873+
version: 0.0.18
2874+
resolution: "@sendbird/uikit-tools@npm:0.0.18"
28762875
peerDependencies:
28772876
"@sendbird/chat": ">=4.10.5 <5"
28782877
react: ">=16.8.6"
2879-
checksum: 1b92fe4a5caced7efff4397fdf87912bc958b45f5eae1f986f78961759b18687901cc28bbc6f797a6fb0e1552e56ef5e04a16da0125883f18b00e99fbee5f44b
2878+
checksum: 045565a9e0df7bd180e9a88da8d23543dedc7628b892c1f7e052f576dbc3529f4272852d93434b644a58933371a160de467d9534112df9f9622ab07ca3706b55
28802879
languageName: node
28812880
linkType: hard
28822881

0 commit comments

Comments
 (0)