@droppii-org/chat-mobile 0.2.47 → 0.2.49
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/module/config/api-endpoints.js +3 -2
- package/lib/module/config/api-endpoints.js.map +1 -1
- package/lib/module/context/ChatContext.js +3 -0
- package/lib/module/context/ChatContext.js.map +1 -1
- package/lib/module/core/notification/pushToken.js +37 -18
- package/lib/module/core/notification/pushToken.js.map +1 -1
- package/lib/module/core/useChatListener.js +3 -2
- package/lib/module/core/useChatListener.js.map +1 -1
- package/lib/module/hooks/message/useSendMessage.js +6 -5
- package/lib/module/hooks/message/useSendMessage.js.map +1 -1
- package/lib/module/hooks/query-keys.js +6 -1
- package/lib/module/hooks/query-keys.js.map +1 -1
- package/lib/module/hooks/useChatCompose.js +18 -1
- package/lib/module/hooks/useChatCompose.js.map +1 -1
- package/lib/module/hooks/users/useGetUsersInfo.js +14 -0
- package/lib/module/hooks/users/useGetUsersInfo.js.map +1 -0
- package/lib/module/screens/chat-detail/ChatDetail.js +8 -5
- package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatDetailHeader.js +21 -4
- package/lib/module/screens/chat-detail/ChatDetailHeader.js.map +1 -1
- package/lib/module/screens/inbox/Inbox.js +3 -3
- package/lib/module/screens/inbox/Inbox.js.map +1 -1
- package/lib/module/services/endpoints.js +9 -5
- package/lib/module/services/endpoints.js.map +1 -1
- package/lib/module/store/conversation.js +24 -3
- package/lib/module/store/conversation.js.map +1 -1
- package/lib/module/store/user.js +5 -0
- package/lib/module/store/user.js.map +1 -1
- package/lib/module/types/chat.js +11 -0
- package/lib/module/types/chat.js.map +1 -1
- package/lib/module/utils/message.js +2 -2
- package/lib/module/utils/message.js.map +1 -1
- package/lib/typescript/src/config/api-endpoints.d.ts +2 -1
- package/lib/typescript/src/config/api-endpoints.d.ts.map +1 -1
- package/lib/typescript/src/context/ChatContext.d.ts.map +1 -1
- package/lib/typescript/src/core/notification/pushToken.d.ts +3 -13
- package/lib/typescript/src/core/notification/pushToken.d.ts.map +1 -1
- package/lib/typescript/src/core/useChatListener.d.ts.map +1 -1
- package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
- package/lib/typescript/src/hooks/query-keys.d.ts +5 -0
- package/lib/typescript/src/hooks/query-keys.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useChatCompose.d.ts.map +1 -1
- package/lib/typescript/src/hooks/users/useGetUsersInfo.d.ts +2 -0
- package/lib/typescript/src/hooks/users/useGetUsersInfo.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatDetailHeader.d.ts +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatDetailHeader.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/types.d.ts +1 -0
- package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
- package/lib/typescript/src/screens/inbox/Inbox.d.ts +2 -2
- package/lib/typescript/src/screens/inbox/Inbox.d.ts.map +1 -1
- package/lib/typescript/src/services/endpoints.d.ts +2 -0
- package/lib/typescript/src/services/endpoints.d.ts.map +1 -1
- package/lib/typescript/src/store/conversation.d.ts +6 -1
- package/lib/typescript/src/store/conversation.d.ts.map +1 -1
- package/lib/typescript/src/store/user.d.ts +2 -0
- package/lib/typescript/src/store/user.d.ts.map +1 -1
- package/lib/typescript/src/types/chat.d.ts +28 -0
- package/lib/typescript/src/types/chat.d.ts.map +1 -1
- package/lib/typescript/src/utils/message.d.ts +1 -1
- package/lib/typescript/src/utils/message.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/config/api-endpoints.ts +4 -2
- package/src/context/ChatContext.tsx +3 -0
- package/src/core/notification/pushToken.ts +52 -16
- package/src/core/useChatListener.ts +3 -2
- package/src/hooks/message/useSendMessage.ts +9 -3
- package/src/hooks/query-keys.ts +6 -0
- package/src/hooks/useChatCompose.ts +19 -0
- package/src/hooks/users/useGetUsersInfo.ts +13 -0
- package/src/screens/chat-detail/ChatDetail.tsx +13 -5
- package/src/screens/chat-detail/ChatDetailHeader.tsx +20 -4
- package/src/screens/chat-detail/types.ts +1 -0
- package/src/screens/inbox/Inbox.tsx +9 -4
- package/src/services/endpoints.ts +8 -5
- package/src/store/conversation.ts +37 -3
- package/src/store/user.ts +5 -0
- package/src/types/chat.ts +32 -0
- package/src/utils/message.ts +7 -2
|
@@ -12,17 +12,19 @@
|
|
|
12
12
|
export interface ApiEndpoints {
|
|
13
13
|
// Chat service (relative paths - used with axios baseURL)
|
|
14
14
|
urlMetadata: string;
|
|
15
|
-
|
|
15
|
+
conversation: string;
|
|
16
16
|
// Image upload service (relative path - full URL constructed in imageUpload service)
|
|
17
17
|
imageUpload: string;
|
|
18
18
|
bot: string;
|
|
19
|
+
uploadFcmToken: string;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
const DEFAULT_ENDPOINTS: ApiEndpoints = {
|
|
22
23
|
urlMetadata: '/chat-service/v1/utils/url-metadata',
|
|
23
|
-
|
|
24
|
+
conversation: '/chat-service/v1/app/conversations',
|
|
24
25
|
imageUpload: '/uploader-service/v1/uploader/permanently',
|
|
25
26
|
bot: '/chat-service/v1/app/bots/',
|
|
27
|
+
uploadFcmToken: '/chat-service/third/fcm_update_token',
|
|
26
28
|
};
|
|
27
29
|
|
|
28
30
|
let endpoints: ApiEndpoints = { ...DEFAULT_ENDPOINTS };
|
|
@@ -42,6 +42,9 @@ const ChatProviderInner = ({
|
|
|
42
42
|
if (getChatToken) {
|
|
43
43
|
try {
|
|
44
44
|
const res = await getChatToken();
|
|
45
|
+
if (res?.token) {
|
|
46
|
+
useUserStore.getState().setToken(res.token);
|
|
47
|
+
}
|
|
45
48
|
const loginStatus = await OpenIMSDK.getLoginStatus();
|
|
46
49
|
if (!!res?.id && !!res?.token && loginStatus === LoginStatus.Logout) {
|
|
47
50
|
await OpenIMSDK.login(
|
|
@@ -1,24 +1,60 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import uuid from 'react-native-uuid';
|
|
3
|
+
import { apiInstance } from '../../services/apis';
|
|
4
|
+
import { ENDPOINTS } from '../../services/endpoints';
|
|
5
|
+
import { useUserStore } from '../../store/user';
|
|
6
|
+
import { DChatPlatform, type DChatProject } from '../../types/chat';
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
const PUSH_TOKEN_EXPIRE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
9
|
+
|
|
10
|
+
const platformID =
|
|
11
|
+
Platform.OS === 'ios' ? DChatPlatform.IOS : DChatPlatform.ANDROID;
|
|
12
|
+
|
|
13
|
+
const uploadFcmToken = async (
|
|
14
|
+
fcmToken: string,
|
|
15
|
+
userID: string,
|
|
16
|
+
project: DChatProject,
|
|
17
|
+
expireTime: number
|
|
18
|
+
): Promise<void> => {
|
|
19
|
+
console.log('[chat-mobile] uploadFcmToken', {
|
|
20
|
+
platformID,
|
|
21
|
+
fcmToken,
|
|
22
|
+
account: userID,
|
|
23
|
+
project,
|
|
24
|
+
expireTime,
|
|
25
|
+
});
|
|
26
|
+
const token = useUserStore.getState().token;
|
|
27
|
+
if (!token) {
|
|
28
|
+
console.warn(
|
|
29
|
+
'[chat-mobile] uploadFcmToken: missing OpenIM token, request will likely be rejected'
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
await apiInstance?.post(
|
|
34
|
+
ENDPOINTS.chatService.uploadFcmToken,
|
|
35
|
+
{
|
|
36
|
+
platformID,
|
|
37
|
+
fcmToken,
|
|
38
|
+
account: userID,
|
|
39
|
+
expireTime,
|
|
40
|
+
project,
|
|
41
|
+
},
|
|
42
|
+
{ headers: { operationID: uuid.v4(), token } }
|
|
43
|
+
);
|
|
44
|
+
};
|
|
8
45
|
|
|
9
46
|
export const registerPushToken = (
|
|
10
47
|
fcmToken: string,
|
|
11
|
-
|
|
48
|
+
userID: string,
|
|
49
|
+
project: DChatProject,
|
|
50
|
+
expireTime: number = Date.now() + PUSH_TOKEN_EXPIRE_MS
|
|
12
51
|
): Promise<void> => {
|
|
13
|
-
return
|
|
52
|
+
return uploadFcmToken(fcmToken, userID, project, expireTime);
|
|
14
53
|
};
|
|
15
54
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
*/
|
|
22
|
-
export const unregisterPushToken = (): Promise<void> => {
|
|
23
|
-
return OpenIMSDK.updateFcmToken('', 0);
|
|
55
|
+
export const unregisterPushToken = (
|
|
56
|
+
userID: string,
|
|
57
|
+
project: DChatProject
|
|
58
|
+
): Promise<void> => {
|
|
59
|
+
return uploadFcmToken('', userID, project, 0);
|
|
24
60
|
};
|
|
@@ -124,9 +124,10 @@ export const useChatListener = () => {
|
|
|
124
124
|
console.log('[Listener] OnRecvNewMessages', messages);
|
|
125
125
|
const conversationId =
|
|
126
126
|
useConversationStore.getState().currentConversationId;
|
|
127
|
-
|
|
127
|
+
const targetUserId = useConversationStore.getState().currentUserId;
|
|
128
|
+
if (!conversationId && !targetUserId) return;
|
|
128
129
|
const relevant = messages.filter((message) =>
|
|
129
|
-
belongsToConversation(message, conversationId)
|
|
130
|
+
belongsToConversation(message, conversationId, targetUserId)
|
|
130
131
|
);
|
|
131
132
|
|
|
132
133
|
if (!relevant.length) return;
|
|
@@ -66,7 +66,7 @@ export const useSendMessage = () => {
|
|
|
66
66
|
extendMessageInfo,
|
|
67
67
|
plainText
|
|
68
68
|
);
|
|
69
|
-
console.log('[useSendMessage] dispatchSend params', sendParams);
|
|
69
|
+
// console.log('[useSendMessage] dispatchSend params', sendParams);
|
|
70
70
|
const sent = await OpenIMSDK.sendMessage(sendParams);
|
|
71
71
|
deleteOneMessage(message.clientMsgID);
|
|
72
72
|
pushNewMessage(sent);
|
|
@@ -91,8 +91,14 @@ export const useSendMessage = () => {
|
|
|
91
91
|
flow?: IRunConversationFlowPayload;
|
|
92
92
|
customMessage?: CustomMessagePayload;
|
|
93
93
|
}) => {
|
|
94
|
-
const
|
|
95
|
-
|
|
94
|
+
const currentConversation = useConversationStore
|
|
95
|
+
.getState()
|
|
96
|
+
.getCurrentConversation();
|
|
97
|
+
const targetUserId = useConversationStore.getState().currentUserId;
|
|
98
|
+
const targetGroupId = useConversationStore.getState().currentGroupId;
|
|
99
|
+
|
|
100
|
+
const recvID = currentConversation?.userID || targetUserId;
|
|
101
|
+
const groupID = currentConversation?.groupID || targetGroupId;
|
|
96
102
|
if (!recvID && !groupID) return;
|
|
97
103
|
|
|
98
104
|
const messageList: MessageItem[] = [];
|
package/src/hooks/query-keys.ts
CHANGED
|
@@ -25,6 +25,12 @@ export const conversationQueryKeys = {
|
|
|
25
25
|
detailByBotId: (botId: string) => ['conversationByBotId', botId],
|
|
26
26
|
detailBySourceId: (sourceId: string) => ['detailBySourceId', sourceId],
|
|
27
27
|
joinedGroup: (groupId?: string) => [...conversationQueryKeys.all, groupId],
|
|
28
|
+
create: (userId?: string) => ['create', userId],
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const usersQueryKeys = {
|
|
32
|
+
all: ['users'] as const,
|
|
33
|
+
list: (userIds: string[]) => [...usersQueryKeys.all, ...userIds],
|
|
28
34
|
};
|
|
29
35
|
|
|
30
36
|
export type ConversationQueryKeys = typeof conversationQueryKeys;
|
|
@@ -13,6 +13,9 @@ import {
|
|
|
13
13
|
generateAndUploadVideoThumbnails,
|
|
14
14
|
type VideoWithUploadStatus,
|
|
15
15
|
} from '../utils/videoThumbnailUpload';
|
|
16
|
+
import { useConversationStore } from '../store';
|
|
17
|
+
import { DChatCategory } from '../types/chat';
|
|
18
|
+
import { useChatContext } from '../context';
|
|
16
19
|
|
|
17
20
|
export function useChatCompose() {
|
|
18
21
|
const [text, setText] = useState('');
|
|
@@ -22,6 +25,7 @@ export function useChatCompose() {
|
|
|
22
25
|
const linkPreview = useLinkPreview(text);
|
|
23
26
|
const { send: sendAttachments } = useSendAttachment();
|
|
24
27
|
const { sendMessage } = useSendMessage();
|
|
28
|
+
const { applicationType } = useChatContext();
|
|
25
29
|
|
|
26
30
|
const isUploading = useMemo(
|
|
27
31
|
() =>
|
|
@@ -49,6 +53,20 @@ export function useChatCompose() {
|
|
|
49
53
|
const { selectedImages, clearAllImages } = imageAttachment;
|
|
50
54
|
const { selectedFiles, clearAllFiles } = fileAttachment;
|
|
51
55
|
const urlMeta = linkPreview.isVisible ? linkPreview.metadata : undefined;
|
|
56
|
+
const currentConversationId =
|
|
57
|
+
useConversationStore.getState().currentConversationId;
|
|
58
|
+
const targetUserId = useConversationStore.getState().currentUserId;
|
|
59
|
+
const isCreatingConversation =
|
|
60
|
+
useConversationStore.getState().isCreatingConversation;
|
|
61
|
+
|
|
62
|
+
if (targetUserId && !currentConversationId && !isCreatingConversation) {
|
|
63
|
+
await useConversationStore.getState().createConversation({
|
|
64
|
+
chatType: 'SINGLE',
|
|
65
|
+
chatCategory: DChatCategory.BIZ_BIZ,
|
|
66
|
+
applicationType,
|
|
67
|
+
peerUserId: targetUserId,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
52
70
|
|
|
53
71
|
// --- Attachments ---
|
|
54
72
|
if (selectedImages.length > 0 || selectedFiles.length > 0) {
|
|
@@ -161,6 +179,7 @@ export function useChatCompose() {
|
|
|
161
179
|
sendAttachments,
|
|
162
180
|
sendMessage,
|
|
163
181
|
text,
|
|
182
|
+
applicationType,
|
|
164
183
|
]);
|
|
165
184
|
|
|
166
185
|
return {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query';
|
|
2
|
+
import { usersQueryKeys } from '../query-keys';
|
|
3
|
+
import OpenIMSDK from '@droppii/openim-rn-client-sdk';
|
|
4
|
+
|
|
5
|
+
export const useGetUsersInfo = (userIds: string[]) =>
|
|
6
|
+
useQuery({
|
|
7
|
+
queryKey: [usersQueryKeys.list(userIds)],
|
|
8
|
+
queryFn: async () => {
|
|
9
|
+
const users = await OpenIMSDK.getUsersInfo(userIds);
|
|
10
|
+
return users || [];
|
|
11
|
+
},
|
|
12
|
+
enabled: userIds.length > 0,
|
|
13
|
+
});
|
|
@@ -36,6 +36,7 @@ import type { MessageItem } from '@droppii/openim-rn-client-sdk';
|
|
|
36
36
|
import { useMessages } from '../../hooks/message/useMessages';
|
|
37
37
|
import { getBotId } from '../../utils/conversation';
|
|
38
38
|
import { ChatEvent } from '../../types/events';
|
|
39
|
+
import { useSetIsShowFLashMessage } from '../../context/global';
|
|
39
40
|
|
|
40
41
|
const ChatDetail = memo(
|
|
41
42
|
({
|
|
@@ -107,17 +108,23 @@ const ChatDetail = memo(
|
|
|
107
108
|
hasMoreNew,
|
|
108
109
|
} = useMessages({ conversationId });
|
|
109
110
|
|
|
111
|
+
const setShowFLashMessage = useSetIsShowFLashMessage();
|
|
112
|
+
|
|
110
113
|
const { pinnedMessages, pinMessage, unpinMessage } =
|
|
111
114
|
usePinMessage(conversationId);
|
|
112
115
|
|
|
113
116
|
useEffect(() => {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
+
useConversationStore
|
|
118
|
+
.getState()
|
|
119
|
+
.setCurrentConversation(conversationId, targetUserId, targetGroupId);
|
|
120
|
+
setShowFLashMessage(false);
|
|
117
121
|
return () => {
|
|
118
|
-
useConversationStore
|
|
122
|
+
useConversationStore
|
|
123
|
+
.getState()
|
|
124
|
+
.setCurrentConversation(undefined, undefined, undefined);
|
|
125
|
+
setShowFLashMessage(true);
|
|
119
126
|
};
|
|
120
|
-
}, [conversationId]);
|
|
127
|
+
}, [conversationId, targetUserId, targetGroupId, setShowFLashMessage]);
|
|
121
128
|
|
|
122
129
|
const resolvedShowAddMember =
|
|
123
130
|
showAddMember ?? shouldShowAddMember(conversation);
|
|
@@ -160,6 +167,7 @@ const ChatDetail = memo(
|
|
|
160
167
|
<KContainer.Page flex edges={['bottom']}>
|
|
161
168
|
<ChatDetailHeader
|
|
162
169
|
conversationId={conversationId}
|
|
170
|
+
targetUserId={targetUserId}
|
|
163
171
|
showAddMember={resolvedShowAddMember}
|
|
164
172
|
onBack={onBack ?? handleBackDefault}
|
|
165
173
|
onPressSearch={onPressSearch}
|
|
@@ -11,11 +11,13 @@ import { NamePrefixIcon } from '../../components/ThreadCard/NamePrefixIcon';
|
|
|
11
11
|
import type { ChatDetailHeaderProps } from './types';
|
|
12
12
|
import { useConversation } from '../../store';
|
|
13
13
|
import { getConversationSubtitle } from './conversationHeader.utils';
|
|
14
|
+
import { useGetUsersInfo } from '../../hooks/users/useGetUsersInfo';
|
|
14
15
|
|
|
15
16
|
const ChatDetailHeader = memo(
|
|
16
17
|
({
|
|
17
18
|
showAddMember = false,
|
|
18
19
|
conversationId,
|
|
20
|
+
targetUserId,
|
|
19
21
|
onBack,
|
|
20
22
|
onPressSearch,
|
|
21
23
|
onPressAddMember,
|
|
@@ -23,6 +25,20 @@ const ChatDetailHeader = memo(
|
|
|
23
25
|
onPressAvatar,
|
|
24
26
|
}: ChatDetailHeaderProps) => {
|
|
25
27
|
const conversation = useConversation(conversationId);
|
|
28
|
+
const { data: usersInfo } = useGetUsersInfo(
|
|
29
|
+
targetUserId ? [targetUserId] : []
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const { faceURL, showName } = useMemo(() => {
|
|
33
|
+
const userInfo = usersInfo?.[0];
|
|
34
|
+
const resolvedFaceURL = conversation?.faceURL || userInfo?.faceURL;
|
|
35
|
+
const resolvedShowName = conversation?.showName || userInfo?.nickname;
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
faceURL: resolvedFaceURL,
|
|
39
|
+
showName: resolvedShowName,
|
|
40
|
+
};
|
|
41
|
+
}, [conversation, usersInfo]);
|
|
26
42
|
const rightButtons = useMemo(() => {
|
|
27
43
|
const buttons = [
|
|
28
44
|
{
|
|
@@ -76,8 +92,8 @@ const ChatDetailHeader = memo(
|
|
|
76
92
|
activeOpacity={0.7}
|
|
77
93
|
>
|
|
78
94
|
<AvatarSection
|
|
79
|
-
avatar={
|
|
80
|
-
fullName={
|
|
95
|
+
avatar={faceURL || null}
|
|
96
|
+
fullName={showName || ''}
|
|
81
97
|
peerType={conversation?.peerType}
|
|
82
98
|
/>
|
|
83
99
|
|
|
@@ -90,7 +106,7 @@ const ChatDetailHeader = memo(
|
|
|
90
106
|
numberOfLines={1}
|
|
91
107
|
flex
|
|
92
108
|
>
|
|
93
|
-
{
|
|
109
|
+
{showName || ''}
|
|
94
110
|
</KLabel.Text>
|
|
95
111
|
</KContainer.View>
|
|
96
112
|
{!!conversation && (
|
|
@@ -106,7 +122,7 @@ const ChatDetailHeader = memo(
|
|
|
106
122
|
</KContainer.Touchable>
|
|
107
123
|
</KContainer.View>
|
|
108
124
|
),
|
|
109
|
-
[onBack, onPressAvatar, conversation]
|
|
125
|
+
[onBack, onPressAvatar, conversation, faceURL, showName]
|
|
110
126
|
);
|
|
111
127
|
|
|
112
128
|
return (
|
|
@@ -8,13 +8,18 @@ interface InboxProps {
|
|
|
8
8
|
onPressThread?: (item: string) => void;
|
|
9
9
|
onPressSearch?: () => void;
|
|
10
10
|
onPressEdit?: () => void;
|
|
11
|
-
|
|
11
|
+
onPressContact?: () => void;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
type TabRoute = { key: string; title: string };
|
|
15
15
|
|
|
16
16
|
const Inbox = memo(
|
|
17
|
-
({
|
|
17
|
+
({
|
|
18
|
+
onPressThread,
|
|
19
|
+
onPressSearch,
|
|
20
|
+
onPressEdit,
|
|
21
|
+
onPressContact,
|
|
22
|
+
}: InboxProps) => {
|
|
18
23
|
const [index, setIndex] = useState(0);
|
|
19
24
|
const [routes] = useState<TabRoute[]>([
|
|
20
25
|
{ key: 'messages', title: 'Tin nhắn' },
|
|
@@ -91,7 +96,7 @@ const Inbox = memo(
|
|
|
91
96
|
/>
|
|
92
97
|
</KContainer.Touchable>
|
|
93
98
|
<KContainer.Touchable
|
|
94
|
-
onPress={
|
|
99
|
+
onPress={onPressContact}
|
|
95
100
|
padding="0.5rem"
|
|
96
101
|
activeOpacity={0.7}
|
|
97
102
|
>
|
|
@@ -105,7 +110,7 @@ const Inbox = memo(
|
|
|
105
110
|
</KContainer.View>
|
|
106
111
|
</KContainer.View>
|
|
107
112
|
),
|
|
108
|
-
[onPressSearch, onPressEdit,
|
|
113
|
+
[onPressSearch, onPressEdit, onPressContact]
|
|
109
114
|
);
|
|
110
115
|
|
|
111
116
|
return (
|
|
@@ -16,18 +16,21 @@ export const ENDPOINTS = {
|
|
|
16
16
|
get urlMetadata() {
|
|
17
17
|
return getApiEndpoint('urlMetadata');
|
|
18
18
|
},
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
get uploadFcmToken() {
|
|
20
|
+
return getApiEndpoint('uploadFcmToken');
|
|
21
|
+
},
|
|
22
|
+
conversationFlow: (id: string) => `${getApiEndpoint('conversation')}/${id}`,
|
|
21
23
|
resetConversationFlow: (id: string) =>
|
|
22
|
-
`${getApiEndpoint('
|
|
24
|
+
`${getApiEndpoint('conversation')}/${id}/bot-flows/reset`,
|
|
23
25
|
runConversationFlow: (id: string) =>
|
|
24
|
-
`${getApiEndpoint('
|
|
26
|
+
`${getApiEndpoint('conversation')}/${id}/bot-flows/run`,
|
|
25
27
|
getConversationByBotId: (botId: string) =>
|
|
26
28
|
`${getApiEndpoint('bot')}/${botId}/conversation`,
|
|
27
29
|
conversationFlowMainMenu: (id: string) =>
|
|
28
|
-
`${getApiEndpoint('
|
|
30
|
+
`${getApiEndpoint('conversation')}/${id}/bot-flows/main-menu`,
|
|
29
31
|
getConversationStatusByBotId: (botId: string) =>
|
|
30
32
|
`${getApiEndpoint('bot')}/${botId}`,
|
|
33
|
+
createConversation: () => getApiEndpoint('conversation'),
|
|
31
34
|
},
|
|
32
35
|
uploaderService: {
|
|
33
36
|
get uploadImage() {
|
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
import { create } from 'zustand';
|
|
2
2
|
import { sortConversation } from '../utils/conversation';
|
|
3
3
|
import type { ConversationItem } from '@droppii/openim-rn-client-sdk';
|
|
4
|
+
import type {
|
|
5
|
+
CreateConversationParams,
|
|
6
|
+
CreateConversationResponse,
|
|
7
|
+
} from '../types/chat';
|
|
8
|
+
import { apiInstance } from '../services/apis';
|
|
9
|
+
import { ENDPOINTS } from '../services/endpoints';
|
|
10
|
+
import type { BaseResponse } from '../types/auth';
|
|
4
11
|
|
|
5
12
|
type ConversationID = string;
|
|
6
13
|
|
|
7
14
|
export interface ConversationStore {
|
|
8
15
|
currentConversationId?: ConversationID;
|
|
9
|
-
|
|
16
|
+
currentUserId?: string;
|
|
17
|
+
currentGroupId?: string;
|
|
18
|
+
isCreatingConversation?: boolean;
|
|
19
|
+
createConversation: (params: CreateConversationParams) => Promise<void>;
|
|
20
|
+
setCurrentConversation(
|
|
21
|
+
id?: ConversationID,
|
|
22
|
+
userId?: string,
|
|
23
|
+
groupId?: string
|
|
24
|
+
): void;
|
|
10
25
|
getCurrentConversation(): ConversationItem | undefined;
|
|
11
26
|
list: ConversationID[];
|
|
12
27
|
map: Record<ConversationID, ConversationItem>;
|
|
@@ -26,8 +41,12 @@ export const useConversationStore = create<ConversationStore>()((set, get) => ({
|
|
|
26
41
|
list: [],
|
|
27
42
|
map: {},
|
|
28
43
|
newConversationSignal: 0,
|
|
29
|
-
setCurrentConversation(id) {
|
|
30
|
-
set({
|
|
44
|
+
setCurrentConversation(id, userId, groupId) {
|
|
45
|
+
set({
|
|
46
|
+
currentConversationId: id,
|
|
47
|
+
currentUserId: userId,
|
|
48
|
+
currentGroupId: groupId,
|
|
49
|
+
});
|
|
31
50
|
},
|
|
32
51
|
getCurrentConversation() {
|
|
33
52
|
const id = get().currentConversationId;
|
|
@@ -68,12 +87,27 @@ export const useConversationStore = create<ConversationStore>()((set, get) => ({
|
|
|
68
87
|
list: get().list.filter((item) => item !== id),
|
|
69
88
|
});
|
|
70
89
|
},
|
|
90
|
+
createConversation: async (params) => {
|
|
91
|
+
set({ isCreatingConversation: true });
|
|
92
|
+
const res = await apiInstance?.post<
|
|
93
|
+
BaseResponse<CreateConversationResponse>
|
|
94
|
+
>(ENDPOINTS.chatService.createConversation(), params);
|
|
95
|
+
if (res?.data?.data?.conversationId) {
|
|
96
|
+
set({
|
|
97
|
+
currentConversationId: res?.data?.data?.conversationId,
|
|
98
|
+
isCreatingConversation: false,
|
|
99
|
+
});
|
|
100
|
+
} else {
|
|
101
|
+
set({ isCreatingConversation: false });
|
|
102
|
+
}
|
|
103
|
+
},
|
|
71
104
|
reset() {
|
|
72
105
|
set({
|
|
73
106
|
currentConversationId: undefined,
|
|
74
107
|
list: [],
|
|
75
108
|
map: {},
|
|
76
109
|
newConversationSignal: 0,
|
|
110
|
+
isCreatingConversation: false,
|
|
77
111
|
});
|
|
78
112
|
},
|
|
79
113
|
}));
|
package/src/store/user.ts
CHANGED
|
@@ -5,6 +5,8 @@ import { ConnectStatus, SyncStatus } from '../types/chat';
|
|
|
5
5
|
export interface UserStore {
|
|
6
6
|
user?: SelfUserInfo;
|
|
7
7
|
setUser: (user: SelfUserInfo) => void;
|
|
8
|
+
token?: string;
|
|
9
|
+
setToken: (token: string) => void;
|
|
8
10
|
connectStatus: ConnectStatus;
|
|
9
11
|
updateConnectStatus: (status: ConnectStatus) => void;
|
|
10
12
|
syncStatus: SyncStatus;
|
|
@@ -17,6 +19,9 @@ export const useUserStore = create<UserStore>()((set) => ({
|
|
|
17
19
|
setUser(user) {
|
|
18
20
|
set({ user });
|
|
19
21
|
},
|
|
22
|
+
setToken(token) {
|
|
23
|
+
set({ token });
|
|
24
|
+
},
|
|
20
25
|
updateConnectStatus(connectStatus) {
|
|
21
26
|
set({ connectStatus });
|
|
22
27
|
},
|
package/src/types/chat.ts
CHANGED
|
@@ -53,6 +53,17 @@ export enum DChatApplicationType {
|
|
|
53
53
|
OBEFE = 'OBEFE',
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
export enum DChatPlatform {
|
|
57
|
+
IOS = 1,
|
|
58
|
+
ANDROID = 2,
|
|
59
|
+
WEB = 5,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export enum DChatProject {
|
|
63
|
+
BIZ = 'BIZ',
|
|
64
|
+
CUS = 'CUS',
|
|
65
|
+
}
|
|
66
|
+
|
|
56
67
|
export enum DChatCategory {
|
|
57
68
|
BIZ_BIZ = 'BIZ_BIZ',
|
|
58
69
|
BIZ_MALL = 'BIZ_MALL',
|
|
@@ -218,3 +229,24 @@ export type CustomElemOrderData = {
|
|
|
218
229
|
export type CustomMessagePayload =
|
|
219
230
|
| { type: typeof CustomMessageType.Order; data: CustomElemOrderData }
|
|
220
231
|
| { type: typeof CustomMessageType.Product; data: Record<string, unknown> };
|
|
232
|
+
|
|
233
|
+
export interface CreateConversationParams {
|
|
234
|
+
peerUserId: string;
|
|
235
|
+
chatCategory: DChatCategory;
|
|
236
|
+
applicationType: DChatApplicationType;
|
|
237
|
+
chatType: 'SINGLE' | 'GROUP';
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export interface CreateConversationResponse {
|
|
241
|
+
conversationId: string;
|
|
242
|
+
groupId?: string;
|
|
243
|
+
groupName?: string;
|
|
244
|
+
groupAvatar?: string;
|
|
245
|
+
chatCategory: DChatCategory;
|
|
246
|
+
applicationType: DChatApplicationType;
|
|
247
|
+
chatType: 'SINGLE' | 'GROUP';
|
|
248
|
+
members?: {
|
|
249
|
+
userId: string;
|
|
250
|
+
memberRole?: string;
|
|
251
|
+
}[];
|
|
252
|
+
}
|
package/src/utils/message.ts
CHANGED
|
@@ -100,7 +100,8 @@ export const hasNewHistoryMessages = (
|
|
|
100
100
|
|
|
101
101
|
export const belongsToConversation = (
|
|
102
102
|
message: MessageItem,
|
|
103
|
-
conversationId
|
|
103
|
+
conversationId?: string,
|
|
104
|
+
targetUserId?: string
|
|
104
105
|
): boolean => {
|
|
105
106
|
switch (message.sessionType) {
|
|
106
107
|
case SessionType.Single: {
|
|
@@ -114,7 +115,11 @@ export const belongsToConversation = (
|
|
|
114
115
|
message.recvID,
|
|
115
116
|
message.sendID
|
|
116
117
|
);
|
|
117
|
-
return conversationId
|
|
118
|
+
return conversationId
|
|
119
|
+
? conversationId === forwardId || conversationId === reverseId
|
|
120
|
+
: targetUserId
|
|
121
|
+
? message.sendID === targetUserId || message.recvID === targetUserId
|
|
122
|
+
: false;
|
|
118
123
|
}
|
|
119
124
|
|
|
120
125
|
case SessionType.Group: {
|