@droppii-org/chat-mobile 0.2.35 → 0.2.38
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/components/messages/linkMessage/index.js +1 -10
- package/lib/module/components/messages/linkMessage/index.js.map +1 -1
- package/lib/module/components/messages/quotedMessage/index.js +173 -0
- package/lib/module/components/messages/quotedMessage/index.js.map +1 -0
- package/lib/module/context/ChatContext.js +26 -22
- package/lib/module/context/ChatContext.js.map +1 -1
- package/lib/module/context/ChatDetailContext.js +7 -4
- package/lib/module/context/ChatDetailContext.js.map +1 -1
- package/lib/module/core/useChatListener.js +0 -1
- package/lib/module/core/useChatListener.js.map +1 -1
- package/lib/module/core/useUserListener.js +12 -21
- package/lib/module/core/useUserListener.js.map +1 -1
- package/lib/module/hooks/message/useSendMessage.js +26 -4
- package/lib/module/hooks/message/useSendMessage.js.map +1 -1
- package/lib/module/hooks/useChatMessages.js.map +1 -1
- package/lib/module/hooks/useFileAttachment.js +3 -1
- package/lib/module/hooks/useFileAttachment.js.map +1 -1
- package/lib/module/index.js +0 -7
- package/lib/module/index.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatComposer.js +2 -1
- package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatCurrentQuotedMessage.js +142 -0
- package/lib/module/screens/chat-detail/ChatCurrentQuotedMessage.js.map +1 -0
- package/lib/module/screens/chat-detail/ChatDetail.js +10 -1
- package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
- package/lib/module/screens/chat-detail/PinnedMessageBar.js +8 -3
- package/lib/module/screens/chat-detail/PinnedMessageBar.js.map +1 -1
- package/lib/module/screens/chat-detail/PinnedMessagesSheet.js +173 -0
- package/lib/module/screens/chat-detail/PinnedMessagesSheet.js.map +1 -0
- package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +2 -1
- package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxMenu.js +17 -1
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxMenu.js.map +1 -1
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxOverlay.js +11 -1
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxOverlay.js.map +1 -1
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js +1 -0
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js.map +1 -1
- package/lib/module/screens/chat-detail/messageToolbox/messageToolbox.utils.js +5 -2
- package/lib/module/screens/chat-detail/messageToolbox/messageToolbox.utils.js.map +1 -1
- package/lib/module/screens/inbox/Inbox.js +1 -5
- package/lib/module/screens/inbox/Inbox.js.map +1 -1
- package/lib/module/services/apis.js +0 -3
- package/lib/module/services/apis.js.map +1 -1
- package/lib/module/services/message.js.map +1 -1
- package/lib/module/store/message.js.map +1 -1
- package/lib/module/store/pinnedMessage.js.map +1 -1
- package/lib/module/store/user.js +2 -3
- package/lib/module/store/user.js.map +1 -1
- package/lib/module/translation/resources/i18n.js +9 -2
- package/lib/module/translation/resources/i18n.js.map +1 -1
- package/lib/module/types/auth.js +0 -7
- package/lib/module/types/auth.js.map +1 -1
- package/lib/module/types/chat.js +12 -0
- package/lib/module/types/chat.js.map +1 -1
- package/lib/module/utils/UIUtils.js +6 -0
- package/lib/module/utils/UIUtils.js.map +1 -1
- package/lib/module/utils/legendListMessage.js +1 -0
- package/lib/module/utils/legendListMessage.js.map +1 -1
- package/lib/module/utils/message.js.map +1 -1
- package/lib/module/utils/messageUtils.js +18 -1
- package/lib/module/utils/messageUtils.js.map +1 -1
- package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/quotedMessage/index.d.ts +7 -0
- package/lib/typescript/src/components/messages/quotedMessage/index.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/types.d.ts +2 -2
- package/lib/typescript/src/components/messages/types.d.ts.map +1 -1
- package/lib/typescript/src/context/ChatContext.d.ts.map +1 -1
- package/lib/typescript/src/context/ChatDetailContext.d.ts.map +1 -1
- package/lib/typescript/src/core/useChatListener.d.ts.map +1 -1
- package/lib/typescript/src/core/useUserListener.d.ts.map +1 -1
- package/lib/typescript/src/hooks/message/usePinMessage.d.ts +1 -1
- package/lib/typescript/src/hooks/message/useSendMessage.d.ts +2 -1
- package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useChatMessages.d.ts +2 -2
- package/lib/typescript/src/hooks/useChatMessages.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useFileAttachment.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatCurrentQuotedMessage.d.ts +2 -0
- package/lib/typescript/src/screens/chat-detail/ChatCurrentQuotedMessage.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/PinnedMessageBar.d.ts +4 -3
- package/lib/typescript/src/screens/chat-detail/PinnedMessageBar.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/PinnedMessagesSheet.d.ts +9 -0
- package/lib/typescript/src/screens/chat-detail/PinnedMessagesSheet.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +2 -3
- package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.d.ts +11 -7
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.d.ts +4 -4
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/messageToolbox/messageToolbox.utils.d.ts +5 -3
- package/lib/typescript/src/screens/chat-detail/messageToolbox/messageToolbox.utils.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/messageToolbox/types.d.ts +2 -2
- package/lib/typescript/src/screens/chat-detail/messageToolbox/types.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/types.d.ts +5 -5
- package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
- package/lib/typescript/src/screens/inbox/Inbox.d.ts.map +1 -1
- package/lib/typescript/src/services/apis.d.ts +0 -1
- package/lib/typescript/src/services/apis.d.ts.map +1 -1
- package/lib/typescript/src/services/message.d.ts +1 -2
- package/lib/typescript/src/services/message.d.ts.map +1 -1
- package/lib/typescript/src/store/message.d.ts.map +1 -1
- package/lib/typescript/src/store/pinnedMessage.d.ts +4 -4
- package/lib/typescript/src/store/pinnedMessage.d.ts.map +1 -1
- package/lib/typescript/src/store/user.d.ts +4 -4
- package/lib/typescript/src/store/user.d.ts.map +1 -1
- package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
- package/lib/typescript/src/types/auth.d.ts +0 -5
- package/lib/typescript/src/types/auth.d.ts.map +1 -1
- package/lib/typescript/src/types/chat.d.ts +19 -36
- package/lib/typescript/src/types/chat.d.ts.map +1 -1
- package/lib/typescript/src/utils/UIUtils.d.ts.map +1 -1
- package/lib/typescript/src/utils/legendListMessage.d.ts +4 -4
- package/lib/typescript/src/utils/legendListMessage.d.ts.map +1 -1
- package/lib/typescript/src/utils/message.d.ts +4 -5
- package/lib/typescript/src/utils/message.d.ts.map +1 -1
- package/lib/typescript/src/utils/messageUtils.d.ts +9 -7
- package/lib/typescript/src/utils/messageUtils.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/components/messages/linkMessage/index.tsx +1 -11
- package/src/components/messages/quotedMessage/index.tsx +197 -0
- package/src/components/messages/types.ts +2 -2
- package/src/context/ChatContext.tsx +30 -25
- package/src/context/ChatDetailContext.tsx +9 -3
- package/src/core/useChatListener.ts +0 -1
- package/src/core/useUserListener.ts +9 -25
- package/src/hooks/message/useSendMessage.ts +25 -4
- package/src/hooks/useChatMessages.ts +4 -6
- package/src/hooks/useFileAttachment.ts +3 -1
- package/src/index.tsx +5 -6
- package/src/screens/chat-detail/ChatComposer.tsx +2 -0
- package/src/screens/chat-detail/ChatCurrentQuotedMessage.tsx +150 -0
- package/src/screens/chat-detail/ChatDetail.tsx +13 -2
- package/src/screens/chat-detail/ChatListLegend.tsx +3 -3
- package/src/screens/chat-detail/PinnedMessageBar.tsx +53 -49
- package/src/screens/chat-detail/PinnedMessagesSheet.tsx +243 -0
- package/src/screens/chat-detail/legend/LegendChatMessage.tsx +4 -4
- package/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.tsx +30 -6
- package/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.tsx +15 -6
- package/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.tsx +1 -0
- package/src/screens/chat-detail/messageToolbox/messageToolbox.utils.ts +21 -12
- package/src/screens/chat-detail/messageToolbox/types.ts +2 -2
- package/src/screens/chat-detail/types.ts +5 -5
- package/src/screens/inbox/Inbox.tsx +1 -5
- package/src/services/apis.ts +0 -4
- package/src/services/message.ts +1 -2
- package/src/store/message.ts +3 -3
- package/src/store/pinnedMessage.ts +4 -4
- package/src/store/user.ts +5 -5
- package/src/translation/resources/i18n.ts +10 -1
- package/src/types/auth.ts +0 -6
- package/src/types/chat.ts +19 -40
- package/src/utils/UIUtils.ts +5 -0
- package/src/utils/legendListMessage.ts +4 -5
- package/src/utils/message.ts +10 -11
- package/src/utils/messageUtils.ts +37 -9
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { memo, useCallback, useMemo } from 'react';
|
|
2
|
+
import { messageStyles } from '../styles';
|
|
3
|
+
import { formatMessageTime, type BaseLegendMessageProps } from '../types';
|
|
4
|
+
import {
|
|
5
|
+
KColors,
|
|
6
|
+
KContainer,
|
|
7
|
+
KImage,
|
|
8
|
+
KLabel,
|
|
9
|
+
KRadiusValue,
|
|
10
|
+
KSpacingValue,
|
|
11
|
+
} from '@droppii/libs';
|
|
12
|
+
import { StyleSheet } from 'react-native';
|
|
13
|
+
import { CHAT_BUBBLE_COLORS } from '../../../screens/chat-detail/constants';
|
|
14
|
+
import { MessageType } from '@droppii/openim-rn-client-sdk';
|
|
15
|
+
import {
|
|
16
|
+
getMessagePreview,
|
|
17
|
+
getReplySenderName,
|
|
18
|
+
parseUrlMetadata,
|
|
19
|
+
} from '../../../utils/messageUtils';
|
|
20
|
+
import { getFileIcon, getMimeType } from '../../../utils/imageUtils';
|
|
21
|
+
import { useUserStore } from '../../../store';
|
|
22
|
+
import { useChatDetailContext } from '../../../context';
|
|
23
|
+
|
|
24
|
+
interface QuotedMessageProps extends BaseLegendMessageProps {
|
|
25
|
+
onPressQuotedMessage?: (clientMsgId: string) => void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const QuotedMessage = memo((props: QuotedMessageProps) => {
|
|
29
|
+
const { message, isOutgoing, onPressQuotedMessage, createdAtTime } =
|
|
30
|
+
props || {};
|
|
31
|
+
|
|
32
|
+
const { conversation } = useChatDetailContext();
|
|
33
|
+
|
|
34
|
+
const currentUserId = useUserStore((s) => s.user?.userID);
|
|
35
|
+
|
|
36
|
+
const quotedMessage = message?.quoteElem?.quoteMessage;
|
|
37
|
+
|
|
38
|
+
const timeLabel = formatMessageTime(createdAtTime);
|
|
39
|
+
|
|
40
|
+
const imageUrl = useMemo(() => {
|
|
41
|
+
switch (quotedMessage?.contentType) {
|
|
42
|
+
case MessageType.PictureMessage:
|
|
43
|
+
return quotedMessage?.pictureElem?.snapshotPicture?.url || '';
|
|
44
|
+
case MessageType.VideoMessage:
|
|
45
|
+
return quotedMessage?.videoElem?.snapshotUrl || '';
|
|
46
|
+
case MessageType.UrlTextMessage:
|
|
47
|
+
const metadata = parseUrlMetadata(quotedMessage?.ex);
|
|
48
|
+
return metadata?.image || '';
|
|
49
|
+
default:
|
|
50
|
+
return '';
|
|
51
|
+
}
|
|
52
|
+
}, [quotedMessage]);
|
|
53
|
+
|
|
54
|
+
const iconSource = useMemo(() => {
|
|
55
|
+
if (quotedMessage?.contentType !== MessageType.FileMessage) return '';
|
|
56
|
+
const mimeType = getMimeType(quotedMessage?.fileElem?.fileName || '');
|
|
57
|
+
return getFileIcon(mimeType);
|
|
58
|
+
}, [quotedMessage]);
|
|
59
|
+
|
|
60
|
+
const handlePressQuotedMessage = useCallback(() => {
|
|
61
|
+
onPressQuotedMessage?.(quotedMessage?.clientMsgID || '');
|
|
62
|
+
}, [quotedMessage, onPressQuotedMessage]);
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<>
|
|
66
|
+
<KContainer.View
|
|
67
|
+
style={[
|
|
68
|
+
messageStyles.bubble,
|
|
69
|
+
styles.container,
|
|
70
|
+
isOutgoing ? messageStyles.bubbleSent : messageStyles.bubbleReceived,
|
|
71
|
+
]}
|
|
72
|
+
>
|
|
73
|
+
<KContainer.Touchable
|
|
74
|
+
style={styles.quotedContainer}
|
|
75
|
+
onPress={handlePressQuotedMessage}
|
|
76
|
+
>
|
|
77
|
+
<KContainer.View style={styles.dot} />
|
|
78
|
+
<KContainer.VisibleView visible={!!imageUrl}>
|
|
79
|
+
<KContainer.View style={styles.imageContainer}>
|
|
80
|
+
<KImage.Base uri={imageUrl} style={styles.imageContainer} />
|
|
81
|
+
<KContainer.VisibleView
|
|
82
|
+
visible={
|
|
83
|
+
quotedMessage?.contentType === MessageType.VideoMessage
|
|
84
|
+
}
|
|
85
|
+
>
|
|
86
|
+
<KContainer.View style={styles.playIconContainer}>
|
|
87
|
+
<KContainer.View style={styles.playIcon}>
|
|
88
|
+
<KImage.VectorIcons
|
|
89
|
+
name="play-b"
|
|
90
|
+
size={12}
|
|
91
|
+
color={KColors.white}
|
|
92
|
+
/>
|
|
93
|
+
</KContainer.View>
|
|
94
|
+
</KContainer.View>
|
|
95
|
+
</KContainer.VisibleView>
|
|
96
|
+
</KContainer.View>
|
|
97
|
+
</KContainer.VisibleView>
|
|
98
|
+
<KContainer.VisibleView visible={!!iconSource}>
|
|
99
|
+
<KImage.Base
|
|
100
|
+
uri={iconSource}
|
|
101
|
+
style={styles.icon}
|
|
102
|
+
resizeMode="contain"
|
|
103
|
+
/>
|
|
104
|
+
</KContainer.VisibleView>
|
|
105
|
+
<KContainer.View style={styles.content}>
|
|
106
|
+
<KLabel.Text typo="TextNmMedium" numberOfLines={1}>
|
|
107
|
+
{getReplySenderName(
|
|
108
|
+
quotedMessage,
|
|
109
|
+
currentUserId,
|
|
110
|
+
conversation,
|
|
111
|
+
true
|
|
112
|
+
)}
|
|
113
|
+
</KLabel.Text>
|
|
114
|
+
<KLabel.Text
|
|
115
|
+
typo="TextSmNormal"
|
|
116
|
+
color={KColors.gray.light}
|
|
117
|
+
numberOfLines={1}
|
|
118
|
+
>
|
|
119
|
+
{getMessagePreview(quotedMessage)}
|
|
120
|
+
</KLabel.Text>
|
|
121
|
+
</KContainer.View>
|
|
122
|
+
</KContainer.Touchable>
|
|
123
|
+
<KLabel.Text typo="TextMdNormal" color={CHAT_BUBBLE_COLORS.text}>
|
|
124
|
+
{message?.quoteElem?.text || ''}
|
|
125
|
+
</KLabel.Text>
|
|
126
|
+
</KContainer.View>
|
|
127
|
+
|
|
128
|
+
<KContainer.View row alignItems style={styles.timeLabel}>
|
|
129
|
+
{!isOutgoing && timeLabel ? (
|
|
130
|
+
<KLabel.Text
|
|
131
|
+
typo="TextXsNormal"
|
|
132
|
+
color={CHAT_BUBBLE_COLORS.timestamp}
|
|
133
|
+
marginL="0.25rem"
|
|
134
|
+
>
|
|
135
|
+
{timeLabel}
|
|
136
|
+
</KLabel.Text>
|
|
137
|
+
) : null}
|
|
138
|
+
</KContainer.View>
|
|
139
|
+
</>
|
|
140
|
+
);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
QuotedMessage.displayName = 'QuotedMessage';
|
|
144
|
+
|
|
145
|
+
export default QuotedMessage;
|
|
146
|
+
|
|
147
|
+
const styles = StyleSheet.create({
|
|
148
|
+
container: {
|
|
149
|
+
gap: KSpacingValue['0.25rem'],
|
|
150
|
+
},
|
|
151
|
+
quotedContainer: {
|
|
152
|
+
backgroundColor: KColors.white,
|
|
153
|
+
flexDirection: 'row',
|
|
154
|
+
alignItems: 'center',
|
|
155
|
+
gap: KSpacingValue['0.5rem'],
|
|
156
|
+
borderTopRightRadius: KRadiusValue['3x'],
|
|
157
|
+
borderBottomRightRadius: KRadiusValue['3x'],
|
|
158
|
+
paddingRight: KSpacingValue['0.5rem'],
|
|
159
|
+
},
|
|
160
|
+
dot: {
|
|
161
|
+
width: 3,
|
|
162
|
+
height: '100%',
|
|
163
|
+
backgroundColor: KColors.palette.grayCool.w200,
|
|
164
|
+
borderRadius: KRadiusValue.x,
|
|
165
|
+
marginRight: -2,
|
|
166
|
+
},
|
|
167
|
+
content: {
|
|
168
|
+
paddingHorizontal: KSpacingValue['0.25rem'],
|
|
169
|
+
paddingVertical: KSpacingValue['0.25rem'],
|
|
170
|
+
},
|
|
171
|
+
icon: {
|
|
172
|
+
width: 24,
|
|
173
|
+
height: 24,
|
|
174
|
+
},
|
|
175
|
+
imageContainer: {
|
|
176
|
+
width: 42,
|
|
177
|
+
height: 42,
|
|
178
|
+
borderRadius: KRadiusValue['2x'],
|
|
179
|
+
},
|
|
180
|
+
playIconContainer: {
|
|
181
|
+
position: 'absolute',
|
|
182
|
+
top: 0,
|
|
183
|
+
left: 0,
|
|
184
|
+
right: 0,
|
|
185
|
+
bottom: 0,
|
|
186
|
+
justifyContent: 'center',
|
|
187
|
+
alignItems: 'center',
|
|
188
|
+
},
|
|
189
|
+
playIcon: {
|
|
190
|
+
borderRadius: 8,
|
|
191
|
+
padding: KSpacingValue['0.25rem'],
|
|
192
|
+
backgroundColor: KColors.hexToRgba(KColors.black, 0.6),
|
|
193
|
+
justifyContent: 'center',
|
|
194
|
+
alignItems: 'center',
|
|
195
|
+
},
|
|
196
|
+
timeLabel: { gap: 4, marginTop: 2 },
|
|
197
|
+
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { DMessageItem } from '../../types/chat';
|
|
2
1
|
import type { MediaItem } from '../../hooks/useMediaViewer';
|
|
2
|
+
import type { MessageItem } from '@droppii/openim-rn-client-sdk';
|
|
3
3
|
|
|
4
4
|
export interface BaseLegendMessageProps {
|
|
5
|
-
message:
|
|
5
|
+
message: MessageItem;
|
|
6
6
|
isOutgoing: boolean;
|
|
7
7
|
createdAtTime: number;
|
|
8
8
|
onMediaPress?: (items: MediaItem[], index?: number) => void;
|
|
@@ -12,9 +12,10 @@ import OpenIMSDK, {
|
|
|
12
12
|
type ConversationItem,
|
|
13
13
|
} from '@droppii/openim-rn-client-sdk';
|
|
14
14
|
import Toast from 'react-native-toast-message';
|
|
15
|
-
import { useUserStore } from '../store';
|
|
16
15
|
import { useChatSdk } from '../core';
|
|
17
16
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
17
|
+
import uuid from 'react-native-uuid';
|
|
18
|
+
import { useUserStore } from '../store';
|
|
18
19
|
|
|
19
20
|
export const ChatContext = createContext<ChatContextType | undefined>(
|
|
20
21
|
undefined
|
|
@@ -35,30 +36,35 @@ const ChatProviderInner = ({
|
|
|
35
36
|
getChatToken,
|
|
36
37
|
onFlashMessagePress,
|
|
37
38
|
}: ChatProviderProps) => {
|
|
38
|
-
const connectStatus = useUserStore((state) => state.connectStatus);
|
|
39
39
|
const [isShowFLashMessage, setShow] = useState(true);
|
|
40
40
|
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
OpenIMSDK.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
const handleLoginSdk = useCallback(async () => {
|
|
42
|
+
if (getChatToken) {
|
|
43
|
+
try {
|
|
44
|
+
const res = await getChatToken();
|
|
45
|
+
const loginStatus = await OpenIMSDK.getLoginStatus();
|
|
46
|
+
if (!!res?.id && !!res?.token && loginStatus === LoginStatus.Logout) {
|
|
47
|
+
await OpenIMSDK.login(
|
|
48
|
+
{
|
|
49
|
+
token: res.token,
|
|
50
|
+
userID: res.id,
|
|
51
|
+
},
|
|
52
|
+
uuid.v4()
|
|
53
|
+
);
|
|
54
|
+
const userInfo = await OpenIMSDK.getSelfUserInfo();
|
|
55
|
+
if (userInfo) {
|
|
56
|
+
useUserStore.getState().setUser(userInfo);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error('Failed to login chat sdk', error);
|
|
55
61
|
}
|
|
56
62
|
}
|
|
57
|
-
}, [getChatToken
|
|
63
|
+
}, [getChatToken]);
|
|
58
64
|
|
|
59
65
|
useEffect(() => {
|
|
60
|
-
|
|
61
|
-
}, [
|
|
66
|
+
handleLoginSdk();
|
|
67
|
+
}, [handleLoginSdk]);
|
|
62
68
|
|
|
63
69
|
const onPressFlashMessage = useCallback(
|
|
64
70
|
(c: ConversationItem) => {
|
|
@@ -68,26 +74,25 @@ const ChatProviderInner = ({
|
|
|
68
74
|
);
|
|
69
75
|
|
|
70
76
|
const setIsShowFLashMessage = useCallback((v: boolean) => {
|
|
71
|
-
console.log('setIsShowFLashMessage');
|
|
72
77
|
setShow(v);
|
|
73
78
|
}, []);
|
|
74
79
|
|
|
75
|
-
const value = useMemo(
|
|
80
|
+
const value: ChatContextType = useMemo(
|
|
76
81
|
() => ({
|
|
77
82
|
logGA,
|
|
78
83
|
applicationType,
|
|
79
|
-
getChatToken,
|
|
80
84
|
onPressFlashMessage,
|
|
81
|
-
isShowFLashMessage
|
|
82
|
-
setIsShowFLashMessage
|
|
85
|
+
isShowFLashMessage,
|
|
86
|
+
setIsShowFLashMessage,
|
|
87
|
+
handleLoginSdk,
|
|
83
88
|
}),
|
|
84
89
|
[
|
|
85
90
|
logGA,
|
|
86
91
|
applicationType,
|
|
87
|
-
getChatToken,
|
|
88
92
|
onPressFlashMessage,
|
|
89
93
|
isShowFLashMessage,
|
|
90
94
|
setIsShowFLashMessage,
|
|
95
|
+
handleLoginSdk,
|
|
91
96
|
]
|
|
92
97
|
);
|
|
93
98
|
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from '../types/chat';
|
|
14
14
|
import { fechtCurrentConversationFlow } from '../hooks/flows/useCurrentConversationFlow';
|
|
15
15
|
import { useConversationStore } from '../store';
|
|
16
|
-
import { PeerType } from '@droppii/openim-rn-client-sdk';
|
|
16
|
+
import { PeerType, type MessageItem } from '@droppii/openim-rn-client-sdk';
|
|
17
17
|
import {
|
|
18
18
|
DFlowContext,
|
|
19
19
|
NodeTypes,
|
|
@@ -27,11 +27,12 @@ import { CONTEXT_BUTTON_PREFIX, isContextButton } from '../utils/flows';
|
|
|
27
27
|
export const ChatDetailContext = createContext<ChatDetailContextType>({
|
|
28
28
|
isBotConversation: false,
|
|
29
29
|
conversationFlow: undefined,
|
|
30
|
-
refetchConversationFlow: () => {},
|
|
31
30
|
setConverationFlowStep: () => {},
|
|
32
31
|
flowState: undefined,
|
|
33
32
|
runButtonContext: () => Promise.resolve(false),
|
|
34
33
|
conversation: undefined,
|
|
34
|
+
quotedMessage: undefined,
|
|
35
|
+
setQuotedMessage: () => {},
|
|
35
36
|
});
|
|
36
37
|
|
|
37
38
|
export const useChatDetailContext = (): ChatDetailContextType => {
|
|
@@ -55,6 +56,10 @@ export const ChatDetailProvider = ({ children }: ChatDetailProviderProps) => {
|
|
|
55
56
|
IConversationFlow | undefined
|
|
56
57
|
>(undefined);
|
|
57
58
|
|
|
59
|
+
const [quotedMessage, setQuotedMessage] = useState<MessageItem | undefined>(
|
|
60
|
+
undefined
|
|
61
|
+
);
|
|
62
|
+
|
|
58
63
|
const flowState = useMemo(() => {
|
|
59
64
|
return conversationFlow
|
|
60
65
|
? conversationFlow?.flowCurrentStep?.data?.children?.some(
|
|
@@ -124,12 +129,13 @@ export const ChatDetailProvider = ({ children }: ChatDetailProviderProps) => {
|
|
|
124
129
|
<ChatDetailContext.Provider
|
|
125
130
|
value={{
|
|
126
131
|
conversationFlow,
|
|
127
|
-
refetchConversationFlow: () => {},
|
|
128
132
|
setConverationFlowStep,
|
|
129
133
|
isBotConversation,
|
|
130
134
|
flowState,
|
|
131
135
|
runButtonContext,
|
|
132
136
|
conversation,
|
|
137
|
+
quotedMessage,
|
|
138
|
+
setQuotedMessage,
|
|
133
139
|
}}
|
|
134
140
|
>
|
|
135
141
|
{children}
|
|
@@ -37,7 +37,6 @@ export const useChatListener = () => {
|
|
|
37
37
|
|
|
38
38
|
const onConversationChanged = useCallback(
|
|
39
39
|
(conversations: ConversationItem[]) => {
|
|
40
|
-
// console.log('isShowFLashMessage', isShowFLashMessage);
|
|
41
40
|
useConversationStore.getState().updateConversations(conversations);
|
|
42
41
|
if (isShowFLashMessage) {
|
|
43
42
|
for (const conversation of conversations) {
|
|
@@ -1,45 +1,28 @@
|
|
|
1
1
|
import OpenIMSDK, {
|
|
2
|
-
LoginStatus,
|
|
3
2
|
OpenIMEvent,
|
|
4
3
|
type OpenIMEventBaseErrorType,
|
|
5
4
|
} from '@droppii/openim-rn-client-sdk';
|
|
6
5
|
import { useCallback, useEffect } from 'react';
|
|
7
6
|
import { useUserStore } from '../store';
|
|
8
|
-
import { SyncStatus } from '../types/
|
|
9
|
-
import {
|
|
7
|
+
import { ConnectStatus, SyncStatus } from '../types/chat';
|
|
8
|
+
import { useChatContext } from '../context';
|
|
10
9
|
|
|
11
10
|
export const useUserListener = () => {
|
|
12
|
-
const
|
|
13
|
-
(state) => state.connectStatus === LoginStatus.Logged
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
const fetchAndUpdateUser = useCallback(async () => {
|
|
17
|
-
try {
|
|
18
|
-
const user = await ChatAPI.getUser();
|
|
19
|
-
useUserStore.getState().setUser(user);
|
|
20
|
-
} catch (error) {
|
|
21
|
-
console.error('OpenIM get user failed', error);
|
|
22
|
-
}
|
|
23
|
-
}, []);
|
|
24
|
-
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
if (isLoggedIn) {
|
|
27
|
-
fetchAndUpdateUser();
|
|
28
|
-
}
|
|
29
|
-
}, [isLoggedIn, fetchAndUpdateUser]);
|
|
11
|
+
const { handleLoginSdk } = useChatContext();
|
|
30
12
|
|
|
31
13
|
const onConnecting = useCallback(() => {
|
|
32
14
|
console.log('[Listener] OnConnecting');
|
|
33
|
-
useUserStore.getState().updateConnectStatus(
|
|
15
|
+
useUserStore.getState().updateConnectStatus(ConnectStatus.Connecting);
|
|
34
16
|
}, []);
|
|
35
17
|
|
|
36
18
|
const onConnectSuccess = useCallback(() => {
|
|
37
19
|
console.log('[Listener] OnConnectSuccess');
|
|
38
|
-
useUserStore.getState().updateConnectStatus(
|
|
20
|
+
useUserStore.getState().updateConnectStatus(ConnectStatus.Connected);
|
|
39
21
|
}, []);
|
|
40
22
|
|
|
41
23
|
const onConnectFailed = useCallback((data: OpenIMEventBaseErrorType) => {
|
|
42
24
|
console.log('[Listener] OnConnectFailed', data);
|
|
25
|
+
useUserStore.getState().updateConnectStatus(ConnectStatus.Disconnected);
|
|
43
26
|
}, []);
|
|
44
27
|
|
|
45
28
|
const onSyncServerStart = useCallback((isSyncing: boolean) => {
|
|
@@ -59,7 +42,8 @@ export const useUserListener = () => {
|
|
|
59
42
|
|
|
60
43
|
const onUserToken = useCallback(() => {
|
|
61
44
|
console.log('[Listener] OnUserToken expired/invalid');
|
|
62
|
-
|
|
45
|
+
handleLoginSdk();
|
|
46
|
+
}, [handleLoginSdk]);
|
|
63
47
|
|
|
64
48
|
useEffect(() => {
|
|
65
49
|
// User
|
|
@@ -88,5 +72,5 @@ export const useUserListener = () => {
|
|
|
88
72
|
OpenIMSDK.off(OpenIMEvent.OnSyncServerFailed, onSyncServerFailed);
|
|
89
73
|
};
|
|
90
74
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
91
|
-
}, []);
|
|
75
|
+
}, [onUserToken]);
|
|
92
76
|
};
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
CustomMsgParams,
|
|
6
6
|
MessageItem,
|
|
7
7
|
OfflinePush,
|
|
8
|
+
QuoteMsgParams,
|
|
8
9
|
} from '@droppii/openim-rn-client-sdk';
|
|
9
10
|
import { MessageStatus, MessageType } from '@droppii/openim-rn-client-sdk';
|
|
10
11
|
import { extractUrls } from '../../utils/url';
|
|
@@ -14,7 +15,7 @@ import {
|
|
|
14
15
|
type CustomMessagePayload,
|
|
15
16
|
type IMessageItemEx,
|
|
16
17
|
} from '../../types/chat';
|
|
17
|
-
import { useChatContext } from '../../context';
|
|
18
|
+
import { useChatContext, useChatDetailContext } from '../../context';
|
|
18
19
|
import { generateContentBasedOnMessageType } from '../../utils/conversation';
|
|
19
20
|
import { markMessageRevoked, useMessageStore } from '../../store/message';
|
|
20
21
|
import uuid from 'react-native-uuid';
|
|
@@ -40,6 +41,8 @@ export const useSendMessage = () => {
|
|
|
40
41
|
const pushNewMessage = useMessageStore((state) => state.pushNewMessage);
|
|
41
42
|
const updateOneMessage = useMessageStore((state) => state.updateOneMessage);
|
|
42
43
|
const deleteOneMessage = useMessageStore((state) => state.deleteOneMessage);
|
|
44
|
+
const { quotedMessage, setQuotedMessage } = useChatDetailContext();
|
|
45
|
+
|
|
43
46
|
const dispatchSend = useCallback(
|
|
44
47
|
async (
|
|
45
48
|
message: MessageItem,
|
|
@@ -91,12 +94,18 @@ export const useSendMessage = () => {
|
|
|
91
94
|
const hasPreview = !!urlMetadata?.url;
|
|
92
95
|
|
|
93
96
|
//text msg
|
|
94
|
-
if (hasText
|
|
97
|
+
if (hasText) {
|
|
95
98
|
const urls = hasText ? extractUrls(plainText) : [];
|
|
96
99
|
const isUrlMessage = urls.length > 0 || hasPreview;
|
|
97
100
|
let message: MessageItem | null = null;
|
|
98
101
|
|
|
99
|
-
if (
|
|
102
|
+
if (quotedMessage) {
|
|
103
|
+
message = await createQuotedMessage({
|
|
104
|
+
text: plainText || '',
|
|
105
|
+
message: quotedMessage,
|
|
106
|
+
});
|
|
107
|
+
setQuotedMessage(undefined);
|
|
108
|
+
} else if (isUrlMessage) {
|
|
100
109
|
message = await createUrlTextMessage(plainText || '', urls);
|
|
101
110
|
} else if (hasText) {
|
|
102
111
|
message = await createTextMessage(plainText);
|
|
@@ -137,7 +146,7 @@ export const useSendMessage = () => {
|
|
|
137
146
|
);
|
|
138
147
|
}
|
|
139
148
|
},
|
|
140
|
-
[applicationType, dispatchSend]
|
|
149
|
+
[applicationType, dispatchSend, quotedMessage, setQuotedMessage]
|
|
141
150
|
);
|
|
142
151
|
|
|
143
152
|
const retryMessage = useCallback(
|
|
@@ -274,3 +283,15 @@ export const createCustomMessage = async (params: CustomMsgParams) => {
|
|
|
274
283
|
});
|
|
275
284
|
return customMessage;
|
|
276
285
|
};
|
|
286
|
+
|
|
287
|
+
export const createQuotedMessage = async (params: QuoteMsgParams) => {
|
|
288
|
+
let quotedMessage = await OpenIMSDK.createQuoteMessage(params, uuid.v4())
|
|
289
|
+
.then((data) => {
|
|
290
|
+
return data;
|
|
291
|
+
})
|
|
292
|
+
.catch(({ errCode, errMsg }) => {
|
|
293
|
+
console.error('createQuotedMessage', errCode, errMsg);
|
|
294
|
+
return null;
|
|
295
|
+
});
|
|
296
|
+
return quotedMessage;
|
|
297
|
+
};
|
|
@@ -4,7 +4,6 @@ import OpenIMSDK, {
|
|
|
4
4
|
} from '@droppii/openim-rn-client-sdk';
|
|
5
5
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
6
6
|
import { ChatMessageAPI } from '../services/message';
|
|
7
|
-
import type { DMessageItem } from '../types/chat';
|
|
8
7
|
import {
|
|
9
8
|
belongsToConversation,
|
|
10
9
|
hasNewHistoryMessages,
|
|
@@ -71,8 +70,7 @@ export function useChatMessages({
|
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
if (historyResult.status === 'fulfilled') {
|
|
74
|
-
const initialMessages = historyResult.value
|
|
75
|
-
.messageList as DMessageItem[];
|
|
73
|
+
const initialMessages = historyResult.value.messageList;
|
|
76
74
|
setMessages(
|
|
77
75
|
mergeMessages([], initialMessages),
|
|
78
76
|
!historyResult.value.isEnd
|
|
@@ -92,7 +90,7 @@ export function useChatMessages({
|
|
|
92
90
|
);
|
|
93
91
|
const localMessages = (localResult?.searchResultItems ?? []).flatMap(
|
|
94
92
|
(item: any) => item.messageList ?? []
|
|
95
|
-
)
|
|
93
|
+
);
|
|
96
94
|
console.log(
|
|
97
95
|
'[useChatMessages] searchLocalMessages fallback result:',
|
|
98
96
|
localMessages.length,
|
|
@@ -126,7 +124,7 @@ export function useChatMessages({
|
|
|
126
124
|
}
|
|
127
125
|
);
|
|
128
126
|
|
|
129
|
-
const incoming = history.messageList
|
|
127
|
+
const incoming = history.messageList;
|
|
130
128
|
const hasNew = hasNewHistoryMessages(messages, incoming);
|
|
131
129
|
|
|
132
130
|
if (hasNew) {
|
|
@@ -166,7 +164,7 @@ export function useChatMessages({
|
|
|
166
164
|
}
|
|
167
165
|
);
|
|
168
166
|
|
|
169
|
-
const incoming = history.messageList
|
|
167
|
+
const incoming = history.messageList;
|
|
170
168
|
const hasNew = incoming.length > 0;
|
|
171
169
|
|
|
172
170
|
if (hasNew) {
|
|
@@ -99,7 +99,9 @@ export const useFileAttachment = (): UseFileAttachmentReturn => {
|
|
|
99
99
|
let candidates = picked;
|
|
100
100
|
if (oversized.length > 0) {
|
|
101
101
|
UIUtils.toast.open({
|
|
102
|
-
title: trans('chat:file_too_large'
|
|
102
|
+
title: trans('chat:file_too_large', {
|
|
103
|
+
maxSize: String(MAX_FILE_SIZE / 1024 / 1024),
|
|
104
|
+
}),
|
|
103
105
|
theme: 'danger',
|
|
104
106
|
});
|
|
105
107
|
candidates = picked.filter((f) => f.size <= MAX_FILE_SIZE);
|
package/src/index.tsx
CHANGED
|
@@ -31,12 +31,11 @@ export { Inbox } from './screens/inbox';
|
|
|
31
31
|
export { default as MediaViewerScreen } from './screens/MediaView';
|
|
32
32
|
export * from './screens/chat-detail';
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
export type { ConversationItem } from '@droppii/openim-rn-client-sdk';
|
|
34
|
+
export type {
|
|
35
|
+
PeerType,
|
|
36
|
+
MessageItem,
|
|
37
|
+
ConversationItem,
|
|
38
|
+
} from '@droppii/openim-rn-client-sdk';
|
|
40
39
|
export { LoginStatus, MessageType } from '@droppii/openim-rn-client-sdk';
|
|
41
40
|
export * from './screens/chat-detail';
|
|
42
41
|
export type {
|
|
@@ -32,6 +32,7 @@ import { ReactFlowsNodeTypes } from '../../types/flows';
|
|
|
32
32
|
import { useAttachmentMapping } from './hooks/useAttachmentMapping';
|
|
33
33
|
import type { AttachmentType } from '../../types/attachment';
|
|
34
34
|
import { useChatCompose } from '../../hooks/useChatCompose';
|
|
35
|
+
import { ChatCurrentQuotedMessage } from './ChatCurrentQuotedMessage';
|
|
35
36
|
|
|
36
37
|
interface ChatComposerInternalProps {
|
|
37
38
|
isEmptyMessage?: boolean;
|
|
@@ -213,6 +214,7 @@ export const ChatComposer = memo(
|
|
|
213
214
|
|
|
214
215
|
return (
|
|
215
216
|
<KContainer.View background={'rgba(131, 137, 157, 0.05)'}>
|
|
217
|
+
<ChatCurrentQuotedMessage />
|
|
216
218
|
<ChatQuickActions
|
|
217
219
|
visible
|
|
218
220
|
actions={DEFAULT_QUICK_ACTIONS}
|