@sendbird/uikit-chat-hooks 1.1.1 → 2.0.0-rc.0

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.
Files changed (89) hide show
  1. package/README.md +1 -1
  2. package/lib/commonjs/channel/useActiveGroupChannel.js +1 -1
  3. package/lib/commonjs/channel/useActiveGroupChannel.js.map +1 -1
  4. package/lib/commonjs/channel/useGroupChannelList/index.js +3 -0
  5. package/lib/commonjs/channel/useGroupChannelList/index.js.map +1 -1
  6. package/lib/commonjs/channel/useGroupChannelList/useGroupChannelListWithCollection.js +26 -27
  7. package/lib/commonjs/channel/useGroupChannelList/useGroupChannelListWithCollection.js.map +1 -1
  8. package/lib/commonjs/channel/useGroupChannelList/useGroupChannelListWithQuery.js +8 -11
  9. package/lib/commonjs/channel/useGroupChannelList/useGroupChannelListWithQuery.js.map +1 -1
  10. package/lib/commonjs/channel/useGroupChannelMessages/index.js +3 -0
  11. package/lib/commonjs/channel/useGroupChannelMessages/index.js.map +1 -1
  12. package/lib/commonjs/channel/useGroupChannelMessages/reducer.js.map +1 -1
  13. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +83 -87
  14. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
  15. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +32 -20
  16. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
  17. package/lib/commonjs/common/useMessageOutgoingStatus.js +8 -4
  18. package/lib/commonjs/common/useMessageOutgoingStatus.js.map +1 -1
  19. package/lib/commonjs/common/usePushTrigger.js +13 -5
  20. package/lib/commonjs/common/usePushTrigger.js.map +1 -1
  21. package/lib/commonjs/common/useTotalUnreadChannelCount.js +4 -2
  22. package/lib/commonjs/common/useTotalUnreadChannelCount.js.map +1 -1
  23. package/lib/commonjs/common/useTotalUnreadMessageCount.js +12 -15
  24. package/lib/commonjs/common/useTotalUnreadMessageCount.js.map +1 -1
  25. package/lib/commonjs/handler/useChannelHandler.js +5 -3
  26. package/lib/commonjs/handler/useChannelHandler.js.map +1 -1
  27. package/lib/commonjs/handler/useConnectionHandler.js +5 -3
  28. package/lib/commonjs/handler/useConnectionHandler.js.map +1 -1
  29. package/lib/commonjs/handler/useUserEventHandler.js +19 -6
  30. package/lib/commonjs/handler/useUserEventHandler.js.map +1 -1
  31. package/lib/commonjs/types.js.map +1 -1
  32. package/lib/module/channel/useActiveGroupChannel.js +1 -1
  33. package/lib/module/channel/useActiveGroupChannel.js.map +1 -1
  34. package/lib/module/channel/useGroupChannelList/index.js +2 -0
  35. package/lib/module/channel/useGroupChannelList/index.js.map +1 -1
  36. package/lib/module/channel/useGroupChannelList/useGroupChannelListWithCollection.js +26 -28
  37. package/lib/module/channel/useGroupChannelList/useGroupChannelListWithCollection.js.map +1 -1
  38. package/lib/module/channel/useGroupChannelList/useGroupChannelListWithQuery.js +8 -12
  39. package/lib/module/channel/useGroupChannelList/useGroupChannelListWithQuery.js.map +1 -1
  40. package/lib/module/channel/useGroupChannelMessages/index.js +2 -0
  41. package/lib/module/channel/useGroupChannelMessages/index.js.map +1 -1
  42. package/lib/module/channel/useGroupChannelMessages/reducer.js.map +1 -1
  43. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +81 -87
  44. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
  45. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +33 -21
  46. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
  47. package/lib/module/common/useMessageOutgoingStatus.js +8 -4
  48. package/lib/module/common/useMessageOutgoingStatus.js.map +1 -1
  49. package/lib/module/common/usePushTrigger.js +11 -5
  50. package/lib/module/common/usePushTrigger.js.map +1 -1
  51. package/lib/module/common/useTotalUnreadChannelCount.js +4 -2
  52. package/lib/module/common/useTotalUnreadChannelCount.js.map +1 -1
  53. package/lib/module/common/useTotalUnreadMessageCount.js +12 -17
  54. package/lib/module/common/useTotalUnreadMessageCount.js.map +1 -1
  55. package/lib/module/handler/useChannelHandler.js +4 -3
  56. package/lib/module/handler/useChannelHandler.js.map +1 -1
  57. package/lib/module/handler/useConnectionHandler.js +4 -3
  58. package/lib/module/handler/useConnectionHandler.js.map +1 -1
  59. package/lib/module/handler/useUserEventHandler.js +19 -7
  60. package/lib/module/handler/useUserEventHandler.js.map +1 -1
  61. package/lib/module/types.js.map +1 -1
  62. package/lib/typescript/src/channel/useActiveGroupChannel.d.ts +2 -2
  63. package/lib/typescript/src/channel/useGroupChannelList/reducer.d.ts +1 -1
  64. package/lib/typescript/src/channel/useGroupChannelMessages/reducer.d.ts +4 -4
  65. package/lib/typescript/src/common/useMessageOutgoingStatus.d.ts +2 -2
  66. package/lib/typescript/src/common/usePushTrigger.d.ts +9 -3
  67. package/lib/typescript/src/common/useTotalUnreadMessageCount.d.ts +4 -4
  68. package/lib/typescript/src/common/useUserList.d.ts +1 -1
  69. package/lib/typescript/src/handler/useChannelHandler.d.ts +2 -2
  70. package/lib/typescript/src/handler/useConnectionHandler.d.ts +2 -2
  71. package/lib/typescript/src/handler/useUserEventHandler.d.ts +2 -3
  72. package/lib/typescript/src/types.d.ts +7 -8
  73. package/package.json +5 -5
  74. package/src/channel/useActiveGroupChannel.ts +1 -1
  75. package/src/channel/useGroupChannelList/index.ts +3 -0
  76. package/src/channel/useGroupChannelList/useGroupChannelListWithCollection.ts +22 -25
  77. package/src/channel/useGroupChannelList/useGroupChannelListWithQuery.ts +10 -15
  78. package/src/channel/useGroupChannelMessages/index.ts +3 -0
  79. package/src/channel/useGroupChannelMessages/reducer.ts +4 -9
  80. package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.ts +79 -78
  81. package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.ts +59 -34
  82. package/src/common/useMessageOutgoingStatus.ts +8 -13
  83. package/src/common/usePushTrigger.ts +13 -7
  84. package/src/common/useTotalUnreadChannelCount.ts +4 -2
  85. package/src/common/useTotalUnreadMessageCount.ts +14 -25
  86. package/src/handler/useChannelHandler.ts +5 -5
  87. package/src/handler/useConnectionHandler.ts +5 -5
  88. package/src/handler/useUserEventHandler.ts +15 -8
  89. package/src/types.ts +10 -10
@@ -1,14 +1,19 @@
1
1
  import { useCallback, useEffect, useRef } from 'react';
2
2
 
3
+ import { MessageCollectionInitPolicy, MessageFilter } from '@sendbird/chat/groupChannel';
3
4
  import type {
4
5
  SendbirdChannel,
5
- SendbirdChatSDK,
6
6
  SendbirdFileMessage,
7
7
  SendbirdGroupChannel,
8
8
  SendbirdMessageCollection,
9
- SendbirdUserMessage,
10
9
  } from '@sendbird/uikit-utils';
11
- import { Logger, NOOP, isDifferentChannel, useForceUpdate, useIsMountedRef } from '@sendbird/uikit-utils';
10
+ import {
11
+ Logger,
12
+ confirmAndMarkAsDelivered,
13
+ confirmAndMarkAsRead,
14
+ isDifferentChannel,
15
+ useForceUpdate,
16
+ } from '@sendbird/uikit-utils';
12
17
 
13
18
  import { useAppFeatures } from '../../common/useAppFeatures';
14
19
  import { useChannelHandler } from '../../handler/useChannelHandler';
@@ -17,25 +22,17 @@ import { useActiveGroupChannel } from '../useActiveGroupChannel';
17
22
  import { useGroupChannelMessagesReducer } from './reducer';
18
23
 
19
24
  const createMessageCollection = (
20
- sdk: SendbirdChatSDK,
21
25
  channel: SendbirdGroupChannel,
22
26
  creator?: UseGroupChannelMessagesOptions['collectionCreator'],
23
27
  ) => {
24
28
  if (creator) return creator();
25
- const collection = channel.createMessageCollection();
26
- const filter = new sdk.MessageFilter();
27
- return collection.setLimit(100).setFilter(filter).build();
29
+ const filter = new MessageFilter();
30
+ return channel.createMessageCollection({ filter, limit: 100 });
28
31
  };
29
32
 
30
33
  const HOOK_NAME = 'useGroupChannelMessagesWithCollection';
31
34
 
32
- // FIXME: MessageCollection event handler bug, initialize(run async addObserver) -> dispose -> removeObserver -> addObserver called
33
35
  export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (sdk, channel, userId, options) => {
34
- const isMounted = useIsMountedRef();
35
- const disposeManuallyAfterUnmounted = () => {
36
- if (!isMounted.current && collectionRef.current) collectionRef.current.dispose();
37
- };
38
-
39
36
  const { deliveryReceiptEnabled } = useAppFeatures(sdk);
40
37
 
41
38
  const collectionRef = useRef<SendbirdMessageCollection>();
@@ -60,12 +57,12 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
60
57
 
61
58
  const channelMarkAs = async () => {
62
59
  try {
63
- if (deliveryReceiptEnabled) sdk.markAsDelivered(activeChannel.url);
60
+ if (deliveryReceiptEnabled) await confirmAndMarkAsDelivered(sdk, activeChannel);
64
61
  } catch (e) {
65
62
  Logger.warn(`[${HOOK_NAME}/channelMarkAs/Delivered]`, e);
66
63
  }
67
64
  try {
68
- await sdk.markAsReadWithChannelUrls([activeChannel.url]);
65
+ await confirmAndMarkAsRead(sdk, [activeChannel]);
69
66
  } catch (e) {
70
67
  Logger.warn(`[${HOOK_NAME}/channelMarkAs/Read]`, e);
71
68
  }
@@ -82,12 +79,38 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
82
79
  if (collectionRef.current) collectionRef.current?.dispose();
83
80
 
84
81
  if (uid) {
85
- collectionRef.current = createMessageCollection(sdk, activeChannel, options?.collectionCreator);
82
+ collectionRef.current = createMessageCollection(activeChannel, options?.collectionCreator);
86
83
  updateNextMessages([], true, sdk.currentUser.userId);
87
84
  channelMarkAs();
88
85
 
86
+ collectionRef.current?.setMessageCollectionHandler({
87
+ onMessagesAdded: (_, channel, messages) => {
88
+ channelMarkAs();
89
+ updateNextMessages(messages, false, sdk.currentUser.userId);
90
+ updateChannel(channel);
91
+ },
92
+ onMessagesUpdated: (_, channel, messages) => {
93
+ updateMessages(messages, false, sdk.currentUser.userId);
94
+ updateChannel(channel);
95
+ },
96
+ onMessagesDeleted: (_, channel, messageIds) => {
97
+ deleteMessages(messageIds, []);
98
+ deleteNextMessages(messageIds, []);
99
+ updateChannel(channel);
100
+ },
101
+ onChannelDeleted: () => {
102
+ options?.onChannelDeleted?.();
103
+ },
104
+ onChannelUpdated: (_, channel) => {
105
+ updateChannel(channel);
106
+ },
107
+ onHugeGapDetected: () => {
108
+ init(uid);
109
+ },
110
+ });
111
+
89
112
  collectionRef.current
90
- .initialize(sdk.MessageCollection.MessageCollectionInitPolicy.CACHE_AND_REPLACE_BY_API)
113
+ .initialize(MessageCollectionInitPolicy.CACHE_AND_REPLACE_BY_API)
91
114
  .onCacheResult((err, messages) => {
92
115
  if (err) sdk.isCacheEnabled && Logger.error(`[${HOOK_NAME}/onCacheResult]`, err);
93
116
  else {
@@ -110,43 +133,6 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
110
133
  }
111
134
  callback?.();
112
135
  });
113
-
114
- collectionRef.current.setMessageCollectionHandler({
115
- onMessagesAdded(_, channel, messages) {
116
- disposeManuallyAfterUnmounted();
117
- channelMarkAs();
118
- updateNextMessages(messages, false, sdk.currentUser.userId);
119
- updateChannel(channel);
120
- },
121
- onMessagesUpdated(_, channel, messages) {
122
- disposeManuallyAfterUnmounted();
123
- updateMessages(messages, false, sdk.currentUser.userId);
124
- updateChannel(channel);
125
- },
126
- onMessagesDeleted(_, channel, messages) {
127
- disposeManuallyAfterUnmounted();
128
- const msgIds = messages.map((m) => m.messageId);
129
- const reqIds = messages
130
- .filter((m): m is SendbirdUserMessage | SendbirdFileMessage => 'reqId' in m)
131
- .map((m) => m.reqId);
132
-
133
- deleteMessages(msgIds, reqIds);
134
- deleteNextMessages(msgIds, reqIds);
135
- updateChannel(channel);
136
- },
137
- onChannelDeleted() {
138
- disposeManuallyAfterUnmounted();
139
- options?.onChannelDeleted?.();
140
- },
141
- onChannelUpdated(_, channel) {
142
- disposeManuallyAfterUnmounted();
143
- updateChannel(channel);
144
- },
145
- onHugeGapDetected() {
146
- disposeManuallyAfterUnmounted();
147
- init(uid);
148
- },
149
- });
150
136
  }
151
137
  },
152
138
  [sdk, activeChannel.url, options?.collectionCreator],
@@ -154,7 +140,6 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
154
140
 
155
141
  useChannelHandler(sdk, HOOK_NAME, {
156
142
  onUserBanned(channel, bannedUser) {
157
- disposeManuallyAfterUnmounted();
158
143
  if (channel.isGroupChannel() && !isDifferentChannel(channel, activeChannel)) {
159
144
  if (bannedUser.userId === sdk.currentUser.userId) {
160
145
  options?.onChannelDeleted?.();
@@ -214,16 +199,23 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
214
199
  const sendUserMessage: ReturnType<UseGroupChannelMessages>['sendUserMessage'] = useCallback(
215
200
  (params, onPending) => {
216
201
  return new Promise((resolve, reject) => {
217
- const pendingMessage = activeChannel.sendUserMessage(params, (sentMessage, error) => {
218
- if (error) reject(error);
219
- else {
220
- updateMessages([sentMessage], false, sdk.currentUser.userId);
221
- resolve(sentMessage);
222
- }
223
- });
224
-
225
- onPending?.(pendingMessage);
226
- updateMessages([pendingMessage], false, sdk.currentUser.userId);
202
+ activeChannel
203
+ .sendUserMessage(params)
204
+ .onPending((pendingMessage) => {
205
+ if (pendingMessage.isUserMessage()) {
206
+ onPending?.(pendingMessage);
207
+ updateMessages([pendingMessage], false, sdk.currentUser.userId);
208
+ }
209
+ })
210
+ .onSucceeded((sentMessage) => {
211
+ if (sentMessage.isUserMessage()) {
212
+ updateMessages([sentMessage], false, sdk.currentUser.userId);
213
+ resolve(sentMessage);
214
+ }
215
+ })
216
+ .onFailed((err) => {
217
+ reject(err);
218
+ });
227
219
  });
228
220
  },
229
221
  [activeChannel],
@@ -231,23 +223,30 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
231
223
  const sendFileMessage: ReturnType<UseGroupChannelMessages>['sendFileMessage'] = useCallback(
232
224
  (params, onPending) => {
233
225
  return new Promise((resolve, reject) => {
234
- const pendingMessage = activeChannel.sendFileMessage(params, (sentMessage, error) => {
235
- if (error) reject(error);
236
- else {
237
- updateMessages([sentMessage], false, sdk.currentUser.userId);
238
- resolve(sentMessage as SendbirdFileMessage);
239
- }
240
- });
241
-
242
- updateMessages([pendingMessage], false, sdk.currentUser.userId);
243
- onPending?.(pendingMessage);
226
+ activeChannel
227
+ .sendFileMessage(params)
228
+ .onPending((pendingMessage) => {
229
+ if (pendingMessage.isFileMessage()) {
230
+ updateMessages([pendingMessage], false, sdk.currentUser.userId);
231
+ onPending?.(pendingMessage);
232
+ }
233
+ })
234
+ .onSucceeded((sentMessage) => {
235
+ if (sentMessage.isFileMessage()) {
236
+ updateMessages([sentMessage], false, sdk.currentUser.userId);
237
+ resolve(sentMessage as SendbirdFileMessage);
238
+ }
239
+ })
240
+ .onFailed((err) => {
241
+ reject(err);
242
+ });
244
243
  });
245
244
  },
246
245
  [activeChannel],
247
246
  );
248
247
  const updateUserMessage: ReturnType<UseGroupChannelMessages>['updateUserMessage'] = useCallback(
249
248
  async (messageId, params) => {
250
- const updatedMessage = await activeChannel.updateUserMessage(messageId, params, NOOP);
249
+ const updatedMessage = await activeChannel.updateUserMessage(messageId, params);
251
250
  updateMessages([updatedMessage], false, sdk.currentUser.userId);
252
251
  return updatedMessage;
253
252
  },
@@ -255,7 +254,7 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
255
254
  );
256
255
  const updateFileMessage: ReturnType<UseGroupChannelMessages>['updateFileMessage'] = useCallback(
257
256
  async (messageId, params) => {
258
- const updatedMessage = await activeChannel.updateFileMessage(messageId, params, NOOP);
257
+ const updatedMessage = await activeChannel.updateFileMessage(messageId, params);
259
258
  updateMessages([updatedMessage], false, sdk.currentUser.userId);
260
259
  return updatedMessage;
261
260
  },
@@ -265,6 +264,8 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
265
264
  async (failedMessage) => {
266
265
  const message = await (() => {
267
266
  if (failedMessage.isUserMessage()) return activeChannel.resendUserMessage(failedMessage);
267
+ // FIXME: v4 bugs
268
+ // @ts-ignore
268
269
  if (failedMessage.isFileMessage()) return activeChannel.resendFileMessage(failedMessage);
269
270
  return null;
270
271
  })();
@@ -280,7 +281,7 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
280
281
  if (message.isFileMessage()) await activeChannel.deleteMessage(message);
281
282
  } else {
282
283
  try {
283
- await collectionRef.current?.removeFailedMessages([message]);
284
+ await collectionRef.current?.removeFailedMessage(message.reqId);
284
285
  } finally {
285
286
  deleteMessages([message.messageId], [message.reqId]);
286
287
  }
@@ -1,8 +1,15 @@
1
1
  import { useCallback, useRef } from 'react';
2
- import type Sendbird from 'sendbird';
3
2
 
4
- import type { SendbirdFileMessage, SendbirdGroupChannel, SendbirdOpenChannel } from '@sendbird/uikit-utils';
5
- import { Logger, isDifferentChannel, useAsyncEffect, useForceUpdate } from '@sendbird/uikit-utils';
3
+ import type { SendbirdBaseChannel, SendbirdGroupChannel } from '@sendbird/uikit-utils';
4
+ import {
5
+ Logger,
6
+ confirmAndMarkAsDelivered,
7
+ confirmAndMarkAsRead,
8
+ isDifferentChannel,
9
+ useAsyncEffect,
10
+ useForceUpdate,
11
+ } from '@sendbird/uikit-utils';
12
+ import type { SendbirdPreviousMessageListQuery } from '@sendbird/uikit-utils';
6
13
 
7
14
  import { useAppFeatures } from '../../common/useAppFeatures';
8
15
  import { useChannelHandler } from '../../handler/useChannelHandler';
@@ -15,17 +22,17 @@ const createMessageQuery = (
15
22
  creator?: UseGroupChannelMessagesOptions['queryCreator'],
16
23
  ) => {
17
24
  if (creator) return creator();
18
- const query = channel.createPreviousMessageListQuery();
19
- query.limit = 100;
20
- query.reverse = true;
21
- return query;
25
+ return channel.createPreviousMessageListQuery({
26
+ limit: 100,
27
+ reverse: true,
28
+ });
22
29
  };
23
30
 
24
31
  const HOOK_NAME = 'useGroupChannelMessagesWithQuery';
25
32
  export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, channel, userId, options) => {
26
33
  const { deliveryReceiptEnabled } = useAppFeatures(sdk);
27
34
 
28
- const queryRef = useRef<Sendbird.PreviousMessageListQuery>();
35
+ const queryRef = useRef<SendbirdPreviousMessageListQuery>();
29
36
 
30
37
  // NOTE: We cannot determine the channel object of Sendbird SDK is stale or not, so force update after setActiveChannel
31
38
  const { activeChannel, setActiveChannel } = useActiveGroupChannel(sdk, channel);
@@ -47,12 +54,12 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
47
54
 
48
55
  const channelMarkAs = async () => {
49
56
  try {
50
- if (deliveryReceiptEnabled) sdk.markAsDelivered(activeChannel.url);
57
+ if (deliveryReceiptEnabled) await confirmAndMarkAsDelivered(sdk, activeChannel);
51
58
  } catch (e) {
52
59
  Logger.warn(`[${HOOK_NAME}/channelMarkAs/Delivered]`, e);
53
60
  }
54
61
  try {
55
- await sdk.markAsReadWithChannelUrls([activeChannel.url]);
62
+ await confirmAndMarkAsRead(sdk, [activeChannel]);
56
63
  } catch (e) {
57
64
  Logger.warn(`[${HOOK_NAME}/channelMarkAs/Read]`, e);
58
65
  }
@@ -62,8 +69,8 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
62
69
  async (uid?: string) => {
63
70
  if (uid) {
64
71
  queryRef.current = createMessageQuery(activeChannel, options?.queryCreator);
65
- channelMarkAs();
66
- if (queryRef.current?.hasMore) {
72
+ channelMarkAs().catch();
73
+ if (queryRef.current?.hasNext) {
67
74
  const list = await queryRef.current?.load();
68
75
  updateMessages(list, true, sdk.currentUser.userId);
69
76
  }
@@ -73,7 +80,7 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
73
80
  [sdk, activeChannel.url, options?.queryCreator],
74
81
  );
75
82
 
76
- const channelUpdater = (channel: SendbirdGroupChannel | SendbirdOpenChannel) => {
83
+ const channelUpdater = (channel: SendbirdBaseChannel) => {
77
84
  if (channel.isGroupChannel() && !isDifferentChannel(channel, activeChannel)) {
78
85
  setActiveChannel(channel);
79
86
  forceUpdate();
@@ -111,8 +118,8 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
111
118
  // Users
112
119
  onOperatorUpdated: channelUpdater,
113
120
  onUserLeft: channelUpdater,
114
- onUserEntered: channelUpdater,
115
- onUserExited: channelUpdater,
121
+ // onUserEntered: channelUpdater,
122
+ // onUserExited: channelUpdater,
116
123
  onUserJoined: channelUpdater,
117
124
  onUserUnbanned: channelUpdater,
118
125
  onUserMuted: channelUpdater,
@@ -141,7 +148,7 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
141
148
  }, [init, userId]);
142
149
 
143
150
  const prev: ReturnType<UseGroupChannelMessages>['prev'] = useCallback(async () => {
144
- if (queryRef.current && queryRef.current?.hasMore) {
151
+ if (queryRef.current && queryRef.current?.hasNext) {
145
152
  const list = await queryRef.current?.load();
146
153
  updateMessages(list, false, sdk.currentUser.userId);
147
154
  }
@@ -157,15 +164,23 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
157
164
  const sendUserMessage: ReturnType<UseGroupChannelMessages>['sendUserMessage'] = useCallback(
158
165
  (params, onPending) => {
159
166
  return new Promise((resolve, reject) => {
160
- const pendingMessage = activeChannel.sendUserMessage(params, (sentMessage, error) => {
161
- if (error) reject(error);
162
- else {
163
- updateNextMessages([sentMessage], false, sdk.currentUser.userId);
164
- resolve(sentMessage);
165
- }
166
- });
167
- updateNextMessages([pendingMessage], false, sdk.currentUser.userId);
168
- onPending?.(pendingMessage);
167
+ activeChannel
168
+ .sendUserMessage(params)
169
+ .onPending((pendingMessage) => {
170
+ if (pendingMessage.isUserMessage()) {
171
+ updateNextMessages([pendingMessage], false, sdk.currentUser.userId);
172
+ onPending?.(pendingMessage);
173
+ }
174
+ })
175
+ .onSucceeded((sentMessage) => {
176
+ if (sentMessage.isUserMessage()) {
177
+ updateNextMessages([sentMessage], false, sdk.currentUser.userId);
178
+ resolve(sentMessage);
179
+ }
180
+ })
181
+ .onFailed((err) => {
182
+ reject(err);
183
+ });
169
184
  });
170
185
  },
171
186
  [activeChannel],
@@ -173,15 +188,23 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
173
188
  const sendFileMessage: ReturnType<UseGroupChannelMessages>['sendFileMessage'] = useCallback(
174
189
  (params, onPending) => {
175
190
  return new Promise((resolve, reject) => {
176
- const pendingMessage = activeChannel.sendFileMessage(params, (sentMessage, error) => {
177
- if (error) reject(error);
178
- else {
179
- updateNextMessages([sentMessage], false, sdk.currentUser.userId);
180
- resolve(sentMessage as SendbirdFileMessage);
181
- }
182
- });
183
- updateNextMessages([pendingMessage], false, sdk.currentUser.userId);
184
- onPending?.(pendingMessage);
191
+ activeChannel
192
+ .sendFileMessage(params)
193
+ .onPending((pendingMessage) => {
194
+ if (pendingMessage.isFileMessage()) {
195
+ updateNextMessages([pendingMessage], false, sdk.currentUser.userId);
196
+ onPending?.(pendingMessage);
197
+ }
198
+ })
199
+ .onSucceeded((sentMessage) => {
200
+ if (sentMessage.isFileMessage()) {
201
+ updateNextMessages([sentMessage], false, sdk.currentUser.userId);
202
+ resolve(sentMessage);
203
+ }
204
+ })
205
+ .onFailed((err) => {
206
+ reject(err);
207
+ });
185
208
  });
186
209
  },
187
210
  [activeChannel],
@@ -206,6 +229,8 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
206
229
  async (failedMessage) => {
207
230
  const message = await (() => {
208
231
  if (failedMessage.isUserMessage()) return activeChannel.resendUserMessage(failedMessage);
232
+ // FIXME: v4 bugs
233
+ // @ts-ignore
209
234
  if (failedMessage.isFileMessage()) return activeChannel.resendFileMessage(failedMessage);
210
235
  return null;
211
236
  })();
@@ -1,10 +1,4 @@
1
- import type {
2
- SendbirdAdminMessage,
3
- SendbirdChatSDK,
4
- SendbirdFileMessage,
5
- SendbirdGroupChannel,
6
- SendbirdUserMessage,
7
- } from '@sendbird/uikit-utils';
1
+ import type { SendbirdChatSDK, SendbirdGroupChannel, SendbirdMessage } from '@sendbird/uikit-utils';
8
2
  import { isDifferentChannel, isMyMessage, useForceUpdate, useUniqId } from '@sendbird/uikit-utils';
9
3
 
10
4
  import { useChannelHandler } from '../handler/useChannelHandler';
@@ -17,7 +11,7 @@ export type SBUOutgoingStatus = 'NONE' | 'PENDING' | 'FAILED' | 'UNDELIVERED' |
17
11
  export const useMessageOutgoingStatus = (
18
12
  sdk: SendbirdChatSDK,
19
13
  channel: SendbirdGroupChannel,
20
- message?: SendbirdFileMessage | SendbirdUserMessage | SendbirdAdminMessage | null,
14
+ message?: SendbirdMessage | null,
21
15
  ): SBUOutgoingStatus => {
22
16
  const features = useAppFeatures(sdk);
23
17
  const forceUpdate = useForceUpdate();
@@ -25,13 +19,13 @@ export const useMessageOutgoingStatus = (
25
19
 
26
20
  const uniqId = useUniqId(HOOK_NAME);
27
21
  useChannelHandler(sdk, `${HOOK_NAME}_${uniqId}`, {
28
- onDeliveryReceiptUpdated(eventChannel) {
22
+ onUndeliveredMemberStatusUpdated(eventChannel) {
29
23
  if (isDifferentChannel(channel, eventChannel)) return;
30
24
  if (!isMyMessage(message, currentUser?.userId)) return;
31
25
 
32
26
  forceUpdate();
33
27
  },
34
- onReadReceiptUpdated(eventChannel) {
28
+ onUnreadMemberStatusUpdated(eventChannel) {
35
29
  if (isDifferentChannel(channel, eventChannel)) return;
36
30
  if (!isMyMessage(message, currentUser?.userId)) return;
37
31
 
@@ -41,9 +35,10 @@ export const useMessageOutgoingStatus = (
41
35
 
42
36
  if (!message) return 'NONE';
43
37
 
44
- if (message.sendingStatus === 'pending') return 'PENDING';
45
-
46
- if (message.sendingStatus === 'failed') return 'FAILED';
38
+ if ('sendingStatus' in message) {
39
+ if (message.sendingStatus === 'pending') return 'PENDING';
40
+ if (message.sendingStatus === 'failed') return 'FAILED';
41
+ }
47
42
 
48
43
  if (channel.getUnreadMemberCount(message) === 0) return 'READ';
49
44
 
@@ -1,17 +1,24 @@
1
1
  import { useCallback, useState } from 'react';
2
2
 
3
+ import { PushTriggerOption } from '@sendbird/chat';
3
4
  import type { SendbirdChatSDK } from '@sendbird/uikit-utils';
4
5
  import { Logger, useAsyncEffect } from '@sendbird/uikit-utils';
5
6
 
6
- type PushTriggerOptionType = 'all' | 'mention_only' | 'off';
7
+ const PushTriggerMap = {
8
+ 'all': PushTriggerOption.ALL,
9
+ 'mention_only': PushTriggerOption.MENTION_ONLY,
10
+ 'off': PushTriggerOption.OFF,
11
+ 'default': PushTriggerOption.DEFAULT,
12
+ };
13
+
7
14
  export const usePushTrigger = (sdk: SendbirdChatSDK) => {
8
- const [option, setOption] = useState<PushTriggerOptionType>('off');
15
+ const [option, setOption] = useState<PushTriggerOption>(PushTriggerOption.DEFAULT);
9
16
 
10
17
  const updateOption = useCallback(
11
- async (value: PushTriggerOptionType) => {
18
+ async (value: keyof typeof PushTriggerMap) => {
12
19
  try {
13
- await sdk.setPushTriggerOption(value);
14
- setOption(value);
20
+ const _option = PushTriggerMap[value];
21
+ await sdk.setPushTriggerOption(_option).then(() => setOption(_option));
15
22
  } catch (e) {
16
23
  Logger.warn('[usePushTrigger]', 'Cannot update push trigger option', e);
17
24
  }
@@ -20,8 +27,7 @@ export const usePushTrigger = (sdk: SendbirdChatSDK) => {
20
27
  );
21
28
 
22
29
  useAsyncEffect(async () => {
23
- const currentOption = await sdk.getPushTriggerOption();
24
- setOption(currentOption as PushTriggerOptionType);
30
+ setOption(await sdk.getPushTriggerOption());
25
31
  }, [sdk, sdk.currentUser]);
26
32
 
27
33
  return {
@@ -15,11 +15,13 @@ export const useTotalUnreadChannelCount = (sdk: SendbirdChatSDK, params?: Params
15
15
  const [unreadChannelCount, setUnreadChannelCount] = useState(0);
16
16
 
17
17
  useAsyncEffect(async () => {
18
- setUnreadChannelCount(await sdk.getTotalUnreadChannelCount());
18
+ setUnreadChannelCount(await sdk.groupChannel.getTotalUnreadChannelCount());
19
19
  }, [sdk]);
20
20
 
21
21
  useUserEventHandler(sdk, HOOK_NAME + id, {
22
- onTotalUnreadMessageCountUpdated: async () => setUnreadChannelCount(await sdk.getTotalUnreadChannelCount()),
22
+ onTotalUnreadMessageCountUpdated: async () => {
23
+ setUnreadChannelCount(await sdk.groupChannel.getTotalUnreadChannelCount());
24
+ },
23
25
  });
24
26
 
25
27
  return truncatedBadgeCount(unreadChannelCount, params?.maxCount);
@@ -1,43 +1,32 @@
1
1
  import { useState } from 'react';
2
- import type Sendbird from 'sendbird';
3
2
 
3
+ import { SuperChannelFilter, TotalUnreadMessageCountParams } from '@sendbird/chat/groupChannel';
4
4
  import type { SendbirdChatSDK } from '@sendbird/uikit-utils';
5
- import { truncatedBadgeCount, useAsyncEffect } from '@sendbird/uikit-utils';
6
- import { useUniqId } from '@sendbird/uikit-utils';
5
+ import { truncatedBadgeCount, useAsyncEffect, useUniqId } from '@sendbird/uikit-utils';
7
6
 
8
7
  import { useUserEventHandler } from '../handler/useUserEventHandler';
9
8
 
10
- type Params = {
11
- paramCreator?: () => Sendbird.GroupChannelTotalUnreadMessageCountParams;
9
+ type Options = {
10
+ params?: TotalUnreadMessageCountParams;
12
11
  maxCount?: number;
13
12
  };
14
13
 
15
14
  const HOOK_NAME = 'useTotalUnreadMessageCount';
16
- export const useTotalUnreadMessageCount = (sdk: SendbirdChatSDK, params?: Params) => {
15
+ export const useTotalUnreadMessageCount = (sdk: SendbirdChatSDK, options?: Options) => {
17
16
  const id = useUniqId(HOOK_NAME);
18
17
  const [unreadMessageCount, setUnreadMessageCount] = useState(0);
19
18
 
20
19
  useAsyncEffect(async () => {
21
- let param;
22
- if (params?.paramCreator) {
23
- param = params.paramCreator();
24
- } else {
25
- const params = new sdk.GroupChannelTotalUnreadMessageCountParams();
26
- params.superChannelFilter = 'all';
27
- param = params;
28
- }
29
- const unreadCount = await sdk.getTotalUnreadMessageCount(param);
20
+ const unreadCount = await sdk.groupChannel.getTotalUnreadMessageCount({
21
+ superChannelFilter: SuperChannelFilter.ALL,
22
+ ...options?.params,
23
+ });
30
24
  setUnreadMessageCount(unreadCount);
31
- }, [sdk, params?.paramCreator]);
25
+ }, [sdk, options?.params?.superChannelFilter, options?.params?.channelCustomTypesFilter]);
32
26
 
33
- useUserEventHandler(
34
- sdk,
35
- `${HOOK_NAME}_${id}`,
36
- {
37
- onTotalUnreadMessageCountUpdated: (totalCount: number) => setUnreadMessageCount(totalCount),
38
- },
39
- [sdk],
40
- );
27
+ useUserEventHandler(sdk, `${HOOK_NAME}_${id}`, {
28
+ onTotalUnreadMessageCountUpdated: (totalCount: number) => setUnreadMessageCount(totalCount),
29
+ });
41
30
 
42
- return truncatedBadgeCount(unreadMessageCount, params?.maxCount);
31
+ return truncatedBadgeCount(unreadMessageCount, options?.maxCount);
43
32
  };
@@ -1,12 +1,12 @@
1
1
  import { useEffect, useLayoutEffect, useRef } from 'react';
2
- import type Sendbird from 'sendbird';
3
2
 
3
+ import { GroupChannelHandler } from '@sendbird/chat/groupChannel';
4
4
  import { Logger, SendbirdChatSDK } from '@sendbird/uikit-utils';
5
5
 
6
6
  export const useChannelHandler = (
7
7
  sdk: SendbirdChatSDK,
8
8
  handlerId: string,
9
- hookHandler: Partial<Sendbird.ChannelHandler>,
9
+ hookHandler: Partial<GroupChannelHandler>,
10
10
  ) => {
11
11
  const handlerRef = useRef(hookHandler);
12
12
  useLayoutEffect(() => {
@@ -16,7 +16,7 @@ export const useChannelHandler = (
16
16
  useEffect(() => {
17
17
  Logger.debug('[useChannelHandler] hook called by', handlerId);
18
18
 
19
- const handler = new sdk.ChannelHandler();
19
+ const handler = new GroupChannelHandler();
20
20
  const handlerKeys = Object.keys(handler) as (keyof typeof handler)[];
21
21
  handlerKeys.forEach((key) => {
22
22
  handler[key] = (...args: unknown[]) => {
@@ -25,7 +25,7 @@ export const useChannelHandler = (
25
25
  };
26
26
  });
27
27
 
28
- sdk.addChannelHandler(handlerId, handler);
29
- return () => sdk.removeChannelHandler(handlerId);
28
+ sdk.groupChannel.addGroupChannelHandler(handlerId, handler);
29
+ return () => sdk.groupChannel.removeGroupChannelHandler(handlerId);
30
30
  }, [sdk, handlerId]);
31
31
  };
@@ -1,22 +1,22 @@
1
1
  import React, { useEffect } from 'react';
2
- import type Sendbird from 'sendbird';
3
2
 
3
+ import { ConnectionHandler } from '@sendbird/chat';
4
4
  import { Logger, SendbirdChatSDK } from '@sendbird/uikit-utils';
5
5
 
6
6
  export const useConnectionHandler = (
7
7
  sdk: SendbirdChatSDK,
8
8
  handlerId: string,
9
- hookHandler: Partial<Sendbird.ConnectionHandler>,
9
+ hookHandler: Partial<ConnectionHandler>,
10
10
  deps: React.DependencyList = [],
11
11
  ) => {
12
12
  useEffect(() => {
13
13
  Logger.info('[useConnectionHandler]', handlerId);
14
14
 
15
- const handler = new sdk.ConnectionHandler();
15
+ const handler = new ConnectionHandler();
16
16
  const handlerKeys = Object.keys(handler) as (keyof typeof handler)[];
17
17
  handlerKeys.forEach((key) => {
18
- const hookHandlerFn = hookHandler[key];
19
- if (hookHandlerFn) handler[key] = hookHandlerFn;
18
+ // @ts-ignore
19
+ if (hookHandler[key]) handler[key] = hookHandler[key];
20
20
  });
21
21
 
22
22
  sdk.addConnectionHandler(handlerId, handler);