@sendbird/uikit-chat-hooks 2.4.2 → 2.5.0-rc.1
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.
- package/lib/commonjs/channel/{useGroupChannelMessages/reducer.js → useChannelMessagesReducer.js} +39 -30
- package/lib/commonjs/channel/useChannelMessagesReducer.js.map +1 -0
- package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +169 -99
- package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
- package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +56 -25
- package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
- package/lib/commonjs/channel/useOpenChannelList/useOpenChannelListWithQuery.js +0 -4
- package/lib/commonjs/channel/useOpenChannelList/useOpenChannelListWithQuery.js.map +1 -1
- package/lib/commonjs/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js +128 -28
- package/lib/commonjs/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js.map +1 -1
- package/lib/commonjs/common/useUserList.js +2 -2
- package/lib/commonjs/common/useUserList.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/module/channel/{useGroupChannelMessages/reducer.js → useChannelMessagesReducer.js} +38 -29
- package/lib/module/channel/useChannelMessagesReducer.js.map +1 -0
- package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +170 -100
- package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
- package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +57 -26
- package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
- package/lib/module/channel/useOpenChannelList/useOpenChannelListWithQuery.js +0 -4
- package/lib/module/channel/useOpenChannelList/useOpenChannelListWithQuery.js.map +1 -1
- package/lib/module/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js +129 -29
- package/lib/module/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js.map +1 -1
- package/lib/module/common/useUserList.js +2 -2
- package/lib/module/common/useUserList.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/src/channel/useChannelMessagesReducer.d.ts +18 -0
- package/lib/typescript/src/types.d.ts +51 -20
- package/package.json +4 -5
- package/src/channel/useChannelMessagesReducer.ts +143 -0
- package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.ts +168 -96
- package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.ts +62 -25
- package/src/channel/useOpenChannelList/useOpenChannelListWithQuery.ts +0 -4
- package/src/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.ts +142 -25
- package/src/common/useUserList.ts +2 -2
- package/src/types.ts +58 -20
- package/lib/commonjs/channel/useGroupChannelMessages/reducer.js.map +0 -1
- package/lib/commonjs/channel/useOpenChannelMessages/reducer.js +0 -144
- package/lib/commonjs/channel/useOpenChannelMessages/reducer.js.map +0 -1
- package/lib/module/channel/useGroupChannelMessages/reducer.js.map +0 -1
- package/lib/module/channel/useOpenChannelMessages/reducer.js +0 -137
- package/lib/module/channel/useOpenChannelMessages/reducer.js.map +0 -1
- package/lib/typescript/src/channel/useGroupChannelMessages/reducer.d.ts +0 -15
- package/lib/typescript/src/channel/useOpenChannelMessages/reducer.d.ts +0 -15
- package/src/channel/useGroupChannelMessages/reducer.ts +0 -126
- package/src/channel/useOpenChannelMessages/reducer.ts +0 -126
|
@@ -1,16 +1,12 @@
|
|
|
1
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 {
|
|
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
|
-
|
|
26
|
+
limit: number,
|
|
27
|
+
options?: UseGroupChannelMessagesOptions,
|
|
26
28
|
) => {
|
|
27
|
-
if (
|
|
29
|
+
if (options?.collectionCreator) return options?.collectionCreator({ startingPoint: options?.startingPoint });
|
|
28
30
|
const filter = new MessageFilter();
|
|
29
|
-
return channel.createMessageCollection({ filter, limit:
|
|
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
|
-
|
|
42
|
-
newMessagesFromMembers,
|
|
52
|
+
newMessages,
|
|
43
53
|
updateMessages,
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
updateNewMessages,
|
|
55
|
+
deleteNewMessages,
|
|
46
56
|
deleteMessages,
|
|
47
57
|
updateLoading,
|
|
48
58
|
updateRefreshing,
|
|
49
|
-
} =
|
|
59
|
+
} = useChannelMessagesReducer(options?.sortComparator);
|
|
50
60
|
|
|
51
61
|
const channelMarkAsRead = async (source?: MessageEventSource) => {
|
|
52
62
|
try {
|
|
@@ -63,81 +73,120 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
63
73
|
}
|
|
64
74
|
};
|
|
65
75
|
|
|
66
|
-
const
|
|
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
|
+
};
|
|
81
|
+
|
|
82
|
+
const init = useFreshCallback(async (startingPoint: number, limit: number, callback?: () => void) => {
|
|
67
83
|
if (collectionRef.current) collectionRef.current?.dispose();
|
|
68
84
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
updateNextMessages([], true, sdk.currentUser.userId);
|
|
72
|
-
channelMarkAsRead();
|
|
85
|
+
channelMarkAsRead();
|
|
86
|
+
updateNewMessages([], true, sdk.currentUser.userId);
|
|
73
87
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
onMessagesUpdated: (_, __, messages) => {
|
|
80
|
-
channelMarkAsRead(_.source);
|
|
88
|
+
collectionInitializedRef.current = false;
|
|
89
|
+
collectionRef.current = createMessageCollection(channel, limit, {
|
|
90
|
+
collectionCreator: options?.collectionCreator,
|
|
91
|
+
startingPoint,
|
|
92
|
+
});
|
|
81
93
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const nonAddedMessagesFromReceivedEvent = messages.filter(
|
|
86
|
-
(it) => nextMessageIds.indexOf(it.messageId) === -1,
|
|
87
|
-
);
|
|
88
|
-
updateNextMessages(nonAddedMessagesFromReceivedEvent, false, sdk.currentUser.userId);
|
|
89
|
-
}
|
|
94
|
+
collectionRef.current?.setMessageCollectionHandler({
|
|
95
|
+
onMessagesAdded: (_, __, messages) => {
|
|
96
|
+
channelMarkAsRead(_.source);
|
|
90
97
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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;
|
|
95
106
|
}
|
|
96
|
-
}
|
|
97
|
-
onMessagesDeleted: (_, __, messageIds) => {
|
|
98
|
-
deleteMessages(messageIds, []);
|
|
99
|
-
deleteNextMessages(messageIds, []);
|
|
100
|
-
},
|
|
101
|
-
onChannelDeleted: () => {
|
|
102
|
-
options?.onChannelDeleted?.();
|
|
103
|
-
},
|
|
104
|
-
onChannelUpdated: (_, eventChannel) => {
|
|
105
|
-
if (eventChannel.isGroupChannel() && !isDifferentChannel(eventChannel, channel)) {
|
|
106
|
-
forceUpdate();
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
onHugeGapDetected: () => {
|
|
110
|
-
init(uid);
|
|
111
|
-
},
|
|
112
|
-
});
|
|
107
|
+
});
|
|
113
108
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
.onCacheResult((err, messages) => {
|
|
117
|
-
if (err) sdk.isCacheEnabled && Logger.error('[useGroupChannelMessagesWithCollection/onCacheResult]', err);
|
|
118
|
-
else {
|
|
119
|
-
Logger.debug('[useGroupChannelMessagesWithCollection/onCacheResult]', 'message length:', messages.length);
|
|
109
|
+
if (incomingMessages.length > 0) {
|
|
110
|
+
updateMessages(incomingMessages, false, sdk.currentUser.userId);
|
|
120
111
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
updateMessages(collectionRef.current?.failedMessages ?? [], false, sdk.currentUser.userId);
|
|
112
|
+
if (options?.shouldCountNewMessages?.()) {
|
|
113
|
+
updateNewMessages(incomingMessages, false, sdk.currentUser.userId);
|
|
124
114
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
Logger.debug('[useGroupChannelMessagesWithCollection/onApiResult]', 'message length:', messages.length);
|
|
131
|
-
|
|
132
|
-
updateMessages(messages, true, sdk.currentUser.userId);
|
|
133
|
-
if (sdk.isCacheEnabled) {
|
|
134
|
-
updateMessages(collectionRef.current?.pendingMessages ?? [], false, sdk.currentUser.userId);
|
|
135
|
-
updateMessages(collectionRef.current?.failedMessages ?? [], false, sdk.currentUser.userId);
|
|
115
|
+
|
|
116
|
+
switch (_.source) {
|
|
117
|
+
case MessageEventSource.EVENT_MESSAGE_RECEIVED:
|
|
118
|
+
case MessageEventSource.SYNC_MESSAGE_FILL: {
|
|
119
|
+
options?.onMessagesReceived?.(incomingMessages);
|
|
136
120
|
}
|
|
137
121
|
}
|
|
138
|
-
|
|
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
|
+
}
|
|
139
134
|
});
|
|
140
|
-
|
|
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);
|
|
143
|
+
}
|
|
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
|
+
});
|
|
141
190
|
});
|
|
142
191
|
|
|
143
192
|
useChannelHandler(sdk, handlerId, {
|
|
@@ -156,7 +205,7 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
156
205
|
// NOTE: Cache read is heavy task, and it prevents smooth ui transition
|
|
157
206
|
setTimeout(async () => {
|
|
158
207
|
updateLoading(true);
|
|
159
|
-
init(
|
|
208
|
+
init(initialStartingPoint, initialLimit, () => updateLoading(false));
|
|
160
209
|
}, 0);
|
|
161
210
|
}, [channel.url, userId]);
|
|
162
211
|
|
|
@@ -168,7 +217,7 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
168
217
|
|
|
169
218
|
const refresh: ReturnType<UseGroupChannelMessages>['refresh'] = useFreshCallback(async () => {
|
|
170
219
|
updateRefreshing(true);
|
|
171
|
-
init(
|
|
220
|
+
init(Number.MAX_SAFE_INTEGER, MESSAGE_LIMIT.DEFAULT, () => updateRefreshing(false));
|
|
172
221
|
});
|
|
173
222
|
|
|
174
223
|
const prev: ReturnType<UseGroupChannelMessages>['prev'] = useFreshCallback(async () => {
|
|
@@ -180,23 +229,28 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
180
229
|
}
|
|
181
230
|
});
|
|
182
231
|
|
|
183
|
-
const
|
|
184
|
-
|
|
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
|
+
});
|
|
185
239
|
|
|
240
|
+
const next: ReturnType<UseGroupChannelMessages>['next'] = useFreshCallback(async () => {
|
|
186
241
|
if (collectionRef.current && collectionRef.current?.hasNext) {
|
|
187
242
|
try {
|
|
188
243
|
const fetchedList = await collectionRef.current?.loadNext();
|
|
189
|
-
|
|
244
|
+
updateMessages(fetchedList, false, sdk.currentUser.userId);
|
|
190
245
|
} catch {}
|
|
191
246
|
}
|
|
247
|
+
});
|
|
192
248
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
updateMessages(messageCandidates, false, sdk.currentUser.userId);
|
|
199
|
-
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;
|
|
200
254
|
}
|
|
201
255
|
});
|
|
202
256
|
|
|
@@ -217,8 +271,8 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
217
271
|
resolve(sentMessage);
|
|
218
272
|
}
|
|
219
273
|
})
|
|
220
|
-
.onFailed((err,
|
|
221
|
-
|
|
274
|
+
.onFailed((err, failedMessage) => {
|
|
275
|
+
updateMessages([failedMessage], false, sdk.currentUser.userId);
|
|
222
276
|
reject(err);
|
|
223
277
|
});
|
|
224
278
|
});
|
|
@@ -241,8 +295,8 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
241
295
|
resolve(sentMessage as SendbirdFileMessage);
|
|
242
296
|
}
|
|
243
297
|
})
|
|
244
|
-
.onFailed((err,
|
|
245
|
-
|
|
298
|
+
.onFailed((err, failedMessage) => {
|
|
299
|
+
updateMessages([failedMessage], false, sdk.currentUser.userId);
|
|
246
300
|
reject(err);
|
|
247
301
|
});
|
|
248
302
|
});
|
|
@@ -285,21 +339,39 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
285
339
|
}
|
|
286
340
|
}
|
|
287
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
|
+
);
|
|
288
355
|
|
|
289
356
|
return {
|
|
290
357
|
loading,
|
|
291
358
|
refreshing,
|
|
292
359
|
refresh,
|
|
293
360
|
messages,
|
|
294
|
-
nextMessages,
|
|
295
|
-
newMessagesFromMembers,
|
|
296
361
|
next,
|
|
362
|
+
hasNext,
|
|
297
363
|
prev,
|
|
364
|
+
hasPrev,
|
|
365
|
+
newMessages,
|
|
366
|
+
resetNewMessages,
|
|
298
367
|
sendUserMessage,
|
|
299
368
|
sendFileMessage,
|
|
300
369
|
updateUserMessage,
|
|
301
370
|
updateFileMessage,
|
|
302
371
|
resendMessage,
|
|
303
372
|
deleteMessage,
|
|
373
|
+
resetWithStartingPoint,
|
|
374
|
+
nextMessages: newMessages,
|
|
375
|
+
newMessagesFromMembers: newMessages,
|
|
304
376
|
};
|
|
305
377
|
};
|
|
@@ -6,9 +6,11 @@ import type {
|
|
|
6
6
|
SendbirdPreviousMessageListQuery,
|
|
7
7
|
} from '@sendbird/uikit-utils';
|
|
8
8
|
import {
|
|
9
|
+
ASYNC_NOOP,
|
|
9
10
|
Logger,
|
|
10
11
|
confirmAndMarkAsRead,
|
|
11
12
|
isDifferentChannel,
|
|
13
|
+
isMyMessage,
|
|
12
14
|
useAsyncEffect,
|
|
13
15
|
useForceUpdate,
|
|
14
16
|
useFreshCallback,
|
|
@@ -17,7 +19,7 @@ import {
|
|
|
17
19
|
|
|
18
20
|
import { useChannelHandler } from '../../handler/useChannelHandler';
|
|
19
21
|
import type { UseGroupChannelMessages, UseGroupChannelMessagesOptions } from '../../types';
|
|
20
|
-
import {
|
|
22
|
+
import { useChannelMessagesReducer } from '../useChannelMessagesReducer';
|
|
21
23
|
|
|
22
24
|
const createMessageQuery = (
|
|
23
25
|
channel: SendbirdGroupChannel,
|
|
@@ -40,15 +42,14 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
|
|
|
40
42
|
loading,
|
|
41
43
|
refreshing,
|
|
42
44
|
messages,
|
|
43
|
-
|
|
44
|
-
newMessagesFromMembers,
|
|
45
|
+
newMessages,
|
|
45
46
|
updateMessages,
|
|
46
|
-
updateNextMessages,
|
|
47
|
-
deleteNextMessages,
|
|
48
47
|
deleteMessages,
|
|
48
|
+
updateNewMessages,
|
|
49
|
+
deleteNewMessages,
|
|
49
50
|
updateLoading,
|
|
50
51
|
updateRefreshing,
|
|
51
|
-
} =
|
|
52
|
+
} = useChannelMessagesReducer(options?.sortComparator);
|
|
52
53
|
|
|
53
54
|
const channelMarkAsRead = async () => {
|
|
54
55
|
try {
|
|
@@ -60,13 +61,14 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
|
|
|
60
61
|
|
|
61
62
|
const init = useFreshCallback(async (uid?: string) => {
|
|
62
63
|
if (uid) {
|
|
63
|
-
queryRef.current = createMessageQuery(channel, options?.queryCreator);
|
|
64
64
|
channelMarkAsRead();
|
|
65
|
+
updateNewMessages([], true, sdk.currentUser.userId);
|
|
66
|
+
|
|
67
|
+
queryRef.current = createMessageQuery(channel, options?.queryCreator);
|
|
65
68
|
if (queryRef.current?.hasNext) {
|
|
66
69
|
const list = await queryRef.current?.load();
|
|
67
70
|
updateMessages(list, true, sdk.currentUser.userId);
|
|
68
71
|
}
|
|
69
|
-
updateNextMessages([], true, sdk.currentUser.userId);
|
|
70
72
|
}
|
|
71
73
|
});
|
|
72
74
|
|
|
@@ -80,17 +82,42 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
|
|
|
80
82
|
// Messages
|
|
81
83
|
onMessageReceived(eventChannel, message) {
|
|
82
84
|
if (isDifferentChannel(channel, eventChannel)) return;
|
|
85
|
+
if (isMyMessage(message, sdk.currentUser.userId)) return;
|
|
86
|
+
|
|
83
87
|
channelMarkAsRead();
|
|
84
|
-
|
|
88
|
+
|
|
89
|
+
updateMessages([message], false, sdk.currentUser.userId);
|
|
90
|
+
if (options?.shouldCountNewMessages?.()) {
|
|
91
|
+
updateNewMessages([message], false, sdk.currentUser.userId);
|
|
92
|
+
}
|
|
93
|
+
if (options?.onMessagesReceived) {
|
|
94
|
+
options.onMessagesReceived([message]);
|
|
95
|
+
}
|
|
85
96
|
},
|
|
86
97
|
onMessageUpdated(eventChannel, message) {
|
|
87
98
|
if (isDifferentChannel(channel, eventChannel)) return;
|
|
99
|
+
if (isMyMessage(message, sdk.currentUser.userId)) return;
|
|
100
|
+
|
|
88
101
|
updateMessages([message], false, sdk.currentUser.userId);
|
|
89
102
|
},
|
|
90
103
|
onMessageDeleted(eventChannel, messageId) {
|
|
91
104
|
if (isDifferentChannel(channel, eventChannel)) return;
|
|
92
105
|
deleteMessages([messageId], []);
|
|
93
|
-
|
|
106
|
+
deleteNewMessages([messageId], []);
|
|
107
|
+
},
|
|
108
|
+
async onReactionUpdated(eventChannel, reactionEvent) {
|
|
109
|
+
if (isDifferentChannel(channel, eventChannel)) return;
|
|
110
|
+
|
|
111
|
+
const message = await sdk.message.getMessage({
|
|
112
|
+
messageId: reactionEvent.messageId,
|
|
113
|
+
includeReactions: true,
|
|
114
|
+
includeParentMessageInfo: true,
|
|
115
|
+
includeThreadInfo: true,
|
|
116
|
+
includeMetaArray: true,
|
|
117
|
+
channelUrl: channel.url,
|
|
118
|
+
channelType: channel.channelType,
|
|
119
|
+
});
|
|
120
|
+
updateMessages([message], false, sdk.currentUser.userId);
|
|
94
121
|
},
|
|
95
122
|
// Channels
|
|
96
123
|
onChannelChanged: channelUpdater,
|
|
@@ -142,13 +169,12 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
|
|
|
142
169
|
updateMessages(list, false, sdk.currentUser.userId);
|
|
143
170
|
}
|
|
144
171
|
});
|
|
172
|
+
const hasPrev: ReturnType<UseGroupChannelMessages>['hasPrev'] = useFreshCallback(
|
|
173
|
+
() => queryRef.current?.hasNext ?? false,
|
|
174
|
+
);
|
|
145
175
|
|
|
146
|
-
const next: ReturnType<UseGroupChannelMessages>['next'] = useFreshCallback(
|
|
147
|
-
|
|
148
|
-
updateMessages(nextMessages, false, sdk.currentUser.userId);
|
|
149
|
-
updateNextMessages([], true, sdk.currentUser.userId);
|
|
150
|
-
}
|
|
151
|
-
});
|
|
176
|
+
const next: ReturnType<UseGroupChannelMessages>['next'] = useFreshCallback(ASYNC_NOOP);
|
|
177
|
+
const hasNext: ReturnType<UseGroupChannelMessages>['hasNext'] = useFreshCallback(() => false);
|
|
152
178
|
|
|
153
179
|
const sendUserMessage: ReturnType<UseGroupChannelMessages>['sendUserMessage'] = useFreshCallback(
|
|
154
180
|
(params, onPending) => {
|
|
@@ -157,18 +183,18 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
|
|
|
157
183
|
.sendUserMessage(params)
|
|
158
184
|
.onPending((pendingMessage) => {
|
|
159
185
|
if (pendingMessage.isUserMessage()) {
|
|
160
|
-
|
|
186
|
+
updateMessages([pendingMessage], false, sdk.currentUser.userId);
|
|
161
187
|
onPending?.(pendingMessage);
|
|
162
188
|
}
|
|
163
189
|
})
|
|
164
190
|
.onSucceeded((sentMessage) => {
|
|
165
191
|
if (sentMessage.isUserMessage()) {
|
|
166
|
-
|
|
192
|
+
updateMessages([sentMessage], false, sdk.currentUser.userId);
|
|
167
193
|
resolve(sentMessage);
|
|
168
194
|
}
|
|
169
195
|
})
|
|
170
196
|
.onFailed((err, sentMessage) => {
|
|
171
|
-
|
|
197
|
+
updateMessages([sentMessage], false, sdk.currentUser.userId);
|
|
172
198
|
reject(err);
|
|
173
199
|
});
|
|
174
200
|
});
|
|
@@ -181,18 +207,18 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
|
|
|
181
207
|
.sendFileMessage(params)
|
|
182
208
|
.onPending((pendingMessage) => {
|
|
183
209
|
if (pendingMessage.isFileMessage()) {
|
|
184
|
-
|
|
210
|
+
updateMessages([pendingMessage], false, sdk.currentUser.userId);
|
|
185
211
|
onPending?.(pendingMessage);
|
|
186
212
|
}
|
|
187
213
|
})
|
|
188
214
|
.onSucceeded((sentMessage) => {
|
|
189
215
|
if (sentMessage.isFileMessage()) {
|
|
190
|
-
|
|
216
|
+
updateMessages([sentMessage], false, sdk.currentUser.userId);
|
|
191
217
|
resolve(sentMessage);
|
|
192
218
|
}
|
|
193
219
|
})
|
|
194
220
|
.onFailed((err, sentMessage) => {
|
|
195
|
-
|
|
221
|
+
updateMessages([sentMessage], false, sdk.currentUser.userId);
|
|
196
222
|
reject(err);
|
|
197
223
|
});
|
|
198
224
|
});
|
|
@@ -220,7 +246,7 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
|
|
|
220
246
|
return null;
|
|
221
247
|
})();
|
|
222
248
|
|
|
223
|
-
if (message)
|
|
249
|
+
if (message) updateMessages([message], false, sdk.currentUser.userId);
|
|
224
250
|
},
|
|
225
251
|
);
|
|
226
252
|
const deleteMessage: ReturnType<UseGroupChannelMessages>['deleteMessage'] = useFreshCallback(async (message) => {
|
|
@@ -231,21 +257,32 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
|
|
|
231
257
|
deleteMessages([message.messageId], [message.reqId]);
|
|
232
258
|
}
|
|
233
259
|
});
|
|
260
|
+
const resetNewMessages: ReturnType<UseGroupChannelMessages>['resetNewMessages'] = useFreshCallback(() => {
|
|
261
|
+
updateNewMessages([], true, sdk.currentUser.userId);
|
|
262
|
+
});
|
|
234
263
|
|
|
235
264
|
return {
|
|
236
265
|
loading,
|
|
237
266
|
refreshing,
|
|
238
267
|
refresh,
|
|
239
268
|
messages,
|
|
240
|
-
|
|
241
|
-
|
|
269
|
+
newMessages,
|
|
270
|
+
resetNewMessages,
|
|
242
271
|
next,
|
|
272
|
+
hasNext,
|
|
243
273
|
prev,
|
|
274
|
+
hasPrev,
|
|
244
275
|
sendUserMessage,
|
|
245
276
|
sendFileMessage,
|
|
246
277
|
updateUserMessage,
|
|
247
278
|
updateFileMessage,
|
|
248
279
|
resendMessage,
|
|
249
280
|
deleteMessage,
|
|
281
|
+
resetWithStartingPoint() {
|
|
282
|
+
Logger.warn('resetWithStartingPoint is not supported in Query, please use Collection instead.');
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
nextMessages: newMessages,
|
|
286
|
+
newMessagesFromMembers: newMessages,
|
|
250
287
|
};
|
|
251
288
|
};
|
|
@@ -53,10 +53,6 @@ export const useOpenChannelListWithQuery: UseOpenChannelList = (sdk, userId, opt
|
|
|
53
53
|
onChannelFrozen: updateChannel,
|
|
54
54
|
onChannelUnfrozen: updateChannel,
|
|
55
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
56
|
onUserEntered: (channel, user) => {
|
|
61
57
|
const isMe = user.userId === userId;
|
|
62
58
|
if (isMe && channel.isOpenChannel() && !openChannels.find((it) => it.url === channel.url)) {
|