@messenger-box/platform-mobile 10.0.3-alpha.5 → 10.0.3-alpha.54

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.
Files changed (98) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/lib/compute.js +2 -3
  3. package/lib/compute.js.map +1 -1
  4. package/lib/index.js.map +1 -1
  5. package/lib/queries/inboxQueries.js +65 -0
  6. package/lib/queries/inboxQueries.js.map +1 -0
  7. package/lib/routes.json +2 -3
  8. package/lib/screens/inbox/DialogMessages.js +1 -1
  9. package/lib/screens/inbox/DialogMessages.js.map +1 -1
  10. package/lib/screens/inbox/DialogThreadMessages.js +4 -8
  11. package/lib/screens/inbox/DialogThreadMessages.js.map +1 -1
  12. package/lib/screens/inbox/DialogThreads.js +57 -12
  13. package/lib/screens/inbox/DialogThreads.js.map +1 -1
  14. package/lib/screens/inbox/Inbox.js +1 -1
  15. package/lib/screens/inbox/Inbox.js.map +1 -1
  16. package/lib/screens/inbox/components/CachedImage/consts.js +1 -1
  17. package/lib/screens/inbox/components/CachedImage/consts.js.map +1 -1
  18. package/lib/screens/inbox/components/CachedImage/index.js +168 -46
  19. package/lib/screens/inbox/components/CachedImage/index.js.map +1 -1
  20. package/lib/screens/inbox/components/DialogItem.js +169 -0
  21. package/lib/screens/inbox/components/DialogItem.js.map +1 -0
  22. package/lib/screens/inbox/components/GiftedChatInboxComponent.js +313 -0
  23. package/lib/screens/inbox/components/GiftedChatInboxComponent.js.map +1 -0
  24. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +147 -31
  25. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
  26. package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js +6 -1
  27. package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js.map +1 -1
  28. package/lib/screens/inbox/components/SubscriptionHandler.js +24 -0
  29. package/lib/screens/inbox/components/SubscriptionHandler.js.map +1 -0
  30. package/lib/screens/inbox/components/ThreadsViewItem.js +66 -55
  31. package/lib/screens/inbox/components/ThreadsViewItem.js.map +1 -1
  32. package/lib/screens/inbox/config/config.js +2 -2
  33. package/lib/screens/inbox/config/config.js.map +1 -1
  34. package/lib/screens/inbox/containers/ConversationView.js +1111 -434
  35. package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
  36. package/lib/screens/inbox/containers/Dialogs.js +193 -80
  37. package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
  38. package/lib/screens/inbox/containers/ThreadConversationView.js +725 -216
  39. package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
  40. package/lib/screens/inbox/containers/ThreadsView.js +83 -50
  41. package/lib/screens/inbox/containers/ThreadsView.js.map +1 -1
  42. package/lib/screens/inbox/hooks/useInboxMessages.js +31 -0
  43. package/lib/screens/inbox/hooks/useInboxMessages.js.map +1 -0
  44. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js +108 -0
  45. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js.map +1 -0
  46. package/lib/screens/inbox/workflow/dialog-threads-xstate.js +151 -0
  47. package/lib/screens/inbox/workflow/dialog-threads-xstate.js.map +1 -0
  48. package/package.json +4 -4
  49. package/src/compute.ts +5 -6
  50. package/src/index.ts +2 -0
  51. package/src/navigation/InboxNavigation.tsx +3 -3
  52. package/src/queries/inboxQueries.ts +299 -0
  53. package/src/queries/index.d.ts +2 -0
  54. package/src/queries/index.ts +1 -0
  55. package/src/screens/inbox/DialogMessages.tsx +1 -1
  56. package/src/screens/inbox/DialogThreadMessages.tsx +7 -14
  57. package/src/screens/inbox/DialogThreads.tsx +55 -61
  58. package/src/screens/inbox/Inbox.tsx +1 -1
  59. package/src/screens/inbox/components/Actionsheet.tsx +30 -0
  60. package/src/screens/inbox/components/CachedImage/consts.ts +4 -3
  61. package/src/screens/inbox/components/CachedImage/index.tsx +232 -61
  62. package/src/screens/inbox/components/DialogItem.tsx +306 -0
  63. package/src/screens/inbox/components/DialogsHeader.tsx +6 -13
  64. package/src/screens/inbox/components/DialogsListItem.tsx +262 -198
  65. package/src/screens/inbox/components/ExpandableInput.tsx +460 -0
  66. package/src/screens/inbox/components/ExpandableInputActionSheet.tsx +518 -0
  67. package/src/screens/inbox/components/GiftedChatInboxComponent.tsx +411 -0
  68. package/src/screens/inbox/components/ServiceDialogsListItem.tsx +337 -194
  69. package/src/screens/inbox/components/SlackInput.tsx +23 -0
  70. package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +233 -23
  71. package/src/screens/inbox/components/SlackMessageContainer/SlackMessage.tsx +1 -1
  72. package/src/screens/inbox/components/SmartLoader.tsx +61 -0
  73. package/src/screens/inbox/components/SubscriptionHandler.tsx +41 -0
  74. package/src/screens/inbox/components/SupportServiceDialogsListItem.tsx +53 -55
  75. package/src/screens/inbox/components/ThreadsViewItem.tsx +178 -285
  76. package/src/screens/inbox/components/workflow/dialogs-list-item-xstate.ts +145 -0
  77. package/src/screens/inbox/components/workflow/service-dialogs-list-item-xstate.ts +159 -0
  78. package/src/screens/inbox/config/config.ts +2 -2
  79. package/src/screens/inbox/containers/ConversationView.tsx +1843 -702
  80. package/src/screens/inbox/containers/ConversationView.tsx.bk +1467 -0
  81. package/src/screens/inbox/containers/Dialogs.tsx +402 -204
  82. package/src/screens/inbox/containers/SupportServiceDialogs.tsx +4 -4
  83. package/src/screens/inbox/containers/ThreadConversationView.tsx +1350 -319
  84. package/src/screens/inbox/containers/ThreadsView.tsx +105 -193
  85. package/src/screens/inbox/containers/workflow/apollo/handleResult.ts +20 -0
  86. package/src/screens/inbox/containers/workflow/conversation-xstate.ts +313 -0
  87. package/src/screens/inbox/containers/workflow/dialogs-xstate.ts +196 -0
  88. package/src/screens/inbox/containers/workflow/thread-conversation-xstate.ts +401 -0
  89. package/src/screens/inbox/hooks/useInboxMessages.ts +34 -0
  90. package/src/screens/inbox/hooks/useSafeDialogThreadsMachine.ts +136 -0
  91. package/src/screens/inbox/index.ts +37 -0
  92. package/src/screens/inbox/machines/threadsMachine.ts +147 -0
  93. package/src/screens/inbox/workflow/dialog-threads-xstate.ts +163 -0
  94. package/tsconfig.json +11 -54
  95. package/lib/screens/inbox/components/DialogsListItem.js +0 -171
  96. package/lib/screens/inbox/components/DialogsListItem.js.map +0 -1
  97. package/lib/screens/inbox/components/ServiceDialogsListItem.js +0 -171
  98. package/lib/screens/inbox/components/ServiceDialogsListItem.js.map +0 -1
@@ -0,0 +1,411 @@
1
+ import React, { forwardRef, useCallback, useMemo } from 'react';
2
+ import { Platform, View, KeyboardAvoidingView, TouchableOpacity, TextInput, ScrollView, Animated } from 'react-native';
3
+ import { Spinner, Box, Image, HStack, Text } from '@admin-layout/gluestack-ui-mobile';
4
+ import { GiftedChat, Send } from 'react-native-gifted-chat';
5
+ import { Ionicons, MaterialCommunityIcons, MaterialIcons } from '@expo/vector-icons';
6
+ import colors from 'tailwindcss/colors';
7
+ // If you have a SlackMessage component, import it:
8
+ // import SlackMessage from './SlackMessage';
9
+
10
+ export interface GiftedChatInboxComponentProps {
11
+ messages: any[];
12
+ onSend: (messages: any[]) => void;
13
+ text: string;
14
+ onInputTextChanged: (text: string) => void;
15
+ user: any;
16
+ images: any[];
17
+ onSelectImages: () => void;
18
+ onRemoveImage: (index: number) => void;
19
+ selectedImage: string;
20
+ setSelectedImage: (img: string) => void;
21
+ isUploadingImage: boolean;
22
+ loading: boolean;
23
+ errorMessage: string;
24
+ notificationType?: string;
25
+ onCloseError?: () => void;
26
+ inputToolbarHeight?: number;
27
+ bottomMargin?: number;
28
+ renderMessageText?: any;
29
+ renderActions?: any;
30
+ renderAccessory?: any;
31
+ renderMessage?: any;
32
+ renderInputToolbar?: any;
33
+ renderChatFooter?: any;
34
+ renderLoadEarlier?: any;
35
+ loadEarlier?: boolean;
36
+ isLoadingEarlier?: boolean;
37
+ totalCount?: number;
38
+ channelMessagesLength?: number;
39
+ keyboardVerticalOffset?: number;
40
+ placeholder?: string;
41
+ listViewProps?: any;
42
+ wrapInSafeArea?: boolean;
43
+ minComposerHeight?: number;
44
+ maxComposerHeight?: number;
45
+ renderFooter?: any;
46
+ lightboxProps?: any;
47
+ infiniteScroll?: boolean;
48
+ alwaysShowSend?: boolean;
49
+ minInputToolbarHeight?: number;
50
+ textInputProps?: any;
51
+ messagesContainerStyle?: any;
52
+ renderHeader?: any;
53
+ [key: string]: any;
54
+ }
55
+
56
+ // Helper to get the current ref if it's an object
57
+ function getRefCurrent(ref: React.ForwardedRef<any>) {
58
+ if (ref && typeof ref === 'object' && 'current' in ref) {
59
+ return ref.current;
60
+ }
61
+ return null;
62
+ }
63
+
64
+ export const GiftedChatInboxComponent = forwardRef<any, GiftedChatInboxComponentProps>((props, ref) => {
65
+ const {
66
+ messages,
67
+ onSend,
68
+ text,
69
+ onInputTextChanged,
70
+ user,
71
+ images,
72
+ setImages,
73
+ onSelectImages,
74
+ onRemoveImage,
75
+ selectedImage,
76
+ setSelectedImage,
77
+ isUploadingImage,
78
+ loading,
79
+ errorMessage,
80
+ notificationType = 'error',
81
+ onCloseError,
82
+ inputToolbarHeight = 56,
83
+ bottomMargin = 0,
84
+ renderMessageText,
85
+ renderActions,
86
+ renderAccessory,
87
+ renderMessage,
88
+ renderInputToolbar,
89
+ renderChatFooter,
90
+ renderLoadEarlier,
91
+ loadEarlier,
92
+ isLoadingEarlier,
93
+ keyboardVerticalOffset = Platform.OS === 'ios' ? 64 : 0,
94
+ placeholder = 'Jot something down',
95
+ listViewProps,
96
+ wrapInSafeArea = true,
97
+ minComposerHeight = 36,
98
+ maxComposerHeight = 100,
99
+ renderFooter,
100
+ lightboxProps = {
101
+ underlayColor: 'transparent',
102
+ springConfig: { tension: 90000, friction: 90000 },
103
+ disabled: true,
104
+ },
105
+ infiniteScroll = false,
106
+ alwaysShowSend = true,
107
+ minInputToolbarHeight = 30,
108
+ textInputProps = {
109
+ multiline: true,
110
+ returnKeyType: 'default',
111
+ enablesReturnKeyAutomatically: true,
112
+ placeholderTextColor: colors.gray[400],
113
+ },
114
+ messagesContainerStyle = { paddingTop: 8 },
115
+ renderHeader,
116
+ ...rest
117
+ } = props;
118
+
119
+ // Error Notification
120
+ const renderErrorNotification = () => {
121
+ if (!errorMessage) return null;
122
+ return (
123
+ <Animated.View
124
+ style={{
125
+ position: 'absolute',
126
+ top: 10,
127
+ left: 10,
128
+ right: 10,
129
+ backgroundColor: notificationType === 'error' ? '#f44336' : '#ff9800',
130
+ padding: 15,
131
+ borderRadius: 8,
132
+ shadowColor: '#000',
133
+ shadowOffset: { width: 0, height: 2 },
134
+ shadowOpacity: 0.25,
135
+ shadowRadius: 3.84,
136
+ elevation: 5,
137
+ zIndex: 1000,
138
+ }}
139
+ >
140
+ <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
141
+ <View>
142
+ <Text style={{ color: 'white', fontWeight: 'bold' }}>
143
+ {notificationType === 'error' ? 'Error' : 'Warning'}
144
+ </Text>
145
+ </View>
146
+ <View>
147
+ <TouchableOpacity onPress={onCloseError}>
148
+ <Ionicons name="close" size={20} color="white" />
149
+ </TouchableOpacity>
150
+ </View>
151
+ </View>
152
+ <Text style={{ color: 'white', marginTop: 5 }}>{errorMessage}</Text>
153
+ </Animated.View>
154
+ );
155
+ };
156
+
157
+ const renderInputToolbarDefault = useCallback(
158
+ (props) => (
159
+ <View style={{ backgroundColor: '#fff', paddingBottom: 4, paddingTop: 4 }}>
160
+ <View
161
+ style={{
162
+ flexDirection: 'row',
163
+ alignItems: 'center',
164
+ minHeight: 44,
165
+ maxHeight: 56,
166
+ backgroundColor: '#fff',
167
+ borderRadius: 22,
168
+ marginHorizontal: 8,
169
+ paddingHorizontal: 8,
170
+ borderTopWidth: 1,
171
+ borderTopColor: '#e0e0e0',
172
+ }}
173
+ >
174
+ <TouchableOpacity
175
+ onPress={onSelectImages}
176
+ style={{
177
+ width: 32,
178
+ height: 32,
179
+ borderRadius: 16,
180
+ backgroundColor: '#fff',
181
+ alignItems: 'center',
182
+ justifyContent: 'center',
183
+ marginRight: 8,
184
+ }}
185
+ >
186
+ <MaterialIcons name="add" size={24} color="#888" />
187
+ </TouchableOpacity>
188
+ <TextInput
189
+ ref={ref}
190
+ style={{
191
+ flex: 1,
192
+ //minHeight: 36,
193
+ maxHeight: 44,
194
+ backgroundColor: 'transparent',
195
+ color: '#444',
196
+ paddingHorizontal: 8,
197
+ paddingVertical: 0,
198
+ alignSelf: 'center',
199
+ textAlignVertical: 'center',
200
+ }}
201
+ placeholder={placeholder || 'Jot something down'}
202
+ placeholderTextColor={colors.gray[400]}
203
+ multiline
204
+ value={text}
205
+ onChangeText={onInputTextChanged}
206
+ />
207
+ <TouchableOpacity
208
+ onPress={() => onSend([{ text: text }])}
209
+ // disabled={(!messageText.trim() && images.length === 0) || isUploadingImage || loading}
210
+ disabled={false}
211
+ style={{
212
+ marginLeft: 8,
213
+ // opacity: (!messageText.trim() && images.length === 0) || isUploadingImage || loading ? 0.5 : 1,
214
+ opacity: !text.trim() && images.length === 0 ? 0.5 : 1,
215
+ }}
216
+ >
217
+ <MaterialCommunityIcons
218
+ name="send-circle"
219
+ size={32}
220
+ color={!text.trim() && images.length === 0 ? colors.gray[400] : colors.blue[500]}
221
+ // color={
222
+ // (!messageText.trim() && images.length === 0) || isUploadingImage || loading
223
+ // ? colors.gray[400]
224
+ // : colors.blue[500]
225
+ // }
226
+ />
227
+ </TouchableOpacity>
228
+ </View>
229
+ {/* Selected Images Row */}
230
+ {images && images.length > 0 && (
231
+ <ScrollView
232
+ horizontal
233
+ showsHorizontalScrollIndicator={false}
234
+ style={{ marginTop: 4, marginLeft: 8 }}
235
+ >
236
+ {images.map((img, index) => (
237
+ <View
238
+ key={`image-preview-${index}`}
239
+ style={{
240
+ width: 48,
241
+ height: 48,
242
+ marginRight: 8,
243
+ borderRadius: 6,
244
+ overflow: 'hidden',
245
+ position: 'relative',
246
+ backgroundColor: colors.gray[200],
247
+ }}
248
+ >
249
+ <Image
250
+ source={{ uri: img.uri || img.url }}
251
+ style={{ width: '100%', height: '100%' }}
252
+ alt={`selected image ${index + 1}`}
253
+ />
254
+ <TouchableOpacity
255
+ onPress={() => {
256
+ onRemoveImage(index);
257
+ }}
258
+ style={{
259
+ position: 'absolute',
260
+ top: 2,
261
+ right: 2,
262
+ backgroundColor: 'rgba(0,0,0,0.6)',
263
+ borderRadius: 10,
264
+ width: 20,
265
+ height: 20,
266
+ alignItems: 'center',
267
+ justifyContent: 'center',
268
+ }}
269
+ >
270
+ <Ionicons name="close" size={14} color="white" />
271
+ </TouchableOpacity>
272
+ </View>
273
+ ))}
274
+ </ScrollView>
275
+ )}
276
+ </View>
277
+ ),
278
+ [onSelectImages, text, images, isUploadingImage, loading, onSend, onRemoveImage, placeholder, ref],
279
+ );
280
+
281
+ const renderAccessoryDefault = useCallback(() => {
282
+ if (!images.length) return null;
283
+ return (
284
+ <Box style={{ position: 'relative', height: 70, backgroundColor: 'transparent', justifyContent: 'center' }}>
285
+ <ScrollView
286
+ horizontal
287
+ showsHorizontalScrollIndicator={false}
288
+ style={{
289
+ flexDirection: 'row',
290
+ paddingLeft: 15,
291
+ paddingRight: 5,
292
+ }}
293
+ contentContainerStyle={{
294
+ alignItems: 'center',
295
+ height: '100%',
296
+ }}
297
+ >
298
+ {images.map((img, index) => (
299
+ <View
300
+ key={`image-preview-${index}`}
301
+ style={{
302
+ width: 40,
303
+ height: 40,
304
+ marginRight: 15,
305
+ borderRadius: 4,
306
+ backgroundColor: colors.gray[200],
307
+ overflow: 'hidden',
308
+ borderWidth: 1,
309
+ borderColor: '#e0e0e0',
310
+ position: 'relative',
311
+ zIndex: 10,
312
+ }}
313
+ >
314
+ <Image
315
+ source={{ uri: img.uri || img.url }}
316
+ style={{ width: '100%', height: '100%' }}
317
+ alt={`selected image ${index + 1}`}
318
+ />
319
+ {/* Cross button at top right */}
320
+ <TouchableOpacity
321
+ onPress={() => {
322
+ const newImages = [...images];
323
+ newImages.splice(index, 1);
324
+ setImages(newImages);
325
+ if (newImages.length === 0) {
326
+ setSelectedImage('');
327
+ const inputRef = getRefCurrent(ref);
328
+ if (inputRef && typeof inputRef.focus === 'function') {
329
+ inputRef.focus();
330
+ }
331
+ }
332
+ }}
333
+ style={{
334
+ position: 'absolute',
335
+ top: -1,
336
+ right: -1,
337
+ backgroundColor: 'rgba(0,0,0,0.6)',
338
+ borderRadius: 12,
339
+ width: 20,
340
+ height: 20,
341
+ alignItems: 'center',
342
+ justifyContent: 'center',
343
+ zIndex: 9999,
344
+ }}
345
+ >
346
+ <Ionicons name="close" size={16} color="white" />
347
+ </TouchableOpacity>
348
+ </View>
349
+ ))}
350
+ </ScrollView>
351
+ </Box>
352
+ );
353
+ }, [images, setImages, setSelectedImage, ref]);
354
+
355
+ return (
356
+ <KeyboardAvoidingView
357
+ style={{ flex: 1, justifyContent: 'flex-end', backgroundColor: '#fff' }}
358
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
359
+ keyboardVerticalOffset={keyboardVerticalOffset}
360
+ >
361
+ <View
362
+ style={{
363
+ flex: 1,
364
+ backgroundColor: '#fff',
365
+ position: 'relative',
366
+ marginBottom: bottomMargin,
367
+ }}
368
+ >
369
+ {renderErrorNotification()}
370
+ {loading && <Spinner color={colors.blue[500]} />}
371
+ <GiftedChat
372
+ ref={ref}
373
+ wrapInSafeArea={wrapInSafeArea}
374
+ messages={messages}
375
+ onSend={onSend}
376
+ text={text}
377
+ onInputTextChanged={onInputTextChanged}
378
+ user={user}
379
+ renderMessageText={renderMessageText}
380
+ renderActions={renderActions || null}
381
+ renderAccessory={renderAccessory || renderAccessoryDefault}
382
+ renderMessage={renderMessage}
383
+ renderInputToolbar={renderInputToolbar || renderInputToolbarDefault}
384
+ renderLoading={props.renderLoading || null}
385
+ renderChatFooter={renderChatFooter}
386
+ renderLoadEarlier={renderLoadEarlier}
387
+ listViewProps={listViewProps}
388
+ loadEarlier={loadEarlier}
389
+ isLoadingEarlier={isLoadingEarlier}
390
+ bottomOffset={props.bottomOffset || 0}
391
+ isKeyboardInternallyHandled={props.isKeyboardInternallyHandled || false}
392
+ renderFooter={() => (renderFooter ? renderFooter() : null)}
393
+ minComposerHeight={minComposerHeight}
394
+ maxComposerHeight={maxComposerHeight}
395
+ placeholder={placeholder || 'Jot something down'}
396
+ lightboxProps={lightboxProps}
397
+ infiniteScroll={infiniteScroll}
398
+ alwaysShowSend={alwaysShowSend}
399
+ minInputToolbarHeight={minInputToolbarHeight}
400
+ textInputProps={textInputProps}
401
+ messagesContainerStyle={messagesContainerStyle}
402
+ isTyping={props.isTyping || false}
403
+ renderChatEmpty={props.renderChatEmpty || null}
404
+ {...rest}
405
+ />
406
+ </View>
407
+ </KeyboardAvoidingView>
408
+ );
409
+ });
410
+
411
+ export default GiftedChatInboxComponent;