@messenger-box/platform-mobile 10.0.3-alpha.18 → 10.0.3-alpha.180

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/lib/compute.js +2 -3
  2. package/lib/compute.js.map +1 -1
  3. package/lib/index.js.map +1 -1
  4. package/lib/module.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 +8 -3
  9. package/lib/screens/inbox/DialogMessages.js.map +1 -1
  10. package/lib/screens/inbox/DialogThreadMessages.js +6 -11
  11. package/lib/screens/inbox/DialogThreadMessages.js.map +1 -1
  12. package/lib/screens/inbox/DialogThreads.js +58 -20
  13. package/lib/screens/inbox/DialogThreads.js.map +1 -1
  14. package/lib/screens/inbox/Inbox.js.map +1 -1
  15. package/lib/screens/inbox/components/CachedImage/consts.js.map +1 -1
  16. package/lib/screens/inbox/components/CachedImage/index.js +125 -115
  17. package/lib/screens/inbox/components/CachedImage/index.js.map +1 -1
  18. package/lib/screens/inbox/components/DialogItem.js +160 -0
  19. package/lib/screens/inbox/components/DialogItem.js.map +1 -0
  20. package/lib/screens/inbox/components/GiftedChatInboxComponent.js +313 -0
  21. package/lib/screens/inbox/components/GiftedChatInboxComponent.js.map +1 -0
  22. package/lib/screens/inbox/components/SlackMessageContainer/ImageViewerModal.js +2 -0
  23. package/lib/screens/inbox/components/SlackMessageContainer/ImageViewerModal.js.map +1 -1
  24. package/lib/screens/inbox/components/SlackMessageContainer/PaymentMessage.js +194 -0
  25. package/lib/screens/inbox/components/SlackMessageContainer/PaymentMessage.js.map +1 -0
  26. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +144 -32
  27. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
  28. package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js +3 -4
  29. package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js.map +1 -1
  30. package/lib/screens/inbox/components/SubscriptionHandler.js +22 -0
  31. package/lib/screens/inbox/components/SubscriptionHandler.js.map +1 -0
  32. package/lib/screens/inbox/components/ThreadsViewItem.js +67 -47
  33. package/lib/screens/inbox/components/ThreadsViewItem.js.map +1 -1
  34. package/lib/screens/inbox/config/config.js +4 -2
  35. package/lib/screens/inbox/config/config.js.map +1 -1
  36. package/lib/screens/inbox/containers/ConversationView.js +1098 -1093
  37. package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
  38. package/lib/screens/inbox/containers/Dialogs.js +179 -333
  39. package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
  40. package/lib/screens/inbox/containers/ThreadConversationView.js +873 -866
  41. package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
  42. package/lib/screens/inbox/containers/ThreadsView.js +81 -54
  43. package/lib/screens/inbox/containers/ThreadsView.js.map +1 -1
  44. package/lib/screens/inbox/hooks/useInboxMessages.js +31 -0
  45. package/lib/screens/inbox/hooks/useInboxMessages.js.map +1 -0
  46. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js +108 -0
  47. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js.map +1 -0
  48. package/lib/screens/inbox/workflow/dialog-threads-xstate.js +151 -0
  49. package/lib/screens/inbox/workflow/dialog-threads-xstate.js.map +1 -0
  50. package/package.json +5 -5
  51. package/CHANGELOG.md +0 -156
  52. package/jest.config.js +0 -24
  53. package/lib/screens/inbox/components/DialogsListItem.js +0 -175
  54. package/lib/screens/inbox/components/DialogsListItem.js.map +0 -1
  55. package/lib/screens/inbox/components/ServiceDialogsListItem.js +0 -165
  56. package/lib/screens/inbox/components/ServiceDialogsListItem.js.map +0 -1
  57. package/lib/screens/inbox/containers/workflow/conversation-xstate.js +0 -380
  58. package/lib/screens/inbox/containers/workflow/conversation-xstate.js.map +0 -1
  59. package/lib/screens/inbox/containers/workflow/dialogs-xstate.js +0 -235
  60. package/lib/screens/inbox/containers/workflow/dialogs-xstate.js.map +0 -1
  61. package/lib/screens/inbox/containers/workflow/thread-conversation-xstate.js +0 -438
  62. package/lib/screens/inbox/containers/workflow/thread-conversation-xstate.js.map +0 -1
  63. package/rollup.config.mjs +0 -45
  64. package/src/components/index.ts +0 -0
  65. package/src/compute.ts +0 -63
  66. package/src/index.ts +0 -7
  67. package/src/module.ts +0 -10
  68. package/src/navigation/InboxNavigation.tsx +0 -102
  69. package/src/navigation/index.ts +0 -1
  70. package/src/screens/inbox/DialogMessages.tsx +0 -21
  71. package/src/screens/inbox/DialogThreadMessages.tsx +0 -97
  72. package/src/screens/inbox/DialogThreads.tsx +0 -129
  73. package/src/screens/inbox/Inbox.tsx +0 -17
  74. package/src/screens/inbox/components/CachedImage/consts.ts +0 -6
  75. package/src/screens/inbox/components/CachedImage/index.tsx +0 -223
  76. package/src/screens/inbox/components/DialogsHeader.tsx +0 -30
  77. package/src/screens/inbox/components/DialogsListItem.tsx +0 -302
  78. package/src/screens/inbox/components/ServiceDialogsListItem.tsx +0 -287
  79. package/src/screens/inbox/components/SlackMessageContainer/ImageViewerModal.tsx +0 -113
  80. package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +0 -313
  81. package/src/screens/inbox/components/SlackMessageContainer/SlackMessage.tsx +0 -145
  82. package/src/screens/inbox/components/SlackMessageContainer/index.ts +0 -3
  83. package/src/screens/inbox/components/SupportServiceDialogsListItem.tsx +0 -283
  84. package/src/screens/inbox/components/ThreadsViewItem.tsx +0 -321
  85. package/src/screens/inbox/config/config.ts +0 -15
  86. package/src/screens/inbox/config/index.ts +0 -1
  87. package/src/screens/inbox/containers/ConversationView.tsx +0 -1782
  88. package/src/screens/inbox/containers/Dialogs.tsx +0 -544
  89. package/src/screens/inbox/containers/SupportServiceDialogs.tsx +0 -119
  90. package/src/screens/inbox/containers/ThreadConversationView.tsx +0 -1537
  91. package/src/screens/inbox/containers/ThreadsView.tsx +0 -305
  92. package/src/screens/inbox/containers/workflow/apollo/handleResult.ts +0 -20
  93. package/src/screens/inbox/containers/workflow/conversation-xstate.ts +0 -313
  94. package/src/screens/inbox/containers/workflow/dialogs-xstate.ts +0 -196
  95. package/src/screens/inbox/containers/workflow/thread-conversation-xstate.ts +0 -401
  96. package/src/screens/index.ts +0 -4
  97. package/tsconfig.json +0 -13
  98. package/webpack.config.js +0 -58
@@ -1,544 +0,0 @@
1
- import React, { useCallback, useMemo, useEffect, useState, useRef } from 'react';
2
- import {
3
- FlatList,
4
- Box,
5
- Heading,
6
- Input,
7
- InputField,
8
- Text,
9
- Icon,
10
- Center,
11
- Spinner,
12
- } from '@admin-layout/gluestack-ui-mobile';
13
- import { Ionicons } from '@expo/vector-icons';
14
- import { useSelector, useDispatch } from 'react-redux';
15
- import { useNavigation, useRoute, useIsFocused, useFocusEffect } from '@react-navigation/native';
16
- import { orderBy, uniqBy, startCase } from 'lodash-es';
17
- import { DialogsListItem } from '../components/DialogsListItem';
18
- import { ServiceDialogsListItem } from '../components/ServiceDialogsListItem';
19
- import { useGetChannelsByUserQuery, useGetChannelsByUserWithServiceChannelsQuery } from 'common/graphql';
20
- import { RoomType } from 'common';
21
- import { userSelector } from '@adminide-stack/user-auth0-client';
22
- import { CHANGE_SETTINGS_ACTION } from '@admin-layout/client';
23
- import { config } from '../config';
24
- import colors from 'tailwindcss/colors';
25
- import { dialogsXstate, Actions as DialogsActions, BaseState, MainState } from './workflow/dialogs-xstate';
26
-
27
- export interface InboxProps {
28
- channelFilters?: Record<string, unknown>;
29
- channelRole?: string;
30
- supportServices: boolean;
31
- }
32
-
33
- // Define state type for the state machine
34
- interface SafeStateType {
35
- context: {
36
- channels: any[];
37
- refreshing: boolean;
38
- loading: boolean;
39
- error: string | null;
40
- searchQuery: string;
41
- selectedChannelId: string | null;
42
- channelRole: string | null;
43
- channelFilters: Record<string, any>;
44
- supportServices: boolean;
45
- };
46
- value: string;
47
- matches?: (stateValue: string) => boolean;
48
- }
49
-
50
- // Interface for the return type to ensure proper typing
51
- type UseSafeMachineReturnType = [SafeStateType & { matches: (stateValue: string) => boolean }, (event: any) => void];
52
-
53
- // Create a safer version of useMachine to handle potential errors
54
- function useSafeMachine(machine): UseSafeMachineReturnType {
55
- // Initialize with default state
56
- const [state, setState] = useState<SafeStateType>({
57
- context: {
58
- channels: [],
59
- refreshing: false,
60
- loading: false,
61
- error: null,
62
- searchQuery: '',
63
- selectedChannelId: null,
64
- channelRole: null,
65
- channelFilters: {},
66
- supportServices: false,
67
- },
68
- value: 'idle',
69
- });
70
-
71
- // Create a safe send function
72
- const send = useCallback((event) => {
73
- try {
74
- // Log event for debugging
75
- console.log('Dialogs Event received:', event.type);
76
-
77
- // Handle specific events manually
78
- if (event.type === DialogsActions.INITIAL_CONTEXT) {
79
- setState((prev) => ({
80
- ...prev,
81
- context: {
82
- ...prev.context,
83
- channelRole: event.data?.channelRole || null,
84
- channelFilters: event.data?.channelFilters || {},
85
- supportServices: event.data?.supportServices || false,
86
- selectedChannelId: event.data?.selectedChannelId || null,
87
- },
88
- value: BaseState.FetchChannels,
89
- }));
90
- } else if (event.type === DialogsActions.SET_SEARCH_QUERY) {
91
- setState((prev) => ({
92
- ...prev,
93
- context: {
94
- ...prev.context,
95
- searchQuery: event.data?.searchQuery || '',
96
- },
97
- }));
98
- } else if (event.type === DialogsActions.REFRESH_CHANNELS) {
99
- setState((prev) => ({
100
- ...prev,
101
- context: {
102
- ...prev.context,
103
- refreshing: true,
104
- },
105
- value: MainState.RefreshChannels,
106
- }));
107
- } else if (event.type === DialogsActions.SELECT_CHANNEL) {
108
- setState((prev) => ({
109
- ...prev,
110
- context: {
111
- ...prev.context,
112
- selectedChannelId: event.data?.channelId || null,
113
- },
114
- value: MainState.SelectChannel,
115
- }));
116
- } else if (event.type === DialogsActions.START_LOADING) {
117
- setState((prev) => ({
118
- ...prev,
119
- context: {
120
- ...prev.context,
121
- loading: true,
122
- },
123
- }));
124
- } else if (event.type === DialogsActions.STOP_LOADING) {
125
- setState((prev) => ({
126
- ...prev,
127
- context: {
128
- ...prev.context,
129
- loading: false,
130
- },
131
- }));
132
- } else if (event.type === 'FETCH_CHANNELS_SUCCESS') {
133
- setState((prev) => ({
134
- ...prev,
135
- context: {
136
- ...prev.context,
137
- channels: event.data?.channels || [],
138
- loading: false,
139
- refreshing: false,
140
- },
141
- value: BaseState.Idle,
142
- }));
143
- } else if (event.type === 'REFRESH_CHANNELS_SUCCESS') {
144
- setState((prev) => ({
145
- ...prev,
146
- context: {
147
- ...prev.context,
148
- channels: event.data?.channels || [],
149
- refreshing: false,
150
- },
151
- value: BaseState.Idle,
152
- }));
153
- } else if (event.type === 'ERROR') {
154
- setState((prev) => ({
155
- ...prev,
156
- context: {
157
- ...prev.context,
158
- error: event.data?.message || 'An error occurred',
159
- loading: false,
160
- refreshing: false,
161
- },
162
- value: BaseState.Error,
163
- }));
164
- }
165
- } catch (err) {
166
- console.error('Error in send function:', err);
167
- }
168
- }, []);
169
-
170
- // Add a matches method for state compatibility
171
- const stateWithMatches = useMemo(() => {
172
- return {
173
- ...state,
174
- matches: (value: string) => state.value === value,
175
- };
176
- }, [state]);
177
-
178
- // Return as a tuple to match useMachine API
179
- return [stateWithMatches, send];
180
- }
181
-
182
- const DialogsComponent = (props: InboxProps) => {
183
- const { channelFilters: channelFilterProp, channelRole, supportServices } = props;
184
- const channelFilters = { ...channelFilterProp };
185
- channelFilters.type = channelFilters?.type ?? RoomType.Direct;
186
- const { params } = useRoute<any>();
187
- const auth = useSelector(userSelector);
188
- const dispatch = useDispatch();
189
- const navigation = useNavigation<any>();
190
- const isFocused = useIsFocused();
191
- const isMountedRef = useRef(true);
192
-
193
- // Use our safer custom implementation instead of the problematic useMachine
194
- const [state, send] = useSafeMachine(dialogsXstate);
195
-
196
- // Define safe functions first to avoid "used before declaration" errors
197
- const safeContext = useCallback(() => {
198
- try {
199
- return state?.context || {};
200
- } catch (error) {
201
- console.error('Error accessing state.context:', error);
202
- return {};
203
- }
204
- }, [state]);
205
-
206
- const safeContextProperty = useCallback(
207
- (property, defaultValue = null) => {
208
- try {
209
- return state?.context?.[property] ?? defaultValue;
210
- } catch (error) {
211
- console.error(`Error accessing state.context.${property}:`, error);
212
- return defaultValue;
213
- }
214
- },
215
- [state],
216
- );
217
-
218
- const safeMatches = useCallback(
219
- (stateValue) => {
220
- try {
221
- return state?.matches?.(stateValue) || false;
222
- } catch (error) {
223
- console.error(`Error calling state.matches with ${stateValue}:`, error);
224
- return false;
225
- }
226
- },
227
- [state],
228
- );
229
-
230
- const safeSend = useCallback(
231
- (event) => {
232
- try {
233
- send(event);
234
- } catch (error) {
235
- console.error('Error sending event to state machine:', error, event);
236
- }
237
- },
238
- [send],
239
- );
240
-
241
- // Use a ref to track the current machine snapshot for safer access
242
- const stateRef = useRef(state);
243
-
244
- // Keep the ref updated with the latest snapshot
245
- useEffect(() => {
246
- stateRef.current = state;
247
- }, [state]);
248
-
249
- // Use cleanup function to prevent setting state after unmount
250
- useEffect(() => {
251
- return () => {
252
- isMountedRef.current = false;
253
- };
254
- }, []);
255
-
256
- const {
257
- data: userChannels,
258
- loading: userChannelsLoading,
259
- refetch: getChannelsRefetch,
260
- } = useGetChannelsByUserWithServiceChannelsQuery({
261
- variables: {
262
- role: channelRole,
263
- criteria: channelFilters,
264
- supportServices: supportServices ? true : false,
265
- supportServiceCriteria: {
266
- type: RoomType.Service,
267
- },
268
- },
269
- onCompleted: (data) => {
270
- if (isMountedRef.current) {
271
- const allChannels = [...(data?.supportServiceChannels ?? []), ...(data?.channelsByUser ?? [])];
272
- safeSend({
273
- type: 'FETCH_CHANNELS_SUCCESS',
274
- data: { channels: allChannels },
275
- });
276
- }
277
- },
278
- onError: (error) => {
279
- if (isMountedRef.current) {
280
- safeSend({
281
- type: 'ERROR',
282
- data: { message: error.message },
283
- });
284
- }
285
- },
286
- });
287
-
288
- // Set initial context once on mount, but don't fetch data as useFocusEffect will handle it
289
- useEffect(() => {
290
- console.log('Setting initial context');
291
- // Only set the initial context with configuration, but don't trigger data fetching
292
- // This prevents double fetching with useFocusEffect
293
- safeSend({
294
- type: DialogsActions.INITIAL_CONTEXT,
295
- data: {
296
- channelRole,
297
- channelFilters: channelFiltersRef.current,
298
- supportServices,
299
- selectedChannelId: params?.channelId,
300
- },
301
- });
302
- // eslint-disable-next-line react-hooks/exhaustive-deps
303
- }, []); // Empty dependency array ensures this runs only once on mount
304
-
305
- // Ref to track if we've already refreshed to prevent infinite loop
306
- const hasRefreshedRef = useRef(false);
307
- // Ref to store the current channelFilters to detect real changes
308
- const channelFiltersRef = useRef(channelFilters);
309
-
310
- // Shared function to handle channel refreshing
311
- const refreshChannels = useCallback(() => {
312
- // Skip if already refreshing to prevent loops
313
- if (safeContextProperty('refreshing', false)) {
314
- console.log('Skipping refresh - already in progress');
315
- return Promise.resolve();
316
- }
317
-
318
- console.log('Starting channel refresh');
319
-
320
- // Start refreshing
321
- safeSend({
322
- type: DialogsActions.REFRESH_CHANNELS,
323
- });
324
-
325
- // Use ref for filters to avoid dependency cycles
326
- const currentFilters = channelFiltersRef.current;
327
-
328
- // Fetch the channels
329
- return getChannelsRefetch({
330
- role: channelRole,
331
- criteria: currentFilters,
332
- supportServices: supportServices ? true : false,
333
- supportServiceCriteria: {
334
- type: RoomType.Service,
335
- },
336
- })
337
- .then((data) => {
338
- if (isMountedRef.current) {
339
- const allChannels = [
340
- ...(data?.data?.supportServiceChannels ?? []),
341
- ...(data?.data?.channelsByUser ?? []),
342
- ];
343
- console.log(`Refresh completed, found ${allChannels.length} channels`);
344
- safeSend({
345
- type: 'REFRESH_CHANNELS_SUCCESS',
346
- data: { channels: allChannels },
347
- });
348
- }
349
- })
350
- .catch((error) => {
351
- if (isMountedRef.current) {
352
- console.error('Channel refresh error:', error.message);
353
- safeSend({
354
- type: 'ERROR',
355
- data: { message: error.message },
356
- });
357
- }
358
- });
359
- }, [channelRole, supportServices, getChannelsRefetch, safeSend, safeContextProperty]);
360
-
361
- // Update the channelFiltersRef when channelFilters changes
362
- useEffect(() => {
363
- const filtersChanged = JSON.stringify(channelFiltersRef.current) !== JSON.stringify(channelFilters);
364
- if (filtersChanged) {
365
- console.log('Channel filters changed, updating ref');
366
- channelFiltersRef.current = channelFilters;
367
-
368
- // Only refresh if already mounted and initialized
369
- if (isMountedRef.current && safeContextProperty('channelRole') !== null) {
370
- console.log('Refreshing due to filter change');
371
- refreshChannels();
372
- }
373
- }
374
- }, [channelFilters, refreshChannels, safeContextProperty]);
375
-
376
- // Handle focus effects
377
- useFocusEffect(
378
- useCallback(() => {
379
- if (!isFocused) return;
380
-
381
- console.log('Screen focused, checking if refresh needed');
382
-
383
- // Only refresh on focus if we're not already loading and haven't refreshed
384
- if (isMountedRef.current && !hasRefreshedRef.current) {
385
- console.log('Refreshing on focus');
386
- hasRefreshedRef.current = true;
387
- refreshChannels();
388
- }
389
-
390
- return () => {
391
- // Reset the ref when the screen loses focus
392
- console.log('Screen unfocused, resetting refresh state');
393
- hasRefreshedRef.current = false;
394
- };
395
- }, [isFocused, refreshChannels]),
396
- );
397
-
398
- const handleRefresh = useCallback(() => {
399
- // Don't allow manual refresh while already refreshing
400
- if (safeContextProperty('refreshing', false)) {
401
- console.log('Manual refresh ignored - refresh already in progress');
402
- return;
403
- }
404
-
405
- console.log('Manual refresh triggered');
406
- refreshChannels();
407
- }, [refreshChannels, safeContextProperty]);
408
-
409
- const channels = React.useMemo(() => {
410
- const allChannels = [...(userChannels?.supportServiceChannels ?? []), ...(userChannels?.channelsByUser ?? [])];
411
- let uChannels: any =
412
- allChannels?.filter((c: any) =>
413
- c.members.some((u: any) => u !== null && u?.user?.id != auth?.id && u.user.__typename == 'UserAccount'),
414
- ) ?? [];
415
- return (uChannels && orderBy(uChannels, ['updatedAt'], ['desc'])) || [];
416
- }, [userChannels, auth?.id]);
417
-
418
- const handleSelectChannel = useCallback(
419
- (id: any, title: any) => {
420
- safeSend({
421
- type: DialogsActions.SELECT_CHANNEL,
422
- data: { channelId: id },
423
- });
424
-
425
- if (params?.channelId) {
426
- navigation.navigate(config.INBOX_MESSEGE_PATH as any, {
427
- channelId: params?.channelId,
428
- role: params?.role,
429
- title: params?.title ?? null,
430
- hideTabBar: true,
431
- });
432
- } else {
433
- navigation.navigate(config.INBOX_MESSEGE_PATH as any, {
434
- channelId: id,
435
- role: channelRole,
436
- title: title,
437
- hideTabBar: true,
438
- });
439
- }
440
- },
441
- [params, navigation, channelRole, safeSend],
442
- );
443
-
444
- const handleSelectServiceChannel = useCallback(
445
- (id: any, title: any, postParentId: any) => {
446
- safeSend({
447
- type: DialogsActions.SELECT_CHANNEL,
448
- data: { channelId: id },
449
- });
450
-
451
- if (params?.channelId) {
452
- navigation.navigate(
453
- params?.postParentId || params?.postParentId == 0
454
- ? config.THREAD_MESSEGE_PATH
455
- : (config.THREADS_PATH as any),
456
- {
457
- channelId: params?.channelId,
458
- role: params?.role,
459
- title: params?.title ?? null,
460
- postParentId: params?.postParentId,
461
- hideTabBar: true,
462
- },
463
- );
464
- } else {
465
- navigation.navigate(
466
- postParentId || postParentId == 0 ? config.THREAD_MESSEGE_PATH : (config.THREADS_PATH as any),
467
- {
468
- channelId: id,
469
- role: channelRole,
470
- title: title,
471
- postParentId: postParentId,
472
- hideTabBar: true,
473
- },
474
- );
475
- }
476
- },
477
- [params, navigation, channelRole, safeSend],
478
- );
479
-
480
- const searchQuery = safeContextProperty('searchQuery', '');
481
-
482
- return (
483
- <Box className="p-2">
484
- <FlatList
485
- data={channels && channels?.length > 0 ? channels : []}
486
- onRefresh={handleRefresh}
487
- refreshing={safeContextProperty('refreshing', false)}
488
- contentContainerStyle={{ minHeight: '100%' }}
489
- ItemSeparatorComponent={() => <Box className="h-0.5 bg-gray-200" />}
490
- renderItem={({ item: channel }: any) =>
491
- channel?.type === RoomType.Service ? (
492
- <ServiceDialogsListItem
493
- onOpen={handleSelectServiceChannel}
494
- currentUser={auth}
495
- channel={channel}
496
- refreshing={safeContextProperty('refreshing', false)}
497
- selectedChannelId={safeContextProperty('selectedChannelId', params?.channelId)}
498
- role={channelRole}
499
- />
500
- ) : (
501
- <DialogsListItem
502
- onOpen={handleSelectChannel}
503
- currentUser={auth}
504
- channel={channel}
505
- selectedChannelId={safeContextProperty('selectedChannelId', params?.channelId)}
506
- />
507
- )
508
- }
509
- ListEmptyComponent={() => (
510
- <>
511
- {userChannelsLoading || safeContextProperty('loading', false) ? (
512
- <Center className="flex-1 justify-center items-center">
513
- <Spinner color={colors.blue[500]} />
514
- </Center>
515
- ) : (
516
- <Box className="p-5">
517
- <Heading>Chat</Heading>
518
- <Input className={`h-[50] mt-3 rounded-[50] border-gray-200 border `}>
519
- <InputField
520
- placeholder="Search"
521
- value={searchQuery}
522
- onChangeText={(text) =>
523
- safeSend({
524
- type: DialogsActions.SET_SEARCH_QUERY,
525
- data: { searchQuery: text },
526
- })
527
- }
528
- />
529
- </Input>
530
- <Center className="mt-6">
531
- <Ionicons name="chatbubbles" size={50} />
532
- <Text>You don't have any messages yet!</Text>
533
- </Center>
534
- </Box>
535
- )}
536
- </>
537
- )}
538
- keyExtractor={(item, index) => 'key' + index}
539
- />
540
- </Box>
541
- );
542
- };
543
-
544
- export const Dialogs = React.memo(DialogsComponent);
@@ -1,119 +0,0 @@
1
- import React, { useCallback, useState } from 'react';
2
- import { FlatList, Box } from '@admin-layout/gluestack-ui-mobile';
3
- import { useSelector, useDispatch } from 'react-redux';
4
- import { useNavigation, useRoute, useIsFocused, useFocusEffect } from '@react-navigation/native';
5
- import { useSupportServiceChannelsQuery } from 'common/graphql';
6
- import { userSelector } from '@adminide-stack/user-auth0-client';
7
- import { CHANGE_SETTINGS_ACTION } from '@admin-layout/client';
8
- import { SupportServiceDialogsListItem } from '../components/SupportServiceDialogsListItem';
9
- import { config } from '../config';
10
-
11
- export interface SupportServiceInboxProps {
12
- channelFilters?: Record<string, unknown>;
13
- channelRole?: string;
14
- }
15
-
16
- const SupportServiceDialogsComponent = (props: SupportServiceInboxProps) => {
17
- const { channelFilters, channelRole } = props;
18
- const { params } = useRoute<any>();
19
- const auth = useSelector(userSelector);
20
- const dispatch = useDispatch();
21
- const navigation = useNavigation<any>();
22
- const isFocused = useIsFocused();
23
- const [refreshing, setRefresh] = useState<boolean>(false);
24
- // const [userDirectChannel, setUserDirectChannel] = useState<any>([]);
25
-
26
- const {
27
- data: serviceChannels,
28
- loading: serviceChannelsLoading,
29
- refetch: getServiceChannelsRefetch,
30
- } = useSupportServiceChannelsQuery({
31
- variables: {
32
- criteria: { type: 'SERVICE' },
33
- },
34
- onCompleted: (data: any) => {
35
- //setRefresh(false);
36
- },
37
- });
38
-
39
- useFocusEffect(
40
- React.useCallback(() => {
41
- // Do something when the screen is focused
42
- setRefresh(false);
43
- getServiceChannelsRefetch({ criteria: { type: 'SERVICE' } });
44
-
45
- return () => {
46
- // Do something when the screen is unfocused
47
- // Useful for cleanup functions
48
- };
49
- }, []),
50
- );
51
-
52
- const channels = React.useMemo(() => {
53
- if (!serviceChannels?.supportServiceChannels?.length) return null;
54
- let uChannels: any =
55
- serviceChannels?.supportServiceChannels?.filter((c: any) =>
56
- c.members.some((u: any) => u !== null && u.user.__typename == 'UserAccount'),
57
- ) ?? [];
58
- return uChannels || [];
59
- }, [serviceChannels]);
60
-
61
- const handleSelectChannel = useCallback((id: any, title: any, postParentId: any) => {
62
- if (params?.channelId) {
63
- navigation.navigate(
64
- params?.postParentId || params?.postParentId == 0
65
- ? config.THREAD_MESSEGE_PATH
66
- : (config.THREADS_PATH as any),
67
- {
68
- channelId: params?.channelId,
69
- role: params?.role,
70
- title: params?.title ?? null,
71
- postParentId: params?.postParentId,
72
- hideTabBar: true,
73
- },
74
- );
75
- } else {
76
- navigation.navigate(
77
- postParentId || postParentId == 0 ? config.THREAD_MESSEGE_PATH : (config.THREADS_PATH as any),
78
- {
79
- channelId: id,
80
- role: channelRole,
81
- title: title,
82
- postParentId: postParentId,
83
- hideTabBar: true,
84
- },
85
- );
86
- }
87
- }, []);
88
-
89
- const handleRefresh = useCallback(() => {
90
- //if(userChannels?.channelsByUser?.length != channels?.length)setRefresh(true);
91
- setRefresh(true);
92
- getServiceChannelsRefetch({ criteria: { type: 'SERVICE' } })?.then((res: any) => setRefresh(false));
93
- }, []);
94
-
95
- return (
96
- <Box className="p-2 pb-0">
97
- <FlatList
98
- data={channels && channels?.length > 0 ? channels : []}
99
- onRefresh={handleRefresh}
100
- refreshing={refreshing}
101
- contentContainerStyle={{}}
102
- ItemSeparatorComponent={() => <Box className="h-0.5 bg-gray-200" />}
103
- renderItem={({ item: channel }) => (
104
- <SupportServiceDialogsListItem
105
- onOpen={handleSelectChannel}
106
- currentUser={auth}
107
- channel={channel}
108
- refreshing={refreshing}
109
- selectedChannelId={params?.channelId}
110
- role={channelRole}
111
- />
112
- )}
113
- keyExtractor={(item, index) => 'support-service-key' + index}
114
- />
115
- </Box>
116
- );
117
- };
118
-
119
- export const SupportServiceDialogs = React.memo(SupportServiceDialogsComponent);