@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.
- package/CHANGELOG.md +4 -0
- package/lib/screens/inbox/DialogThreads.js +52 -12
- package/lib/screens/inbox/DialogThreads.js.map +1 -1
- package/lib/screens/inbox/components/ThreadsViewItem.js +66 -44
- package/lib/screens/inbox/components/ThreadsViewItem.js.map +1 -1
- package/lib/screens/inbox/containers/ConversationView.js +36 -34
- package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
- package/lib/screens/inbox/containers/Dialogs.js +82 -37
- package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
- package/lib/screens/inbox/containers/ThreadConversationView.js +282 -219
- package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
- package/lib/screens/inbox/containers/ThreadsView.js +83 -50
- package/lib/screens/inbox/containers/ThreadsView.js.map +1 -1
- package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js +108 -0
- package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js.map +1 -0
- package/lib/screens/inbox/workflow/dialog-threads-xstate.js +151 -0
- package/lib/screens/inbox/workflow/dialog-threads-xstate.js.map +1 -0
- package/package.json +2 -2
- package/src/screens/inbox/DialogThreads.tsx +49 -53
- package/src/screens/inbox/components/SmartLoader.tsx +61 -0
- package/src/screens/inbox/components/ThreadsViewItem.tsx +177 -265
- package/src/screens/inbox/containers/ConversationView.tsx +32 -30
- package/src/screens/inbox/containers/Dialogs.tsx +57 -22
- package/src/screens/inbox/containers/ThreadConversationView.tsx +467 -484
- package/src/screens/inbox/containers/ThreadsView.tsx +102 -183
- package/src/screens/inbox/hooks/useSafeDialogThreadsMachine.ts +136 -0
- package/src/screens/inbox/index.ts +37 -0
- package/src/screens/inbox/machines/threadsMachine.ts +147 -0
- 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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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;
|