@sendbird/uikit-chat-hooks 2.3.0 → 2.4.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 (105) hide show
  1. package/lib/commonjs/channel/useGroupChannelList/useGroupChannelListWithCollection.js +2 -4
  2. package/lib/commonjs/channel/useGroupChannelList/useGroupChannelListWithCollection.js.map +1 -1
  3. package/lib/commonjs/channel/useGroupChannelList/useGroupChannelListWithQuery.js +2 -3
  4. package/lib/commonjs/channel/useGroupChannelList/useGroupChannelListWithQuery.js.map +1 -1
  5. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +7 -8
  6. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
  7. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +8 -7
  8. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
  9. package/lib/commonjs/channel/useOpenChannel.js +33 -0
  10. package/lib/commonjs/channel/useOpenChannel.js.map +1 -0
  11. package/lib/commonjs/channel/useOpenChannelList/index.js +15 -0
  12. package/lib/commonjs/channel/useOpenChannelList/index.js.map +1 -0
  13. package/lib/commonjs/channel/useOpenChannelList/reducer.js +149 -0
  14. package/lib/commonjs/channel/useOpenChannelList/reducer.js.map +1 -0
  15. package/lib/commonjs/channel/useOpenChannelList/useOpenChannelListWithQuery.js +119 -0
  16. package/lib/commonjs/channel/useOpenChannelList/useOpenChannelListWithQuery.js.map +1 -0
  17. package/lib/commonjs/channel/useOpenChannelMessages/index.js +15 -0
  18. package/lib/commonjs/channel/useOpenChannelMessages/index.js.map +1 -0
  19. package/lib/commonjs/channel/useOpenChannelMessages/reducer.js +154 -0
  20. package/lib/commonjs/channel/useOpenChannelMessages/reducer.js.map +1 -0
  21. package/lib/commonjs/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js +240 -0
  22. package/lib/commonjs/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js.map +1 -0
  23. package/lib/commonjs/common/useMessageOutgoingStatus.js +2 -4
  24. package/lib/commonjs/common/useMessageOutgoingStatus.js.map +1 -1
  25. package/lib/commonjs/common/useTotalUnreadChannelCount.js +2 -4
  26. package/lib/commonjs/common/useTotalUnreadChannelCount.js.map +1 -1
  27. package/lib/commonjs/common/useTotalUnreadMessageCount.js +2 -4
  28. package/lib/commonjs/common/useTotalUnreadMessageCount.js.map +1 -1
  29. package/lib/commonjs/common/useUserList.js +2 -0
  30. package/lib/commonjs/common/useUserList.js.map +1 -1
  31. package/lib/commonjs/handler/useChannelHandler.js +34 -4
  32. package/lib/commonjs/handler/useChannelHandler.js.map +1 -1
  33. package/lib/commonjs/index.js +24 -8
  34. package/lib/commonjs/index.js.map +1 -1
  35. package/lib/commonjs/types.js.map +1 -1
  36. package/lib/module/channel/useGroupChannelList/useGroupChannelListWithCollection.js +3 -4
  37. package/lib/module/channel/useGroupChannelList/useGroupChannelListWithCollection.js.map +1 -1
  38. package/lib/module/channel/useGroupChannelList/useGroupChannelListWithQuery.js +3 -3
  39. package/lib/module/channel/useGroupChannelList/useGroupChannelListWithQuery.js.map +1 -1
  40. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +8 -8
  41. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
  42. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +9 -7
  43. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
  44. package/lib/module/channel/useOpenChannel.js +22 -0
  45. package/lib/module/channel/useOpenChannel.js.map +1 -0
  46. package/lib/module/channel/useOpenChannelList/index.js +5 -0
  47. package/lib/module/channel/useOpenChannelList/index.js.map +1 -0
  48. package/lib/module/channel/useOpenChannelList/reducer.js +139 -0
  49. package/lib/module/channel/useOpenChannelList/reducer.js.map +1 -0
  50. package/lib/module/channel/useOpenChannelList/useOpenChannelListWithQuery.js +107 -0
  51. package/lib/module/channel/useOpenChannelList/useOpenChannelListWithQuery.js.map +1 -0
  52. package/lib/module/channel/useOpenChannelMessages/index.js +5 -0
  53. package/lib/module/channel/useOpenChannelMessages/index.js.map +1 -0
  54. package/lib/module/channel/useOpenChannelMessages/reducer.js +144 -0
  55. package/lib/module/channel/useOpenChannelMessages/reducer.js.map +1 -0
  56. package/lib/module/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js +228 -0
  57. package/lib/module/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js.map +1 -0
  58. package/lib/module/common/useMessageOutgoingStatus.js +3 -4
  59. package/lib/module/common/useMessageOutgoingStatus.js.map +1 -1
  60. package/lib/module/common/useTotalUnreadChannelCount.js +3 -5
  61. package/lib/module/common/useTotalUnreadChannelCount.js.map +1 -1
  62. package/lib/module/common/useTotalUnreadMessageCount.js +3 -4
  63. package/lib/module/common/useTotalUnreadMessageCount.js.map +1 -1
  64. package/lib/module/common/useUserList.js +2 -0
  65. package/lib/module/common/useUserList.js.map +1 -1
  66. package/lib/module/handler/useChannelHandler.js +34 -4
  67. package/lib/module/handler/useChannelHandler.js.map +1 -1
  68. package/lib/module/index.js +3 -1
  69. package/lib/module/index.js.map +1 -1
  70. package/lib/module/types.js.map +1 -1
  71. package/lib/typescript/src/channel/useOpenChannel.d.ts +6 -0
  72. package/lib/typescript/src/channel/useOpenChannelList/index.d.ts +2 -0
  73. package/lib/typescript/src/channel/useOpenChannelList/reducer.d.ts +13 -0
  74. package/lib/typescript/src/channel/useOpenChannelList/useOpenChannelListWithQuery.d.ts +2 -0
  75. package/lib/typescript/src/channel/useOpenChannelMessages/index.d.ts +2 -0
  76. package/lib/typescript/src/channel/useOpenChannelMessages/reducer.d.ts +15 -0
  77. package/lib/typescript/src/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.d.ts +2 -0
  78. package/lib/typescript/src/handler/useChannelHandler.d.ts +4 -1
  79. package/lib/typescript/src/index.d.ts +4 -2
  80. package/lib/typescript/src/types.d.ts +141 -3
  81. package/package.json +4 -4
  82. package/src/channel/useGroupChannelList/useGroupChannelListWithCollection.ts +3 -5
  83. package/src/channel/useGroupChannelList/useGroupChannelListWithQuery.ts +3 -4
  84. package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.ts +8 -8
  85. package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.ts +9 -6
  86. package/src/channel/useOpenChannel.ts +21 -0
  87. package/src/channel/useOpenChannelList/index.ts +6 -0
  88. package/src/channel/useOpenChannelList/reducer.ts +115 -0
  89. package/src/channel/useOpenChannelList/useOpenChannelListWithQuery.ts +112 -0
  90. package/src/channel/useOpenChannelMessages/index.ts +6 -0
  91. package/src/channel/useOpenChannelMessages/reducer.ts +125 -0
  92. package/src/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.ts +247 -0
  93. package/src/common/useMessageOutgoingStatus.ts +3 -5
  94. package/src/common/useTotalUnreadChannelCount.ts +3 -5
  95. package/src/common/useTotalUnreadMessageCount.ts +3 -4
  96. package/src/common/useUserList.ts +2 -0
  97. package/src/handler/useChannelHandler.ts +31 -5
  98. package/src/index.ts +8 -1
  99. package/src/types.ts +171 -2
  100. package/lib/commonjs/channel/useActiveGroupChannel.js +0 -22
  101. package/lib/commonjs/channel/useActiveGroupChannel.js.map +0 -1
  102. package/lib/module/channel/useActiveGroupChannel.js +0 -12
  103. package/lib/module/channel/useActiveGroupChannel.js.map +0 -1
  104. package/lib/typescript/src/channel/useActiveGroupChannel.d.ts +0 -5
  105. package/src/channel/useActiveGroupChannel.ts +0 -13
@@ -1,4 +1,4 @@
1
- import type { SendbirdChatSDK, SendbirdError, SendbirdFileMessage, SendbirdFileMessageCreateParams, SendbirdGroupChannel, SendbirdGroupChannelCollection, SendbirdGroupChannelListQuery, SendbirdMessage, SendbirdMessageCollection, SendbirdPreviousMessageListQuery, SendbirdUserMessage, SendbirdUserMessageCreateParams, UserStruct } from '@sendbird/uikit-utils';
1
+ import type { SendbirdChatSDK, SendbirdError, SendbirdFileMessage, SendbirdFileMessageCreateParams, SendbirdFileMessageUpdateParams, SendbirdGroupChannel, SendbirdGroupChannelCollection, SendbirdGroupChannelListQuery, SendbirdMessage, SendbirdMessageCollection, SendbirdOpenChannel, SendbirdOpenChannelListQuery, SendbirdPreviousMessageListQuery, SendbirdUserMessage, SendbirdUserMessageCreateParams, SendbirdUserMessageUpdateParams, UserStruct } from '@sendbird/uikit-utils';
2
2
  export interface CustomQueryInterface<Data> {
3
3
  isLoading: boolean;
4
4
  next: () => Promise<Data[]>;
@@ -119,14 +119,14 @@ export interface UseGroupChannelMessages {
119
119
  * @param params file message params
120
120
  * @return updated message
121
121
  * */
122
- updateFileMessage: (messageId: number, params: SendbirdFileMessageCreateParams) => Promise<SendbirdFileMessage>;
122
+ updateFileMessage: (messageId: number, params: SendbirdFileMessageUpdateParams) => Promise<SendbirdFileMessage>;
123
123
  /**
124
124
  * Update user message
125
125
  * @param messageId
126
126
  * @param params user message params
127
127
  * @return updated message
128
128
  * */
129
- updateUserMessage: (messageId: number, params: SendbirdUserMessageCreateParams) => Promise<SendbirdUserMessage>;
129
+ updateUserMessage: (messageId: number, params: SendbirdUserMessageUpdateParams) => Promise<SendbirdUserMessage>;
130
130
  /**
131
131
  * Resend failed message
132
132
  * @param failedMessage failed message to resend
@@ -148,6 +148,144 @@ export type UseGroupChannelMessagesOptions = {
148
148
  enableCollectionWithoutLocalCache?: boolean;
149
149
  onChannelDeleted?: () => void;
150
150
  };
151
+ /**
152
+ * @interface UseOpenChannelList
153
+ * @description interface for open channel list hook
154
+ * */
155
+ export interface UseOpenChannelList {
156
+ (sdk: SendbirdChatSDK, userId?: string, options?: UseOpenChannelListOptions): {
157
+ /**
158
+ * Loading state, only available on first render
159
+ * */
160
+ loading: boolean;
161
+ /**
162
+ * Refreshing state, status is changes when the refresh is called.
163
+ * */
164
+ refreshing: boolean;
165
+ /**
166
+ * Refresh, clear and reload messages from latest
167
+ * @return {Promise<void>}
168
+ * */
169
+ refresh: () => Promise<void>;
170
+ /**
171
+ * Error state
172
+ * */
173
+ error: unknown | null;
174
+ /**
175
+ * Get open channels state
176
+ * */
177
+ openChannels: SendbirdOpenChannel[];
178
+ /**
179
+ * Fetch next channels to state
180
+ * @return {Promise<void>}
181
+ * */
182
+ next: () => Promise<void>;
183
+ };
184
+ }
185
+ export type UseOpenChannelListOptions = {
186
+ queryCreator?: () => SendbirdOpenChannelListQuery;
187
+ };
188
+ /**
189
+ * @interface UseOpenChannelMessages
190
+ * @description interface for open channel messages hook
191
+ * - Receive new messages from other users -> append to state(nextMessages)
192
+ * - onTopReached -> prev() -> fetch prev messages and append to state(messages)
193
+ * - onBottomReached -> next() -> nextMessages append to state(messages)
194
+ * */
195
+ export interface UseOpenChannelMessages {
196
+ (sdk: SendbirdChatSDK, channel: SendbirdOpenChannel, userId?: string, options?: UseOpenChannelMessagesOptions): {
197
+ /**
198
+ * Loading state, only available on first render
199
+ * */
200
+ loading: boolean;
201
+ /**
202
+ * Refreshing state, status is changes when the refresh is called.
203
+ * */
204
+ refreshing: boolean;
205
+ /**
206
+ * Refresh, clear and reload messages from latest
207
+ * @return {Promise<void>}
208
+ * */
209
+ refresh: () => Promise<void>;
210
+ /**
211
+ * Get messages, this state is for render
212
+ * For example, if a user receives a new messages while searching for an old message
213
+ * for this case, new messages will be included here.
214
+ * @return {SendbirdMessage[]}
215
+ * */
216
+ messages: SendbirdMessage[];
217
+ /**
218
+ * Fetch prev messages to state
219
+ * @return {Promise<void>}
220
+ * */
221
+ prev: () => Promise<void>;
222
+ /**
223
+ * Get messages, this state is for temporary data before render
224
+ * For example, if a user receives a new messages while searching for an old message
225
+ * for this case, new messages will be included here.
226
+ * */
227
+ nextMessages: SendbirdMessage[];
228
+ /**
229
+ * Get new messages from nextMessages
230
+ * A new message means a message that meets the below conditions
231
+ * - Not admin message
232
+ * - Not updated message
233
+ * - Not current user's message
234
+ * */
235
+ newMessagesFromMembers: SendbirdMessage[];
236
+ /**
237
+ * Fetch next messages to state
238
+ * @return {Promise<void>}
239
+ * */
240
+ next: () => Promise<void>;
241
+ /**
242
+ * Send file message
243
+ * @param params file message params
244
+ * @param callback sent message callback
245
+ * @return pending message
246
+ * */
247
+ sendFileMessage: (params: SendbirdFileMessageCreateParams, onPending?: (message: SendbirdFileMessage, error?: SendbirdError) => void) => Promise<SendbirdFileMessage>;
248
+ /**
249
+ * Send user message
250
+ * @param params user message params
251
+ * @param callback sent message callback
252
+ * @return pending message
253
+ * */
254
+ sendUserMessage: (params: SendbirdUserMessageCreateParams, onPending?: (message: SendbirdUserMessage, error?: SendbirdError) => void) => Promise<SendbirdUserMessage>;
255
+ /**
256
+ * Update file message
257
+ * @param messageId
258
+ * @param params file message params
259
+ * @return updated message
260
+ * */
261
+ updateFileMessage: (messageId: number, params: SendbirdFileMessageUpdateParams) => Promise<SendbirdFileMessage>;
262
+ /**
263
+ * Update user message
264
+ * @param messageId
265
+ * @param params user message params
266
+ * @return updated message
267
+ * */
268
+ updateUserMessage: (messageId: number, params: SendbirdUserMessageUpdateParams) => Promise<SendbirdUserMessage>;
269
+ /**
270
+ * Resend failed message
271
+ * @param failedMessage failed message to resend
272
+ * @return {Promise<void>}
273
+ * */
274
+ resendMessage: (failedMessage: SendbirdFileMessage | SendbirdUserMessage) => Promise<void>;
275
+ /**
276
+ * Delete message
277
+ * @param message sent or failed message
278
+ * @return {Promise<void>}
279
+ * */
280
+ deleteMessage: (message: SendbirdFileMessage | SendbirdUserMessage) => Promise<void>;
281
+ };
282
+ }
283
+ export type UseOpenChannelMessagesOptions = {
284
+ sortComparator?: (a: SendbirdMessage, b: SendbirdMessage) => number;
285
+ queryCreator?: () => SendbirdPreviousMessageListQuery;
286
+ onChannelDeleted?: () => void;
287
+ onError?: (error?: unknown) => void;
288
+ };
151
289
  /**
152
290
  * @interface UseUserListReturn
153
291
  * @description interface for user list hook return value
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendbird/uikit-chat-hooks",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
4
4
  "description": "React hooks that built with SendbirdChat SDK",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -38,7 +38,7 @@
38
38
  "access": "public"
39
39
  },
40
40
  "dependencies": {
41
- "@sendbird/uikit-utils": "2.3.0"
41
+ "@sendbird/uikit-utils": "2.4.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/react": "*",
@@ -47,7 +47,7 @@
47
47
  "typescript": "4.9.4"
48
48
  },
49
49
  "peerDependencies": {
50
- "@sendbird/chat": "^4.0.13",
50
+ "@sendbird/chat": "^4.3.0",
51
51
  "react": ">=16.13.1"
52
52
  },
53
53
  "react-native-builder-bob": {
@@ -69,5 +69,5 @@
69
69
  "readmeFile": "./README.md",
70
70
  "displayName": "@sendbird/uikit-chat-hooks"
71
71
  },
72
- "gitHead": "a9bf41fd7919436db99f6cc3bacd0f8d791b7729"
72
+ "gitHead": "05ec076e3a2433089586870c9a7e7bf7639b06be"
73
73
  }
@@ -2,15 +2,13 @@ import { useEffect, useRef } from 'react';
2
2
 
3
3
  import { GroupChannelEventSource, GroupChannelFilter, GroupChannelListOrder } from '@sendbird/chat/groupChannel';
4
4
  import type { SendbirdBaseChannel, SendbirdChatSDK, SendbirdGroupChannelCollection } from '@sendbird/uikit-utils';
5
- import { confirmAndMarkAsDelivered, useAsyncEffect, useFreshCallback, useUniqId } from '@sendbird/uikit-utils';
5
+ import { confirmAndMarkAsDelivered, useAsyncEffect, useFreshCallback, useUniqHandlerId } from '@sendbird/uikit-utils';
6
6
 
7
7
  import { useAppFeatures } from '../../common/useAppFeatures';
8
8
  import { useChannelHandler } from '../../handler/useChannelHandler';
9
9
  import type { UseGroupChannelList, UseGroupChannelListOptions } from '../../types';
10
10
  import { useGroupChannelListReducer } from './reducer';
11
11
 
12
- const HOOK_NAME = 'useGroupChannelListWithCollection';
13
-
14
12
  const createGroupChannelListCollection = (
15
13
  sdk: SendbirdChatSDK,
16
14
  collectionCreator: UseGroupChannelListOptions['collectionCreator'],
@@ -29,7 +27,7 @@ const createGroupChannelListCollection = (
29
27
  };
30
28
 
31
29
  export const useGroupChannelListWithCollection: UseGroupChannelList = (sdk, userId, options) => {
32
- const id = useUniqId(HOOK_NAME);
30
+ const handlerId = useUniqHandlerId('useGroupChannelListWithCollection');
33
31
  const { deliveryReceiptEnabled } = useAppFeatures(sdk);
34
32
 
35
33
  const collectionRef = useRef<SendbirdGroupChannelCollection>();
@@ -94,7 +92,7 @@ export const useGroupChannelListWithCollection: UseGroupChannelList = (sdk, user
94
92
  updateLoading(false);
95
93
  }, [init, userId]);
96
94
 
97
- useChannelHandler(sdk, `${HOOK_NAME}_${id}`, {
95
+ useChannelHandler(sdk, handlerId, {
98
96
  onUserBanned: (channel, user) => {
99
97
  const isMe = user.userId === userId;
100
98
  if (isMe) deleteChannels([channel.url]);
@@ -2,15 +2,13 @@ import { useRef } from 'react';
2
2
 
3
3
  import { GroupChannelListOrder } from '@sendbird/chat/groupChannel';
4
4
  import type { SendbirdChannel, SendbirdChatSDK, SendbirdGroupChannelListQuery } from '@sendbird/uikit-utils';
5
- import { confirmAndMarkAsDelivered, useAsyncEffect, useFreshCallback } from '@sendbird/uikit-utils';
5
+ import { confirmAndMarkAsDelivered, useAsyncEffect, useFreshCallback, useUniqHandlerId } from '@sendbird/uikit-utils';
6
6
 
7
7
  import { useAppFeatures } from '../../common/useAppFeatures';
8
8
  import { useChannelHandler } from '../../handler/useChannelHandler';
9
9
  import type { UseGroupChannelList, UseGroupChannelListOptions } from '../../types';
10
10
  import { useGroupChannelListReducer } from './reducer';
11
11
 
12
- const HOOK_NAME = 'useGroupChannelListWithQuery';
13
-
14
12
  const createGroupChannelListQuery = (
15
13
  sdk: SendbirdChatSDK,
16
14
  queryCreator: UseGroupChannelListOptions['queryCreator'],
@@ -28,6 +26,7 @@ const createGroupChannelListQuery = (
28
26
  export const useGroupChannelListWithQuery: UseGroupChannelList = (sdk, userId, options) => {
29
27
  const { deliveryReceiptEnabled } = useAppFeatures(sdk);
30
28
  const queryRef = useRef<SendbirdGroupChannelListQuery>();
29
+ const handlerId = useUniqHandlerId('useGroupChannelListWithQuery');
31
30
 
32
31
  const {
33
32
  loading,
@@ -66,7 +65,7 @@ export const useGroupChannelListWithQuery: UseGroupChannelList = (sdk, userId, o
66
65
  updateLoading(false);
67
66
  }, [init, userId]);
68
67
 
69
- useChannelHandler(sdk, HOOK_NAME, {
68
+ useChannelHandler(sdk, handlerId, {
70
69
  onChannelChanged: (channel) => updateChannels([channel]),
71
70
  onChannelFrozen: (channel) => updateChannels([channel]),
72
71
  onChannelUnfrozen: (channel) => updateChannels([channel]),
@@ -13,6 +13,7 @@ import {
13
13
  isDifferentChannel,
14
14
  useForceUpdate,
15
15
  useFreshCallback,
16
+ useUniqHandlerId,
16
17
  } from '@sendbird/uikit-utils';
17
18
 
18
19
  import { useChannelHandler } from '../../handler/useChannelHandler';
@@ -28,11 +29,10 @@ const createMessageCollection = (
28
29
  return channel.createMessageCollection({ filter, limit: 100 });
29
30
  };
30
31
 
31
- const HOOK_NAME = 'useGroupChannelMessagesWithCollection';
32
-
33
32
  export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (sdk, channel, userId, options) => {
34
33
  const forceUpdate = useForceUpdate();
35
34
  const collectionRef = useRef<SendbirdMessageCollection>();
35
+ const handlerId = useUniqHandlerId('useGroupChannelMessagesWithCollection');
36
36
 
37
37
  const {
38
38
  loading,
@@ -59,7 +59,7 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
59
59
  break;
60
60
  }
61
61
  } catch (e) {
62
- Logger.warn(`[${HOOK_NAME}/channelMarkAsRead]`, e);
62
+ Logger.warn('[useGroupChannelMessagesWithCollection/channelMarkAsRead]', e);
63
63
  }
64
64
  };
65
65
 
@@ -115,9 +115,9 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
115
115
  collectionRef.current
116
116
  .initialize(MessageCollectionInitPolicy.CACHE_AND_REPLACE_BY_API)
117
117
  .onCacheResult((err, messages) => {
118
- if (err) sdk.isCacheEnabled && Logger.error(`[${HOOK_NAME}/onCacheResult]`, err);
118
+ if (err) sdk.isCacheEnabled && Logger.error('[useGroupChannelMessagesWithCollection/onCacheResult]', err);
119
119
  else {
120
- Logger.debug(`[${HOOK_NAME}/onCacheResult]`, 'message length:', messages.length);
120
+ Logger.debug('[useGroupChannelMessagesWithCollection/onCacheResult]', 'message length:', messages.length);
121
121
 
122
122
  updateMessages(messages, true, sdk.currentUser.userId);
123
123
  updateMessages(collectionRef.current?.pendingMessages ?? [], false, sdk.currentUser.userId);
@@ -126,9 +126,9 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
126
126
  callback?.();
127
127
  })
128
128
  .onApiResult((err, messages) => {
129
- if (err) Logger.warn(`[${HOOK_NAME}/onApiResult]`, err);
129
+ if (err) Logger.warn('[useGroupChannelMessagesWithCollection/onApiResult]', err);
130
130
  else {
131
- Logger.debug(`[${HOOK_NAME}/onApiResult]`, 'message length:', messages.length);
131
+ Logger.debug('[useGroupChannelMessagesWithCollection/onApiResult]', 'message length:', messages.length);
132
132
 
133
133
  updateMessages(messages, true, sdk.currentUser.userId);
134
134
  if (sdk.isCacheEnabled) {
@@ -143,7 +143,7 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
143
143
  [sdk, channel.url, options?.collectionCreator],
144
144
  );
145
145
 
146
- useChannelHandler(sdk, HOOK_NAME, {
146
+ useChannelHandler(sdk, handlerId, {
147
147
  onUserBanned(channel, bannedUser) {
148
148
  if (channel.isGroupChannel() && !isDifferentChannel(channel, channel)) {
149
149
  if (bannedUser.userId === sdk.currentUser.userId) {
@@ -11,6 +11,7 @@ import {
11
11
  isDifferentChannel,
12
12
  useAsyncEffect,
13
13
  useForceUpdate,
14
+ useUniqHandlerId,
14
15
  } from '@sendbird/uikit-utils';
15
16
 
16
17
  import { useChannelHandler } from '../../handler/useChannelHandler';
@@ -28,9 +29,9 @@ const createMessageQuery = (
28
29
  });
29
30
  };
30
31
 
31
- const HOOK_NAME = 'useGroupChannelMessagesWithQuery';
32
32
  export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, channel, userId, options) => {
33
33
  const queryRef = useRef<SendbirdPreviousMessageListQuery>();
34
+ const handlerId = useUniqHandlerId('useGroupChannelMessagesWithQuery');
34
35
 
35
36
  const forceUpdate = useForceUpdate();
36
37
 
@@ -52,7 +53,7 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
52
53
  try {
53
54
  await confirmAndMarkAsRead([channel]);
54
55
  } catch (e) {
55
- Logger.warn(`[${HOOK_NAME}/channelMarkAsRead]`, e);
56
+ Logger.warn('[useGroupChannelMessagesWithQuery/channelMarkAsRead]', e);
56
57
  }
57
58
  };
58
59
 
@@ -60,7 +61,7 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
60
61
  async (uid?: string) => {
61
62
  if (uid) {
62
63
  queryRef.current = createMessageQuery(channel, options?.queryCreator);
63
- channelMarkAsRead().catch();
64
+ channelMarkAsRead();
64
65
  if (queryRef.current?.hasNext) {
65
66
  const list = await queryRef.current?.load();
66
67
  updateMessages(list, true, sdk.currentUser.userId);
@@ -77,7 +78,7 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
77
78
  }
78
79
  };
79
80
 
80
- useChannelHandler(sdk, HOOK_NAME, {
81
+ useChannelHandler(sdk, handlerId, {
81
82
  // Messages
82
83
  onMessageReceived(eventChannel, message) {
83
84
  if (isDifferentChannel(channel, eventChannel)) return;
@@ -168,7 +169,8 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
168
169
  resolve(sentMessage);
169
170
  }
170
171
  })
171
- .onFailed((err) => {
172
+ .onFailed((err, sentMessage) => {
173
+ updateNextMessages([sentMessage], false, sdk.currentUser.userId);
172
174
  reject(err);
173
175
  });
174
176
  });
@@ -192,7 +194,8 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
192
194
  resolve(sentMessage);
193
195
  }
194
196
  })
195
- .onFailed((err) => {
197
+ .onFailed((err, sentMessage) => {
198
+ updateNextMessages([sentMessage], false, sdk.currentUser.userId);
196
199
  reject(err);
197
200
  });
198
201
  });
@@ -0,0 +1,21 @@
1
+ import { useState } from 'react';
2
+
3
+ import { SendbirdChatSDK, SendbirdOpenChannel, useAsyncEffect } from '@sendbird/uikit-utils';
4
+
5
+ export const useOpenChannel = (sdk: SendbirdChatSDK, channelUrl: string) => {
6
+ const [channel, setChannel] = useState<SendbirdOpenChannel>();
7
+ const [loading, setLoading] = useState(true);
8
+ const [error, setError] = useState<unknown>();
9
+
10
+ useAsyncEffect(async () => {
11
+ try {
12
+ setChannel(await sdk.openChannel.getChannel(channelUrl));
13
+ } catch (e) {
14
+ setError(e);
15
+ } finally {
16
+ setLoading(false);
17
+ }
18
+ }, []);
19
+
20
+ return { channel, loading, error };
21
+ };
@@ -0,0 +1,6 @@
1
+ import type { UseOpenChannelList } from '../../types';
2
+ import { useOpenChannelListWithQuery } from './useOpenChannelListWithQuery';
3
+
4
+ export const useOpenChannelList: UseOpenChannelList = (sdk, userId, options) => {
5
+ return useOpenChannelListWithQuery(sdk, userId, options);
6
+ };
@@ -0,0 +1,115 @@
1
+ import { useReducer } from 'react';
2
+
3
+ import type { SendbirdChannel, SendbirdOpenChannel } from '@sendbird/uikit-utils';
4
+ import { getOpenChannels } from '@sendbird/uikit-utils';
5
+
6
+ type Action =
7
+ | {
8
+ type: 'update_error';
9
+ value: { error: unknown | null };
10
+ }
11
+ | {
12
+ type: 'update_loading' | 'update_refreshing';
13
+ value: { status: boolean };
14
+ }
15
+ | {
16
+ type: 'update_channels';
17
+ value: { channels: SendbirdChannel[] };
18
+ }
19
+ | {
20
+ type: 'delete_channels';
21
+ value: { channelUrls: string[] };
22
+ }
23
+ | {
24
+ type: 'append_channels';
25
+ value: { channels: SendbirdChannel[]; clearBeforeAction: boolean };
26
+ };
27
+
28
+ type State = {
29
+ error: unknown | null;
30
+ loading: boolean;
31
+ refreshing: boolean;
32
+ openChannels: SendbirdOpenChannel[];
33
+ };
34
+
35
+ const defaultReducer = ({ ...draft }: State, action: Action) => {
36
+ switch (action.type) {
37
+ case 'update_error': {
38
+ draft.error = action.value.error;
39
+ break;
40
+ }
41
+ case 'update_refreshing':
42
+ case 'update_loading': {
43
+ const key = action.type === 'update_loading' ? 'loading' : 'refreshing';
44
+ draft[key] = action.value.status;
45
+ break;
46
+ }
47
+ case 'update_channels': {
48
+ getOpenChannels(action.value.channels).forEach((freshChannel) => {
49
+ const idx = draft.openChannels.findIndex((staleChannel) => staleChannel.url === freshChannel.url);
50
+ if (idx > -1) draft.openChannels[idx] = freshChannel;
51
+ });
52
+ break;
53
+ }
54
+ case 'delete_channels': {
55
+ action.value.channelUrls.forEach((url) => {
56
+ const idx = draft.openChannels.findIndex((c) => c.url === url);
57
+ if (idx > -1) draft.openChannels.splice(idx, 1);
58
+ });
59
+ break;
60
+ }
61
+ case 'append_channels': {
62
+ const openChannels = getOpenChannels(action.value.channels);
63
+ if (action.value.clearBeforeAction) {
64
+ draft.openChannels = openChannels;
65
+ } else {
66
+ draft.openChannels = [...draft.openChannels, ...openChannels];
67
+ }
68
+ break;
69
+ }
70
+ }
71
+ return draft;
72
+ };
73
+
74
+ export const useOpenChannelListReducer = () => {
75
+ const [{ error, loading, refreshing, openChannels }, dispatch] = useReducer(defaultReducer, {
76
+ loading: true,
77
+ refreshing: false,
78
+ openChannels: [],
79
+ error: null,
80
+ });
81
+
82
+ const updateChannels = (channels: SendbirdChannel[]) => {
83
+ dispatch({ type: 'update_channels', value: { channels } });
84
+ };
85
+ const deleteChannels = (channelUrls: string[]) => {
86
+ dispatch({ type: 'delete_channels', value: { channelUrls } });
87
+ };
88
+ const appendChannels = (channels: SendbirdChannel[], clearBeforeAction: boolean) => {
89
+ dispatch({ type: 'append_channels', value: { channels, clearBeforeAction } });
90
+ };
91
+ const updateLoading = (status: boolean) => {
92
+ dispatch({ type: 'update_loading', value: { status } });
93
+ };
94
+ const updateRefreshing = (status: boolean) => {
95
+ dispatch({ type: 'update_refreshing', value: { status } });
96
+ };
97
+
98
+ const updateError = (error: unknown | null) => {
99
+ dispatch({ type: 'update_error', value: { error } });
100
+ };
101
+
102
+ return {
103
+ updateError,
104
+ updateLoading,
105
+ updateRefreshing,
106
+ updateChannels,
107
+ deleteChannels,
108
+ appendChannels,
109
+
110
+ error,
111
+ loading,
112
+ refreshing,
113
+ openChannels,
114
+ };
115
+ };
@@ -0,0 +1,112 @@
1
+ import { useRef } from 'react';
2
+
3
+ import type { SendbirdBaseChannel, SendbirdChatSDK, SendbirdOpenChannelListQuery } from '@sendbird/uikit-utils';
4
+ import { useAsyncEffect, useFreshCallback, useUniqHandlerId } from '@sendbird/uikit-utils';
5
+
6
+ import { useChannelHandler } from '../../handler/useChannelHandler';
7
+ import type { UseOpenChannelList, UseOpenChannelListOptions } from '../../types';
8
+ import { useOpenChannelListReducer } from './reducer';
9
+
10
+ const createOpenChannelListQuery = (sdk: SendbirdChatSDK, queryCreator: UseOpenChannelListOptions['queryCreator']) => {
11
+ const passedQuery = queryCreator?.();
12
+ if (passedQuery) return passedQuery;
13
+ return sdk.openChannel.createOpenChannelListQuery({});
14
+ };
15
+
16
+ export const useOpenChannelListWithQuery: UseOpenChannelList = (sdk, userId, options) => {
17
+ const queryRef = useRef<SendbirdOpenChannelListQuery>();
18
+ const handlerId = useUniqHandlerId('useOpenChannelListWithQuery');
19
+
20
+ const {
21
+ error,
22
+ loading,
23
+ openChannels,
24
+ refreshing,
25
+ updateChannels,
26
+ appendChannels,
27
+ deleteChannels,
28
+ updateRefreshing,
29
+ updateLoading,
30
+ updateError,
31
+ } = useOpenChannelListReducer();
32
+
33
+ const init = useFreshCallback(async (uid?: string) => {
34
+ if (uid) {
35
+ queryRef.current = createOpenChannelListQuery(sdk, options?.queryCreator);
36
+
37
+ if (queryRef.current?.hasNext) {
38
+ const channels = await queryRef.current.next();
39
+ appendChannels(channels, true);
40
+ }
41
+ }
42
+ });
43
+
44
+ const updateChannel = (channel: SendbirdBaseChannel) => {
45
+ if (channel.isOpenChannel()) updateChannels([channel]);
46
+ };
47
+
48
+ useChannelHandler(
49
+ sdk,
50
+ handlerId,
51
+ {
52
+ onChannelChanged: updateChannel,
53
+ onChannelFrozen: updateChannel,
54
+ onChannelUnfrozen: updateChannel,
55
+ onChannelDeleted: (url) => deleteChannels([url]),
56
+ onUserBanned(channel, user) {
57
+ const isMe = user.userId === userId;
58
+ if (isMe && channel.isOpenChannel()) deleteChannels([channel.url]);
59
+ },
60
+ onUserEntered: (channel, user) => {
61
+ const isMe = user.userId === userId;
62
+ if (isMe && channel.isOpenChannel() && !openChannels.find((it) => it.url === channel.url)) {
63
+ appendChannels([], true);
64
+ refresh();
65
+ }
66
+ },
67
+ },
68
+ 'open',
69
+ );
70
+
71
+ useAsyncEffect(async () => {
72
+ updateLoading(true);
73
+ updateError(null);
74
+ try {
75
+ await init(userId);
76
+ } catch (e) {
77
+ updateError(e);
78
+ appendChannels([], true);
79
+ } finally {
80
+ updateLoading(false);
81
+ }
82
+ }, [init, userId]);
83
+
84
+ const refresh = useFreshCallback(async () => {
85
+ updateRefreshing(true);
86
+ updateError(null);
87
+ try {
88
+ await init(userId);
89
+ } catch (e) {
90
+ updateError(e);
91
+ appendChannels([], true);
92
+ } finally {
93
+ updateRefreshing(false);
94
+ }
95
+ });
96
+
97
+ const next = useFreshCallback(async () => {
98
+ if (queryRef.current?.hasNext) {
99
+ const channels = await queryRef.current.next();
100
+ appendChannels(channels, false);
101
+ }
102
+ });
103
+
104
+ return {
105
+ error,
106
+ loading,
107
+ openChannels,
108
+ refresh,
109
+ refreshing,
110
+ next,
111
+ };
112
+ };
@@ -0,0 +1,6 @@
1
+ import type { UseOpenChannelMessages } from '../../types';
2
+ import { useOpenChannelMessagesWithQuery } from './useOpenChannelMessagesWithQuery';
3
+
4
+ export const useOpenChannelMessages: UseOpenChannelMessages = (sdk, channel, userId, options) => {
5
+ return useOpenChannelMessagesWithQuery(sdk, channel, userId, options);
6
+ };