@droppii-org/chat-mobile 0.2.24 → 0.2.26
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/assets/images/btn_resend.png +0 -0
- package/lib/module/assets/images/index.js +2 -1
- package/lib/module/assets/images/index.js.map +1 -1
- package/lib/module/components/AttachmentPreview/FilePreview.js +1 -1
- package/lib/module/components/AttachmentPreview/FilePreview.js.map +1 -1
- package/lib/module/components/flows/inputButtons/index.js +3 -6
- package/lib/module/components/flows/inputButtons/index.js.map +1 -1
- package/lib/module/components/messages/MessageStatusIndicator.js +70 -0
- package/lib/module/components/messages/MessageStatusIndicator.js.map +1 -0
- package/lib/module/components/messages/fileMessage/index.js +1 -1
- package/lib/module/components/messages/fileMessage/index.js.map +1 -1
- package/lib/module/components/messages/imageMessage/index.js +60 -51
- package/lib/module/components/messages/imageMessage/index.js.map +1 -1
- package/lib/module/components/messages/linkMessage/index.js +17 -9
- package/lib/module/components/messages/linkMessage/index.js.map +1 -1
- package/lib/module/components/messages/mergedMessage/index.js +5 -8
- package/lib/module/components/messages/mergedMessage/index.js.map +1 -1
- package/lib/module/components/messages/styles.js +12 -0
- package/lib/module/components/messages/styles.js.map +1 -1
- package/lib/module/components/messages/textMessage/index.js +20 -9
- package/lib/module/components/messages/textMessage/index.js.map +1 -1
- package/lib/module/components/messages/videoMessage/index.js +7 -11
- package/lib/module/components/messages/videoMessage/index.js.map +1 -1
- package/lib/module/config/uploadLimits.js +1 -1
- package/lib/module/config/uploadLimits.js.map +1 -1
- package/lib/module/core/useChatListener.js +35 -4
- package/lib/module/core/useChatListener.js.map +1 -1
- package/lib/module/core/useUserListener.js +17 -7
- package/lib/module/core/useUserListener.js.map +1 -1
- package/lib/module/hooks/message/useSendMessage.js +62 -15
- package/lib/module/hooks/message/useSendMessage.js.map +1 -1
- package/lib/module/hooks/useChatCompose.js +39 -28
- package/lib/module/hooks/useChatCompose.js.map +1 -1
- package/lib/module/hooks/useChatMessages.js +39 -8
- package/lib/module/hooks/useChatMessages.js.map +1 -1
- package/lib/module/hooks/useFileAttachment.js +1 -1
- package/lib/module/hooks/useFileAttachment.js.map +1 -1
- package/lib/module/hooks/useFileDownload.js +1 -1
- package/lib/module/hooks/useFileDownload.js.map +1 -1
- package/lib/module/hooks/useImageAttachment.js +12 -3
- package/lib/module/hooks/useImageAttachment.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatDetail.js +24 -1
- package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatListLegend.js +40 -28
- package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
- package/lib/module/screens/chat-detail/constants.js +3 -2
- package/lib/module/screens/chat-detail/constants.js.map +1 -1
- package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +48 -15
- package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxMenu.js +98 -0
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxMenu.js.map +1 -0
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxOverlay.js +110 -0
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxOverlay.js.map +1 -0
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js +64 -0
- package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js.map +1 -0
- package/lib/module/screens/chat-detail/messageToolbox/messageToolbox.utils.js +37 -0
- package/lib/module/screens/chat-detail/messageToolbox/messageToolbox.utils.js.map +1 -0
- package/lib/module/screens/chat-detail/messageToolbox/types.js +4 -0
- package/lib/module/screens/chat-detail/messageToolbox/types.js.map +1 -0
- package/lib/module/services/attachmentOrchestrator.js +34 -12
- package/lib/module/services/attachmentOrchestrator.js.map +1 -1
- package/lib/module/services/message.js +13 -5
- package/lib/module/services/message.js.map +1 -1
- package/lib/module/translation/resources/i18n.js +9 -3
- package/lib/module/translation/resources/i18n.js.map +1 -1
- package/lib/module/types/chat.js.map +1 -1
- package/lib/module/types/global.d.js +2 -0
- package/lib/module/types/global.d.js.map +1 -0
- package/lib/module/types/index.d.js +3 -0
- package/lib/module/types/index.d.js.map +1 -0
- package/lib/module/utils/UIUtils.js +37 -0
- package/lib/module/utils/UIUtils.js.map +1 -0
- package/lib/module/utils/ui.js +15 -13
- package/lib/module/utils/ui.js.map +1 -1
- package/lib/module/utils/videoThumbnailUpload.js +1 -1
- package/lib/module/utils/videoThumbnailUpload.js.map +1 -1
- package/lib/typescript/src/assets/images/index.d.ts +1 -0
- package/lib/typescript/src/assets/images/index.d.ts.map +1 -1
- package/lib/typescript/src/components/flows/inputButtons/index.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/MessageStatusIndicator.d.ts +9 -0
- package/lib/typescript/src/components/messages/MessageStatusIndicator.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/fileMessage/index.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/imageMessage/index.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/linkMessage/index.d.ts +3 -8
- package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/mergedMessage/index.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/styles.d.ts +15 -3
- package/lib/typescript/src/components/messages/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/textMessage/index.d.ts +2 -8
- package/lib/typescript/src/components/messages/textMessage/index.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/videoMessage/index.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/useSendMessage.d.ts +2 -0
- package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useChatCompose.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useChatMessages.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useImageAttachment.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/constants.d.ts +2 -2
- package/lib/typescript/src/screens/chat-detail/constants.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +4 -5
- 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 -0
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.d.ts +10 -0
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.d.ts +11 -0
- package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/messageToolbox/messageToolbox.utils.d.ts +18 -0
- package/lib/typescript/src/screens/chat-detail/messageToolbox/messageToolbox.utils.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/messageToolbox/types.d.ts +12 -0
- package/lib/typescript/src/screens/chat-detail/messageToolbox/types.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/types.d.ts +2 -0
- package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
- package/lib/typescript/src/services/attachmentOrchestrator.d.ts.map +1 -1
- package/lib/typescript/src/services/message.d.ts +7 -0
- package/lib/typescript/src/services/message.d.ts.map +1 -1
- package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
- package/lib/typescript/src/types/chat.d.ts +11 -0
- package/lib/typescript/src/types/chat.d.ts.map +1 -1
- package/lib/typescript/src/utils/UIUtils.d.ts +4 -0
- package/lib/typescript/src/utils/UIUtils.d.ts.map +1 -0
- package/lib/typescript/src/utils/ui.d.ts +1 -12
- package/lib/typescript/src/utils/ui.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/assets/images/btn_resend.png +0 -0
- package/src/assets/images/index.ts +1 -0
- package/src/components/AttachmentPreview/FilePreview.tsx +1 -1
- package/src/components/flows/inputButtons/index.tsx +3 -5
- package/src/components/messages/MessageStatusIndicator.tsx +82 -0
- package/src/components/messages/fileMessage/index.tsx +0 -2
- package/src/components/messages/imageMessage/index.tsx +72 -58
- package/src/components/messages/linkMessage/index.tsx +16 -21
- package/src/components/messages/mergedMessage/index.tsx +13 -18
- package/src/components/messages/styles.ts +12 -0
- package/src/components/messages/textMessage/index.tsx +20 -20
- package/src/components/messages/videoMessage/index.tsx +8 -11
- package/src/config/uploadLimits.ts +1 -1
- package/src/core/useChatListener.ts +38 -4
- package/src/core/useUserListener.ts +17 -7
- package/src/hooks/message/useSendMessage.ts +103 -24
- package/src/hooks/useChatCompose.ts +42 -33
- package/src/hooks/useChatMessages.ts +54 -10
- package/src/hooks/useFileAttachment.ts +1 -1
- package/src/hooks/useFileDownload.ts +1 -1
- package/src/hooks/useImageAttachment.ts +13 -5
- package/src/index.tsx +2 -0
- package/src/screens/chat-detail/ChatDetail.tsx +29 -0
- package/src/screens/chat-detail/ChatListLegend.tsx +45 -28
- package/src/screens/chat-detail/constants.ts +3 -2
- package/src/screens/chat-detail/legend/LegendChatMessage.tsx +60 -15
- package/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.tsx +114 -0
- package/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.tsx +130 -0
- package/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.tsx +99 -0
- package/src/screens/chat-detail/messageToolbox/messageToolbox.utils.ts +56 -0
- package/src/screens/chat-detail/messageToolbox/types.ts +13 -0
- package/src/screens/chat-detail/types.ts +2 -0
- package/src/services/attachmentOrchestrator.ts +45 -21
- package/src/services/message.ts +21 -4
- package/src/translation/resources/i18n.ts +11 -3
- package/src/types/chat.ts +6 -0
- package/src/types/global.d.ts +299 -0
- package/src/types/index.d.ts +1 -0
- package/src/utils/UIUtils.ts +31 -0
- package/src/utils/ui.ts +20 -16
- package/src/utils/videoThumbnailUpload.ts +1 -1
- package/lib/module/hooks/useVideoAttachment.js +0 -251
- package/lib/module/hooks/useVideoAttachment.js.map +0 -1
- package/lib/typescript/src/hooks/useVideoAttachment.d.ts +0 -29
- package/lib/typescript/src/hooks/useVideoAttachment.d.ts.map +0 -1
- package/src/hooks/useVideoAttachment.ts +0 -334
|
@@ -7,18 +7,10 @@ import {
|
|
|
7
7
|
KColors,
|
|
8
8
|
KSpacingValue,
|
|
9
9
|
} from '@droppii/libs';
|
|
10
|
-
import type { DMessageItem } from '../../../types/chat';
|
|
11
10
|
import type { IUrlMetadata } from '../../../types/common';
|
|
12
11
|
import { formatMessageTime } from '../types';
|
|
12
|
+
import type { BaseLegendMessageProps } from '../types';
|
|
13
13
|
import { CHAT_BUBBLE_COLORS } from '../../../screens/chat-detail/constants';
|
|
14
|
-
|
|
15
|
-
interface BaseLegendMessageProps {
|
|
16
|
-
message: DMessageItem;
|
|
17
|
-
isOutgoing: boolean;
|
|
18
|
-
createdAtTime: number;
|
|
19
|
-
onPressUrl?: (url: string) => void;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
14
|
const parseUrlMetadata = (ex?: string): IUrlMetadata | undefined => {
|
|
23
15
|
if (!ex) return undefined;
|
|
24
16
|
try {
|
|
@@ -80,14 +72,14 @@ export const LinkMessage = memo(
|
|
|
80
72
|
isOutgoing,
|
|
81
73
|
createdAtTime,
|
|
82
74
|
onPressUrl,
|
|
83
|
-
}: BaseLegendMessageProps) => {
|
|
75
|
+
}: BaseLegendMessageProps & { onPressUrl?: (url: string) => void }) => {
|
|
84
76
|
const content = message?.urlTextElem?.content;
|
|
85
77
|
const urls = message?.urlTextElem?.urls ?? [];
|
|
86
78
|
const metadata = parseUrlMetadata(message.ex);
|
|
87
79
|
const timeLabel = formatMessageTime(createdAtTime);
|
|
88
80
|
|
|
89
81
|
return (
|
|
90
|
-
|
|
82
|
+
<>
|
|
91
83
|
<KContainer.View
|
|
92
84
|
style={[
|
|
93
85
|
styles.bubble,
|
|
@@ -147,16 +139,18 @@ export const LinkMessage = memo(
|
|
|
147
139
|
)}
|
|
148
140
|
</KContainer.View>
|
|
149
141
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
142
|
+
<KContainer.View row alignItems style={styles.timeLabel}>
|
|
143
|
+
{!isOutgoing && timeLabel ? (
|
|
144
|
+
<KLabel.Text
|
|
145
|
+
typo="TextXsNormal"
|
|
146
|
+
color={CHAT_BUBBLE_COLORS.timestamp}
|
|
147
|
+
marginL="0.25rem"
|
|
148
|
+
>
|
|
149
|
+
{timeLabel}
|
|
150
|
+
</KLabel.Text>
|
|
151
|
+
) : null}
|
|
152
|
+
</KContainer.View>
|
|
153
|
+
</>
|
|
160
154
|
);
|
|
161
155
|
}
|
|
162
156
|
);
|
|
@@ -197,4 +191,5 @@ const styles = StyleSheet.create({
|
|
|
197
191
|
paddingVertical: KSpacingValue['0.5rem'],
|
|
198
192
|
gap: 2,
|
|
199
193
|
},
|
|
194
|
+
timeLabel: { gap: 4, marginTop: 2 },
|
|
200
195
|
});
|
|
@@ -3,7 +3,6 @@ import { KContainer } from '@droppii/libs';
|
|
|
3
3
|
import { MergedImageGrid } from '../../MergedImageGrid';
|
|
4
4
|
import { messageStyles } from '../styles';
|
|
5
5
|
import type { BaseLegendMessageProps } from '../types';
|
|
6
|
-
|
|
7
6
|
export const MergedMessage = memo(
|
|
8
7
|
({ message, isOutgoing, onMediaPress }: BaseLegendMessageProps) => {
|
|
9
8
|
const mergeElem = (message as any).mergeElem;
|
|
@@ -18,23 +17,19 @@ export const MergedMessage = memo(
|
|
|
18
17
|
);
|
|
19
18
|
|
|
20
19
|
return (
|
|
21
|
-
<KContainer.View
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
onMediaPress={onMediaPress}
|
|
35
|
-
/>
|
|
36
|
-
)}
|
|
37
|
-
</KContainer.View>
|
|
20
|
+
<KContainer.View
|
|
21
|
+
style={[
|
|
22
|
+
messageStyles.bubble,
|
|
23
|
+
isOutgoing ? messageStyles.bubbleSent : messageStyles.bubbleReceived,
|
|
24
|
+
]}
|
|
25
|
+
>
|
|
26
|
+
{imageMessages.length > 0 && (
|
|
27
|
+
<MergedImageGrid
|
|
28
|
+
images={imageMessages}
|
|
29
|
+
maxDisplay={3}
|
|
30
|
+
onMediaPress={onMediaPress}
|
|
31
|
+
/>
|
|
32
|
+
)}
|
|
38
33
|
</KContainer.View>
|
|
39
34
|
);
|
|
40
35
|
}
|
|
@@ -36,4 +36,16 @@ export const messageStyles = StyleSheet.create({
|
|
|
36
36
|
bottom: 0,
|
|
37
37
|
backgroundColor: 'rgba(0, 0, 0, 0.3)',
|
|
38
38
|
},
|
|
39
|
+
messageRowLeft: {
|
|
40
|
+
width: '100%',
|
|
41
|
+
paddingHorizontal: KSpacingValue['0.75rem'],
|
|
42
|
+
marginBottom: KSpacingValue['0.25rem'],
|
|
43
|
+
alignItems: 'flex-start',
|
|
44
|
+
},
|
|
45
|
+
messageRowRight: {
|
|
46
|
+
width: '100%',
|
|
47
|
+
paddingHorizontal: KSpacingValue['0.75rem'],
|
|
48
|
+
marginBottom: KSpacingValue['0.25rem'],
|
|
49
|
+
alignItems: 'flex-end',
|
|
50
|
+
},
|
|
39
51
|
});
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import { memo } from 'react';
|
|
2
2
|
import { KContainer, KLabel } from '@droppii/libs';
|
|
3
3
|
import { getMessageText } from '../../../utils/legendListMessage';
|
|
4
|
-
import type { DMessageItem } from '../../../types/chat';
|
|
5
4
|
import { CHAT_BUBBLE_COLORS } from '../../../screens/chat-detail/constants';
|
|
6
5
|
import { messageStyles } from '../styles';
|
|
7
6
|
import { formatMessageTime } from '../types';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
message: DMessageItem;
|
|
11
|
-
isOutgoing: boolean;
|
|
12
|
-
createdAtTime: number;
|
|
13
|
-
}
|
|
14
|
-
|
|
7
|
+
import type { BaseLegendMessageProps } from '../types';
|
|
8
|
+
import { StyleSheet } from 'react-native';
|
|
15
9
|
export const TextMessage = memo(
|
|
16
|
-
({ message, isOutgoing, createdAtTime }:
|
|
10
|
+
({ message, isOutgoing, createdAtTime }: BaseLegendMessageProps) => {
|
|
17
11
|
const messageText = getMessageText(message);
|
|
18
12
|
const timeLabel = formatMessageTime(createdAtTime);
|
|
19
13
|
|
|
@@ -22,7 +16,7 @@ export const TextMessage = memo(
|
|
|
22
16
|
}
|
|
23
17
|
|
|
24
18
|
return (
|
|
25
|
-
|
|
19
|
+
<>
|
|
26
20
|
<KContainer.View
|
|
27
21
|
style={[
|
|
28
22
|
messageStyles.bubble,
|
|
@@ -36,18 +30,24 @@ export const TextMessage = memo(
|
|
|
36
30
|
</KLabel.Text>
|
|
37
31
|
</KContainer.View>
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
33
|
+
<KContainer.View row alignItems style={styles.timeLabel}>
|
|
34
|
+
{!isOutgoing && timeLabel ? (
|
|
35
|
+
<KLabel.Text
|
|
36
|
+
typo="TextXsNormal"
|
|
37
|
+
color={CHAT_BUBBLE_COLORS.timestamp}
|
|
38
|
+
marginL={'0.25rem'}
|
|
39
|
+
>
|
|
40
|
+
{timeLabel}
|
|
41
|
+
</KLabel.Text>
|
|
42
|
+
) : null}
|
|
43
|
+
</KContainer.View>
|
|
44
|
+
</>
|
|
49
45
|
);
|
|
50
46
|
}
|
|
51
47
|
);
|
|
52
48
|
|
|
53
49
|
TextMessage.displayName = 'TextMessage';
|
|
50
|
+
|
|
51
|
+
const styles = StyleSheet.create({
|
|
52
|
+
timeLabel: { gap: 4, marginTop: 2 },
|
|
53
|
+
});
|
|
@@ -7,7 +7,6 @@ import ChatImageDimens, {
|
|
|
7
7
|
import { CHAT_BUBBLE_COLORS } from '../../../screens/chat-detail/constants';
|
|
8
8
|
import { messageStyles } from '../styles';
|
|
9
9
|
import type { BaseLegendMessageProps } from '../types';
|
|
10
|
-
|
|
11
10
|
const formatDuration = (durationMs: number): string => {
|
|
12
11
|
const totalSeconds = Math.floor(durationMs / 1000);
|
|
13
12
|
const minutes = Math.floor(totalSeconds / 60);
|
|
@@ -30,14 +29,12 @@ export const VideoMessage = memo(
|
|
|
30
29
|
|
|
31
30
|
if (!videoUrl) {
|
|
32
31
|
return (
|
|
33
|
-
<KContainer.View
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
</KLabel.Text>
|
|
40
|
-
</KContainer.View>
|
|
32
|
+
<KContainer.View
|
|
33
|
+
style={[messageStyles.bubble, messageStyles.videoPlaceholder]}
|
|
34
|
+
>
|
|
35
|
+
<KLabel.Text typo="TextSmNormal" color={CHAT_BUBBLE_COLORS.text}>
|
|
36
|
+
📹 [Video unavailable]
|
|
37
|
+
</KLabel.Text>
|
|
41
38
|
</KContainer.View>
|
|
42
39
|
);
|
|
43
40
|
}
|
|
@@ -47,7 +44,7 @@ export const VideoMessage = memo(
|
|
|
47
44
|
);
|
|
48
45
|
|
|
49
46
|
return (
|
|
50
|
-
|
|
47
|
+
<>
|
|
51
48
|
<KContainer.Touchable
|
|
52
49
|
onPress={handlePress}
|
|
53
50
|
style={[
|
|
@@ -83,7 +80,7 @@ export const VideoMessage = memo(
|
|
|
83
80
|
</KContainer.View>
|
|
84
81
|
)}
|
|
85
82
|
</KContainer.Touchable>
|
|
86
|
-
|
|
83
|
+
</>
|
|
87
84
|
);
|
|
88
85
|
}
|
|
89
86
|
);
|
|
@@ -2,30 +2,58 @@ import OpenIMSDK, {
|
|
|
2
2
|
OpenIMEvent,
|
|
3
3
|
type ConversationItem,
|
|
4
4
|
type GroupMemberItem,
|
|
5
|
+
type MessageItem,
|
|
5
6
|
} from '@droppii/openim-rn-client-sdk';
|
|
6
7
|
import { useCallback, useEffect } from 'react';
|
|
7
8
|
import { useConversationStore } from '../store/conversation';
|
|
9
|
+
import { useMessageStore } from '../store/message';
|
|
8
10
|
|
|
9
11
|
export const useChatListener = () => {
|
|
12
|
+
const updateOneMessage = useMessageStore((state) => state.updateOneMessage);
|
|
13
|
+
|
|
14
|
+
const onSendMessageProgress = useCallback(
|
|
15
|
+
({ progress, message }: { progress: number; message: MessageItem }) => {
|
|
16
|
+
console.log('[Listener] SendMessageProgress', {
|
|
17
|
+
clientMsgID: message.clientMsgID,
|
|
18
|
+
status: message.status,
|
|
19
|
+
progress,
|
|
20
|
+
});
|
|
21
|
+
updateOneMessage(message);
|
|
22
|
+
},
|
|
23
|
+
[updateOneMessage]
|
|
24
|
+
);
|
|
25
|
+
|
|
10
26
|
const onConversationChanged = useCallback(
|
|
11
27
|
(conversations: ConversationItem[]) => {
|
|
12
|
-
console.log('
|
|
28
|
+
console.log('[Listener] OnConversationChanged', {
|
|
29
|
+
count: conversations.length,
|
|
30
|
+
ids: conversations.map((c) => c.conversationID),
|
|
31
|
+
});
|
|
13
32
|
useConversationStore.getState().updateConversations(conversations);
|
|
14
33
|
},
|
|
15
34
|
[]
|
|
16
35
|
);
|
|
17
36
|
|
|
18
37
|
const onNewConversation = useCallback((conversations: ConversationItem[]) => {
|
|
19
|
-
console.log('
|
|
38
|
+
console.log('[Listener] OnNewConversation', {
|
|
39
|
+
count: conversations.length,
|
|
40
|
+
ids: conversations.map((c) => c.conversationID),
|
|
41
|
+
});
|
|
20
42
|
useConversationStore.getState().updateConversations(conversations);
|
|
21
43
|
}, []);
|
|
22
44
|
|
|
23
45
|
const onGroupMemberAdded = useCallback((member: GroupMemberItem) => {
|
|
24
|
-
console.log('
|
|
46
|
+
console.log('[Listener] OnGroupMemberAdded', {
|
|
47
|
+
userID: member.userID,
|
|
48
|
+
groupID: member.groupID,
|
|
49
|
+
});
|
|
25
50
|
}, []);
|
|
26
51
|
|
|
27
52
|
const onGroupMemberDeleted = useCallback((member: GroupMemberItem) => {
|
|
28
|
-
console.log('
|
|
53
|
+
console.log('[Listener] OnGroupMemberDeleted', {
|
|
54
|
+
userID: member.userID,
|
|
55
|
+
groupID: member.groupID,
|
|
56
|
+
});
|
|
29
57
|
}, []);
|
|
30
58
|
|
|
31
59
|
useEffect(() => {
|
|
@@ -37,6 +65,9 @@ export const useChatListener = () => {
|
|
|
37
65
|
OpenIMSDK.on(OpenIMEvent.OnGroupMemberAdded, onGroupMemberAdded);
|
|
38
66
|
OpenIMSDK.on(OpenIMEvent.OnGroupMemberDeleted, onGroupMemberDeleted);
|
|
39
67
|
|
|
68
|
+
// Message status
|
|
69
|
+
OpenIMSDK.on(OpenIMEvent.SendMessageProgress, onSendMessageProgress);
|
|
70
|
+
|
|
40
71
|
return () => {
|
|
41
72
|
// Conversation
|
|
42
73
|
OpenIMSDK.off(OpenIMEvent.OnConversationChanged, onConversationChanged);
|
|
@@ -45,6 +76,9 @@ export const useChatListener = () => {
|
|
|
45
76
|
// Group members
|
|
46
77
|
OpenIMSDK.off(OpenIMEvent.OnGroupMemberAdded, onGroupMemberAdded);
|
|
47
78
|
OpenIMSDK.off(OpenIMEvent.OnGroupMemberDeleted, onGroupMemberDeleted);
|
|
79
|
+
|
|
80
|
+
// Message status
|
|
81
|
+
OpenIMSDK.off(OpenIMEvent.SendMessageProgress, onSendMessageProgress);
|
|
48
82
|
};
|
|
49
83
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
50
84
|
}, []);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import OpenIMSDK, {
|
|
2
2
|
LoginStatus,
|
|
3
3
|
OpenIMEvent,
|
|
4
|
+
type OpenIMEventBaseErrorType,
|
|
4
5
|
} from '@droppii/openim-rn-client-sdk';
|
|
5
6
|
import { useCallback, useEffect } from 'react';
|
|
6
7
|
import { useUserStore } from '../store';
|
|
@@ -28,36 +29,45 @@ export const useUserListener = () => {
|
|
|
28
29
|
}, [isLoggedIn, fetchAndUpdateUser]);
|
|
29
30
|
|
|
30
31
|
const onConnecting = useCallback(() => {
|
|
32
|
+
console.log('[Listener] OnConnecting');
|
|
31
33
|
useUserStore.getState().updateConnectStatus(LoginStatus.Logging);
|
|
32
34
|
}, []);
|
|
33
35
|
|
|
34
36
|
const onConnectSuccess = useCallback(() => {
|
|
37
|
+
console.log('[Listener] OnConnectSuccess');
|
|
35
38
|
useUserStore.getState().updateConnectStatus(LoginStatus.Logged);
|
|
36
39
|
}, []);
|
|
37
40
|
|
|
38
|
-
const onConnectFailed = useCallback(() => {
|
|
39
|
-
|
|
41
|
+
const onConnectFailed = useCallback((data: OpenIMEventBaseErrorType) => {
|
|
42
|
+
console.log('[Listener] OnConnectFailed', data);
|
|
40
43
|
}, []);
|
|
41
44
|
|
|
42
|
-
const onSyncServerStart = useCallback(() => {
|
|
45
|
+
const onSyncServerStart = useCallback((isSyncing: boolean) => {
|
|
46
|
+
console.log('[Listener] OnSyncServerStart', { isSyncing });
|
|
43
47
|
useUserStore.getState().updateSyncStatus(SyncStatus.Loading);
|
|
44
48
|
}, []);
|
|
45
49
|
|
|
46
50
|
const onSyncServerFinish = useCallback(() => {
|
|
51
|
+
console.log('[Listener] OnSyncServerFinish');
|
|
47
52
|
useUserStore.getState().updateSyncStatus(SyncStatus.Success);
|
|
48
53
|
}, []);
|
|
49
54
|
|
|
50
55
|
const onSyncServerFailed = useCallback(() => {
|
|
56
|
+
console.log('[Listener] OnSyncServerFailed');
|
|
51
57
|
useUserStore.getState().updateSyncStatus(SyncStatus.Failed);
|
|
52
58
|
}, []);
|
|
53
59
|
|
|
60
|
+
const onUserToken = useCallback(() => {
|
|
61
|
+
console.log('[Listener] OnUserToken expired/invalid');
|
|
62
|
+
}, []);
|
|
63
|
+
|
|
54
64
|
useEffect(() => {
|
|
55
65
|
// User
|
|
56
66
|
OpenIMSDK.on(OpenIMEvent.OnConnecting, onConnecting);
|
|
57
67
|
OpenIMSDK.on(OpenIMEvent.OnConnectSuccess, onConnectSuccess);
|
|
58
68
|
OpenIMSDK.on(OpenIMEvent.OnConnectFailed, onConnectFailed);
|
|
59
|
-
OpenIMSDK.on(OpenIMEvent.OnUserTokenExpired,
|
|
60
|
-
OpenIMSDK.on(OpenIMEvent.OnUserTokenInvalid,
|
|
69
|
+
OpenIMSDK.on(OpenIMEvent.OnUserTokenExpired, onUserToken);
|
|
70
|
+
OpenIMSDK.on(OpenIMEvent.OnUserTokenInvalid, onUserToken);
|
|
61
71
|
|
|
62
72
|
// Sync
|
|
63
73
|
OpenIMSDK.on(OpenIMEvent.OnSyncServerStart, onSyncServerStart);
|
|
@@ -69,8 +79,8 @@ export const useUserListener = () => {
|
|
|
69
79
|
OpenIMSDK.off(OpenIMEvent.OnConnecting, onConnecting);
|
|
70
80
|
OpenIMSDK.off(OpenIMEvent.OnConnectSuccess, onConnectSuccess);
|
|
71
81
|
OpenIMSDK.off(OpenIMEvent.OnConnectFailed, onConnectFailed);
|
|
72
|
-
OpenIMSDK.
|
|
73
|
-
OpenIMSDK.
|
|
82
|
+
OpenIMSDK.off(OpenIMEvent.OnUserTokenExpired, onUserToken);
|
|
83
|
+
OpenIMSDK.off(OpenIMEvent.OnUserTokenInvalid, onUserToken);
|
|
74
84
|
|
|
75
85
|
// Sync
|
|
76
86
|
OpenIMSDK.off(OpenIMEvent.OnSyncServerStart, onSyncServerStart);
|
|
@@ -1,23 +1,64 @@
|
|
|
1
1
|
import { useCallback } from 'react';
|
|
2
2
|
import type { UploadFileItem } from 'react-native-fs';
|
|
3
|
-
import { useConversationStore } from '../../store';
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
MessageType,
|
|
7
|
-
OfflinePush,
|
|
8
|
-
} from '@droppii/openim-rn-client-sdk';
|
|
3
|
+
import { useConversationStore } from '../../store/conversation';
|
|
4
|
+
import type { MessageItem, OfflinePush } from '@droppii/openim-rn-client-sdk';
|
|
5
|
+
import { MessageStatus, MessageType } from '@droppii/openim-rn-client-sdk';
|
|
9
6
|
import { extractUrls } from '../../utils/url';
|
|
10
7
|
import OpenIMSDK from '@droppii/openim-rn-client-sdk';
|
|
11
8
|
import type { IMessageItemEx } from '../../types/chat';
|
|
12
9
|
import { useChatContext } from '../../context';
|
|
13
10
|
import { generateContentBasedOnMessageType } from '../../utils/conversation';
|
|
14
11
|
import { useMessageStore } from '../../store/message';
|
|
12
|
+
|
|
15
13
|
import type { IUrlMetadata } from '../../types/common';
|
|
16
14
|
import type { IRunConversationFlowPayload } from '../../types/flows';
|
|
17
15
|
|
|
16
|
+
const buildSendParams = (
|
|
17
|
+
message: MessageItem,
|
|
18
|
+
recvID: string,
|
|
19
|
+
groupID: string,
|
|
20
|
+
extendMessageInfo: IMessageItemEx,
|
|
21
|
+
plainText: string
|
|
22
|
+
) => ({
|
|
23
|
+
groupID,
|
|
24
|
+
recvID,
|
|
25
|
+
message: { ...message, ex: JSON.stringify(extendMessageInfo) || '{}' },
|
|
26
|
+
offlinePushInfo: generateOfflinePushInfo(message.contentType, plainText),
|
|
27
|
+
});
|
|
28
|
+
|
|
18
29
|
export const useSendMessage = () => {
|
|
19
30
|
const applicationType = useChatContext().applicationType;
|
|
20
31
|
const pushNewMessage = useMessageStore((state) => state.pushNewMessage);
|
|
32
|
+
const updateOneMessage = useMessageStore((state) => state.updateOneMessage);
|
|
33
|
+
const deleteOneMessage = useMessageStore((state) => state.deleteOneMessage);
|
|
34
|
+
const dispatchSend = useCallback(
|
|
35
|
+
async (
|
|
36
|
+
message: MessageItem,
|
|
37
|
+
recvID: string,
|
|
38
|
+
groupID: string,
|
|
39
|
+
extendMessageInfo: IMessageItemEx,
|
|
40
|
+
plainText: string
|
|
41
|
+
) => {
|
|
42
|
+
pushNewMessage({ ...message, status: MessageStatus.Sending });
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const sent = await OpenIMSDK.sendMessage(
|
|
46
|
+
buildSendParams(
|
|
47
|
+
message,
|
|
48
|
+
recvID,
|
|
49
|
+
groupID,
|
|
50
|
+
extendMessageInfo,
|
|
51
|
+
plainText
|
|
52
|
+
)
|
|
53
|
+
);
|
|
54
|
+
deleteOneMessage(message.clientMsgID);
|
|
55
|
+
pushNewMessage(sent);
|
|
56
|
+
} catch {
|
|
57
|
+
updateOneMessage({ ...message, status: MessageStatus.Failed });
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
[pushNewMessage, updateOneMessage, deleteOneMessage]
|
|
61
|
+
);
|
|
21
62
|
|
|
22
63
|
const sendMessage = useCallback(
|
|
23
64
|
async ({
|
|
@@ -27,7 +68,7 @@ export const useSendMessage = () => {
|
|
|
27
68
|
flow,
|
|
28
69
|
}: {
|
|
29
70
|
plainText?: string;
|
|
30
|
-
files?: UploadFileItem[];
|
|
71
|
+
files?: UploadFileItem[];
|
|
31
72
|
urlMetadata?: IUrlMetadata;
|
|
32
73
|
flow?: IRunConversationFlowPayload;
|
|
33
74
|
}) => {
|
|
@@ -41,7 +82,6 @@ export const useSendMessage = () => {
|
|
|
41
82
|
if (!file) continue;
|
|
42
83
|
}
|
|
43
84
|
|
|
44
|
-
// Allow empty text if urlMetadata (preview link) is present
|
|
45
85
|
const hasText = !!plainText && plainText.trim() !== '';
|
|
46
86
|
const hasPreview = !!urlMetadata?.url;
|
|
47
87
|
|
|
@@ -51,7 +91,6 @@ export const useSendMessage = () => {
|
|
|
51
91
|
let message: MessageItem | null = null;
|
|
52
92
|
|
|
53
93
|
if (isUrlMessage) {
|
|
54
|
-
// Create URL message even with empty text if preview exists
|
|
55
94
|
message = await createUrlTextMessage(plainText || '', urls);
|
|
56
95
|
} else if (hasText) {
|
|
57
96
|
message = await createTextMessage(plainText);
|
|
@@ -68,27 +107,67 @@ export const useSendMessage = () => {
|
|
|
68
107
|
flow,
|
|
69
108
|
};
|
|
70
109
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
recvID
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
110
|
+
await dispatchSend(
|
|
111
|
+
message,
|
|
112
|
+
recvID || '',
|
|
113
|
+
groupID || '',
|
|
114
|
+
extendMessageInfo,
|
|
115
|
+
plainText || ''
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
[applicationType, dispatchSend]
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const retryMessage = useCallback(
|
|
123
|
+
async (message: MessageItem) => {
|
|
124
|
+
const { userID: recvID, groupID } =
|
|
125
|
+
useConversationStore.getState().getCurrentConversation() || {};
|
|
126
|
+
if (!recvID && !groupID) return;
|
|
127
|
+
|
|
128
|
+
updateOneMessage({ ...message, status: MessageStatus.Sending });
|
|
129
|
+
|
|
130
|
+
// Attachment messages were sent via sendMessageNotOss (URL already uploaded).
|
|
131
|
+
// Text/URL messages use sendMessage (SDK handles upload).
|
|
132
|
+
const isAttachment = (
|
|
133
|
+
[
|
|
134
|
+
MessageType.PictureMessage,
|
|
135
|
+
MessageType.VideoMessage,
|
|
136
|
+
MessageType.FileMessage,
|
|
137
|
+
MessageType.MergeMessage,
|
|
138
|
+
] as MessageType[]
|
|
139
|
+
).includes(message.contentType);
|
|
140
|
+
|
|
141
|
+
const params = {
|
|
142
|
+
recvID: recvID || '',
|
|
143
|
+
groupID: groupID || '',
|
|
144
|
+
message,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
const sent = isAttachment
|
|
149
|
+
? await OpenIMSDK.sendMessageNotOss(params)
|
|
150
|
+
: await OpenIMSDK.sendMessage(
|
|
151
|
+
buildSendParams(
|
|
152
|
+
message,
|
|
153
|
+
recvID || '',
|
|
154
|
+
groupID || '',
|
|
155
|
+
JSON.parse(message.ex || '{}') as IMessageItemEx,
|
|
156
|
+
''
|
|
157
|
+
)
|
|
158
|
+
);
|
|
159
|
+
deleteOneMessage(message.clientMsgID);
|
|
160
|
+
pushNewMessage(sent);
|
|
161
|
+
} catch {
|
|
162
|
+
updateOneMessage({ ...message, status: MessageStatus.Failed });
|
|
85
163
|
}
|
|
86
164
|
},
|
|
87
|
-
[
|
|
165
|
+
[pushNewMessage, updateOneMessage, deleteOneMessage]
|
|
88
166
|
);
|
|
89
167
|
|
|
90
168
|
return {
|
|
91
169
|
sendMessage,
|
|
170
|
+
retryMessage,
|
|
92
171
|
};
|
|
93
172
|
};
|
|
94
173
|
|