@sendbird/uikit-chat-hooks 2.4.1 → 2.5.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 (134) hide show
  1. package/README.md +2 -2
  2. package/lib/commonjs/channel/useChannelMessagesReducer.js +153 -0
  3. package/lib/commonjs/channel/useChannelMessagesReducer.js.map +1 -0
  4. package/lib/commonjs/channel/useGroupChannel.js +0 -4
  5. package/lib/commonjs/channel/useGroupChannel.js.map +1 -1
  6. package/lib/commonjs/channel/useGroupChannelList/index.js +0 -5
  7. package/lib/commonjs/channel/useGroupChannelList/index.js.map +1 -1
  8. package/lib/commonjs/channel/useGroupChannelList/reducer.js +12 -29
  9. package/lib/commonjs/channel/useGroupChannelList/reducer.js.map +1 -1
  10. package/lib/commonjs/channel/useGroupChannelList/useGroupChannelListWithCollection.js +1 -22
  11. package/lib/commonjs/channel/useGroupChannelList/useGroupChannelListWithCollection.js.map +1 -1
  12. package/lib/commonjs/channel/useGroupChannelList/useGroupChannelListWithQuery.js +1 -18
  13. package/lib/commonjs/channel/useGroupChannelList/useGroupChannelListWithQuery.js.map +1 -1
  14. package/lib/commonjs/channel/useGroupChannelMessages/index.js +0 -5
  15. package/lib/commonjs/channel/useGroupChannelMessages/index.js.map +1 -1
  16. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +172 -131
  17. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
  18. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +76 -73
  19. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
  20. package/lib/commonjs/channel/useOpenChannel.js +0 -4
  21. package/lib/commonjs/channel/useOpenChannel.js.map +1 -1
  22. package/lib/commonjs/channel/useOpenChannelList/index.js +0 -3
  23. package/lib/commonjs/channel/useOpenChannelList/index.js.map +1 -1
  24. package/lib/commonjs/channel/useOpenChannelList/reducer.js +2 -21
  25. package/lib/commonjs/channel/useOpenChannelList/reducer.js.map +1 -1
  26. package/lib/commonjs/channel/useOpenChannelList/useOpenChannelListWithQuery.js +1 -22
  27. package/lib/commonjs/channel/useOpenChannelList/useOpenChannelListWithQuery.js.map +1 -1
  28. package/lib/commonjs/channel/useOpenChannelMessages/index.js +0 -3
  29. package/lib/commonjs/channel/useOpenChannelMessages/index.js.map +1 -1
  30. package/lib/commonjs/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js +128 -57
  31. package/lib/commonjs/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js.map +1 -1
  32. package/lib/commonjs/common/useAppFeatures.js +0 -3
  33. package/lib/commonjs/common/useAppFeatures.js.map +1 -1
  34. package/lib/commonjs/common/useMessageOutgoingStatus.js +0 -11
  35. package/lib/commonjs/common/useMessageOutgoingStatus.js.map +1 -1
  36. package/lib/commonjs/common/usePushTrigger.js +0 -6
  37. package/lib/commonjs/common/usePushTrigger.js.map +1 -1
  38. package/lib/commonjs/common/useTotalUnreadMessageCount.js +0 -7
  39. package/lib/commonjs/common/useTotalUnreadMessageCount.js.map +1 -1
  40. package/lib/commonjs/common/useUserList.js +5 -20
  41. package/lib/commonjs/common/useUserList.js.map +1 -1
  42. package/lib/commonjs/handler/useChannelHandler.js +15 -41
  43. package/lib/commonjs/handler/useChannelHandler.js.map +1 -1
  44. package/lib/commonjs/handler/useConnectionHandler.js +14 -11
  45. package/lib/commonjs/handler/useConnectionHandler.js.map +1 -1
  46. package/lib/commonjs/handler/useUserEventHandler.js +0 -8
  47. package/lib/commonjs/handler/useUserEventHandler.js.map +1 -1
  48. package/lib/commonjs/index.js +0 -23
  49. package/lib/commonjs/index.js.map +1 -1
  50. package/lib/commonjs/model/CustomQuery.js +0 -6
  51. package/lib/commonjs/model/CustomQuery.js.map +1 -1
  52. package/lib/commonjs/types.js.map +1 -1
  53. package/lib/module/channel/useChannelMessagesReducer.js +146 -0
  54. package/lib/module/channel/useChannelMessagesReducer.js.map +1 -0
  55. package/lib/module/channel/useGroupChannel.js.map +1 -1
  56. package/lib/module/channel/useGroupChannelList/index.js.map +1 -1
  57. package/lib/module/channel/useGroupChannelList/reducer.js +12 -26
  58. package/lib/module/channel/useGroupChannelList/reducer.js.map +1 -1
  59. package/lib/module/channel/useGroupChannelList/useGroupChannelListWithCollection.js +1 -15
  60. package/lib/module/channel/useGroupChannelList/useGroupChannelListWithCollection.js.map +1 -1
  61. package/lib/module/channel/useGroupChannelList/useGroupChannelListWithQuery.js +1 -11
  62. package/lib/module/channel/useGroupChannelList/useGroupChannelListWithQuery.js.map +1 -1
  63. package/lib/module/channel/useGroupChannelMessages/index.js.map +1 -1
  64. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +174 -125
  65. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
  66. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +78 -70
  67. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
  68. package/lib/module/channel/useOpenChannel.js.map +1 -1
  69. package/lib/module/channel/useOpenChannelList/index.js.map +1 -1
  70. package/lib/module/channel/useOpenChannelList/reducer.js +2 -18
  71. package/lib/module/channel/useOpenChannelList/reducer.js.map +1 -1
  72. package/lib/module/channel/useOpenChannelList/useOpenChannelListWithQuery.js +1 -17
  73. package/lib/module/channel/useOpenChannelList/useOpenChannelListWithQuery.js.map +1 -1
  74. package/lib/module/channel/useOpenChannelMessages/index.js.map +1 -1
  75. package/lib/module/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js +129 -53
  76. package/lib/module/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js.map +1 -1
  77. package/lib/module/common/useAppFeatures.js.map +1 -1
  78. package/lib/module/common/useMessageOutgoingStatus.js +0 -6
  79. package/lib/module/common/useMessageOutgoingStatus.js.map +1 -1
  80. package/lib/module/common/usePushTrigger.js.map +1 -1
  81. package/lib/module/common/useTotalUnreadMessageCount.js +0 -1
  82. package/lib/module/common/useTotalUnreadMessageCount.js.map +1 -1
  83. package/lib/module/common/useUserList.js +5 -15
  84. package/lib/module/common/useUserList.js.map +1 -1
  85. package/lib/module/handler/useChannelHandler.js +15 -35
  86. package/lib/module/handler/useChannelHandler.js.map +1 -1
  87. package/lib/module/handler/useConnectionHandler.js +15 -6
  88. package/lib/module/handler/useConnectionHandler.js.map +1 -1
  89. package/lib/module/handler/useUserEventHandler.js +0 -2
  90. package/lib/module/handler/useUserEventHandler.js.map +1 -1
  91. package/lib/module/index.js +0 -1
  92. package/lib/module/index.js.map +1 -1
  93. package/lib/module/model/CustomQuery.js +0 -4
  94. package/lib/module/model/CustomQuery.js.map +1 -1
  95. package/lib/module/types.js.map +1 -1
  96. package/lib/typescript/src/channel/useChannelMessagesReducer.d.ts +18 -0
  97. package/lib/typescript/src/channel/useGroupChannelList/reducer.d.ts +1 -1
  98. package/lib/typescript/src/common/useUserList.d.ts +1 -1
  99. package/lib/typescript/src/handler/useChannelHandler.d.ts +1 -1
  100. package/lib/typescript/src/handler/useConnectionHandler.d.ts +1 -2
  101. package/lib/typescript/src/index.d.ts +0 -1
  102. package/lib/typescript/src/types.d.ts +51 -20
  103. package/package.json +15 -10
  104. package/src/channel/useChannelMessagesReducer.ts +143 -0
  105. package/src/channel/useGroupChannelList/reducer.ts +11 -7
  106. package/src/channel/useGroupChannelList/useGroupChannelListWithCollection.ts +1 -1
  107. package/src/channel/useGroupChannelList/useGroupChannelListWithQuery.ts +1 -1
  108. package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.ts +174 -105
  109. package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.ts +90 -63
  110. package/src/channel/useOpenChannelList/useOpenChannelListWithQuery.ts +1 -5
  111. package/src/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.ts +143 -26
  112. package/src/common/useUserList.ts +4 -4
  113. package/src/handler/useChannelHandler.ts +11 -24
  114. package/src/handler/useConnectionHandler.ts +11 -5
  115. package/src/index.ts +0 -1
  116. package/src/types.ts +58 -20
  117. package/lib/commonjs/channel/useGroupChannelMessages/reducer.js +0 -154
  118. package/lib/commonjs/channel/useGroupChannelMessages/reducer.js.map +0 -1
  119. package/lib/commonjs/channel/useOpenChannelMessages/reducer.js +0 -154
  120. package/lib/commonjs/channel/useOpenChannelMessages/reducer.js.map +0 -1
  121. package/lib/commonjs/common/useTotalUnreadChannelCount.js +0 -29
  122. package/lib/commonjs/common/useTotalUnreadChannelCount.js.map +0 -1
  123. package/lib/module/channel/useGroupChannelMessages/reducer.js +0 -144
  124. package/lib/module/channel/useGroupChannelMessages/reducer.js.map +0 -1
  125. package/lib/module/channel/useOpenChannelMessages/reducer.js +0 -144
  126. package/lib/module/channel/useOpenChannelMessages/reducer.js.map +0 -1
  127. package/lib/module/common/useTotalUnreadChannelCount.js +0 -17
  128. package/lib/module/common/useTotalUnreadChannelCount.js.map +0 -1
  129. package/lib/typescript/src/channel/useGroupChannelMessages/reducer.d.ts +0 -15
  130. package/lib/typescript/src/channel/useOpenChannelMessages/reducer.d.ts +0 -15
  131. package/lib/typescript/src/common/useTotalUnreadChannelCount.d.ts +0 -6
  132. package/src/channel/useGroupChannelMessages/reducer.ts +0 -125
  133. package/src/channel/useOpenChannelMessages/reducer.ts +0 -125
  134. package/src/common/useTotalUnreadChannelCount.ts +0 -26
@@ -1,16 +1,12 @@
1
- import { useCallback, useEffect, useRef } from 'react';
1
+ import { useEffect, useRef } from 'react';
2
2
 
3
3
  import { MessageCollectionInitPolicy, MessageEventSource, MessageFilter } from '@sendbird/chat/groupChannel';
4
- import type {
5
- SendbirdBaseMessage,
6
- SendbirdFileMessage,
7
- SendbirdGroupChannel,
8
- SendbirdMessageCollection,
9
- } from '@sendbird/uikit-utils';
4
+ import type { SendbirdFileMessage, SendbirdGroupChannel, SendbirdMessageCollection } from '@sendbird/uikit-utils';
10
5
  import {
11
6
  Logger,
12
7
  confirmAndMarkAsRead,
13
8
  isDifferentChannel,
9
+ isMyMessage,
14
10
  useForceUpdate,
15
11
  useFreshCallback,
16
12
  useUniqHandlerId,
@@ -18,35 +14,49 @@ import {
18
14
 
19
15
  import { useChannelHandler } from '../../handler/useChannelHandler';
20
16
  import type { UseGroupChannelMessages, UseGroupChannelMessagesOptions } from '../../types';
21
- import { useGroupChannelMessagesReducer } from './reducer';
17
+ import { useChannelMessagesReducer } from '../useChannelMessagesReducer';
18
+
19
+ const MESSAGE_LIMIT = {
20
+ DEFAULT: 50,
21
+ SEARCH: 20,
22
+ };
22
23
 
23
24
  const createMessageCollection = (
24
25
  channel: SendbirdGroupChannel,
25
- creator?: UseGroupChannelMessagesOptions['collectionCreator'],
26
+ limit: number,
27
+ options?: UseGroupChannelMessagesOptions,
26
28
  ) => {
27
- if (creator) return creator();
29
+ if (options?.collectionCreator) return options?.collectionCreator({ startingPoint: options?.startingPoint });
28
30
  const filter = new MessageFilter();
29
- return channel.createMessageCollection({ filter, limit: 100 });
31
+ return channel.createMessageCollection({ filter, limit, startingPoint: options?.startingPoint });
30
32
  };
31
33
 
34
+ function isNotEmpty(arr?: unknown[]): arr is unknown[] {
35
+ if (!arr) return false;
36
+ return arr.length !== 0;
37
+ }
38
+
32
39
  export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (sdk, channel, userId, options) => {
40
+ const initialStartingPoint = options?.startingPoint ?? Number.MAX_SAFE_INTEGER;
41
+ const initialLimit = typeof options?.startingPoint === 'number' ? MESSAGE_LIMIT.SEARCH : MESSAGE_LIMIT.DEFAULT;
42
+
33
43
  const forceUpdate = useForceUpdate();
34
44
  const collectionRef = useRef<SendbirdMessageCollection>();
45
+ const collectionInitializedRef = useRef(false);
35
46
  const handlerId = useUniqHandlerId('useGroupChannelMessagesWithCollection');
36
47
 
37
48
  const {
38
49
  loading,
39
50
  refreshing,
40
51
  messages,
41
- nextMessages,
42
- newMessagesFromMembers,
52
+ newMessages,
43
53
  updateMessages,
44
- updateNextMessages,
45
- deleteNextMessages,
54
+ updateNewMessages,
55
+ deleteNewMessages,
46
56
  deleteMessages,
47
57
  updateLoading,
48
58
  updateRefreshing,
49
- } = useGroupChannelMessagesReducer(userId, options?.sortComparator);
59
+ } = useChannelMessagesReducer(options?.sortComparator);
50
60
 
51
61
  const channelMarkAsRead = async (source?: MessageEventSource) => {
52
62
  try {
@@ -63,85 +73,121 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
63
73
  }
64
74
  };
65
75
 
66
- const init = useCallback(
67
- async (uid?: string, callback?: () => void) => {
68
- if (collectionRef.current) collectionRef.current?.dispose();
76
+ const updateUnsendMessages = () => {
77
+ const { pendingMessages, failedMessages } = collectionRef.current ?? {};
78
+ if (isNotEmpty(pendingMessages)) updateMessages(pendingMessages, false, sdk.currentUser.userId);
79
+ if (isNotEmpty(failedMessages)) updateMessages(failedMessages, false, sdk.currentUser.userId);
80
+ };
69
81
 
70
- if (uid) {
71
- collectionRef.current = createMessageCollection(channel, options?.collectionCreator);
72
- updateNextMessages([], true, sdk.currentUser.userId);
73
- channelMarkAsRead();
82
+ const init = useFreshCallback(async (startingPoint: number, limit: number, callback?: () => void) => {
83
+ if (collectionRef.current) collectionRef.current?.dispose();
74
84
 
75
- collectionRef.current?.setMessageCollectionHandler({
76
- onMessagesAdded: (_, __, messages) => {
77
- channelMarkAsRead(_.source);
78
- updateNextMessages(messages, false, sdk.currentUser.userId);
79
- },
80
- onMessagesUpdated: (_, __, messages) => {
81
- channelMarkAsRead(_.source);
85
+ channelMarkAsRead();
86
+ updateNewMessages([], true, sdk.currentUser.userId);
82
87
 
83
- // NOTE: admin message is not added via onMessagesAdded handler, not checked yet is this a bug.
84
- if (_.source === MessageEventSource.EVENT_MESSAGE_RECEIVED) {
85
- const nextMessageIds = nextMessages.map((it) => it.messageId);
86
- const nonAddedMessagesFromReceivedEvent = messages.filter(
87
- (it) => nextMessageIds.indexOf(it.messageId) === -1,
88
- );
89
- updateNextMessages(nonAddedMessagesFromReceivedEvent, false, sdk.currentUser.userId);
90
- }
88
+ collectionInitializedRef.current = false;
89
+ collectionRef.current = createMessageCollection(channel, limit, {
90
+ collectionCreator: options?.collectionCreator,
91
+ startingPoint,
92
+ });
91
93
 
92
- // NOTE: v4 MESSAGE_RECEIVED is called twice from onMessagesAdded and onMessagesUpdated when receiving new message.
93
- // This is not intended behavior but not bugs.
94
- if (_.source !== MessageEventSource.EVENT_MESSAGE_RECEIVED) {
95
- updateMessages(messages, false, sdk.currentUser.userId);
96
- }
97
- },
98
- onMessagesDeleted: (_, __, messageIds) => {
99
- deleteMessages(messageIds, []);
100
- deleteNextMessages(messageIds, []);
101
- },
102
- onChannelDeleted: () => {
103
- options?.onChannelDeleted?.();
104
- },
105
- onChannelUpdated: (_, eventChannel) => {
106
- if (eventChannel.isGroupChannel() && !isDifferentChannel(eventChannel, channel)) {
107
- forceUpdate();
108
- }
109
- },
110
- onHugeGapDetected: () => {
111
- init(uid);
112
- },
94
+ collectionRef.current?.setMessageCollectionHandler({
95
+ onMessagesAdded: (_, __, messages) => {
96
+ channelMarkAsRead(_.source);
97
+
98
+ const incomingMessages = messages.filter((it) => {
99
+ switch (_.source) {
100
+ case MessageEventSource.EVENT_MESSAGE_SENT_PENDING:
101
+ case MessageEventSource.EVENT_MESSAGE_SENT_SUCCESS:
102
+ case MessageEventSource.EVENT_MESSAGE_SENT_FAILED:
103
+ return !isMyMessage(it, sdk.currentUser.userId);
104
+ default:
105
+ return true;
106
+ }
113
107
  });
114
108
 
115
- collectionRef.current
116
- .initialize(MessageCollectionInitPolicy.CACHE_AND_REPLACE_BY_API)
117
- .onCacheResult((err, messages) => {
118
- if (err) sdk.isCacheEnabled && Logger.error('[useGroupChannelMessagesWithCollection/onCacheResult]', err);
119
- else {
120
- Logger.debug('[useGroupChannelMessagesWithCollection/onCacheResult]', 'message length:', messages.length);
109
+ if (incomingMessages.length > 0) {
110
+ updateMessages(incomingMessages, false, sdk.currentUser.userId);
111
+
112
+ if (options?.shouldCountNewMessages?.()) {
113
+ updateNewMessages(incomingMessages, false, sdk.currentUser.userId);
114
+ }
121
115
 
122
- updateMessages(messages, true, sdk.currentUser.userId);
123
- updateMessages(collectionRef.current?.pendingMessages ?? [], false, sdk.currentUser.userId);
124
- updateMessages(collectionRef.current?.failedMessages ?? [], false, sdk.currentUser.userId);
116
+ switch (_.source) {
117
+ case MessageEventSource.EVENT_MESSAGE_RECEIVED:
118
+ case MessageEventSource.SYNC_MESSAGE_FILL: {
119
+ options?.onMessagesReceived?.(incomingMessages);
125
120
  }
126
- callback?.();
127
- })
128
- .onApiResult((err, messages) => {
129
- if (err) Logger.warn('[useGroupChannelMessagesWithCollection/onApiResult]', err);
130
- else {
131
- Logger.debug('[useGroupChannelMessagesWithCollection/onApiResult]', 'message length:', messages.length);
132
-
133
- updateMessages(messages, true, sdk.currentUser.userId);
134
- if (sdk.isCacheEnabled) {
135
- updateMessages(collectionRef.current?.pendingMessages ?? [], false, sdk.currentUser.userId);
136
- updateMessages(collectionRef.current?.failedMessages ?? [], false, sdk.currentUser.userId);
137
- }
121
+ }
122
+ }
123
+ },
124
+ onMessagesUpdated: (_, __, messages) => {
125
+ channelMarkAsRead(_.source);
126
+
127
+ const incomingMessages = messages.filter((it) => {
128
+ switch (_.source) {
129
+ case MessageEventSource.EVENT_MESSAGE_UPDATED:
130
+ return !isMyMessage(it, sdk.currentUser.userId);
131
+ default:
132
+ return true;
133
+ }
134
+ });
135
+
136
+ if (incomingMessages.length > 0) {
137
+ // NOTE: admin message is not added via onMessagesAdded handler, not checked yet is this a bug.
138
+ updateMessages(messages, false, sdk.currentUser.userId);
139
+
140
+ if (options?.shouldCountNewMessages?.()) {
141
+ if (_.source === MessageEventSource.EVENT_MESSAGE_RECEIVED) {
142
+ updateNewMessages(messages, false, sdk.currentUser.userId);
138
143
  }
139
- callback?.();
140
- });
141
- }
142
- },
143
- [sdk, channel.url, options?.collectionCreator],
144
- );
144
+ }
145
+ }
146
+ },
147
+ onMessagesDeleted: (_, __, messageIds) => {
148
+ deleteMessages(messageIds, []);
149
+ deleteNewMessages(messageIds, []);
150
+ },
151
+ onChannelDeleted: () => {
152
+ options?.onChannelDeleted?.();
153
+ },
154
+ onChannelUpdated: (_, eventChannel) => {
155
+ if (eventChannel.isGroupChannel() && !isDifferentChannel(eventChannel, channel)) {
156
+ forceUpdate();
157
+ }
158
+ },
159
+ onHugeGapDetected: () => {
160
+ init(Number.MAX_SAFE_INTEGER, MESSAGE_LIMIT.DEFAULT);
161
+ },
162
+ });
163
+
164
+ collectionRef.current
165
+ .initialize(MessageCollectionInitPolicy.CACHE_AND_REPLACE_BY_API)
166
+ .onCacheResult((err, messages) => {
167
+ if (err) sdk.isCacheEnabled && Logger.error('[useGroupChannelMessagesWithCollection/onCacheResult]', err);
168
+ else {
169
+ Logger.debug('[useGroupChannelMessagesWithCollection/onCacheResult]', 'message length:', messages.length);
170
+
171
+ updateMessages(messages, true, sdk.currentUser.userId);
172
+ updateUnsendMessages();
173
+ }
174
+
175
+ callback?.();
176
+ })
177
+ .onApiResult((err, messages) => {
178
+ if (err) Logger.warn('[useGroupChannelMessagesWithCollection/onApiResult]', err);
179
+ else {
180
+ Logger.debug('[useGroupChannelMessagesWithCollection/onApiResult]', 'message length:', messages.length);
181
+
182
+ updateMessages(messages, true, sdk.currentUser.userId);
183
+ if (!options?.startingPoint) options?.onMessagesReceived?.(messages);
184
+ if (sdk.isCacheEnabled) updateUnsendMessages();
185
+ }
186
+
187
+ collectionInitializedRef.current = true;
188
+ callback?.();
189
+ });
190
+ });
145
191
 
146
192
  useChannelHandler(sdk, handlerId, {
147
193
  onUserBanned(channel, bannedUser) {
@@ -159,9 +205,9 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
159
205
  // NOTE: Cache read is heavy task, and it prevents smooth ui transition
160
206
  setTimeout(async () => {
161
207
  updateLoading(true);
162
- init(userId, () => updateLoading(false));
208
+ init(initialStartingPoint, initialLimit, () => updateLoading(false));
163
209
  }, 0);
164
- }, [init, userId]);
210
+ }, [channel.url, userId]);
165
211
 
166
212
  useEffect(() => {
167
213
  return () => {
@@ -171,7 +217,7 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
171
217
 
172
218
  const refresh: ReturnType<UseGroupChannelMessages>['refresh'] = useFreshCallback(async () => {
173
219
  updateRefreshing(true);
174
- init(userId, () => updateRefreshing(false));
220
+ init(Number.MAX_SAFE_INTEGER, MESSAGE_LIMIT.DEFAULT, () => updateRefreshing(false));
175
221
  });
176
222
 
177
223
  const prev: ReturnType<UseGroupChannelMessages>['prev'] = useFreshCallback(async () => {
@@ -183,23 +229,28 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
183
229
  }
184
230
  });
185
231
 
186
- const next: ReturnType<UseGroupChannelMessages>['next'] = useFreshCallback(async () => {
187
- const messageCandidates: SendbirdBaseMessage[] = [];
232
+ const hasPrev: ReturnType<UseGroupChannelMessages>['hasPrev'] = useFreshCallback(() => {
233
+ if (collectionInitializedRef.current && collectionRef.current) {
234
+ return collectionRef.current.hasPrevious;
235
+ } else {
236
+ return false;
237
+ }
238
+ });
188
239
 
240
+ const next: ReturnType<UseGroupChannelMessages>['next'] = useFreshCallback(async () => {
189
241
  if (collectionRef.current && collectionRef.current?.hasNext) {
190
242
  try {
191
243
  const fetchedList = await collectionRef.current?.loadNext();
192
- messageCandidates.push(...fetchedList);
244
+ updateMessages(fetchedList, false, sdk.currentUser.userId);
193
245
  } catch {}
194
246
  }
247
+ });
195
248
 
196
- if (nextMessages.length > 0) {
197
- messageCandidates.push(...nextMessages);
198
- }
199
-
200
- if (messageCandidates.length > 0) {
201
- updateMessages(messageCandidates, false, sdk.currentUser.userId);
202
- updateNextMessages([], true, sdk.currentUser.userId);
249
+ const hasNext: ReturnType<UseGroupChannelMessages>['hasNext'] = useFreshCallback(() => {
250
+ if (collectionInitializedRef.current && collectionRef.current) {
251
+ return collectionRef.current.hasNext;
252
+ } else {
253
+ return false;
203
254
  }
204
255
  });
205
256
 
@@ -220,8 +271,8 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
220
271
  resolve(sentMessage);
221
272
  }
222
273
  })
223
- .onFailed((err, _failedMessage) => {
224
- // updateMessages([failedMessage], false, sdk.currentUser.userId);
274
+ .onFailed((err, failedMessage) => {
275
+ updateMessages([failedMessage], false, sdk.currentUser.userId);
225
276
  reject(err);
226
277
  });
227
278
  });
@@ -244,8 +295,8 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
244
295
  resolve(sentMessage as SendbirdFileMessage);
245
296
  }
246
297
  })
247
- .onFailed((err, _failedMessage) => {
248
- // updateMessages([failedMessage], false, sdk.currentUser.userId);
298
+ .onFailed((err, failedMessage) => {
299
+ updateMessages([failedMessage], false, sdk.currentUser.userId);
249
300
  reject(err);
250
301
  });
251
302
  });
@@ -288,21 +339,39 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
288
339
  }
289
340
  }
290
341
  });
342
+ const resetNewMessages: ReturnType<UseGroupChannelMessages>['resetNewMessages'] = useFreshCallback(() => {
343
+ updateNewMessages([], true, sdk.currentUser.userId);
344
+ });
345
+ const resetWithStartingPoint: ReturnType<UseGroupChannelMessages>['resetWithStartingPoint'] = useFreshCallback(
346
+ (startingPoint, callback) => {
347
+ updateLoading(true);
348
+ updateMessages([], true, sdk.currentUser.userId);
349
+ init(startingPoint, MESSAGE_LIMIT.DEFAULT, () => {
350
+ updateLoading(false);
351
+ callback?.();
352
+ });
353
+ },
354
+ );
291
355
 
292
356
  return {
293
357
  loading,
294
358
  refreshing,
295
359
  refresh,
296
360
  messages,
297
- nextMessages,
298
- newMessagesFromMembers,
299
361
  next,
362
+ hasNext,
300
363
  prev,
364
+ hasPrev,
365
+ newMessages,
366
+ resetNewMessages,
301
367
  sendUserMessage,
302
368
  sendFileMessage,
303
369
  updateUserMessage,
304
370
  updateFileMessage,
305
371
  resendMessage,
306
372
  deleteMessage,
373
+ resetWithStartingPoint,
374
+ nextMessages: newMessages,
375
+ newMessagesFromMembers: newMessages,
307
376
  };
308
377
  };