@messenger-box/platform-mobile 10.0.3-alpha.22 → 10.0.3-alpha.23

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 (29) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/screens/inbox/DialogThreads.js +52 -12
  3. package/lib/screens/inbox/DialogThreads.js.map +1 -1
  4. package/lib/screens/inbox/components/ThreadsViewItem.js +66 -44
  5. package/lib/screens/inbox/components/ThreadsViewItem.js.map +1 -1
  6. package/lib/screens/inbox/containers/ConversationView.js +36 -34
  7. package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
  8. package/lib/screens/inbox/containers/Dialogs.js +82 -37
  9. package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
  10. package/lib/screens/inbox/containers/ThreadConversationView.js +282 -219
  11. package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
  12. package/lib/screens/inbox/containers/ThreadsView.js +83 -50
  13. package/lib/screens/inbox/containers/ThreadsView.js.map +1 -1
  14. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js +108 -0
  15. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js.map +1 -0
  16. package/lib/screens/inbox/workflow/dialog-threads-xstate.js +151 -0
  17. package/lib/screens/inbox/workflow/dialog-threads-xstate.js.map +1 -0
  18. package/package.json +2 -2
  19. package/src/screens/inbox/DialogThreads.tsx +49 -53
  20. package/src/screens/inbox/components/SmartLoader.tsx +61 -0
  21. package/src/screens/inbox/components/ThreadsViewItem.tsx +177 -265
  22. package/src/screens/inbox/containers/ConversationView.tsx +32 -30
  23. package/src/screens/inbox/containers/Dialogs.tsx +57 -22
  24. package/src/screens/inbox/containers/ThreadConversationView.tsx +467 -484
  25. package/src/screens/inbox/containers/ThreadsView.tsx +102 -183
  26. package/src/screens/inbox/hooks/useSafeDialogThreadsMachine.ts +136 -0
  27. package/src/screens/inbox/index.ts +37 -0
  28. package/src/screens/inbox/machines/threadsMachine.ts +147 -0
  29. package/src/screens/inbox/workflow/dialog-threads-xstate.ts +163 -0
@@ -7,9 +7,17 @@ import { useFocusEffect } from '@react-navigation/native';
7
7
  import { useSelector } from 'react-redux';
8
8
  import { config } from './config';
9
9
  import colors from 'tailwindcss/colors';
10
+ import { useSafeDialogThreadsMachine } from './hooks/useSafeDialogThreadsMachine';
11
+ import { Actions, BaseState } from './workflow/dialog-threads-xstate';
10
12
  const { MESSAGES_PER_PAGE } = config;
11
13
 
12
14
  export function DialogThreads({ channelId, postParentId, role }) {
15
+ // Use the XState machine for state management
16
+ const [state, send] = useSafeDialogThreadsMachine();
17
+ const { context, value } = state;
18
+ const { channelsDetail, loading, error } = context;
19
+
20
+ // Fetch channel details
13
21
  const {
14
22
  data: channelData,
15
23
  loading: channelLoading,
@@ -20,6 +28,7 @@ export function DialogThreads({ channelId, postParentId, role }) {
20
28
  },
21
29
  });
22
30
 
31
+ // Fetch thread messages
23
32
  const {
24
33
  data: threadsData,
25
34
  loading: threadLoading,
@@ -33,14 +42,46 @@ export function DialogThreads({ channelId, postParentId, role }) {
33
42
  limit: MESSAGES_PER_PAGE,
34
43
  repliesLimit2: 5,
35
44
  },
36
- // fetchPolicy: 'cache-and-network',
37
45
  });
38
46
 
39
- const channelsDetail = React.useMemo(() => {
40
- if (!channelData?.viewChannelDetail) return null;
41
- return channelData?.viewChannelDetail;
47
+ // Initialize the machine with props
48
+ React.useEffect(() => {
49
+ send({
50
+ type: Actions.INITIALIZE,
51
+ data: { channelId, postParentId, role },
52
+ });
53
+ }, [channelId, postParentId, role]);
54
+
55
+ // Update channel detail in state when data changes
56
+ React.useEffect(() => {
57
+ if (channelData?.viewChannelDetail) {
58
+ send({
59
+ type: Actions.SET_CHANNEL_DETAIL,
60
+ data: { channelsDetail: channelData.viewChannelDetail },
61
+ });
62
+ }
42
63
  }, [channelData]);
43
64
 
65
+ // Update thread data in state when data changes
66
+ React.useEffect(() => {
67
+ if (threadsData) {
68
+ send({
69
+ type: Actions.SET_THREADS,
70
+ data: { threadData: threadsData?.threadMessages?.data || [] },
71
+ });
72
+ }
73
+ }, [threadsData]);
74
+
75
+ // Handle errors
76
+ React.useEffect(() => {
77
+ if (threadsError) {
78
+ send({
79
+ type: Actions.ERROR,
80
+ data: { error: threadsError },
81
+ });
82
+ }
83
+ }, [threadsError]);
84
+
44
85
  const refetchChannelDetail = React.useCallback(
45
86
  (id: string) => {
46
87
  return channelRefetch({ id: id?.toString() });
@@ -57,24 +98,18 @@ export function DialogThreads({ channelId, postParentId, role }) {
57
98
  );
58
99
 
59
100
  return (
60
- // <Box bg={'white'} flex={1} pt={5}>
61
101
  <>
62
- {channelLoading ? (
102
+ {state.matches(BaseState.LoadingChannel) || channelLoading ? (
63
103
  <Spinner color={colors.blue[500]} />
64
104
  ) : (
65
105
  <>
66
- <Box
67
- // $dark-borderColor="$coolGray600"
68
- // $dark-backgroundColor="$trueGray700"
69
- // $light-backgroundColor="$trueGray50"
70
- className="flex-1 bg-gray-200 dark:border-gray-500 dark:bg-gray-500 "
71
- >
106
+ <Box className="flex-1 bg-gray-200 dark:border-gray-500 dark:bg-gray-500">
72
107
  <ThreadsView
73
108
  data={threadsData}
74
- loading={threadLoading}
109
+ loading={threadLoading || state.matches(BaseState.LoadingThreads)}
75
110
  refetch={threadsRefetch}
76
111
  subscribeToMore={threadsSubscribeToMore}
77
- error={threadsError}
112
+ error={error || threadsError}
78
113
  channelId={channelId}
79
114
  role={role}
80
115
  channelsDetail={channelsDetail}
@@ -85,45 +120,6 @@ export function DialogThreads({ channelId, postParentId, role }) {
85
120
  )}
86
121
  </>
87
122
  );
88
-
89
- // return (
90
- // // <Box bg={'white'} flex={1} pt={5}>
91
- // <>
92
- // {channelLoading ? (
93
- // <Spinner />
94
- // ) : (
95
- // <>
96
- // {postParentId || postParentId == 0 ? (
97
- // <Box bg={'white'} flex={1}>
98
- // <ThreadConversationView
99
- // channelId={channelId}
100
- // postParentId={postParentId}
101
- // channelsDetail={channelsDetail}
102
- // refetchChannelDetail={refetchChannelDetail}
103
- // />
104
- // </Box>
105
- // ) : (
106
- // <Box
107
- // flex={1}
108
- // _dark={{
109
- // borderColor: 'coolGray.600',
110
- // backgroundColor: 'gray.700',
111
- // }}
112
- // _light={{
113
- // backgroundColor: 'gray.50',
114
- // }}
115
- // >
116
- // <ThreadsView
117
- // channelId={channelId}
118
- // channelsDetail={channelsDetail}
119
- // refetchChannelDetail={refetchChannelDetail}
120
- // />
121
- // </Box>
122
- // )}
123
- // </>
124
- // )}
125
- // </>
126
- // );
127
123
  }
128
124
 
129
125
  export default DialogThreads;
@@ -0,0 +1,61 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { Box, Spinner, Text, VStack, Button, ButtonText } from '@admin-layout/gluestack-ui-mobile';
3
+ import colors from 'tailwindcss/colors';
4
+
5
+ interface SmartLoaderProps {
6
+ isLoading: boolean;
7
+ timeoutMs?: number;
8
+ message?: string;
9
+ onRetry?: () => void;
10
+ }
11
+
12
+ /**
13
+ * SmartLoader component that automatically shows a timeout message
14
+ * if loading takes too long, preventing infinite loading states
15
+ */
16
+ export const SmartLoader: React.FC<SmartLoaderProps> = ({
17
+ isLoading,
18
+ timeoutMs = 20000, // Default 20 seconds
19
+ message = 'Taking longer than expected...',
20
+ onRetry,
21
+ }) => {
22
+ const [showTimeout, setShowTimeout] = useState(false);
23
+
24
+ useEffect(() => {
25
+ if (!isLoading) {
26
+ setShowTimeout(false);
27
+ return;
28
+ }
29
+
30
+ const timeoutId = setTimeout(() => {
31
+ if (isLoading) {
32
+ setShowTimeout(true);
33
+ }
34
+ }, timeoutMs);
35
+
36
+ return () => clearTimeout(timeoutId);
37
+ }, [isLoading, timeoutMs]);
38
+
39
+ if (!isLoading) return null;
40
+
41
+ return (
42
+ <Box className="flex-1 bg-gray-100 dark:bg-gray-800 items-center justify-center">
43
+ <VStack space="md" className="items-center">
44
+ <Spinner color={colors.blue[500]} size="large" />
45
+
46
+ {showTimeout && (
47
+ <VStack space="sm" className="p-4 items-center">
48
+ <Text className="text-gray-700 dark:text-gray-300 text-center">{message}</Text>
49
+ {onRetry && (
50
+ <Button onPress={onRetry} className="bg-blue-500 mt-3 rounded-full">
51
+ <ButtonText>Try Again</ButtonText>
52
+ </Button>
53
+ )}
54
+ </VStack>
55
+ )}
56
+ </VStack>
57
+ </Box>
58
+ );
59
+ };
60
+
61
+ export default SmartLoader;