@sendbird/uikit-chat-hooks 2.4.2 → 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 (46) hide show
  1. package/lib/commonjs/channel/{useGroupChannelMessages/reducer.js → useChannelMessagesReducer.js} +39 -30
  2. package/lib/commonjs/channel/useChannelMessagesReducer.js.map +1 -0
  3. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +169 -99
  4. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
  5. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +56 -25
  6. package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
  7. package/lib/commonjs/channel/useOpenChannelList/useOpenChannelListWithQuery.js +0 -4
  8. package/lib/commonjs/channel/useOpenChannelList/useOpenChannelListWithQuery.js.map +1 -1
  9. package/lib/commonjs/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js +128 -28
  10. package/lib/commonjs/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js.map +1 -1
  11. package/lib/commonjs/common/useUserList.js +2 -2
  12. package/lib/commonjs/common/useUserList.js.map +1 -1
  13. package/lib/commonjs/types.js.map +1 -1
  14. package/lib/module/channel/{useGroupChannelMessages/reducer.js → useChannelMessagesReducer.js} +38 -29
  15. package/lib/module/channel/useChannelMessagesReducer.js.map +1 -0
  16. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +170 -100
  17. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
  18. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +57 -26
  19. package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
  20. package/lib/module/channel/useOpenChannelList/useOpenChannelListWithQuery.js +0 -4
  21. package/lib/module/channel/useOpenChannelList/useOpenChannelListWithQuery.js.map +1 -1
  22. package/lib/module/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js +129 -29
  23. package/lib/module/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.js.map +1 -1
  24. package/lib/module/common/useUserList.js +2 -2
  25. package/lib/module/common/useUserList.js.map +1 -1
  26. package/lib/module/types.js.map +1 -1
  27. package/lib/typescript/src/channel/useChannelMessagesReducer.d.ts +18 -0
  28. package/lib/typescript/src/types.d.ts +51 -20
  29. package/package.json +4 -5
  30. package/src/channel/useChannelMessagesReducer.ts +143 -0
  31. package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.ts +168 -96
  32. package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.ts +62 -25
  33. package/src/channel/useOpenChannelList/useOpenChannelListWithQuery.ts +0 -4
  34. package/src/channel/useOpenChannelMessages/useOpenChannelMessagesWithQuery.ts +142 -25
  35. package/src/common/useUserList.ts +2 -2
  36. package/src/types.ts +58 -20
  37. package/lib/commonjs/channel/useGroupChannelMessages/reducer.js.map +0 -1
  38. package/lib/commonjs/channel/useOpenChannelMessages/reducer.js +0 -144
  39. package/lib/commonjs/channel/useOpenChannelMessages/reducer.js.map +0 -1
  40. package/lib/module/channel/useGroupChannelMessages/reducer.js.map +0 -1
  41. package/lib/module/channel/useOpenChannelMessages/reducer.js +0 -137
  42. package/lib/module/channel/useOpenChannelMessages/reducer.js.map +0 -1
  43. package/lib/typescript/src/channel/useGroupChannelMessages/reducer.d.ts +0 -15
  44. package/lib/typescript/src/channel/useOpenChannelMessages/reducer.d.ts +0 -15
  45. package/src/channel/useGroupChannelMessages/reducer.ts +0 -126
  46. package/src/channel/useOpenChannelMessages/reducer.ts +0 -126
@@ -1,5 +1,5 @@
1
1
  import { useReducer } from 'react';
2
- import { arrayToMapWithGetter, getMessageUniqId, isMyMessage, isNewMessage, useIIFE } from '@sendbird/uikit-utils';
2
+ import { arrayToMapWithGetter, getMessageUniqId, isNewMessage, isSendableMessage, useIIFE } from '@sendbird/uikit-utils';
3
3
  const defaultReducer = (_ref, action) => {
4
4
  let {
5
5
  ...draft
@@ -16,29 +16,40 @@ const defaultReducer = (_ref, action) => {
16
16
  return draft;
17
17
  }
18
18
  case 'update_messages':
19
- case 'update_next_messages':
20
19
  {
21
- const key = action.type === 'update_messages' ? 'messageMap' : 'nextMessageMap';
22
- const receivedMessagesAsMap = arrayToMapWithGetter(action.value.messages, getMessageUniqId);
23
20
  if (action.value.clearBeforeAction) {
24
- draft[key] = receivedMessagesAsMap;
21
+ draft['messageMap'] = arrayToMapWithGetter(action.value.messages, getMessageUniqId);
25
22
  } else {
26
- draft[key] = {
27
- ...draft[key],
28
- ...receivedMessagesAsMap
23
+ // Remove existing messages before update for prevent duplicate display
24
+ const messageKeys = action.value.messages.map(it => isSendableMessage(it) ? [it.messageId, it.reqId] : [it.messageId]).flat();
25
+ messageKeys.forEach(key => delete draft['messageMap'][key]);
26
+ draft['messageMap'] = {
27
+ ...draft['messageMap'],
28
+ ...arrayToMapWithGetter(action.value.messages, getMessageUniqId)
29
+ };
30
+ }
31
+ return draft;
32
+ }
33
+ case 'update_new_messages':
34
+ {
35
+ const newMessages = action.value.messages.filter(it => isNewMessage(it, action.value.currentUserId));
36
+ if (action.value.clearBeforeAction) {
37
+ draft['newMessageMap'] = arrayToMapWithGetter(newMessages, getMessageUniqId);
38
+ } else {
39
+ // Remove existing messages before update for prevent duplicate display
40
+ const messageKeys = newMessages.map(it => it.messageId);
41
+ messageKeys.forEach(key => delete draft['newMessageMap'][key]);
42
+ draft['newMessageMap'] = {
43
+ ...draft['newMessageMap'],
44
+ ...arrayToMapWithGetter(newMessages, getMessageUniqId)
29
45
  };
30
-
31
- // NOTE: Replace pending message to succeeded message
32
- action.value.messages.filter(m => {
33
- return (m.isFileMessage() || m.isUserMessage()) && Boolean(draft[key][m.reqId]) && m.sendingStatus === 'succeeded' && isMyMessage(m, action.value.currentUserId);
34
- }).forEach(m => delete draft[key][m.reqId]);
35
46
  }
36
47
  return draft;
37
48
  }
38
49
  case 'delete_messages':
39
- case 'delete_next_messages':
50
+ case 'delete_new_messages':
40
51
  {
41
- const key = action.type === 'delete_messages' ? 'messageMap' : 'nextMessageMap';
52
+ const key = action.type === 'delete_messages' ? 'messageMap' : 'newMessageMap';
42
53
  draft[key] = {
43
54
  ...draft[key]
44
55
  };
@@ -48,17 +59,17 @@ const defaultReducer = (_ref, action) => {
48
59
  }
49
60
  }
50
61
  };
51
- export const useGroupChannelMessagesReducer = (userId, sortComparator) => {
62
+ export const useChannelMessagesReducer = sortComparator => {
52
63
  const [{
53
64
  loading,
54
65
  refreshing,
55
66
  messageMap,
56
- nextMessageMap
67
+ newMessageMap
57
68
  }, dispatch] = useReducer(defaultReducer, {
58
69
  loading: true,
59
70
  refreshing: false,
60
71
  messageMap: {},
61
- nextMessageMap: {}
72
+ newMessageMap: {}
62
73
  });
63
74
  const updateMessages = (messages, clearBeforeAction, currentUserId) => {
64
75
  dispatch({
@@ -79,9 +90,9 @@ export const useGroupChannelMessagesReducer = (userId, sortComparator) => {
79
90
  }
80
91
  });
81
92
  };
82
- const updateNextMessages = (messages, clearBeforeAction, currentUserId) => {
93
+ const updateNewMessages = (messages, clearBeforeAction, currentUserId) => {
83
94
  dispatch({
84
- type: 'update_next_messages',
95
+ type: 'update_new_messages',
85
96
  value: {
86
97
  messages,
87
98
  clearBeforeAction,
@@ -89,9 +100,9 @@ export const useGroupChannelMessagesReducer = (userId, sortComparator) => {
89
100
  }
90
101
  });
91
102
  };
92
- const deleteNextMessages = (messageIds, reqIds) => {
103
+ const deleteNewMessages = (messageIds, reqIds) => {
93
104
  dispatch({
94
- type: 'delete_next_messages',
105
+ type: 'delete_new_messages',
95
106
  value: {
96
107
  messageIds,
97
108
  reqIds
@@ -118,20 +129,18 @@ export const useGroupChannelMessagesReducer = (userId, sortComparator) => {
118
129
  if (sortComparator) return Object.values(messageMap).sort(sortComparator);
119
130
  return Object.values(messageMap);
120
131
  });
121
- const nextMessages = Object.values(nextMessageMap);
122
- const newMessagesFromMembers = nextMessages.filter(msg => isNewMessage(msg, userId));
132
+ const newMessages = Object.values(newMessageMap);
123
133
  return {
124
134
  updateLoading,
125
135
  updateRefreshing,
126
136
  updateMessages,
127
- updateNextMessages,
128
137
  deleteMessages,
129
- deleteNextMessages,
130
138
  loading,
131
139
  refreshing,
132
140
  messages,
133
- nextMessages,
134
- newMessagesFromMembers
141
+ newMessages,
142
+ updateNewMessages,
143
+ deleteNewMessages
135
144
  };
136
145
  };
137
- //# sourceMappingURL=reducer.js.map
146
+ //# sourceMappingURL=useChannelMessagesReducer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useReducer","arrayToMapWithGetter","getMessageUniqId","isNewMessage","isSendableMessage","useIIFE","defaultReducer","_ref","action","draft","type","value","status","clearBeforeAction","messages","messageKeys","map","it","messageId","reqId","flat","forEach","key","newMessages","filter","currentUserId","messageIds","msgId","reqIds","useChannelMessagesReducer","sortComparator","loading","refreshing","messageMap","newMessageMap","dispatch","updateMessages","deleteMessages","updateNewMessages","deleteNewMessages","updateLoading","updateRefreshing","Object","values","sort"],"sources":["useChannelMessagesReducer.ts"],"sourcesContent":["import { useReducer } from 'react';\n\nimport type { SendbirdBaseMessage } from '@sendbird/uikit-utils';\nimport {\n SendbirdMessage,\n arrayToMapWithGetter,\n getMessageUniqId,\n isNewMessage,\n isSendableMessage,\n useIIFE,\n} from '@sendbird/uikit-utils';\n\ntype Options = {\n sortComparator?: (a: SendbirdMessage, b: SendbirdMessage) => number;\n};\n\ntype Action =\n | {\n type: 'update_loading' | 'update_refreshing';\n value: { status: boolean };\n }\n | {\n type: 'update_messages' | 'update_new_messages';\n value: { messages: SendbirdBaseMessage[]; clearBeforeAction: boolean; currentUserId?: string };\n }\n | {\n type: 'delete_messages' | 'delete_new_messages';\n value: { messageIds: number[]; reqIds: string[] };\n };\n\ntype State = {\n loading: boolean;\n refreshing: boolean;\n messageMap: Record<string, SendbirdBaseMessage>;\n newMessageMap: Record<string, SendbirdBaseMessage>;\n};\n\nconst defaultReducer = ({ ...draft }: State, action: Action) => {\n switch (action.type) {\n case 'update_refreshing': {\n draft['refreshing'] = action.value.status;\n return draft;\n }\n case 'update_loading': {\n draft['loading'] = action.value.status;\n return draft;\n }\n case 'update_messages': {\n if (action.value.clearBeforeAction) {\n draft['messageMap'] = arrayToMapWithGetter(action.value.messages, getMessageUniqId);\n } else {\n // Remove existing messages before update for prevent duplicate display\n const messageKeys = action.value.messages\n .map((it) => (isSendableMessage(it) ? [it.messageId, it.reqId] : [it.messageId]))\n .flat();\n messageKeys.forEach((key) => delete draft['messageMap'][key]);\n\n draft['messageMap'] = {\n ...draft['messageMap'],\n ...arrayToMapWithGetter(action.value.messages, getMessageUniqId),\n };\n }\n\n return draft;\n }\n case 'update_new_messages': {\n const newMessages = action.value.messages.filter((it) => isNewMessage(it, action.value.currentUserId));\n\n if (action.value.clearBeforeAction) {\n draft['newMessageMap'] = arrayToMapWithGetter(newMessages, getMessageUniqId);\n } else {\n // Remove existing messages before update for prevent duplicate display\n const messageKeys = newMessages.map((it) => it.messageId);\n messageKeys.forEach((key) => delete draft['newMessageMap'][key]);\n\n draft['newMessageMap'] = {\n ...draft['newMessageMap'],\n ...arrayToMapWithGetter(newMessages, getMessageUniqId),\n };\n }\n\n return draft;\n }\n case 'delete_messages':\n case 'delete_new_messages': {\n const key = action.type === 'delete_messages' ? 'messageMap' : 'newMessageMap';\n draft[key] = { ...draft[key] };\n action.value.messageIds.forEach((msgId) => delete draft[key][msgId]);\n action.value.reqIds.forEach((reqId) => delete draft[key][reqId]);\n\n return draft;\n }\n }\n};\n\nexport const useChannelMessagesReducer = (sortComparator?: Options['sortComparator']) => {\n const [{ loading, refreshing, messageMap, newMessageMap }, dispatch] = useReducer(defaultReducer, {\n loading: true,\n refreshing: false,\n messageMap: {},\n newMessageMap: {},\n });\n\n const updateMessages = (messages: SendbirdBaseMessage[], clearBeforeAction: boolean, currentUserId?: string) => {\n dispatch({ type: 'update_messages', value: { messages, clearBeforeAction, currentUserId } });\n };\n const deleteMessages = (messageIds: number[], reqIds: string[]) => {\n dispatch({ type: 'delete_messages', value: { messageIds, reqIds } });\n };\n const updateNewMessages = (messages: SendbirdBaseMessage[], clearBeforeAction: boolean, currentUserId?: string) => {\n dispatch({ type: 'update_new_messages', value: { messages, clearBeforeAction, currentUserId } });\n };\n const deleteNewMessages = (messageIds: number[], reqIds: string[]) => {\n dispatch({ type: 'delete_new_messages', value: { messageIds, reqIds } });\n };\n const updateLoading = (status: boolean) => {\n dispatch({ type: 'update_loading', value: { status } });\n };\n const updateRefreshing = (status: boolean) => {\n dispatch({ type: 'update_refreshing', value: { status } });\n };\n\n const messages = useIIFE(() => {\n if (sortComparator) return Object.values(messageMap).sort(sortComparator);\n return Object.values(messageMap);\n });\n const newMessages = Object.values(newMessageMap);\n\n return {\n updateLoading,\n updateRefreshing,\n updateMessages,\n deleteMessages,\n\n loading,\n refreshing,\n messages,\n\n newMessages,\n updateNewMessages,\n deleteNewMessages,\n };\n};\n"],"mappings":"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"}
@@ -1,33 +1,46 @@
1
1
  import { useEffect, useRef } from 'react';
2
2
  import { MessageCollectionInitPolicy, MessageEventSource, MessageFilter } from '@sendbird/chat/groupChannel';
3
- import { Logger, confirmAndMarkAsRead, isDifferentChannel, useForceUpdate, useFreshCallback, useUniqHandlerId } from '@sendbird/uikit-utils';
3
+ import { Logger, confirmAndMarkAsRead, isDifferentChannel, isMyMessage, useForceUpdate, useFreshCallback, useUniqHandlerId } from '@sendbird/uikit-utils';
4
4
  import { useChannelHandler } from '../../handler/useChannelHandler';
5
- import { useGroupChannelMessagesReducer } from './reducer';
6
- const createMessageCollection = (channel, creator) => {
7
- if (creator) return creator();
5
+ import { useChannelMessagesReducer } from '../useChannelMessagesReducer';
6
+ const MESSAGE_LIMIT = {
7
+ DEFAULT: 50,
8
+ SEARCH: 20
9
+ };
10
+ const createMessageCollection = (channel, limit, options) => {
11
+ if (options !== null && options !== void 0 && options.collectionCreator) return options === null || options === void 0 ? void 0 : options.collectionCreator({
12
+ startingPoint: options === null || options === void 0 ? void 0 : options.startingPoint
13
+ });
8
14
  const filter = new MessageFilter();
9
15
  return channel.createMessageCollection({
10
16
  filter,
11
- limit: 100
17
+ limit,
18
+ startingPoint: options === null || options === void 0 ? void 0 : options.startingPoint
12
19
  });
13
20
  };
21
+ function isNotEmpty(arr) {
22
+ if (!arr) return false;
23
+ return arr.length !== 0;
24
+ }
14
25
  export const useGroupChannelMessagesWithCollection = (sdk, channel, userId, options) => {
26
+ const initialStartingPoint = (options === null || options === void 0 ? void 0 : options.startingPoint) ?? Number.MAX_SAFE_INTEGER;
27
+ const initialLimit = typeof (options === null || options === void 0 ? void 0 : options.startingPoint) === 'number' ? MESSAGE_LIMIT.SEARCH : MESSAGE_LIMIT.DEFAULT;
15
28
  const forceUpdate = useForceUpdate();
16
29
  const collectionRef = useRef();
30
+ const collectionInitializedRef = useRef(false);
17
31
  const handlerId = useUniqHandlerId('useGroupChannelMessagesWithCollection');
18
32
  const {
19
33
  loading,
20
34
  refreshing,
21
35
  messages,
22
- nextMessages,
23
- newMessagesFromMembers,
36
+ newMessages,
24
37
  updateMessages,
25
- updateNextMessages,
26
- deleteNextMessages,
38
+ updateNewMessages,
39
+ deleteNewMessages,
27
40
  deleteMessages,
28
41
  updateLoading,
29
42
  updateRefreshing
30
- } = useGroupChannelMessagesReducer(userId, options === null || options === void 0 ? void 0 : options.sortComparator);
43
+ } = useChannelMessagesReducer(options === null || options === void 0 ? void 0 : options.sortComparator);
31
44
  const channelMarkAsRead = async source => {
32
45
  try {
33
46
  switch (source) {
@@ -42,74 +55,109 @@ export const useGroupChannelMessagesWithCollection = (sdk, channel, userId, opti
42
55
  Logger.warn('[useGroupChannelMessagesWithCollection/channelMarkAsRead]', e);
43
56
  }
44
57
  };
45
- const init = useFreshCallback(async (uid, callback) => {
46
- var _collectionRef$curren;
58
+ const updateUnsendMessages = () => {
59
+ const {
60
+ pendingMessages,
61
+ failedMessages
62
+ } = collectionRef.current ?? {};
63
+ if (isNotEmpty(pendingMessages)) updateMessages(pendingMessages, false, sdk.currentUser.userId);
64
+ if (isNotEmpty(failedMessages)) updateMessages(failedMessages, false, sdk.currentUser.userId);
65
+ };
66
+ const init = useFreshCallback(async (startingPoint, limit, callback) => {
67
+ var _collectionRef$curren, _collectionRef$curren2;
47
68
  if (collectionRef.current) (_collectionRef$curren = collectionRef.current) === null || _collectionRef$curren === void 0 ? void 0 : _collectionRef$curren.dispose();
48
- if (uid) {
49
- var _collectionRef$curren2;
50
- collectionRef.current = createMessageCollection(channel, options === null || options === void 0 ? void 0 : options.collectionCreator);
51
- updateNextMessages([], true, sdk.currentUser.userId);
52
- channelMarkAsRead();
53
- (_collectionRef$curren2 = collectionRef.current) === null || _collectionRef$curren2 === void 0 ? void 0 : _collectionRef$curren2.setMessageCollectionHandler({
54
- onMessagesAdded: (_, __, messages) => {
55
- channelMarkAsRead(_.source);
56
- updateNextMessages(messages, false, sdk.currentUser.userId);
57
- },
58
- onMessagesUpdated: (_, __, messages) => {
59
- channelMarkAsRead(_.source);
60
-
61
- // NOTE: admin message is not added via onMessagesAdded handler, not checked yet is this a bug.
62
- if (_.source === MessageEventSource.EVENT_MESSAGE_RECEIVED) {
63
- const nextMessageIds = nextMessages.map(it => it.messageId);
64
- const nonAddedMessagesFromReceivedEvent = messages.filter(it => nextMessageIds.indexOf(it.messageId) === -1);
65
- updateNextMessages(nonAddedMessagesFromReceivedEvent, false, sdk.currentUser.userId);
69
+ channelMarkAsRead();
70
+ updateNewMessages([], true, sdk.currentUser.userId);
71
+ collectionInitializedRef.current = false;
72
+ collectionRef.current = createMessageCollection(channel, limit, {
73
+ collectionCreator: options === null || options === void 0 ? void 0 : options.collectionCreator,
74
+ startingPoint
75
+ });
76
+ (_collectionRef$curren2 = collectionRef.current) === null || _collectionRef$curren2 === void 0 ? void 0 : _collectionRef$curren2.setMessageCollectionHandler({
77
+ onMessagesAdded: (_, __, messages) => {
78
+ channelMarkAsRead(_.source);
79
+ const incomingMessages = messages.filter(it => {
80
+ switch (_.source) {
81
+ case MessageEventSource.EVENT_MESSAGE_SENT_PENDING:
82
+ case MessageEventSource.EVENT_MESSAGE_SENT_SUCCESS:
83
+ case MessageEventSource.EVENT_MESSAGE_SENT_FAILED:
84
+ return !isMyMessage(it, sdk.currentUser.userId);
85
+ default:
86
+ return true;
66
87
  }
67
-
68
- // NOTE: v4 MESSAGE_RECEIVED is called twice from onMessagesAdded and onMessagesUpdated when receiving new message.
69
- // This is not intended behavior but not bugs.
70
- if (_.source !== MessageEventSource.EVENT_MESSAGE_RECEIVED) {
71
- updateMessages(messages, false, sdk.currentUser.userId);
88
+ });
89
+ if (incomingMessages.length > 0) {
90
+ var _options$shouldCountN;
91
+ updateMessages(incomingMessages, false, sdk.currentUser.userId);
92
+ if (options !== null && options !== void 0 && (_options$shouldCountN = options.shouldCountNewMessages) !== null && _options$shouldCountN !== void 0 && _options$shouldCountN.call(options)) {
93
+ updateNewMessages(incomingMessages, false, sdk.currentUser.userId);
72
94
  }
73
- },
74
- onMessagesDeleted: (_, __, messageIds) => {
75
- deleteMessages(messageIds, []);
76
- deleteNextMessages(messageIds, []);
77
- },
78
- onChannelDeleted: () => {
79
- var _options$onChannelDel;
80
- options === null || options === void 0 ? void 0 : (_options$onChannelDel = options.onChannelDeleted) === null || _options$onChannelDel === void 0 ? void 0 : _options$onChannelDel.call(options);
81
- },
82
- onChannelUpdated: (_, eventChannel) => {
83
- if (eventChannel.isGroupChannel() && !isDifferentChannel(eventChannel, channel)) {
84
- forceUpdate();
95
+ switch (_.source) {
96
+ case MessageEventSource.EVENT_MESSAGE_RECEIVED:
97
+ case MessageEventSource.SYNC_MESSAGE_FILL:
98
+ {
99
+ var _options$onMessagesRe;
100
+ options === null || options === void 0 ? void 0 : (_options$onMessagesRe = options.onMessagesReceived) === null || _options$onMessagesRe === void 0 ? void 0 : _options$onMessagesRe.call(options, incomingMessages);
101
+ }
85
102
  }
86
- },
87
- onHugeGapDetected: () => {
88
- init(uid);
89
- }
90
- });
91
- collectionRef.current.initialize(MessageCollectionInitPolicy.CACHE_AND_REPLACE_BY_API).onCacheResult((err, messages) => {
92
- if (err) sdk.isCacheEnabled && Logger.error('[useGroupChannelMessagesWithCollection/onCacheResult]', err);else {
93
- var _collectionRef$curren3, _collectionRef$curren4;
94
- Logger.debug('[useGroupChannelMessagesWithCollection/onCacheResult]', 'message length:', messages.length);
95
- updateMessages(messages, true, sdk.currentUser.userId);
96
- updateMessages(((_collectionRef$curren3 = collectionRef.current) === null || _collectionRef$curren3 === void 0 ? void 0 : _collectionRef$curren3.pendingMessages) ?? [], false, sdk.currentUser.userId);
97
- updateMessages(((_collectionRef$curren4 = collectionRef.current) === null || _collectionRef$curren4 === void 0 ? void 0 : _collectionRef$curren4.failedMessages) ?? [], false, sdk.currentUser.userId);
98
103
  }
99
- callback === null || callback === void 0 ? void 0 : callback();
100
- }).onApiResult((err, messages) => {
101
- if (err) Logger.warn('[useGroupChannelMessagesWithCollection/onApiResult]', err);else {
102
- Logger.debug('[useGroupChannelMessagesWithCollection/onApiResult]', 'message length:', messages.length);
103
- updateMessages(messages, true, sdk.currentUser.userId);
104
- if (sdk.isCacheEnabled) {
105
- var _collectionRef$curren5, _collectionRef$curren6;
106
- updateMessages(((_collectionRef$curren5 = collectionRef.current) === null || _collectionRef$curren5 === void 0 ? void 0 : _collectionRef$curren5.pendingMessages) ?? [], false, sdk.currentUser.userId);
107
- updateMessages(((_collectionRef$curren6 = collectionRef.current) === null || _collectionRef$curren6 === void 0 ? void 0 : _collectionRef$curren6.failedMessages) ?? [], false, sdk.currentUser.userId);
104
+ },
105
+ onMessagesUpdated: (_, __, messages) => {
106
+ channelMarkAsRead(_.source);
107
+ const incomingMessages = messages.filter(it => {
108
+ switch (_.source) {
109
+ case MessageEventSource.EVENT_MESSAGE_UPDATED:
110
+ return !isMyMessage(it, sdk.currentUser.userId);
111
+ default:
112
+ return true;
113
+ }
114
+ });
115
+ if (incomingMessages.length > 0) {
116
+ var _options$shouldCountN2;
117
+ // NOTE: admin message is not added via onMessagesAdded handler, not checked yet is this a bug.
118
+ updateMessages(messages, false, sdk.currentUser.userId);
119
+ if (options !== null && options !== void 0 && (_options$shouldCountN2 = options.shouldCountNewMessages) !== null && _options$shouldCountN2 !== void 0 && _options$shouldCountN2.call(options)) {
120
+ if (_.source === MessageEventSource.EVENT_MESSAGE_RECEIVED) {
121
+ updateNewMessages(messages, false, sdk.currentUser.userId);
122
+ }
108
123
  }
109
124
  }
110
- callback === null || callback === void 0 ? void 0 : callback();
111
- });
112
- }
125
+ },
126
+ onMessagesDeleted: (_, __, messageIds) => {
127
+ deleteMessages(messageIds, []);
128
+ deleteNewMessages(messageIds, []);
129
+ },
130
+ onChannelDeleted: () => {
131
+ var _options$onChannelDel;
132
+ options === null || options === void 0 ? void 0 : (_options$onChannelDel = options.onChannelDeleted) === null || _options$onChannelDel === void 0 ? void 0 : _options$onChannelDel.call(options);
133
+ },
134
+ onChannelUpdated: (_, eventChannel) => {
135
+ if (eventChannel.isGroupChannel() && !isDifferentChannel(eventChannel, channel)) {
136
+ forceUpdate();
137
+ }
138
+ },
139
+ onHugeGapDetected: () => {
140
+ init(Number.MAX_SAFE_INTEGER, MESSAGE_LIMIT.DEFAULT);
141
+ }
142
+ });
143
+ collectionRef.current.initialize(MessageCollectionInitPolicy.CACHE_AND_REPLACE_BY_API).onCacheResult((err, messages) => {
144
+ if (err) sdk.isCacheEnabled && Logger.error('[useGroupChannelMessagesWithCollection/onCacheResult]', err);else {
145
+ Logger.debug('[useGroupChannelMessagesWithCollection/onCacheResult]', 'message length:', messages.length);
146
+ updateMessages(messages, true, sdk.currentUser.userId);
147
+ updateUnsendMessages();
148
+ }
149
+ callback === null || callback === void 0 ? void 0 : callback();
150
+ }).onApiResult((err, messages) => {
151
+ if (err) Logger.warn('[useGroupChannelMessagesWithCollection/onApiResult]', err);else {
152
+ var _options$onMessagesRe2;
153
+ Logger.debug('[useGroupChannelMessagesWithCollection/onApiResult]', 'message length:', messages.length);
154
+ updateMessages(messages, true, sdk.currentUser.userId);
155
+ if (!(options !== null && options !== void 0 && options.startingPoint)) options === null || options === void 0 ? void 0 : (_options$onMessagesRe2 = options.onMessagesReceived) === null || _options$onMessagesRe2 === void 0 ? void 0 : _options$onMessagesRe2.call(options, messages);
156
+ if (sdk.isCacheEnabled) updateUnsendMessages();
157
+ }
158
+ collectionInitializedRef.current = true;
159
+ callback === null || callback === void 0 ? void 0 : callback();
160
+ });
113
161
  });
114
162
  useChannelHandler(sdk, handlerId, {
115
163
  onUserBanned(channel, bannedUser) {
@@ -127,45 +175,51 @@ export const useGroupChannelMessagesWithCollection = (sdk, channel, userId, opti
127
175
  // NOTE: Cache read is heavy task, and it prevents smooth ui transition
128
176
  setTimeout(async () => {
129
177
  updateLoading(true);
130
- init(userId, () => updateLoading(false));
178
+ init(initialStartingPoint, initialLimit, () => updateLoading(false));
131
179
  }, 0);
132
180
  }, [channel.url, userId]);
133
181
  useEffect(() => {
134
182
  return () => {
135
- var _collectionRef$curren7;
136
- if (collectionRef.current) (_collectionRef$curren7 = collectionRef.current) === null || _collectionRef$curren7 === void 0 ? void 0 : _collectionRef$curren7.dispose();
183
+ var _collectionRef$curren3;
184
+ if (collectionRef.current) (_collectionRef$curren3 = collectionRef.current) === null || _collectionRef$curren3 === void 0 ? void 0 : _collectionRef$curren3.dispose();
137
185
  };
138
186
  }, []);
139
187
  const refresh = useFreshCallback(async () => {
140
188
  updateRefreshing(true);
141
- init(userId, () => updateRefreshing(false));
189
+ init(Number.MAX_SAFE_INTEGER, MESSAGE_LIMIT.DEFAULT, () => updateRefreshing(false));
142
190
  });
143
191
  const prev = useFreshCallback(async () => {
144
- var _collectionRef$curren8;
145
- if (collectionRef.current && (_collectionRef$curren8 = collectionRef.current) !== null && _collectionRef$curren8 !== void 0 && _collectionRef$curren8.hasPrevious) {
192
+ var _collectionRef$curren4;
193
+ if (collectionRef.current && (_collectionRef$curren4 = collectionRef.current) !== null && _collectionRef$curren4 !== void 0 && _collectionRef$curren4.hasPrevious) {
146
194
  try {
147
- var _collectionRef$curren9;
148
- const list = await ((_collectionRef$curren9 = collectionRef.current) === null || _collectionRef$curren9 === void 0 ? void 0 : _collectionRef$curren9.loadPrevious());
195
+ var _collectionRef$curren5;
196
+ const list = await ((_collectionRef$curren5 = collectionRef.current) === null || _collectionRef$curren5 === void 0 ? void 0 : _collectionRef$curren5.loadPrevious());
149
197
  updateMessages(list, false, sdk.currentUser.userId);
150
198
  } catch {}
151
199
  }
152
200
  });
201
+ const hasPrev = useFreshCallback(() => {
202
+ if (collectionInitializedRef.current && collectionRef.current) {
203
+ return collectionRef.current.hasPrevious;
204
+ } else {
205
+ return false;
206
+ }
207
+ });
153
208
  const next = useFreshCallback(async () => {
154
- var _collectionRef$curren10;
155
- const messageCandidates = [];
156
- if (collectionRef.current && (_collectionRef$curren10 = collectionRef.current) !== null && _collectionRef$curren10 !== void 0 && _collectionRef$curren10.hasNext) {
209
+ var _collectionRef$curren6;
210
+ if (collectionRef.current && (_collectionRef$curren6 = collectionRef.current) !== null && _collectionRef$curren6 !== void 0 && _collectionRef$curren6.hasNext) {
157
211
  try {
158
- var _collectionRef$curren11;
159
- const fetchedList = await ((_collectionRef$curren11 = collectionRef.current) === null || _collectionRef$curren11 === void 0 ? void 0 : _collectionRef$curren11.loadNext());
160
- messageCandidates.push(...fetchedList);
212
+ var _collectionRef$curren7;
213
+ const fetchedList = await ((_collectionRef$curren7 = collectionRef.current) === null || _collectionRef$curren7 === void 0 ? void 0 : _collectionRef$curren7.loadNext());
214
+ updateMessages(fetchedList, false, sdk.currentUser.userId);
161
215
  } catch {}
162
216
  }
163
- if (nextMessages.length > 0) {
164
- messageCandidates.push(...nextMessages);
165
- }
166
- if (messageCandidates.length > 0) {
167
- updateMessages(messageCandidates, false, sdk.currentUser.userId);
168
- updateNextMessages([], true, sdk.currentUser.userId);
217
+ });
218
+ const hasNext = useFreshCallback(() => {
219
+ if (collectionInitializedRef.current && collectionRef.current) {
220
+ return collectionRef.current.hasNext;
221
+ } else {
222
+ return false;
169
223
  }
170
224
  });
171
225
  const sendUserMessage = useFreshCallback((params, onPending) => {
@@ -180,8 +234,8 @@ export const useGroupChannelMessagesWithCollection = (sdk, channel, userId, opti
180
234
  updateMessages([sentMessage], false, sdk.currentUser.userId);
181
235
  resolve(sentMessage);
182
236
  }
183
- }).onFailed((err, _failedMessage) => {
184
- // updateMessages([failedMessage], false, sdk.currentUser.userId);
237
+ }).onFailed((err, failedMessage) => {
238
+ updateMessages([failedMessage], false, sdk.currentUser.userId);
185
239
  reject(err);
186
240
  });
187
241
  });
@@ -198,8 +252,8 @@ export const useGroupChannelMessagesWithCollection = (sdk, channel, userId, opti
198
252
  updateMessages([sentMessage], false, sdk.currentUser.userId);
199
253
  resolve(sentMessage);
200
254
  }
201
- }).onFailed((err, _failedMessage) => {
202
- // updateMessages([failedMessage], false, sdk.currentUser.userId);
255
+ }).onFailed((err, failedMessage) => {
256
+ updateMessages([failedMessage], false, sdk.currentUser.userId);
203
257
  reject(err);
204
258
  });
205
259
  });
@@ -228,28 +282,44 @@ export const useGroupChannelMessagesWithCollection = (sdk, channel, userId, opti
228
282
  if (message.isFileMessage()) await channel.deleteMessage(message);
229
283
  } else {
230
284
  try {
231
- var _collectionRef$curren12;
232
- await ((_collectionRef$curren12 = collectionRef.current) === null || _collectionRef$curren12 === void 0 ? void 0 : _collectionRef$curren12.removeFailedMessage(message.reqId));
285
+ var _collectionRef$curren8;
286
+ await ((_collectionRef$curren8 = collectionRef.current) === null || _collectionRef$curren8 === void 0 ? void 0 : _collectionRef$curren8.removeFailedMessage(message.reqId));
233
287
  } finally {
234
288
  deleteMessages([message.messageId], [message.reqId]);
235
289
  }
236
290
  }
237
291
  });
292
+ const resetNewMessages = useFreshCallback(() => {
293
+ updateNewMessages([], true, sdk.currentUser.userId);
294
+ });
295
+ const resetWithStartingPoint = useFreshCallback((startingPoint, callback) => {
296
+ updateLoading(true);
297
+ updateMessages([], true, sdk.currentUser.userId);
298
+ init(startingPoint, MESSAGE_LIMIT.DEFAULT, () => {
299
+ updateLoading(false);
300
+ callback === null || callback === void 0 ? void 0 : callback();
301
+ });
302
+ });
238
303
  return {
239
304
  loading,
240
305
  refreshing,
241
306
  refresh,
242
307
  messages,
243
- nextMessages,
244
- newMessagesFromMembers,
245
308
  next,
309
+ hasNext,
246
310
  prev,
311
+ hasPrev,
312
+ newMessages,
313
+ resetNewMessages,
247
314
  sendUserMessage,
248
315
  sendFileMessage,
249
316
  updateUserMessage,
250
317
  updateFileMessage,
251
318
  resendMessage,
252
- deleteMessage
319
+ deleteMessage,
320
+ resetWithStartingPoint,
321
+ nextMessages: newMessages,
322
+ newMessagesFromMembers: newMessages
253
323
  };
254
324
  };
255
325
  //# sourceMappingURL=useGroupChannelMessagesWithCollection.js.map