@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.
- package/lib/commonjs/channel/useGroupChannel.js +33 -0
- package/lib/commonjs/channel/useGroupChannel.js.map +1 -0
- package/lib/commonjs/channel/useGroupChannelMessages/reducer.js +3 -3
- package/lib/commonjs/channel/useGroupChannelMessages/reducer.js.map +1 -1
- package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +75 -79
- package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
- package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +30 -41
- package/lib/commonjs/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
- package/lib/commonjs/common/useAppFeatures.js +4 -4
- package/lib/commonjs/common/useAppFeatures.js.map +1 -1
- package/lib/commonjs/common/useMessageOutgoingStatus.js +1 -0
- package/lib/commonjs/common/useMessageOutgoingStatus.js.map +1 -1
- package/lib/commonjs/common/useTotalUnreadChannelCount.js +1 -1
- package/lib/commonjs/common/useTotalUnreadChannelCount.js.map +1 -1
- package/lib/commonjs/common/useTotalUnreadMessageCount.js +1 -1
- package/lib/commonjs/common/useTotalUnreadMessageCount.js.map +1 -1
- package/lib/commonjs/common/useUserList.js +33 -15
- package/lib/commonjs/common/useUserList.js.map +1 -1
- package/lib/commonjs/index.js +8 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/module/channel/useGroupChannel.js +22 -0
- package/lib/module/channel/useGroupChannel.js.map +1 -0
- package/lib/module/channel/useGroupChannelMessages/reducer.js +3 -3
- package/lib/module/channel/useGroupChannelMessages/reducer.js.map +1 -1
- package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js +76 -79
- package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.js.map +1 -1
- package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js +30 -40
- package/lib/module/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.js.map +1 -1
- package/lib/module/common/useAppFeatures.js +4 -4
- package/lib/module/common/useAppFeatures.js.map +1 -1
- package/lib/module/common/useMessageOutgoingStatus.js +1 -0
- package/lib/module/common/useMessageOutgoingStatus.js.map +1 -1
- package/lib/module/common/useTotalUnreadChannelCount.js +2 -2
- package/lib/module/common/useTotalUnreadChannelCount.js.map +1 -1
- package/lib/module/common/useTotalUnreadMessageCount.js +2 -2
- package/lib/module/common/useTotalUnreadMessageCount.js.map +1 -1
- package/lib/module/common/useUserList.js +35 -17
- package/lib/module/common/useUserList.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/src/channel/useGroupChannel.d.ts +6 -0
- package/lib/typescript/src/channel/useGroupChannelList/reducer.d.ts +1 -1
- package/lib/typescript/src/common/useMessageOutgoingStatus.d.ts +1 -1
- package/lib/typescript/src/common/useTotalUnreadChannelCount.d.ts +1 -1
- package/lib/typescript/src/common/useTotalUnreadMessageCount.d.ts +1 -1
- package/lib/typescript/src/common/useUserList.d.ts +2 -2
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/model/CustomQuery.d.ts +1 -1
- package/lib/typescript/src/types.d.ts +13 -9
- package/package.json +4 -4
- package/src/channel/useGroupChannel.ts +21 -0
- package/src/channel/useGroupChannelMessages/reducer.ts +4 -4
- package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithCollection.ts +92 -86
- package/src/channel/useGroupChannelMessages/useGroupChannelMessagesWithQuery.ts +33 -37
- package/src/common/useAppFeatures.ts +4 -4
- package/src/common/useMessageOutgoingStatus.ts +2 -0
- package/src/common/useTotalUnreadChannelCount.ts +2 -2
- package/src/common/useTotalUnreadMessageCount.ts +2 -2
- package/src/common/useUserList.ts +46 -20
- package/src/index.ts +2 -1
- package/src/types.ts +13 -7
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SendbirdChannel } from '@sendbird/uikit-utils';
|
|
2
|
-
|
|
2
|
+
type Order = 'latest_last_message' | 'chronological' | 'channel_name_alphabetical' | 'metadata_value_alphabetical';
|
|
3
3
|
export declare const useGroupChannelListReducer: (order?: Order) => {
|
|
4
4
|
updateLoading: (status: boolean) => void;
|
|
5
5
|
updateRefreshing: (status: boolean) => void;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { SendbirdChatSDK, SendbirdGroupChannel, SendbirdMessage } from '@sendbird/uikit-utils';
|
|
2
|
-
export
|
|
2
|
+
export type SBUOutgoingStatus = 'NONE' | 'PENDING' | 'FAILED' | 'UNDELIVERED' | 'DELIVERED' | 'UNREAD' | 'READ';
|
|
3
3
|
export declare const useMessageOutgoingStatus: (sdk: SendbirdChatSDK, channel: SendbirdGroupChannel, message?: SendbirdMessage | null) => SBUOutgoingStatus;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Optional, SendbirdChatSDK } from '@sendbird/uikit-utils';
|
|
1
|
+
import type { Optional, SendbirdChatSDK, UserStruct } from '@sendbird/uikit-utils';
|
|
2
2
|
import type { CustomQueryInterface, UseUserListOptions, UseUserListReturn } from '../types';
|
|
3
3
|
/**
|
|
4
4
|
* Get user list from query.
|
|
@@ -21,4 +21,4 @@ import type { CustomQueryInterface, UseUserListOptions, UseUserListReturn } from
|
|
|
21
21
|
* })
|
|
22
22
|
* ```
|
|
23
23
|
* */
|
|
24
|
-
export declare const useUserList: <Options extends UseUserListOptions<QueriedUser>, QueriedUser = Options["queryCreator"] extends Optional<() => CustomQueryInterface<infer User>> ? User : import("@sendbird/chat").User>(sdk: SendbirdChatSDK, options?: Options | undefined) => UseUserListReturn<QueriedUser>;
|
|
24
|
+
export declare const useUserList: <Options extends UseUserListOptions<QueriedUser>, QueriedUser extends UserStruct = Options["queryCreator"] extends Optional<() => CustomQueryInterface<infer User extends UserStruct>> ? User : import("@sendbird/chat").User>(sdk: SendbirdChatSDK, options?: Options | undefined) => UseUserListReturn<QueriedUser>;
|
|
@@ -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
|
export { useAppFeatures } from './common/useAppFeatures';
|
|
5
6
|
export { useMessageOutgoingStatus } from './common/useMessageOutgoingStatus';
|
|
6
7
|
export { usePushTrigger } from './common/usePushTrigger';
|
|
@@ -11,4 +12,4 @@ export { useChannelHandler } from './handler/useChannelHandler';
|
|
|
11
12
|
export { useConnectionHandler } from './handler/useConnectionHandler';
|
|
12
13
|
export { useUserEventHandler } from './handler/useUserEventHandler';
|
|
13
14
|
export { CustomQuery } from './model/CustomQuery';
|
|
14
|
-
export type { UseGroupChannelList, UseGroupChannelListOptions, UseGroupChannelMessages,
|
|
15
|
+
export type { UseGroupChannelList, UseGroupChannelListOptions, UseGroupChannelMessages, UseGroupChannelMessagesOptions, UseUserListOptions, UseUserListReturn, CustomQueryInterface, CustomBidirectionalQueryInterface, } from './types';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SendbirdChatSDK, SendbirdError, SendbirdFileMessage, SendbirdFileMessageCreateParams, SendbirdGroupChannel, SendbirdGroupChannelCollection, SendbirdGroupChannelListQuery, SendbirdMessage, SendbirdMessageCollection, SendbirdPreviousMessageListQuery, SendbirdUserMessage, SendbirdUserMessageCreateParams } from '@sendbird/uikit-utils';
|
|
1
|
+
import type { SendbirdChatSDK, SendbirdError, SendbirdFileMessage, SendbirdFileMessageCreateParams, SendbirdGroupChannel, SendbirdGroupChannelCollection, SendbirdGroupChannelListQuery, SendbirdMessage, SendbirdMessageCollection, SendbirdPreviousMessageListQuery, SendbirdUserMessage, SendbirdUserMessageCreateParams, UserStruct } from '@sendbird/uikit-utils';
|
|
2
2
|
export interface CustomQueryInterface<Data> {
|
|
3
3
|
isLoading: boolean;
|
|
4
4
|
next: () => Promise<Data[]>;
|
|
@@ -41,7 +41,7 @@ export interface UseGroupChannelList {
|
|
|
41
41
|
next: () => Promise<void>;
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
|
-
export
|
|
44
|
+
export type UseGroupChannelListOptions = {
|
|
45
45
|
queryCreator?: () => SendbirdGroupChannelListQuery;
|
|
46
46
|
collectionCreator?: () => SendbirdGroupChannelCollection;
|
|
47
47
|
enableCollectionWithoutLocalCache?: boolean;
|
|
@@ -139,13 +139,9 @@ export interface UseGroupChannelMessages {
|
|
|
139
139
|
* @return {Promise<void>}
|
|
140
140
|
* */
|
|
141
141
|
deleteMessage: (message: SendbirdFileMessage | SendbirdUserMessage) => Promise<void>;
|
|
142
|
-
/**
|
|
143
|
-
* Activated channel
|
|
144
|
-
* */
|
|
145
|
-
activeChannel: SendbirdGroupChannel;
|
|
146
142
|
};
|
|
147
143
|
}
|
|
148
|
-
export
|
|
144
|
+
export type UseGroupChannelMessagesOptions = {
|
|
149
145
|
sortComparator?: (a: SendbirdMessage, b: SendbirdMessage) => number;
|
|
150
146
|
queryCreator?: () => SendbirdPreviousMessageListQuery;
|
|
151
147
|
collectionCreator?: () => SendbirdMessageCollection;
|
|
@@ -156,7 +152,7 @@ export declare type UseGroupChannelMessagesOptions = {
|
|
|
156
152
|
* @interface UseUserListReturn
|
|
157
153
|
* @description interface for user list hook return value
|
|
158
154
|
* */
|
|
159
|
-
export interface UseUserListReturn<User> {
|
|
155
|
+
export interface UseUserListReturn<User extends UserStruct> {
|
|
160
156
|
/**
|
|
161
157
|
* Loading state, only available on first render
|
|
162
158
|
* */
|
|
@@ -178,13 +174,21 @@ export interface UseUserListReturn<User> {
|
|
|
178
174
|
* Get users state
|
|
179
175
|
* */
|
|
180
176
|
users: User[];
|
|
177
|
+
/**
|
|
178
|
+
* Update or Insert user to list
|
|
179
|
+
* */
|
|
180
|
+
upsertUser: (user: User) => void;
|
|
181
|
+
/**
|
|
182
|
+
* Delete user from list
|
|
183
|
+
* */
|
|
184
|
+
deleteUser: (userId: User['userId']) => void;
|
|
181
185
|
/**
|
|
182
186
|
* Fetch next users to state
|
|
183
187
|
* @return {Promise<void>}
|
|
184
188
|
* */
|
|
185
189
|
next: () => Promise<void>;
|
|
186
190
|
}
|
|
187
|
-
export
|
|
191
|
+
export type UseUserListOptions<User extends UserStruct> = {
|
|
188
192
|
sortComparator?: (a: User, b: User) => number;
|
|
189
193
|
queryCreator?: () => CustomQueryInterface<User>;
|
|
190
194
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sendbird/uikit-chat-hooks",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "React hooks that built with SendbirdChat SDK",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@sendbird/uikit-utils": "2.0
|
|
41
|
+
"@sendbird/uikit-utils": "2.2.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/react": "*",
|
|
45
45
|
"react": "^16.13.1",
|
|
46
46
|
"react-native-builder-bob": "^0.18.0",
|
|
47
|
-
"typescript": "
|
|
47
|
+
"typescript": "4.9.4"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@sendbird/chat": "^4.0.13",
|
|
@@ -69,5 +69,5 @@
|
|
|
69
69
|
"readmeFile": "./README.md",
|
|
70
70
|
"displayName": "@sendbird/uikit-chat-hooks"
|
|
71
71
|
},
|
|
72
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "bd7ab217a07e91ba644c0cb69694a92b123326bf"
|
|
73
73
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { SendbirdChatSDK, SendbirdGroupChannel, useAsyncEffect } from '@sendbird/uikit-utils';
|
|
4
|
+
|
|
5
|
+
export const useGroupChannel = (sdk: SendbirdChatSDK, channelUrl: string) => {
|
|
6
|
+
const [channel, setChannel] = useState<SendbirdGroupChannel>();
|
|
7
|
+
const [loading, setLoading] = useState(true);
|
|
8
|
+
const [error, setError] = useState<unknown>();
|
|
9
|
+
|
|
10
|
+
useAsyncEffect(async () => {
|
|
11
|
+
try {
|
|
12
|
+
setChannel(await sdk.groupChannel.getChannel(channelUrl));
|
|
13
|
+
} catch (e) {
|
|
14
|
+
setError(e);
|
|
15
|
+
} finally {
|
|
16
|
+
setLoading(false);
|
|
17
|
+
}
|
|
18
|
+
}, []);
|
|
19
|
+
|
|
20
|
+
return { channel, loading, error };
|
|
21
|
+
};
|
|
@@ -37,12 +37,12 @@ const defaultReducer = ({ ...draft }: State, action: Action) => {
|
|
|
37
37
|
}
|
|
38
38
|
case 'update_messages':
|
|
39
39
|
case 'update_next_messages': {
|
|
40
|
-
const key = action.type === 'update_messages' ? 'messageMap' :
|
|
41
|
-
const
|
|
40
|
+
const key = action.type === 'update_messages' ? 'messageMap' : 'nextMessageMap';
|
|
41
|
+
const receivedMessagesAsMap = arrayToMapWithGetter(action.value.messages, getMessageUniqId);
|
|
42
42
|
if (action.value.clearPrev) {
|
|
43
|
-
draft[key] =
|
|
43
|
+
draft[key] = receivedMessagesAsMap;
|
|
44
44
|
} else {
|
|
45
|
-
draft[key] = { ...draft[key], ...
|
|
45
|
+
draft[key] = { ...draft[key], ...receivedMessagesAsMap };
|
|
46
46
|
|
|
47
47
|
// NOTE: Replace pending message to succeeded message
|
|
48
48
|
action.value.messages
|
|
@@ -2,16 +2,21 @@ import { useCallback, useEffect, useRef } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { MessageCollectionInitPolicy, MessageEventSource, MessageFilter } from '@sendbird/chat/groupChannel';
|
|
4
4
|
import type {
|
|
5
|
-
|
|
5
|
+
SendbirdBaseMessage,
|
|
6
6
|
SendbirdFileMessage,
|
|
7
7
|
SendbirdGroupChannel,
|
|
8
8
|
SendbirdMessageCollection,
|
|
9
9
|
} from '@sendbird/uikit-utils';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
Logger,
|
|
12
|
+
confirmAndMarkAsRead,
|
|
13
|
+
isDifferentChannel,
|
|
14
|
+
useForceUpdate,
|
|
15
|
+
useFreshCallback,
|
|
16
|
+
} from '@sendbird/uikit-utils';
|
|
11
17
|
|
|
12
18
|
import { useChannelHandler } from '../../handler/useChannelHandler';
|
|
13
19
|
import type { UseGroupChannelMessages, UseGroupChannelMessagesOptions } from '../../types';
|
|
14
|
-
import { useActiveGroupChannel } from '../useActiveGroupChannel';
|
|
15
20
|
import { useGroupChannelMessagesReducer } from './reducer';
|
|
16
21
|
|
|
17
22
|
const createMessageCollection = (
|
|
@@ -26,11 +31,8 @@ const createMessageCollection = (
|
|
|
26
31
|
const HOOK_NAME = 'useGroupChannelMessagesWithCollection';
|
|
27
32
|
|
|
28
33
|
export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (sdk, channel, userId, options) => {
|
|
29
|
-
const collectionRef = useRef<SendbirdMessageCollection>();
|
|
30
|
-
|
|
31
|
-
// NOTE: We cannot determine the channel object of Sendbird SDK is stale or not, so force update af
|
|
32
|
-
const { activeChannel, setActiveChannel } = useActiveGroupChannel(sdk, channel);
|
|
33
34
|
const forceUpdate = useForceUpdate();
|
|
35
|
+
const collectionRef = useRef<SendbirdMessageCollection>();
|
|
34
36
|
|
|
35
37
|
const {
|
|
36
38
|
loading,
|
|
@@ -46,17 +48,18 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
46
48
|
updateRefreshing,
|
|
47
49
|
} = useGroupChannelMessagesReducer(userId, options?.sortComparator);
|
|
48
50
|
|
|
49
|
-
const
|
|
51
|
+
const channelMarkAsRead = async (source?: MessageEventSource) => {
|
|
50
52
|
try {
|
|
51
|
-
|
|
53
|
+
switch (source) {
|
|
54
|
+
case MessageEventSource.EVENT_MESSAGE_RECEIVED:
|
|
55
|
+
case MessageEventSource.EVENT_MESSAGE_SENT_SUCCESS:
|
|
56
|
+
case MessageEventSource.SYNC_MESSAGE_FILL:
|
|
57
|
+
case undefined:
|
|
58
|
+
await confirmAndMarkAsRead([channel]);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
52
61
|
} catch (e) {
|
|
53
|
-
Logger.warn(`[${HOOK_NAME}/
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const updateChannel = (channel: SendbirdChannel) => {
|
|
58
|
-
if (channel.isGroupChannel() && !isDifferentChannel(channel, activeChannel)) {
|
|
59
|
-
forceUpdate();
|
|
62
|
+
Logger.warn(`[${HOOK_NAME}/channelMarkAsRead]`, e);
|
|
60
63
|
}
|
|
61
64
|
};
|
|
62
65
|
|
|
@@ -65,36 +68,44 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
65
68
|
if (collectionRef.current) collectionRef.current?.dispose();
|
|
66
69
|
|
|
67
70
|
if (uid) {
|
|
68
|
-
collectionRef.current = createMessageCollection(
|
|
71
|
+
collectionRef.current = createMessageCollection(channel, options?.collectionCreator);
|
|
69
72
|
updateNextMessages([], true, sdk.currentUser.userId);
|
|
70
|
-
|
|
73
|
+
channelMarkAsRead();
|
|
71
74
|
|
|
72
75
|
collectionRef.current?.setMessageCollectionHandler({
|
|
73
76
|
onMessagesAdded: (_, __, messages) => {
|
|
74
|
-
|
|
75
|
-
case MessageEventSource.EVENT_MESSAGE_RECEIVED:
|
|
76
|
-
case MessageEventSource.EVENT_MESSAGE_SENT_SUCCESS:
|
|
77
|
-
case MessageEventSource.SYNC_MESSAGE_FILL:
|
|
78
|
-
channelMarkAs();
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
77
|
+
channelMarkAsRead(_.source);
|
|
81
78
|
updateNextMessages(messages, false, sdk.currentUser.userId);
|
|
82
|
-
updateChannel(channel);
|
|
83
79
|
},
|
|
84
|
-
onMessagesUpdated: (_,
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
onMessagesUpdated: (_, __, messages) => {
|
|
81
|
+
channelMarkAsRead(_.source);
|
|
82
|
+
|
|
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
|
+
}
|
|
91
|
+
|
|
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
|
+
}
|
|
87
97
|
},
|
|
88
|
-
onMessagesDeleted: (_,
|
|
98
|
+
onMessagesDeleted: (_, __, messageIds) => {
|
|
89
99
|
deleteMessages(messageIds, []);
|
|
90
100
|
deleteNextMessages(messageIds, []);
|
|
91
|
-
updateChannel(channel);
|
|
92
101
|
},
|
|
93
102
|
onChannelDeleted: () => {
|
|
94
103
|
options?.onChannelDeleted?.();
|
|
95
104
|
},
|
|
96
|
-
onChannelUpdated: (_,
|
|
97
|
-
|
|
105
|
+
onChannelUpdated: (_, eventChannel) => {
|
|
106
|
+
if (eventChannel.isGroupChannel() && !isDifferentChannel(eventChannel, channel)) {
|
|
107
|
+
forceUpdate();
|
|
108
|
+
}
|
|
98
109
|
},
|
|
99
110
|
onHugeGapDetected: () => {
|
|
100
111
|
init(uid);
|
|
@@ -107,16 +118,18 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
107
118
|
if (err) sdk.isCacheEnabled && Logger.error(`[${HOOK_NAME}/onCacheResult]`, err);
|
|
108
119
|
else {
|
|
109
120
|
Logger.debug(`[${HOOK_NAME}/onCacheResult]`, 'message length:', messages.length);
|
|
121
|
+
|
|
110
122
|
updateMessages(messages, true, sdk.currentUser.userId);
|
|
111
123
|
updateMessages(collectionRef.current?.pendingMessages ?? [], false, sdk.currentUser.userId);
|
|
112
124
|
updateMessages(collectionRef.current?.failedMessages ?? [], false, sdk.currentUser.userId);
|
|
113
|
-
if (messages?.length) callback?.();
|
|
114
125
|
}
|
|
126
|
+
callback?.();
|
|
115
127
|
})
|
|
116
128
|
.onApiResult((err, messages) => {
|
|
117
129
|
if (err) Logger.warn(`[${HOOK_NAME}/onApiResult]`, err);
|
|
118
130
|
else {
|
|
119
131
|
Logger.debug(`[${HOOK_NAME}/onApiResult]`, 'message length:', messages.length);
|
|
132
|
+
|
|
120
133
|
updateMessages(messages, true, sdk.currentUser.userId);
|
|
121
134
|
if (sdk.isCacheEnabled) {
|
|
122
135
|
updateMessages(collectionRef.current?.pendingMessages ?? [], false, sdk.currentUser.userId);
|
|
@@ -127,16 +140,15 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
127
140
|
});
|
|
128
141
|
}
|
|
129
142
|
},
|
|
130
|
-
[sdk,
|
|
143
|
+
[sdk, channel.url, options?.collectionCreator],
|
|
131
144
|
);
|
|
132
145
|
|
|
133
146
|
useChannelHandler(sdk, HOOK_NAME, {
|
|
134
147
|
onUserBanned(channel, bannedUser) {
|
|
135
|
-
if (channel.isGroupChannel() && !isDifferentChannel(channel,
|
|
148
|
+
if (channel.isGroupChannel() && !isDifferentChannel(channel, channel)) {
|
|
136
149
|
if (bannedUser.userId === sdk.currentUser.userId) {
|
|
137
150
|
options?.onChannelDeleted?.();
|
|
138
151
|
} else {
|
|
139
|
-
setActiveChannel(channel);
|
|
140
152
|
forceUpdate();
|
|
141
153
|
}
|
|
142
154
|
}
|
|
@@ -144,7 +156,7 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
144
156
|
});
|
|
145
157
|
|
|
146
158
|
useEffect(() => {
|
|
147
|
-
// NOTE: Cache read is heavy
|
|
159
|
+
// NOTE: Cache read is heavy task, and it prevents smooth ui transition
|
|
148
160
|
setTimeout(async () => {
|
|
149
161
|
updateLoading(true);
|
|
150
162
|
init(userId, () => updateLoading(false));
|
|
@@ -157,41 +169,44 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
157
169
|
};
|
|
158
170
|
}, []);
|
|
159
171
|
|
|
160
|
-
const refresh: ReturnType<UseGroupChannelMessages>['refresh'] =
|
|
172
|
+
const refresh: ReturnType<UseGroupChannelMessages>['refresh'] = useFreshCallback(async () => {
|
|
161
173
|
updateRefreshing(true);
|
|
162
174
|
init(userId, () => updateRefreshing(false));
|
|
163
|
-
}
|
|
175
|
+
});
|
|
164
176
|
|
|
165
|
-
const prev: ReturnType<UseGroupChannelMessages>['prev'] =
|
|
177
|
+
const prev: ReturnType<UseGroupChannelMessages>['prev'] = useFreshCallback(async () => {
|
|
166
178
|
if (collectionRef.current && collectionRef.current?.hasPrevious) {
|
|
167
179
|
try {
|
|
168
180
|
const list = await collectionRef.current?.loadPrevious();
|
|
169
181
|
updateMessages(list, false, sdk.currentUser.userId);
|
|
170
182
|
} catch {}
|
|
171
183
|
}
|
|
172
|
-
}
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const next: ReturnType<UseGroupChannelMessages>['next'] = useFreshCallback(async () => {
|
|
187
|
+
const messageCandidates: SendbirdBaseMessage[] = [];
|
|
173
188
|
|
|
174
|
-
const next: ReturnType<UseGroupChannelMessages>['next'] = useCallback(async () => {
|
|
175
|
-
const list = [];
|
|
176
189
|
if (collectionRef.current && collectionRef.current?.hasNext) {
|
|
177
190
|
try {
|
|
178
191
|
const fetchedList = await collectionRef.current?.loadNext();
|
|
179
|
-
|
|
192
|
+
messageCandidates.push(...fetchedList);
|
|
180
193
|
} catch {}
|
|
181
194
|
}
|
|
195
|
+
|
|
182
196
|
if (nextMessages.length > 0) {
|
|
183
|
-
|
|
197
|
+
messageCandidates.push(...nextMessages);
|
|
184
198
|
}
|
|
185
|
-
|
|
186
|
-
|
|
199
|
+
|
|
200
|
+
if (messageCandidates.length > 0) {
|
|
201
|
+
updateMessages(messageCandidates, false, sdk.currentUser.userId);
|
|
187
202
|
updateNextMessages([], true, sdk.currentUser.userId);
|
|
188
203
|
}
|
|
189
|
-
}
|
|
204
|
+
});
|
|
190
205
|
|
|
191
|
-
const sendUserMessage: ReturnType<UseGroupChannelMessages>['sendUserMessage'] =
|
|
206
|
+
const sendUserMessage: ReturnType<UseGroupChannelMessages>['sendUserMessage'] = useFreshCallback(
|
|
192
207
|
(params, onPending) => {
|
|
193
208
|
return new Promise((resolve, reject) => {
|
|
194
|
-
|
|
209
|
+
channel
|
|
195
210
|
.sendUserMessage(params)
|
|
196
211
|
.onPending((pendingMessage) => {
|
|
197
212
|
if (pendingMessage.isUserMessage()) {
|
|
@@ -205,17 +220,17 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
205
220
|
resolve(sentMessage);
|
|
206
221
|
}
|
|
207
222
|
})
|
|
208
|
-
.onFailed((err) => {
|
|
223
|
+
.onFailed((err, _failedMessage) => {
|
|
224
|
+
// updateMessages([failedMessage], false, sdk.currentUser.userId);
|
|
209
225
|
reject(err);
|
|
210
226
|
});
|
|
211
227
|
});
|
|
212
228
|
},
|
|
213
|
-
[activeChannel],
|
|
214
229
|
);
|
|
215
|
-
const sendFileMessage: ReturnType<UseGroupChannelMessages>['sendFileMessage'] =
|
|
230
|
+
const sendFileMessage: ReturnType<UseGroupChannelMessages>['sendFileMessage'] = useFreshCallback(
|
|
216
231
|
(params, onPending) => {
|
|
217
232
|
return new Promise((resolve, reject) => {
|
|
218
|
-
|
|
233
|
+
channel
|
|
219
234
|
.sendFileMessage(params)
|
|
220
235
|
.onPending((pendingMessage) => {
|
|
221
236
|
if (pendingMessage.isFileMessage()) {
|
|
@@ -229,58 +244,50 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
229
244
|
resolve(sentMessage as SendbirdFileMessage);
|
|
230
245
|
}
|
|
231
246
|
})
|
|
232
|
-
.onFailed((err) => {
|
|
247
|
+
.onFailed((err, _failedMessage) => {
|
|
248
|
+
// updateMessages([failedMessage], false, sdk.currentUser.userId);
|
|
233
249
|
reject(err);
|
|
234
250
|
});
|
|
235
251
|
});
|
|
236
252
|
},
|
|
237
|
-
[activeChannel],
|
|
238
253
|
);
|
|
239
|
-
const updateUserMessage: ReturnType<UseGroupChannelMessages>['updateUserMessage'] =
|
|
254
|
+
const updateUserMessage: ReturnType<UseGroupChannelMessages>['updateUserMessage'] = useFreshCallback(
|
|
240
255
|
async (messageId, params) => {
|
|
241
|
-
const updatedMessage = await
|
|
256
|
+
const updatedMessage = await channel.updateUserMessage(messageId, params);
|
|
242
257
|
updateMessages([updatedMessage], false, sdk.currentUser.userId);
|
|
243
258
|
return updatedMessage;
|
|
244
259
|
},
|
|
245
|
-
[activeChannel],
|
|
246
260
|
);
|
|
247
|
-
const updateFileMessage: ReturnType<UseGroupChannelMessages>['updateFileMessage'] =
|
|
261
|
+
const updateFileMessage: ReturnType<UseGroupChannelMessages>['updateFileMessage'] = useFreshCallback(
|
|
248
262
|
async (messageId, params) => {
|
|
249
|
-
const updatedMessage = await
|
|
263
|
+
const updatedMessage = await channel.updateFileMessage(messageId, params);
|
|
250
264
|
updateMessages([updatedMessage], false, sdk.currentUser.userId);
|
|
251
265
|
return updatedMessage;
|
|
252
266
|
},
|
|
253
|
-
[activeChannel],
|
|
254
267
|
);
|
|
255
|
-
const resendMessage: ReturnType<UseGroupChannelMessages>['resendMessage'] =
|
|
268
|
+
const resendMessage: ReturnType<UseGroupChannelMessages>['resendMessage'] = useFreshCallback(
|
|
256
269
|
async (failedMessage) => {
|
|
257
|
-
const
|
|
258
|
-
if (failedMessage.isUserMessage()) return
|
|
259
|
-
|
|
260
|
-
// @ts-ignore
|
|
261
|
-
if (failedMessage.isFileMessage()) return activeChannel.resendFileMessage(failedMessage);
|
|
270
|
+
const resentMessage = await (() => {
|
|
271
|
+
if (failedMessage.isUserMessage()) return channel.resendUserMessage(failedMessage);
|
|
272
|
+
if (failedMessage.isFileMessage()) return channel.resendFileMessage(failedMessage);
|
|
262
273
|
return null;
|
|
263
274
|
})();
|
|
264
275
|
|
|
265
|
-
if (
|
|
276
|
+
if (resentMessage) updateMessages([resentMessage], false, sdk.currentUser.userId);
|
|
266
277
|
},
|
|
267
|
-
[activeChannel],
|
|
268
278
|
);
|
|
269
|
-
const deleteMessage: ReturnType<UseGroupChannelMessages>['deleteMessage'] =
|
|
270
|
-
|
|
271
|
-
if (message.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
deleteMessages([message.messageId], [message.reqId]);
|
|
279
|
-
}
|
|
279
|
+
const deleteMessage: ReturnType<UseGroupChannelMessages>['deleteMessage'] = useFreshCallback(async (message) => {
|
|
280
|
+
if (message.sendingStatus === 'succeeded') {
|
|
281
|
+
if (message.isUserMessage()) await channel.deleteMessage(message);
|
|
282
|
+
if (message.isFileMessage()) await channel.deleteMessage(message);
|
|
283
|
+
} else {
|
|
284
|
+
try {
|
|
285
|
+
await collectionRef.current?.removeFailedMessage(message.reqId);
|
|
286
|
+
} finally {
|
|
287
|
+
deleteMessages([message.messageId], [message.reqId]);
|
|
280
288
|
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
284
291
|
|
|
285
292
|
return {
|
|
286
293
|
loading,
|
|
@@ -297,6 +304,5 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
|
|
|
297
304
|
updateFileMessage,
|
|
298
305
|
resendMessage,
|
|
299
306
|
deleteMessage,
|
|
300
|
-
activeChannel,
|
|
301
307
|
};
|
|
302
308
|
};
|