@messenger-box/platform-mobile 10.0.3-alpha.40 → 10.0.3-alpha.46
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/CHANGELOG.md +8 -0
- package/lib/compute.js +2 -3
- package/lib/index.js.map +1 -1
- package/lib/queries/inboxQueries.js +77 -0
- package/lib/queries/inboxQueries.js.map +1 -0
- package/lib/routes.json +2 -3
- package/lib/screens/inbox/DialogThreadMessages.js +3 -7
- package/lib/screens/inbox/DialogThreadMessages.js.map +1 -1
- package/lib/screens/inbox/DialogThreads.js +3 -7
- package/lib/screens/inbox/DialogThreads.js.map +1 -1
- package/lib/screens/inbox/components/DialogsListItem.js +47 -46
- package/lib/screens/inbox/components/DialogsListItem.js.map +1 -1
- package/lib/screens/inbox/components/GiftedChatInboxComponent.js +313 -0
- package/lib/screens/inbox/components/GiftedChatInboxComponent.js.map +1 -0
- package/lib/screens/inbox/components/ServiceDialogsListItem.js +72 -57
- package/lib/screens/inbox/components/ServiceDialogsListItem.js.map +1 -1
- package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +115 -14
- package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
- package/lib/screens/inbox/components/SubscriptionHandler.js +24 -0
- package/lib/screens/inbox/components/SubscriptionHandler.js.map +1 -0
- package/lib/screens/inbox/containers/ConversationView.js +640 -493
- package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
- package/lib/screens/inbox/containers/Dialogs.js +100 -181
- package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
- package/lib/screens/inbox/containers/ThreadConversationView.js +659 -245
- package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
- package/lib/screens/inbox/containers/ThreadsView.js +3 -3
- package/lib/screens/inbox/containers/ThreadsView.js.map +1 -1
- package/lib/screens/inbox/hooks/useInboxMessages.js +31 -0
- package/lib/screens/inbox/hooks/useInboxMessages.js.map +1 -0
- package/package.json +4 -4
- package/src/index.ts +2 -0
- package/src/queries/inboxQueries.ts +298 -0
- package/src/queries/index.d.ts +2 -0
- package/src/queries/index.ts +1 -0
- package/src/screens/inbox/DialogThreadMessages.tsx +3 -11
- package/src/screens/inbox/DialogThreads.tsx +3 -7
- package/src/screens/inbox/components/Actionsheet.tsx +30 -0
- package/src/screens/inbox/components/DialogsListItem.tsx +89 -148
- package/src/screens/inbox/components/ExpandableInput.tsx +460 -0
- package/src/screens/inbox/components/ExpandableInputActionSheet.tsx +518 -0
- package/src/screens/inbox/components/GiftedChatInboxComponent.tsx +411 -0
- package/src/screens/inbox/components/ServiceDialogsListItem.tsx +202 -221
- package/src/screens/inbox/components/SlackInput.tsx +23 -0
- package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +216 -30
- package/src/screens/inbox/components/SubscriptionHandler.tsx +41 -0
- package/src/screens/inbox/components/SupportServiceDialogsListItem.tsx +6 -7
- package/src/screens/inbox/containers/ConversationView.tsx +1109 -669
- package/src/screens/inbox/containers/Dialogs.tsx +198 -342
- package/src/screens/inbox/containers/SupportServiceDialogs.tsx +2 -2
- package/src/screens/inbox/containers/ThreadConversationView.tsx +1141 -402
- package/src/screens/inbox/containers/ThreadsView.tsx +5 -5
- package/src/screens/inbox/hooks/useInboxMessages.ts +34 -0
- package/src/screens/inbox/machines/threadsMachine.ts +2 -2
|
@@ -56,25 +56,177 @@ export default class Bubble extends React.Component<any> {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
renderMessageImage() {
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
const { currentMessage, containerStyle, wrapperStyle, ...messageImageProps } = this.props;
|
|
60
|
+
|
|
61
|
+
// Check if we have multiple images
|
|
62
|
+
if (currentMessage.images && Array.isArray(currentMessage.images) && currentMessage.images.length > 0) {
|
|
63
|
+
// Filter out any invalid or empty image URLs first
|
|
64
|
+
const validImages = currentMessage.images.filter((url) => url && typeof url === 'string');
|
|
65
|
+
|
|
66
|
+
// If no valid images after filtering, don't render anything
|
|
67
|
+
if (validImages.length === 0) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Render multiple images in a scrollable horizontal row
|
|
72
|
+
return (
|
|
73
|
+
<View style={{ marginVertical: 0 }}>
|
|
74
|
+
<View
|
|
75
|
+
style={{
|
|
76
|
+
flexDirection: 'row',
|
|
77
|
+
flexWrap: 'wrap',
|
|
78
|
+
gap: 8,
|
|
79
|
+
}}
|
|
80
|
+
>
|
|
81
|
+
{validImages.map((imageUrl, index) => {
|
|
82
|
+
// Check if this is a local image
|
|
83
|
+
const isLocalImage =
|
|
84
|
+
imageUrl.startsWith('file:') ||
|
|
85
|
+
imageUrl.startsWith('data:') ||
|
|
86
|
+
imageUrl.startsWith('content:') ||
|
|
87
|
+
(!imageUrl.startsWith('http://') && !imageUrl.startsWith('https://'));
|
|
88
|
+
|
|
89
|
+
const imageSize =
|
|
90
|
+
validImages.length === 1
|
|
91
|
+
? { width: windowWidth * 0.6, height: windowWidth * 0.4 }
|
|
92
|
+
: { width: windowWidth * 0.3, height: windowWidth * 0.3 };
|
|
93
|
+
|
|
94
|
+
// Show upload indicator if this message is uploading
|
|
95
|
+
const isUploading = currentMessage.isUploading;
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<TouchableHighlight
|
|
99
|
+
key={`image-${index}-${currentMessage._id}`}
|
|
100
|
+
underlayColor={'transparent'}
|
|
101
|
+
onPress={() => {
|
|
102
|
+
// Don't allow viewing while uploading
|
|
103
|
+
if (isUploading) return;
|
|
104
|
+
|
|
105
|
+
// Create a message-like object with this image for the viewer
|
|
106
|
+
const imageObject = {
|
|
107
|
+
_id: `${currentMessage._id}-img-${index}`,
|
|
108
|
+
image: imageUrl,
|
|
109
|
+
};
|
|
110
|
+
this.props.setImageViewer(imageObject, true);
|
|
111
|
+
}}
|
|
112
|
+
>
|
|
113
|
+
<View
|
|
114
|
+
style={{
|
|
115
|
+
...imageSize,
|
|
116
|
+
maxHeight: 200,
|
|
117
|
+
borderRadius: 8,
|
|
118
|
+
overflow: 'hidden',
|
|
119
|
+
borderWidth: 1,
|
|
120
|
+
borderColor: '#e0e0e0',
|
|
121
|
+
backgroundColor: '#f7f7f7',
|
|
122
|
+
}}
|
|
123
|
+
>
|
|
124
|
+
{isLocalImage ? (
|
|
125
|
+
// For local images, use direct Image component with no loading state
|
|
126
|
+
<View style={{ width: '100%', height: '100%' }}>
|
|
127
|
+
<MessageImage
|
|
128
|
+
{...messageImageProps}
|
|
129
|
+
currentMessage={{ ...currentMessage, image: imageUrl }}
|
|
130
|
+
imageStyle={{
|
|
131
|
+
width: '100%',
|
|
132
|
+
height: '100%',
|
|
133
|
+
borderRadius: 8,
|
|
134
|
+
}}
|
|
135
|
+
/>
|
|
136
|
+
|
|
137
|
+
{/* Show upload indicator if needed */}
|
|
138
|
+
{isUploading && (
|
|
139
|
+
<View
|
|
140
|
+
style={{
|
|
141
|
+
position: 'absolute',
|
|
142
|
+
top: 0,
|
|
143
|
+
left: 0,
|
|
144
|
+
right: 0,
|
|
145
|
+
bottom: 0,
|
|
146
|
+
backgroundColor: 'rgba(0,0,0,0.2)',
|
|
147
|
+
justifyContent: 'center',
|
|
148
|
+
alignItems: 'center',
|
|
149
|
+
}}
|
|
150
|
+
>
|
|
151
|
+
<Text style={{ color: 'white', fontWeight: 'bold' }}>
|
|
152
|
+
Uploading...
|
|
153
|
+
</Text>
|
|
154
|
+
</View>
|
|
155
|
+
)}
|
|
156
|
+
</View>
|
|
157
|
+
) : (
|
|
158
|
+
// For remote images, use CachedImage with loading placeholder
|
|
159
|
+
<CachedImage
|
|
160
|
+
style={[styles.slackImage, { width: '100%', height: '100%' }]}
|
|
161
|
+
cacheKey={`${currentMessage._id}-img-${index}-slack-bubble-imageKey`}
|
|
162
|
+
source={{
|
|
163
|
+
uri: imageUrl,
|
|
164
|
+
expiresIn: 86400,
|
|
165
|
+
}}
|
|
166
|
+
resizeMode={'cover'}
|
|
167
|
+
alt={'image'}
|
|
168
|
+
placeholderContent={
|
|
169
|
+
<View
|
|
170
|
+
style={[
|
|
171
|
+
styles.slackImage,
|
|
172
|
+
{
|
|
173
|
+
width: '100%',
|
|
174
|
+
height: '100%',
|
|
175
|
+
backgroundColor: '#e1e1e1',
|
|
176
|
+
justifyContent: 'center',
|
|
177
|
+
alignItems: 'center',
|
|
178
|
+
borderRadius: 8,
|
|
179
|
+
},
|
|
180
|
+
]}
|
|
181
|
+
>
|
|
182
|
+
<Text>{isUploading ? 'Uploading...' : 'Loading...'}</Text>
|
|
183
|
+
</View>
|
|
184
|
+
}
|
|
185
|
+
/>
|
|
186
|
+
)}
|
|
187
|
+
</View>
|
|
188
|
+
</TouchableHighlight>
|
|
189
|
+
);
|
|
190
|
+
})}
|
|
191
|
+
</View>
|
|
192
|
+
</View>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Fall back to single image rendering if no images array
|
|
197
|
+
if (currentMessage.image) {
|
|
61
198
|
if (this.props.renderMessageImage) {
|
|
62
199
|
return this.props.renderMessageImage(messageImageProps);
|
|
63
200
|
}
|
|
64
|
-
const { image, _id } =
|
|
201
|
+
const { image, _id } = currentMessage;
|
|
65
202
|
|
|
66
203
|
// Add validation for image URL
|
|
67
204
|
if (!image || typeof image !== 'string') {
|
|
68
205
|
return null;
|
|
69
206
|
}
|
|
70
207
|
|
|
208
|
+
// Check if this is a local image (from device camera/library)
|
|
209
|
+
const isLocalImage =
|
|
210
|
+
image.startsWith('file:') ||
|
|
211
|
+
image.startsWith('data:') ||
|
|
212
|
+
image.startsWith('content:') ||
|
|
213
|
+
// Check if the image is a pendingUpload by checking if it doesn't start with http/https
|
|
214
|
+
(!image.startsWith('http://') && !image.startsWith('https://'));
|
|
215
|
+
|
|
216
|
+
// Check uploading state
|
|
217
|
+
const isUploading = currentMessage.isUploading;
|
|
218
|
+
|
|
71
219
|
// Class components can't use hooks like useMemo
|
|
72
220
|
// Directly render the CachedImage instead
|
|
73
221
|
return (
|
|
74
222
|
<TouchableHighlight
|
|
75
223
|
underlayColor={'transparent'}
|
|
76
|
-
style={{ width: '100%', marginVertical:
|
|
77
|
-
onPress={() =>
|
|
224
|
+
style={{ width: '100%', marginVertical: 0 }}
|
|
225
|
+
onPress={() => {
|
|
226
|
+
// Don't allow viewing while uploading
|
|
227
|
+
if (isUploading) return;
|
|
228
|
+
this.props.setImageViewer(currentMessage, true);
|
|
229
|
+
}}
|
|
78
230
|
>
|
|
79
231
|
<View
|
|
80
232
|
style={{
|
|
@@ -88,37 +240,71 @@ export default class Bubble extends React.Component<any> {
|
|
|
88
240
|
backgroundColor: '#f7f7f7',
|
|
89
241
|
}}
|
|
90
242
|
>
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
243
|
+
{isLocalImage ? (
|
|
244
|
+
// For local images, use direct Image component with no loading state
|
|
245
|
+
<View style={{ width: '100%', height: '100%', position: 'relative' }}>
|
|
246
|
+
<MessageImage
|
|
247
|
+
{...messageImageProps}
|
|
248
|
+
imageStyle={{
|
|
249
|
+
width: '100%',
|
|
250
|
+
height: '100%',
|
|
251
|
+
borderRadius: 8,
|
|
252
|
+
}}
|
|
253
|
+
/>
|
|
254
|
+
|
|
255
|
+
{/* Show upload indicator if needed */}
|
|
256
|
+
{isUploading && (
|
|
257
|
+
<View
|
|
258
|
+
style={{
|
|
259
|
+
position: 'absolute',
|
|
260
|
+
top: 0,
|
|
261
|
+
left: 0,
|
|
262
|
+
right: 0,
|
|
263
|
+
bottom: 0,
|
|
264
|
+
backgroundColor: 'rgba(0,0,0,0.2)',
|
|
108
265
|
justifyContent: 'center',
|
|
109
266
|
alignItems: 'center',
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
267
|
+
}}
|
|
268
|
+
>
|
|
269
|
+
<Text style={{ color: 'white', fontWeight: 'bold' }}>Uploading...</Text>
|
|
270
|
+
</View>
|
|
271
|
+
)}
|
|
272
|
+
</View>
|
|
273
|
+
) : (
|
|
274
|
+
// For remote images, use CachedImage with loading placeholder
|
|
275
|
+
<CachedImage
|
|
276
|
+
style={[styles.slackImage, { width: '100%', height: '100%' }]}
|
|
277
|
+
cacheKey={`${_id}-slack-bubble-imageKey`}
|
|
278
|
+
source={{
|
|
279
|
+
uri: image,
|
|
280
|
+
expiresIn: 86400,
|
|
281
|
+
}}
|
|
282
|
+
resizeMode={'cover'}
|
|
283
|
+
alt={'image'}
|
|
284
|
+
placeholderContent={
|
|
285
|
+
<View
|
|
286
|
+
style={[
|
|
287
|
+
styles.slackImage,
|
|
288
|
+
{
|
|
289
|
+
width: '100%',
|
|
290
|
+
height: '100%',
|
|
291
|
+
backgroundColor: '#e1e1e1',
|
|
292
|
+
justifyContent: 'center',
|
|
293
|
+
alignItems: 'center',
|
|
294
|
+
borderRadius: 8,
|
|
295
|
+
},
|
|
296
|
+
]}
|
|
297
|
+
>
|
|
298
|
+
<Text>{isUploading ? 'Uploading...' : 'Loading...'}</Text>
|
|
299
|
+
</View>
|
|
300
|
+
}
|
|
301
|
+
/>
|
|
302
|
+
)}
|
|
118
303
|
</View>
|
|
119
304
|
</TouchableHighlight>
|
|
120
305
|
);
|
|
121
306
|
}
|
|
307
|
+
|
|
122
308
|
return null;
|
|
123
309
|
}
|
|
124
310
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared SubscriptionHandler for Apollo subscribeToMore
|
|
5
|
+
*
|
|
6
|
+
* @param subscribeToMore - Apollo subscribeToMore function
|
|
7
|
+
* @param document - GraphQL subscription document
|
|
8
|
+
* @param variables - Variables for the subscription
|
|
9
|
+
* @param updateQuery - Apollo updateQuery function
|
|
10
|
+
* @param onError - Optional error handler
|
|
11
|
+
* @param enabled - If false, disables the subscription
|
|
12
|
+
*/
|
|
13
|
+
export function SubscriptionHandler({
|
|
14
|
+
subscribeToMore,
|
|
15
|
+
document,
|
|
16
|
+
variables,
|
|
17
|
+
updateQuery,
|
|
18
|
+
onError,
|
|
19
|
+
enabled = true,
|
|
20
|
+
}: {
|
|
21
|
+
subscribeToMore: Function;
|
|
22
|
+
document: any;
|
|
23
|
+
variables: Record<string, any>;
|
|
24
|
+
updateQuery: (prev: any, { subscriptionData }: any) => any;
|
|
25
|
+
onError?: (error: any) => void;
|
|
26
|
+
enabled?: boolean;
|
|
27
|
+
}) {
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (!enabled) return;
|
|
30
|
+
const unsubscribe = subscribeToMore({
|
|
31
|
+
document,
|
|
32
|
+
variables,
|
|
33
|
+
updateQuery,
|
|
34
|
+
onError,
|
|
35
|
+
});
|
|
36
|
+
return () => {
|
|
37
|
+
if (unsubscribe && typeof unsubscribe === 'function') unsubscribe();
|
|
38
|
+
};
|
|
39
|
+
}, [subscribeToMore, document, JSON.stringify(variables), updateQuery, onError, enabled]);
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
@@ -16,14 +16,13 @@ import { format, isToday, isYesterday } from 'date-fns';
|
|
|
16
16
|
import { useFocusEffect } from '@react-navigation/native';
|
|
17
17
|
import { IChannel, IUserAccount } from 'common';
|
|
18
18
|
import {
|
|
19
|
+
THREAD_CREATED_UPDATED,
|
|
20
|
+
CHAT_MESSAGE_ADDED,
|
|
19
21
|
useThreadMessagesQuery,
|
|
22
|
+
useThreadCreatedUpdatedSubscription,
|
|
23
|
+
useThreadChatMessageAddedSubscription,
|
|
20
24
|
useMessagesQuery,
|
|
21
|
-
|
|
22
|
-
useOnThreadCreatedUpdatedSubscription,
|
|
23
|
-
useOnThreadChatMessageAddedSubscription,
|
|
24
|
-
OnThreadCreatedUpdatedDocument as THREAD_CHAT_ADDED,
|
|
25
|
-
OnThreadChatMessageAddedDocument as CHAT_MESSAGE_ADDED,
|
|
26
|
-
} from 'common/graphql';
|
|
25
|
+
} from '../../../queries/inboxQueries';
|
|
27
26
|
import { startCase } from 'lodash-es';
|
|
28
27
|
import colors from 'tailwindcss/colors';
|
|
29
28
|
|
|
@@ -204,7 +203,7 @@ export const SupportServiceDialogsListItemComponent: React.FC<IDialogListItemPro
|
|
|
204
203
|
lastMessage={lastMessage}
|
|
205
204
|
subscribeToNewMessages={() =>
|
|
206
205
|
subscribeToMore({
|
|
207
|
-
document:
|
|
206
|
+
document: THREAD_CREATED_UPDATED,
|
|
208
207
|
variables: {
|
|
209
208
|
channelId: channel?.id?.toString(),
|
|
210
209
|
postParentId: postParentId ? servicePostParentId : null,
|