@sendbird/uikit-chat-hooks 2.0.3 → 2.2.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 (63) hide show
  1. package/lib/commonjs/channel/useGroupChannel.js +33 -0
  2. package/lib/commonjs/channel/useGroupChannel.js.map +1 -0
  3. package/lib/commonjs/channel/useGroupChannelMessages/reducer.js +3 -3
  4. package/lib/commonjs/channel/useGroupChannelMessages/reducer.js.map +1 -1
  5. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +75 -79
  6. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
  7. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +30 -41
  8. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
  9. package/lib/commonjs/common/useAppFeatures.js +4 -4
  10. package/lib/commonjs/common/useAppFeatures.js.map +1 -1
  11. package/lib/commonjs/common/useMessageOutgoingStatus.js +1 -0
  12. package/lib/commonjs/common/useMessageOutgoingStatus.js.map +1 -1
  13. package/lib/commonjs/common/useTotalUnreadChannelCount.js +1 -1
  14. package/lib/commonjs/common/useTotalUnreadChannelCount.js.map +1 -1
  15. package/lib/commonjs/common/useTotalUnreadMessageCount.js +1 -1
  16. package/lib/commonjs/common/useTotalUnreadMessageCount.js.map +1 -1
  17. package/lib/commonjs/common/useUserList.js +33 -15
  18. package/lib/commonjs/common/useUserList.js.map +1 -1
  19. package/lib/commonjs/index.js +8 -0
  20. package/lib/commonjs/index.js.map +1 -1
  21. package/lib/commonjs/types.js.map +1 -1
  22. package/lib/module/channel/useGroupChannel.js +22 -0
  23. package/lib/module/channel/useGroupChannel.js.map +1 -0
  24. package/lib/module/channel/useGroupChannelMessages/reducer.js +3 -3
  25. package/lib/module/channel/useGroupChannelMessages/reducer.js.map +1 -1
  26. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +76 -79
  27. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
  28. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +30 -40
  29. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
  30. package/lib/module/common/useAppFeatures.js +4 -4
  31. package/lib/module/common/useAppFeatures.js.map +1 -1
  32. package/lib/module/common/useMessageOutgoingStatus.js +1 -0
  33. package/lib/module/common/useMessageOutgoingStatus.js.map +1 -1
  34. package/lib/module/common/useTotalUnreadChannelCount.js +2 -2
  35. package/lib/module/common/useTotalUnreadChannelCount.js.map +1 -1
  36. package/lib/module/common/useTotalUnreadMessageCount.js +2 -2
  37. package/lib/module/common/useTotalUnreadMessageCount.js.map +1 -1
  38. package/lib/module/common/useUserList.js +35 -17
  39. package/lib/module/common/useUserList.js.map +1 -1
  40. package/lib/module/index.js +1 -0
  41. package/lib/module/index.js.map +1 -1
  42. package/lib/module/types.js.map +1 -1
  43. package/lib/typescript/src/channel/useGroupChannel.d.ts +6 -0
  44. package/lib/typescript/src/channel/useGroupChannelList/reducer.d.ts +1 -1
  45. package/lib/typescript/src/common/useMessageOutgoingStatus.d.ts +1 -1
  46. package/lib/typescript/src/common/useTotalUnreadChannelCount.d.ts +1 -1
  47. package/lib/typescript/src/common/useTotalUnreadMessageCount.d.ts +1 -1
  48. package/lib/typescript/src/common/useUserList.d.ts +2 -2
  49. package/lib/typescript/src/index.d.ts +2 -1
  50. package/lib/typescript/src/model/CustomQuery.d.ts +1 -1
  51. package/lib/typescript/src/types.d.ts +13 -9
  52. package/package.json +4 -4
  53. package/src/channel/useGroupChannel.ts +21 -0
  54. package/src/channel/useGroupChannelMessages/reducer.ts +4 -4
  55. package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.ts +92 -86
  56. package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.ts +33 -37
  57. package/src/common/useAppFeatures.ts +4 -4
  58. package/src/common/useMessageOutgoingStatus.ts +2 -0
  59. package/src/common/useTotalUnreadChannelCount.ts +2 -2
  60. package/src/common/useTotalUnreadMessageCount.ts +2 -2
  61. package/src/common/useUserList.ts +46 -20
  62. package/src/index.ts +2 -1
  63. package/src/types.ts +13 -7
@@ -1,6 +1,10 @@
1
1
  import { useCallback, useRef } from 'react';
2
2
 
3
- import type { SendbirdBaseChannel, SendbirdGroupChannel } from '@sendbird/uikit-utils';
3
+ import type {
4
+ SendbirdBaseChannel,
5
+ SendbirdGroupChannel,
6
+ SendbirdPreviousMessageListQuery,
7
+ } from '@sendbird/uikit-utils';
4
8
  import {
5
9
  Logger,
6
10
  confirmAndMarkAsRead,
@@ -8,11 +12,9 @@ import {
8
12
  useAsyncEffect,
9
13
  useForceUpdate,
10
14
  } from '@sendbird/uikit-utils';
11
- import type { SendbirdPreviousMessageListQuery } from '@sendbird/uikit-utils';
12
15
 
13
16
  import { useChannelHandler } from '../../handler/useChannelHandler';
14
17
  import type { UseGroupChannelMessages, UseGroupChannelMessagesOptions } from '../../types';
15
- import { useActiveGroupChannel } from '../useActiveGroupChannel';
16
18
  import { useGroupChannelMessagesReducer } from './reducer';
17
19
 
18
20
  const createMessageQuery = (
@@ -30,8 +32,6 @@ const HOOK_NAME = 'useGroupChannelMessagesWithQuery';
30
32
  export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, channel, userId, options) => {
31
33
  const queryRef = useRef<SendbirdPreviousMessageListQuery>();
32
34
 
33
- // NOTE: We cannot determine the channel object of Sendbird SDK is stale or not, so force update after setActiveChannel
34
- const { activeChannel, setActiveChannel } = useActiveGroupChannel(sdk, channel);
35
35
  const forceUpdate = useForceUpdate();
36
36
 
37
37
  const {
@@ -48,19 +48,19 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
48
48
  updateRefreshing,
49
49
  } = useGroupChannelMessagesReducer(userId, options?.sortComparator);
50
50
 
51
- const channelMarkAs = async () => {
51
+ const channelMarkAsRead = async () => {
52
52
  try {
53
53
  await confirmAndMarkAsRead([channel]);
54
54
  } catch (e) {
55
- Logger.warn(`[${HOOK_NAME}/channelMarkAs/Read]`, e);
55
+ Logger.warn(`[${HOOK_NAME}/channelMarkAsRead]`, e);
56
56
  }
57
57
  };
58
58
 
59
59
  const init = useCallback(
60
60
  async (uid?: string) => {
61
61
  if (uid) {
62
- queryRef.current = createMessageQuery(activeChannel, options?.queryCreator);
63
- channelMarkAs().catch();
62
+ queryRef.current = createMessageQuery(channel, options?.queryCreator);
63
+ channelMarkAsRead().catch();
64
64
  if (queryRef.current?.hasNext) {
65
65
  const list = await queryRef.current?.load();
66
66
  updateMessages(list, true, sdk.currentUser.userId);
@@ -68,12 +68,11 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
68
68
  updateNextMessages([], true, sdk.currentUser.userId);
69
69
  }
70
70
  },
71
- [sdk, activeChannel.url, options?.queryCreator],
71
+ [sdk, channel.url, options?.queryCreator],
72
72
  );
73
73
 
74
74
  const channelUpdater = (channel: SendbirdBaseChannel) => {
75
- if (channel.isGroupChannel() && !isDifferentChannel(channel, activeChannel)) {
76
- setActiveChannel(channel);
75
+ if (channel.isGroupChannel() && !isDifferentChannel(channel, channel)) {
77
76
  forceUpdate();
78
77
  }
79
78
  };
@@ -81,16 +80,16 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
81
80
  useChannelHandler(sdk, HOOK_NAME, {
82
81
  // Messages
83
82
  onMessageReceived(eventChannel, message) {
84
- if (isDifferentChannel(activeChannel, eventChannel)) return;
85
- channelMarkAs();
83
+ if (isDifferentChannel(channel, eventChannel)) return;
84
+ channelMarkAsRead();
86
85
  updateNextMessages([message], false, sdk.currentUser.userId);
87
86
  },
88
87
  onMessageUpdated(eventChannel, message) {
89
- if (isDifferentChannel(activeChannel, eventChannel)) return;
88
+ if (isDifferentChannel(channel, eventChannel)) return;
90
89
  updateMessages([message], false, sdk.currentUser.userId);
91
90
  },
92
91
  onMessageDeleted(eventChannel, messageId) {
93
- if (isDifferentChannel(activeChannel, eventChannel)) return;
92
+ if (isDifferentChannel(channel, eventChannel)) return;
94
93
  deleteMessages([messageId], []);
95
94
  deleteNextMessages([messageId], []);
96
95
  },
@@ -100,11 +99,11 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
100
99
  onChannelUnfrozen: channelUpdater,
101
100
  onChannelHidden: channelUpdater,
102
101
  onChannelMemberCountChanged(channels) {
103
- const channel = channels.find((c) => !isDifferentChannel(c, activeChannel));
104
- if (channel) channelUpdater(channel);
102
+ const foundChannel = channels.find((c) => !isDifferentChannel(c, channel));
103
+ if (foundChannel) channelUpdater(foundChannel);
105
104
  },
106
105
  onChannelDeleted(channelUrl: string) {
107
- if (activeChannel.url === channelUrl) options?.onChannelDeleted?.();
106
+ if (channel.url === channelUrl) options?.onChannelDeleted?.();
108
107
  },
109
108
  // Users
110
109
  onOperatorUpdated: channelUpdater,
@@ -116,7 +115,7 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
116
115
  onUserMuted: channelUpdater,
117
116
  onUserUnmuted: channelUpdater,
118
117
  onUserBanned(eventChannel, bannedUser) {
119
- if (isDifferentChannel(activeChannel, eventChannel)) return;
118
+ if (isDifferentChannel(channel, eventChannel)) return;
120
119
 
121
120
  if (bannedUser.userId === sdk.currentUser.userId) {
122
121
  options?.onChannelDeleted?.();
@@ -155,7 +154,7 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
155
154
  const sendUserMessage: ReturnType<UseGroupChannelMessages>['sendUserMessage'] = useCallback(
156
155
  (params, onPending) => {
157
156
  return new Promise((resolve, reject) => {
158
- activeChannel
157
+ channel
159
158
  .sendUserMessage(params)
160
159
  .onPending((pendingMessage) => {
161
160
  if (pendingMessage.isUserMessage()) {
@@ -174,12 +173,12 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
174
173
  });
175
174
  });
176
175
  },
177
- [activeChannel],
176
+ [channel],
178
177
  );
179
178
  const sendFileMessage: ReturnType<UseGroupChannelMessages>['sendFileMessage'] = useCallback(
180
179
  (params, onPending) => {
181
180
  return new Promise((resolve, reject) => {
182
- activeChannel
181
+ channel
183
182
  .sendFileMessage(params)
184
183
  .onPending((pendingMessage) => {
185
184
  if (pendingMessage.isFileMessage()) {
@@ -198,48 +197,46 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
198
197
  });
199
198
  });
200
199
  },
201
- [activeChannel],
200
+ [channel],
202
201
  );
203
202
  const updateUserMessage: ReturnType<UseGroupChannelMessages>['updateUserMessage'] = useCallback(
204
203
  async (messageId, params) => {
205
- const updatedMessage = await activeChannel.updateUserMessage(messageId, params);
204
+ const updatedMessage = await channel.updateUserMessage(messageId, params);
206
205
  updateMessages([updatedMessage], false, sdk.currentUser.userId);
207
206
  return updatedMessage;
208
207
  },
209
- [activeChannel],
208
+ [channel],
210
209
  );
211
210
  const updateFileMessage: ReturnType<UseGroupChannelMessages>['updateFileMessage'] = useCallback(
212
211
  async (messageId, params) => {
213
- const updatedMessage = await activeChannel.updateFileMessage(messageId, params);
212
+ const updatedMessage = await channel.updateFileMessage(messageId, params);
214
213
  updateMessages([updatedMessage], false, sdk.currentUser.userId);
215
214
  return updatedMessage;
216
215
  },
217
- [activeChannel],
216
+ [channel],
218
217
  );
219
218
  const resendMessage: ReturnType<UseGroupChannelMessages>['resendMessage'] = useCallback(
220
219
  async (failedMessage) => {
221
220
  const message = await (() => {
222
- if (failedMessage.isUserMessage()) return activeChannel.resendUserMessage(failedMessage);
223
- // FIXME: v4 bugs
224
- // @ts-ignore
225
- if (failedMessage.isFileMessage()) return activeChannel.resendFileMessage(failedMessage);
221
+ if (failedMessage.isUserMessage()) return channel.resendUserMessage(failedMessage);
222
+ if (failedMessage.isFileMessage()) return channel.resendFileMessage(failedMessage);
226
223
  return null;
227
224
  })();
228
225
 
229
226
  if (message) updateNextMessages([message], false, sdk.currentUser.userId);
230
227
  },
231
- [activeChannel],
228
+ [channel],
232
229
  );
233
230
  const deleteMessage: ReturnType<UseGroupChannelMessages>['deleteMessage'] = useCallback(
234
231
  async (message) => {
235
232
  if (message.sendingStatus === 'succeeded') {
236
- if (message.isUserMessage()) await activeChannel.deleteMessage(message);
237
- if (message.isFileMessage()) await activeChannel.deleteMessage(message);
233
+ if (message.isUserMessage()) await channel.deleteMessage(message);
234
+ if (message.isFileMessage()) await channel.deleteMessage(message);
238
235
  } else {
239
236
  deleteMessages([message.messageId], [message.reqId]);
240
237
  }
241
238
  },
242
- [activeChannel],
239
+ [channel],
243
240
  );
244
241
 
245
242
  return {
@@ -257,6 +254,5 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
257
254
  updateFileMessage,
258
255
  resendMessage,
259
256
  deleteMessage,
260
- activeChannel,
261
257
  };
262
258
  };
@@ -3,9 +3,9 @@ import { ApplicationAttributes, PremiumFeatures, SendbirdChatSDK } from '@sendbi
3
3
  export const useAppFeatures = (sdk: SendbirdChatSDK) => {
4
4
  const { premiumFeatureList = [], applicationAttributes = [] } = sdk.appInfo ?? {};
5
5
  return {
6
- deliveryReceiptEnabled: Boolean(premiumFeatureList.includes(PremiumFeatures.delivery_receipt)),
7
- broadcastChannelEnabled: Boolean(applicationAttributes.includes(ApplicationAttributes.allow_broadcast_channel)),
8
- superGroupChannelEnabled: Boolean(applicationAttributes.includes(ApplicationAttributes.allow_super_group_channel)),
9
- reactionEnabled: Boolean(applicationAttributes.includes(ApplicationAttributes.reactions)),
6
+ deliveryReceiptEnabled: premiumFeatureList.includes(PremiumFeatures.delivery_receipt),
7
+ broadcastChannelEnabled: applicationAttributes.includes(ApplicationAttributes.allow_broadcast_channel),
8
+ superGroupChannelEnabled: applicationAttributes.includes(ApplicationAttributes.allow_super_group_channel),
9
+ reactionEnabled: applicationAttributes.includes(ApplicationAttributes.reactions),
10
10
  };
11
11
  };
@@ -40,6 +40,8 @@ export const useMessageOutgoingStatus = (
40
40
  if (message.sendingStatus === 'failed') return 'FAILED';
41
41
  }
42
42
 
43
+ if (channel.isBroadcast || channel.isSuper) return 'NONE';
44
+
43
45
  if (channel.getUnreadMemberCount(message) === 0) return 'READ';
44
46
 
45
47
  if (features.deliveryReceiptEnabled) {
@@ -1,7 +1,7 @@
1
1
  import { useState } from 'react';
2
2
 
3
3
  import type { SendbirdChatSDK } from '@sendbird/uikit-utils';
4
- import { truncatedBadgeCount, useAsyncEffect } from '@sendbird/uikit-utils';
4
+ import { truncatedCount, useAsyncEffect } from '@sendbird/uikit-utils';
5
5
  import { useUniqId } from '@sendbird/uikit-utils';
6
6
 
7
7
  import { useUserEventHandler } from '../handler/useUserEventHandler';
@@ -24,5 +24,5 @@ export const useTotalUnreadChannelCount = (sdk: SendbirdChatSDK, params?: Params
24
24
  },
25
25
  });
26
26
 
27
- return truncatedBadgeCount(unreadChannelCount, params?.maxCount);
27
+ return truncatedCount(unreadChannelCount, params?.maxCount);
28
28
  };
@@ -2,7 +2,7 @@ import { useState } from 'react';
2
2
 
3
3
  import { SuperChannelFilter, TotalUnreadMessageCountParams } from '@sendbird/chat/groupChannel';
4
4
  import type { SendbirdChatSDK } from '@sendbird/uikit-utils';
5
- import { truncatedBadgeCount, useAsyncEffect, useUniqId } from '@sendbird/uikit-utils';
5
+ import { truncatedCount, useAsyncEffect, useUniqId } from '@sendbird/uikit-utils';
6
6
 
7
7
  import { useUserEventHandler } from '../handler/useUserEventHandler';
8
8
 
@@ -28,5 +28,5 @@ export const useTotalUnreadMessageCount = (sdk: SendbirdChatSDK, options?: Optio
28
28
  onTotalUnreadMessageCountUpdated: (totalCount: number) => setUnreadMessageCount(totalCount),
29
29
  });
30
30
 
31
- return truncatedBadgeCount(unreadMessageCount, options?.maxCount);
31
+ return truncatedCount(unreadMessageCount, options?.maxCount);
32
32
  };
@@ -1,11 +1,14 @@
1
- import { useCallback, useMemo, useRef, useState } from 'react';
1
+ import { useMemo, useRef, useState } from 'react';
2
2
 
3
- import type { Optional, SendbirdChatSDK, SendbirdUser } from '@sendbird/uikit-utils';
4
- import { Logger, SBErrorCode, SBErrorMessage, useAsyncEffect } from '@sendbird/uikit-utils';
3
+ import type { Optional, SendbirdChatSDK, SendbirdUser, UserStruct } from '@sendbird/uikit-utils';
4
+ import { Logger, SBErrorCode, SBErrorMessage, useAsyncEffect, useFreshCallback } from '@sendbird/uikit-utils';
5
5
 
6
6
  import type { CustomQueryInterface, UseUserListOptions, UseUserListReturn } from '../types';
7
7
 
8
- const createUserQuery = <User>(sdk: SendbirdChatSDK, queryCreator?: UseUserListOptions<User>['queryCreator']) => {
8
+ const createUserQuery = <User extends UserStruct>(
9
+ sdk: SendbirdChatSDK,
10
+ queryCreator?: UseUserListOptions<User>['queryCreator'],
11
+ ) => {
9
12
  if (queryCreator) return queryCreator();
10
13
  // In order to use the API, the option must be turned on in the dashboard.
11
14
  return sdk.createApplicationUserListQuery() as unknown as CustomQueryInterface<User>;
@@ -34,7 +37,11 @@ const createUserQuery = <User>(sdk: SendbirdChatSDK, queryCreator?: UseUserListO
34
37
  * */
35
38
  export const useUserList = <
36
39
  Options extends UseUserListOptions<QueriedUser>,
37
- QueriedUser = Options['queryCreator'] extends Optional<() => CustomQueryInterface<infer User>> ? User : SendbirdUser,
40
+ QueriedUser extends UserStruct = Options['queryCreator'] extends Optional<
41
+ () => CustomQueryInterface<infer User extends UserStruct>
42
+ >
43
+ ? User
44
+ : SendbirdUser,
38
45
  >(
39
46
  sdk: SendbirdChatSDK,
40
47
  options?: Options,
@@ -51,22 +58,39 @@ export const useUserList = <
51
58
  return users;
52
59
  }, [users, options?.sortComparator]);
53
60
 
61
+ const upsertUser = useFreshCallback((user: QueriedUser) => {
62
+ setUsers(([...draft]) => {
63
+ const userIdx = draft.findIndex((it) => it.userId === user.userId);
64
+ if (userIdx > -1) draft[userIdx] = user;
65
+ else draft.push(user);
66
+ return draft;
67
+ });
68
+ });
69
+
70
+ const deleteUser = useFreshCallback((userId: QueriedUser['userId']) => {
71
+ setUsers(([...draft]) => {
72
+ const userIdx = draft.findIndex((it) => it.userId === userId);
73
+ if (userIdx > -1) draft.splice(userIdx, 1);
74
+ return draft;
75
+ });
76
+ });
77
+
54
78
  const updateUsers = (users: QueriedUser[], clearPrev: boolean) => {
55
79
  if (clearPrev) setUsers(users);
56
80
  else setUsers((prev) => prev.concat(users));
57
81
  };
58
82
 
59
- const init = useCallback(async () => {
83
+ const init = useFreshCallback(async () => {
60
84
  query.current = createUserQuery<QueriedUser>(sdk, options?.queryCreator);
61
85
  if (query.current?.hasNext) {
62
- const users = await query.current?.next().catch((err) => {
63
- Logger.error(error);
64
- if (err.code === SBErrorCode.NON_AUTHORIZED) Logger.warn(SBErrorMessage.ACL);
65
- throw error;
86
+ const users = await query.current?.next().catch((e) => {
87
+ Logger.error(e);
88
+ if (e.code === SBErrorCode.NON_AUTHORIZED) Logger.warn(SBErrorMessage.ACL);
89
+ throw e;
66
90
  });
67
91
  updateUsers(users, true);
68
92
  }
69
- }, [sdk, options?.queryCreator]);
93
+ });
70
94
 
71
95
  useAsyncEffect(async () => {
72
96
  setLoading(true);
@@ -78,9 +102,9 @@ export const useUserList = <
78
102
  } finally {
79
103
  setLoading(false);
80
104
  }
81
- }, [init]);
105
+ }, []);
82
106
 
83
- const refresh = useCallback(async () => {
107
+ const refresh = useFreshCallback(async () => {
84
108
  setRefreshing(true);
85
109
  setError(null);
86
110
  try {
@@ -90,23 +114,25 @@ export const useUserList = <
90
114
  } finally {
91
115
  setRefreshing(false);
92
116
  }
93
- }, [init]);
117
+ });
94
118
 
95
- const next = useCallback(async () => {
119
+ const next = useFreshCallback(async () => {
96
120
  if (query.current && query.current?.hasNext) {
97
- const nextUsers = await query.current.next().catch((err) => {
98
- Logger.error(error);
99
- if (err.code === SBErrorCode.NON_AUTHORIZED) Logger.warn(SBErrorMessage.ACL);
100
- throw error;
121
+ const nextUsers = await query.current.next().catch((e) => {
122
+ Logger.error(e);
123
+ if (e.code === SBErrorCode.NON_AUTHORIZED) Logger.warn(SBErrorMessage.ACL);
124
+ throw e;
101
125
  });
102
126
  updateUsers(nextUsers, false);
103
127
  }
104
- }, []);
128
+ });
105
129
 
106
130
  return {
107
131
  loading,
108
132
  error,
109
133
  users: sortedUsers,
134
+ upsertUser,
135
+ deleteUser,
110
136
  next,
111
137
  refreshing,
112
138
  refresh,
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { useGroupChannelList } from './channel/useGroupChannelList';
2
2
  export { useGroupChannelMessages } from './channel/useGroupChannelMessages';
3
3
  export { useActiveGroupChannel } from './channel/useActiveGroupChannel';
4
+ export { useGroupChannel } from './channel/useGroupChannel';
4
5
 
5
6
  export { useAppFeatures } from './common/useAppFeatures';
6
7
  export { useMessageOutgoingStatus } from './common/useMessageOutgoingStatus';
@@ -19,8 +20,8 @@ export type {
19
20
  UseGroupChannelList,
20
21
  UseGroupChannelListOptions,
21
22
  UseGroupChannelMessages,
22
- UseUserListOptions,
23
23
  UseGroupChannelMessagesOptions,
24
+ UseUserListOptions,
24
25
  UseUserListReturn,
25
26
  CustomQueryInterface,
26
27
  CustomBidirectionalQueryInterface,
package/src/types.ts CHANGED
@@ -11,6 +11,7 @@ import type {
11
11
  SendbirdPreviousMessageListQuery,
12
12
  SendbirdUserMessage,
13
13
  SendbirdUserMessageCreateParams,
14
+ UserStruct,
14
15
  } from '@sendbird/uikit-utils';
15
16
 
16
17
  export interface CustomQueryInterface<Data> {
@@ -178,11 +179,6 @@ export interface UseGroupChannelMessages {
178
179
  * @return {Promise<void>}
179
180
  * */
180
181
  deleteMessage: (message: SendbirdFileMessage | SendbirdUserMessage) => Promise<void>;
181
-
182
- /**
183
- * Activated channel
184
- * */
185
- activeChannel: SendbirdGroupChannel;
186
182
  };
187
183
  }
188
184
 
@@ -198,7 +194,7 @@ export type UseGroupChannelMessagesOptions = {
198
194
  * @interface UseUserListReturn
199
195
  * @description interface for user list hook return value
200
196
  * */
201
- export interface UseUserListReturn<User> {
197
+ export interface UseUserListReturn<User extends UserStruct> {
202
198
  /**
203
199
  * Loading state, only available on first render
204
200
  * */
@@ -225,6 +221,16 @@ export interface UseUserListReturn<User> {
225
221
  * */
226
222
  users: User[];
227
223
 
224
+ /**
225
+ * Update or Insert user to list
226
+ * */
227
+ upsertUser: (user: User) => void;
228
+
229
+ /**
230
+ * Delete user from list
231
+ * */
232
+ deleteUser: (userId: User['userId']) => void;
233
+
228
234
  /**
229
235
  * Fetch next users to state
230
236
  * @return {Promise<void>}
@@ -232,7 +238,7 @@ export interface UseUserListReturn<User> {
232
238
  next: () => Promise<void>;
233
239
  }
234
240
 
235
- export type UseUserListOptions<User> = {
241
+ export type UseUserListOptions<User extends UserStruct> = {
236
242
  sortComparator?: (a: User, b: User) => number;
237
243
  queryCreator?: () => CustomQueryInterface<User>;
238
244
  };