@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,4 +1,4 @@
1
- import React__default,{useRef,useCallback,useEffect,useState,useMemo}from'react';import {Box,FlatList,Center,Spinner,Heading,Input,InputField,Text}from'@admin-layout/gluestack-ui-mobile';import {Ionicons}from'@expo/vector-icons';import {useSelector,useDispatch}from'react-redux';import {useRoute,useNavigation,useIsFocused,useFocusEffect}from'@react-navigation/native';import {orderBy}from'lodash-es';import {DialogsListItem}from'../components/DialogsListItem.js';import {ServiceDialogsListItem}from'../components/ServiceDialogsListItem.js';import {useGetChannelsByUserWithServiceChannelsQuery}from'common/graphql';import {RoomType}from'common';import {userSelector}from'@adminide-stack/user-auth0-client';import {config}from'../config/config.js';import colors from'tailwindcss/colors';import {Actions,BaseState,MainState}from'./workflow/dialogs-xstate.js';var __defProp = Object.defineProperty;
1
+ import React__default,{useState,useRef,useCallback,useMemo,useEffect}from'react';import {Center,Spinner,Text,Box,Heading,Input,InputField,FlatList}from'@admin-layout/gluestack-ui-mobile';import {Ionicons}from'@expo/vector-icons';import {useSelector,shallowEqual}from'react-redux';import {useRoute,useNavigation,useFocusEffect}from'@react-navigation/native';import {DialogItem}from'../components/DialogItem.js';import {useGetChannelsByUserWithLastMessageQuery}from'common/graphql';import {RoomType}from'common';import {userSelector}from'@adminide-stack/user-auth0-client';import {config}from'../config/config.js';import colors from'tailwindcss/colors';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -17,122 +17,6 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- function useSafeMachine(machine) {
21
- const [state, setState] = useState({
22
- context: {
23
- channels: [],
24
- refreshing: false,
25
- loading: false,
26
- error: null,
27
- searchQuery: "",
28
- selectedChannelId: null,
29
- channelRole: null,
30
- channelFilters: {},
31
- supportServices: false
32
- },
33
- value: "idle"
34
- });
35
- const send = useCallback((event) => {
36
- try {
37
- console.log("Dialogs Event received:", event.type);
38
- if (event.type === Actions.INITIAL_CONTEXT) {
39
- setState((prev) => {
40
- var _a, _b, _c, _d;
41
- return __spreadProps(__spreadValues({}, prev), {
42
- context: __spreadProps(__spreadValues({}, prev.context), {
43
- channelRole: ((_a = event.data) == null ? void 0 : _a.channelRole) || null,
44
- channelFilters: ((_b = event.data) == null ? void 0 : _b.channelFilters) || {},
45
- supportServices: ((_c = event.data) == null ? void 0 : _c.supportServices) || false,
46
- selectedChannelId: ((_d = event.data) == null ? void 0 : _d.selectedChannelId) || null
47
- }),
48
- value: BaseState.FetchChannels
49
- });
50
- });
51
- } else if (event.type === Actions.SET_SEARCH_QUERY) {
52
- setState((prev) => {
53
- var _a;
54
- return __spreadProps(__spreadValues({}, prev), {
55
- context: __spreadProps(__spreadValues({}, prev.context), {
56
- searchQuery: ((_a = event.data) == null ? void 0 : _a.searchQuery) || ""
57
- })
58
- });
59
- });
60
- } else if (event.type === Actions.REFRESH_CHANNELS) {
61
- setState((prev) => __spreadProps(__spreadValues({}, prev), {
62
- context: __spreadProps(__spreadValues({}, prev.context), {
63
- refreshing: true
64
- }),
65
- value: MainState.RefreshChannels
66
- }));
67
- } else if (event.type === Actions.SELECT_CHANNEL) {
68
- setState((prev) => {
69
- var _a;
70
- return __spreadProps(__spreadValues({}, prev), {
71
- context: __spreadProps(__spreadValues({}, prev.context), {
72
- selectedChannelId: ((_a = event.data) == null ? void 0 : _a.channelId) || null
73
- }),
74
- value: MainState.SelectChannel
75
- });
76
- });
77
- } else if (event.type === Actions.START_LOADING) {
78
- setState((prev) => __spreadProps(__spreadValues({}, prev), {
79
- context: __spreadProps(__spreadValues({}, prev.context), {
80
- loading: true
81
- })
82
- }));
83
- } else if (event.type === Actions.STOP_LOADING) {
84
- setState((prev) => __spreadProps(__spreadValues({}, prev), {
85
- context: __spreadProps(__spreadValues({}, prev.context), {
86
- loading: false
87
- })
88
- }));
89
- } else if (event.type === "FETCH_CHANNELS_SUCCESS") {
90
- setState((prev) => {
91
- var _a;
92
- return __spreadProps(__spreadValues({}, prev), {
93
- context: __spreadProps(__spreadValues({}, prev.context), {
94
- channels: ((_a = event.data) == null ? void 0 : _a.channels) || [],
95
- loading: false,
96
- refreshing: false
97
- }),
98
- value: BaseState.Idle
99
- });
100
- });
101
- } else if (event.type === "REFRESH_CHANNELS_SUCCESS") {
102
- setState((prev) => {
103
- var _a;
104
- return __spreadProps(__spreadValues({}, prev), {
105
- context: __spreadProps(__spreadValues({}, prev.context), {
106
- channels: ((_a = event.data) == null ? void 0 : _a.channels) || [],
107
- refreshing: false
108
- }),
109
- value: BaseState.Idle
110
- });
111
- });
112
- } else if (event.type === "ERROR") {
113
- setState((prev) => {
114
- var _a;
115
- return __spreadProps(__spreadValues({}, prev), {
116
- context: __spreadProps(__spreadValues({}, prev.context), {
117
- error: ((_a = event.data) == null ? void 0 : _a.message) || "An error occurred",
118
- loading: false,
119
- refreshing: false
120
- }),
121
- value: BaseState.Error
122
- });
123
- });
124
- }
125
- } catch (err) {
126
- console.error("Error in send function:", err);
127
- }
128
- }, []);
129
- const stateWithMatches = useMemo(() => {
130
- return __spreadProps(__spreadValues({}, state), {
131
- matches: (value) => state.value === value
132
- });
133
- }, [state]);
134
- return [stateWithMatches, send];
135
- }
136
20
  const DialogsComponent = (props) => {
137
21
  var _a;
138
22
  const {
@@ -141,251 +25,213 @@ const DialogsComponent = (props) => {
141
25
  supportServices
142
26
  } = props;
143
27
  const channelFilters = __spreadValues({}, channelFilterProp);
144
- channelFilters.type = (_a = channelFilters == null ? void 0 : channelFilters.type) != null ? _a : RoomType.Direct;
28
+ const channelType = (_a = channelFilters == null ? void 0 : channelFilters.type) != null ? _a : RoomType.Direct;
29
+ channelFilters.type = supportServices ? [channelType, RoomType.Service] : channelType;
145
30
  const {
146
31
  params
147
32
  } = useRoute();
148
- const auth = useSelector(userSelector);
149
- useDispatch();
33
+ const auth = useSelector(userSelector, shallowEqual);
150
34
  const navigation = useNavigation();
151
- const isFocused = useIsFocused();
35
+ const [searchQuery, setSearchQuery] = useState("");
152
36
  const isMountedRef = useRef(true);
153
- const [state, send] = useSafeMachine();
154
- useCallback(() => {
155
- try {
156
- return (state == null ? void 0 : state.context) || {};
157
- } catch (error) {
158
- console.error("Error accessing state.context:", error);
159
- return {};
160
- }
161
- }, [state]);
162
- const safeContextProperty = useCallback((property, defaultValue = null) => {
163
- var _a2, _b;
164
- try {
165
- return (_b = (_a2 = state == null ? void 0 : state.context) == null ? void 0 : _a2[property]) != null ? _b : defaultValue;
166
- } catch (error) {
167
- console.error(`Error accessing state.context.${property}:`, error);
168
- return defaultValue;
169
- }
170
- }, [state]);
171
- useCallback((stateValue) => {
172
- var _a2;
173
- try {
174
- return ((_a2 = state == null ? void 0 : state.matches) == null ? void 0 : _a2.call(state, stateValue)) || false;
175
- } catch (error) {
176
- console.error(`Error calling state.matches with ${stateValue}:`, error);
177
- return false;
178
- }
179
- }, [state]);
180
- const safeSend = useCallback((event) => {
181
- try {
182
- send(event);
183
- } catch (error) {
184
- console.error("Error sending event to state machine:", error, event);
185
- }
186
- }, [send]);
187
- const stateRef = useRef(state);
188
- useEffect(() => {
189
- stateRef.current = state;
190
- }, [state]);
191
- useEffect(() => {
192
- return () => {
193
- isMountedRef.current = false;
194
- };
195
- }, []);
37
+ const focusRefreshRef = useRef(null);
38
+ const lastRefreshTimeRef = useRef(Date.now());
39
+ const MIN_REFRESH_INTERVAL = 2e3;
40
+ const lastNavigationTimestamp = useRef(0);
41
+ const activeChannelRef = useRef(null);
42
+ const resetActiveChannelTimeoutRef = useRef(null);
196
43
  const {
197
- data: userChannels,
198
- loading: userChannelsLoading,
199
- refetch: getChannelsRefetch
200
- } = useGetChannelsByUserWithServiceChannelsQuery({
44
+ data,
45
+ loading,
46
+ refetch,
47
+ fetchMore,
48
+ subscribeToMore
49
+ } = useGetChannelsByUserWithLastMessageQuery({
201
50
  variables: {
202
51
  role: channelRole,
203
52
  criteria: channelFilters,
204
- supportServices: supportServices ? true : false,
205
- supportServiceCriteria: {
206
- type: RoomType.Service
207
- }
208
- },
209
- onCompleted: (data) => {
210
- var _a2, _b;
211
- if (isMountedRef.current) {
212
- const allChannels = [...(_a2 = data == null ? void 0 : data.supportServiceChannels) != null ? _a2 : [], ...(_b = data == null ? void 0 : data.channelsByUser) != null ? _b : []];
213
- safeSend({
214
- type: "FETCH_CHANNELS_SUCCESS",
215
- data: {
216
- channels: allChannels
217
- }
218
- });
219
- }
53
+ // supportServices: false,
54
+ // supportServices: supportServices ? true : false,
55
+ // supportServiceCriteria: {
56
+ // type: RoomType.Service,
57
+ // },
58
+ limit: 15,
59
+ skip: 0
220
60
  },
221
- onError: (error) => {
222
- if (isMountedRef.current) {
223
- safeSend({
224
- type: "ERROR",
225
- data: {
226
- message: error.message
227
- }
228
- });
229
- }
230
- }
61
+ notifyOnNetworkStatusChange: true,
62
+ fetchPolicy: "cache-and-network"
231
63
  });
232
- useEffect(() => {
233
- console.log("Setting initial context");
234
- safeSend({
235
- type: Actions.INITIAL_CONTEXT,
236
- data: {
237
- channelRole,
238
- channelFilters: channelFiltersRef.current,
239
- supportServices,
240
- selectedChannelId: params == null ? void 0 : params.channelId
241
- }
64
+ const processChannels = useCallback((rawChannels = []) => {
65
+ if (!(rawChannels == null ? void 0 : rawChannels.length)) return [];
66
+ return rawChannels.filter((c) => {
67
+ if (!(c == null ? void 0 : c.members)) return false;
68
+ return c.members.some((member) => (member == null ? void 0 : member.user) && member.user.id !== (auth == null ? void 0 : auth.id) && member.user.__typename === "UserAccount");
242
69
  });
70
+ }, [auth == null ? void 0 : auth.id]);
71
+ const sortChannels = useCallback((channels2) => {
72
+ if (!(channels2 == null ? void 0 : channels2.length)) return [];
73
+ return channels2;
243
74
  }, []);
244
- const hasRefreshedRef = useRef(false);
245
- const channelFiltersRef = useRef(channelFilters);
246
- const refreshChannels = useCallback(() => {
247
- if (safeContextProperty("refreshing", false)) {
248
- console.log("Skipping refresh - already in progress");
249
- return Promise.resolve();
75
+ const handleSelectChannel = useCallback((id, title) => {
76
+ if (activeChannelRef.current === id) {
77
+ console.log("\u{1F4F1} Ignoring repeated tap on channel:", id);
78
+ return;
79
+ }
80
+ activeChannelRef.current = id;
81
+ if (resetActiveChannelTimeoutRef.current) {
82
+ clearTimeout(resetActiveChannelTimeoutRef.current);
250
83
  }
251
- console.log("Starting channel refresh");
252
- safeSend({
253
- type: Actions.REFRESH_CHANNELS
84
+ resetActiveChannelTimeoutRef.current = setTimeout(() => {
85
+ activeChannelRef.current = null;
86
+ }, 2e3);
87
+ console.log("\u{1F4F1} Navigating to channel:", id);
88
+ navigation.navigate(config.INBOX_MESSEGE_PATH, {
89
+ channelId: id,
90
+ role: channelRole,
91
+ title,
92
+ hideTabBar: true,
93
+ timestamp: (/* @__PURE__ */ new Date()).getTime(),
94
+ orgName: params == null ? void 0 : params.orgName
254
95
  });
255
- const currentFilters = channelFiltersRef.current;
256
- return getChannelsRefetch({
96
+ }, [navigation, channelRole]);
97
+ const handleSelectServiceChannel = useCallback((id, title, postParentId) => {
98
+ if (activeChannelRef.current === id) {
99
+ console.log("\u{1F4F1} Ignoring repeated tap on service channel:", id);
100
+ return;
101
+ }
102
+ activeChannelRef.current = id;
103
+ if (resetActiveChannelTimeoutRef.current) {
104
+ clearTimeout(resetActiveChannelTimeoutRef.current);
105
+ }
106
+ resetActiveChannelTimeoutRef.current = setTimeout(() => {
107
+ activeChannelRef.current = null;
108
+ }, 2e3);
109
+ console.log("\u{1F4F1} Navigating to service channel:", id);
110
+ navigation.navigate(postParentId || postParentId === 0 ? config.THREAD_MESSEGE_PATH : config.THREADS_PATH, {
111
+ channelId: id,
257
112
  role: channelRole,
258
- criteria: currentFilters,
259
- supportServices: supportServices ? true : false,
260
- supportServiceCriteria: {
261
- type: RoomType.Service
262
- }
263
- }).then((data) => {
264
- var _a2, _b, _c, _d;
265
- if (isMountedRef.current) {
266
- const allChannels = [...(_b = (_a2 = data == null ? void 0 : data.data) == null ? void 0 : _a2.supportServiceChannels) != null ? _b : [], ...(_d = (_c = data == null ? void 0 : data.data) == null ? void 0 : _c.channelsByUser) != null ? _d : []];
267
- console.log(`Refresh completed, found ${allChannels.length} channels`);
268
- safeSend({
269
- type: "REFRESH_CHANNELS_SUCCESS",
270
- data: {
271
- channels: allChannels
272
- }
273
- });
274
- }
275
- }).catch((error) => {
276
- if (isMountedRef.current) {
277
- console.error("Channel refresh error:", error.message);
278
- safeSend({
279
- type: "ERROR",
280
- data: {
281
- message: error.message
282
- }
113
+ title,
114
+ postParentId,
115
+ hideTabBar: true,
116
+ orgName: params == null ? void 0 : params.orgName
117
+ });
118
+ }, [navigation, channelRole]);
119
+ const handleSearchChange = useCallback((text) => {
120
+ setSearchQuery(text);
121
+ }, []);
122
+ const allChannels = useMemo(() => [...(data == null ? void 0 : data.channelsByUser) || []], [data]);
123
+ const channels = useMemo(() => sortChannels(processChannels(allChannels)), [allChannels, processChannels, sortChannels]);
124
+ const displayChannels = useMemo(() => {
125
+ if (!searchQuery.trim()) return channels;
126
+ const query = searchQuery.toLowerCase();
127
+ return channels.filter((channel) => {
128
+ if (channel.title && channel.title.toLowerCase().includes(query)) return true;
129
+ if (channel.members) {
130
+ return channel.members.some((member) => {
131
+ const user = member == null ? void 0 : member.user;
132
+ if (!user) return false;
133
+ const fullName = `${user.givenName || ""} ${user.familyName || ""}`.toLowerCase();
134
+ return fullName.includes(query) || user.username && user.username.toLowerCase().includes(query);
283
135
  });
284
136
  }
137
+ return false;
285
138
  });
286
- }, [channelRole, supportServices, getChannelsRefetch, safeSend, safeContextProperty]);
139
+ }, [channels, searchQuery]);
140
+ const renderItem = useCallback(({
141
+ item: channel
142
+ }) => {
143
+ const key = `${channel.type === RoomType.Service ? "service" : "direct"}-${channel.id}`;
144
+ return /* @__PURE__ */ React__default.createElement(DialogItem, { key, onOpen: (channel == null ? void 0 : channel.type) === RoomType.Service ? handleSelectServiceChannel : handleSelectChannel, currentUser: auth, channel });
145
+ }, [auth, handleSelectChannel, handleSelectServiceChannel]);
146
+ const ListFooterComponent = useMemo(() => loading ? /* @__PURE__ */ React__default.createElement(Center, { className: "py-4" }, /* @__PURE__ */ React__default.createElement(Spinner, { color: colors.blue[500], size: "small" })) : null, [loading]);
147
+ const ListEmptyComponent = useMemo(() => {
148
+ if (loading && displayChannels.length === 0) {
149
+ return /* @__PURE__ */ React__default.createElement(Center, { className: "flex-1 justify-center items-center", style: {
150
+ height: 300
151
+ } }, /* @__PURE__ */ React__default.createElement(Spinner, { color: colors.blue[500], size: "large" }), /* @__PURE__ */ React__default.createElement(Text, { className: "mt-4 text-gray-500" }, "Loading conversations..."));
152
+ }
153
+ return /* @__PURE__ */ React__default.createElement(Box, { className: "p-6" }, /* @__PURE__ */ React__default.createElement(Box, { className: "mb-6" }, /* @__PURE__ */ React__default.createElement(Heading, { className: "text-2xl font-bold" }, "Direct Messages"), /* @__PURE__ */ React__default.createElement(Text, { className: "text-gray-600 mt-1" }, "Private conversations with other users")), /* @__PURE__ */ React__default.createElement(Input, { className: "mb-8 h-[50] rounded-md border-gray-300 border", size: "md", style: {
154
+ paddingVertical: 8,
155
+ marginBottom: 10,
156
+ borderColor: "#d1d5db",
157
+ borderRadius: 10
158
+ } }, /* @__PURE__ */ React__default.createElement(InputField, { placeholder: "Search messages...", onChangeText: handleSearchChange, value: searchQuery })), /* @__PURE__ */ React__default.createElement(Center, { className: "items-center", style: {
159
+ paddingVertical: 5
160
+ } }, /* @__PURE__ */ React__default.createElement(Box, { className: "w-16 h-16 rounded-full bg-blue-500 flex items-center justify-center mb-5" }, /* @__PURE__ */ React__default.createElement(Ionicons, { name: "chatbubble-ellipses", size: 30, color: "white" })), /* @__PURE__ */ React__default.createElement(Text, { className: "text-2xl font-bold text-center mb-2" }, "No messages yet"), /* @__PURE__ */ React__default.createElement(Text, { className: "text-gray-600 text-center mb-8" }, "When you start conversations with others,", "\n", "they'll appear here.")));
161
+ }, [loading, displayChannels.length, handleSearchChange, searchQuery]);
287
162
  useEffect(() => {
288
- const filtersChanged = JSON.stringify(channelFiltersRef.current) !== JSON.stringify(channelFilters);
289
- if (filtersChanged) {
290
- console.log("Channel filters changed, updating ref");
291
- channelFiltersRef.current = channelFilters;
292
- if (isMountedRef.current && safeContextProperty("channelRole") !== null) {
293
- console.log("Refreshing due to filter change");
294
- refreshChannels();
163
+ return () => {
164
+ isMountedRef.current = false;
165
+ if (resetActiveChannelTimeoutRef.current) {
166
+ clearTimeout(resetActiveChannelTimeoutRef.current);
295
167
  }
296
- }
297
- }, [channelFilters, refreshChannels, safeContextProperty]);
168
+ };
169
+ }, []);
298
170
  useFocusEffect(useCallback(() => {
299
- if (!isFocused)
300
- return;
301
- console.log("Screen focused, checking if refresh needed");
302
- if (isMountedRef.current && !hasRefreshedRef.current) {
303
- console.log("Refreshing on focus");
304
- hasRefreshedRef.current = true;
305
- refreshChannels();
171
+ const now = Date.now();
172
+ if (now - lastNavigationTimestamp.current > 300) {
173
+ activeChannelRef.current = null;
174
+ console.log("Reset active channel reference on focus");
306
175
  }
307
176
  return () => {
308
- console.log("Screen unfocused, resetting refresh state");
309
- hasRefreshedRef.current = false;
177
+ lastNavigationTimestamp.current = Date.now();
310
178
  };
311
- }, [isFocused, refreshChannels]));
312
- const handleRefresh = useCallback(() => {
313
- if (safeContextProperty("refreshing", false)) {
314
- console.log("Manual refresh ignored - refresh already in progress");
315
- return;
316
- }
317
- console.log("Manual refresh triggered");
318
- refreshChannels();
319
- }, [refreshChannels, safeContextProperty]);
320
- const channels = React__default.useMemo(() => {
321
- var _a2, _b, _c;
322
- const allChannels = [...(_a2 = userChannels == null ? void 0 : userChannels.supportServiceChannels) != null ? _a2 : [], ...(_b = userChannels == null ? void 0 : userChannels.channelsByUser) != null ? _b : []];
323
- let uChannels = (_c = allChannels == null ? void 0 : allChannels.filter((c) => c.members.some((u) => {
324
- var _a3;
325
- return u !== null && ((_a3 = u == null ? void 0 : u.user) == null ? void 0 : _a3.id) != (auth == null ? void 0 : auth.id) && u.user.__typename == "UserAccount";
326
- }))) != null ? _c : [];
327
- return uChannels && orderBy(uChannels, ["updatedAt"], ["desc"]) || [];
328
- }, [userChannels, auth == null ? void 0 : auth.id]);
329
- const handleSelectChannel = useCallback((id, title) => {
330
- var _a2;
331
- safeSend({
332
- type: Actions.SELECT_CHANNEL,
333
- data: {
334
- channelId: id
179
+ }, []));
180
+ useFocusEffect(useCallback(() => {
181
+ console.log("\u{1F4F1} Focus effect triggered for Dialogs screen");
182
+ const performRefresh = () => {
183
+ const now = Date.now();
184
+ if (now - lastRefreshTimeRef.current < MIN_REFRESH_INTERVAL) {
185
+ console.log("\u23E9 Skipping refresh: too soon after previous refresh");
186
+ return;
335
187
  }
336
- });
337
- if (params == null ? void 0 : params.channelId) {
338
- navigation.navigate(config.INBOX_MESSEGE_PATH, {
339
- channelId: params == null ? void 0 : params.channelId,
340
- role: params == null ? void 0 : params.role,
341
- title: (_a2 = params == null ? void 0 : params.title) != null ? _a2 : null,
342
- hideTabBar: true
343
- });
344
- } else {
345
- navigation.navigate(config.INBOX_MESSEGE_PATH, {
346
- channelId: id,
347
- role: channelRole,
348
- title,
349
- hideTabBar: true
350
- });
188
+ console.log("\u{1F504} Performing refresh on screen focus");
189
+ if (isMountedRef.current) {
190
+ lastRefreshTimeRef.current = now;
191
+ refetch();
192
+ }
193
+ };
194
+ const focusRefreshTimeout = setTimeout(performRefresh, 100);
195
+ return () => clearTimeout(focusRefreshTimeout);
196
+ }, [refetch]));
197
+ const handlePullToRefresh = useCallback(() => {
198
+ const now = Date.now();
199
+ focusRefreshRef.current = now;
200
+ console.log("\u{1F504} Pull-to-refresh triggered");
201
+ refetch();
202
+ }, [refetch]);
203
+ const handleLoadMore = useCallback(() => {
204
+ if (loading || !data || channels.length < 10) {
205
+ console.log("Skip loading more: already loading or all data loaded");
206
+ return;
351
207
  }
352
- }, [params, navigation, channelRole, safeSend]);
353
- const handleSelectServiceChannel = useCallback((id, title, postParentId) => {
354
- var _a2;
355
- safeSend({
356
- type: Actions.SELECT_CHANNEL,
357
- data: {
358
- channelId: id
208
+ console.log("Loading more channels");
209
+ fetchMore({
210
+ variables: {
211
+ skip: channels.length
212
+ },
213
+ updateQuery: (prev, {
214
+ fetchMoreResult
215
+ }) => {
216
+ if (!fetchMoreResult) return prev;
217
+ return __spreadProps(__spreadValues({}, fetchMoreResult), {
218
+ channelsByUser: [...prev.channelsByUser || [], ...fetchMoreResult.channelsByUser || []]
219
+ // supportServiceChannels: [
220
+ // ...(prev.supportServiceChannels || []),
221
+ // ...(fetchMoreResult.supportServiceChannels || []),
222
+ // ],
223
+ });
359
224
  }
225
+ }).catch((error) => {
226
+ console.error("Error loading more channels:", error);
360
227
  });
361
- if (params == null ? void 0 : params.channelId) {
362
- navigation.navigate((params == null ? void 0 : params.postParentId) || (params == null ? void 0 : params.postParentId) == 0 ? config.THREAD_MESSEGE_PATH : config.THREADS_PATH, {
363
- channelId: params == null ? void 0 : params.channelId,
364
- role: params == null ? void 0 : params.role,
365
- title: (_a2 = params == null ? void 0 : params.title) != null ? _a2 : null,
366
- postParentId: params == null ? void 0 : params.postParentId,
367
- hideTabBar: true
368
- });
369
- } else {
370
- navigation.navigate(postParentId || postParentId == 0 ? config.THREAD_MESSEGE_PATH : config.THREADS_PATH, {
371
- channelId: id,
372
- role: channelRole,
373
- title,
374
- postParentId,
375
- hideTabBar: true
376
- });
377
- }
378
- }, [params, navigation, channelRole, safeSend]);
379
- const searchQuery = safeContextProperty("searchQuery", "");
380
- return /* @__PURE__ */ React__default.createElement(Box, { className: "p-2" }, /* @__PURE__ */ React__default.createElement(FlatList, { data: channels && (channels == null ? void 0 : channels.length) > 0 ? channels : [], onRefresh: handleRefresh, refreshing: safeContextProperty("refreshing", false), contentContainerStyle: {
228
+ }, [fetchMore, loading, data, channels.length]);
229
+ return /* @__PURE__ */ React__default.createElement(Box, { className: "p-2" }, /* @__PURE__ */ React__default.createElement(FlatList, { data: displayChannels, onRefresh: handlePullToRefresh, refreshing: loading, contentContainerStyle: {
381
230
  minHeight: "100%"
382
- }, ItemSeparatorComponent: () => /* @__PURE__ */ React__default.createElement(Box, { className: "h-0.5 bg-gray-200" }), renderItem: ({
383
- item: channel
384
- }) => (channel == null ? void 0 : channel.type) === RoomType.Service ? /* @__PURE__ */ React__default.createElement(ServiceDialogsListItem, { onOpen: handleSelectServiceChannel, currentUser: auth, channel, refreshing: safeContextProperty("refreshing", false), selectedChannelId: safeContextProperty("selectedChannelId", params == null ? void 0 : params.channelId), role: channelRole }) : /* @__PURE__ */ React__default.createElement(DialogsListItem, { onOpen: handleSelectChannel, currentUser: auth, channel, selectedChannelId: safeContextProperty("selectedChannelId", params == null ? void 0 : params.channelId) }), ListEmptyComponent: () => /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, userChannelsLoading || safeContextProperty("loading", false) ? /* @__PURE__ */ React__default.createElement(Center, { className: "flex-1 justify-center items-center" }, /* @__PURE__ */ React__default.createElement(Spinner, { color: colors.blue[500] })) : /* @__PURE__ */ React__default.createElement(Box, { className: "p-5" }, /* @__PURE__ */ React__default.createElement(Heading, null, "Chat"), /* @__PURE__ */ React__default.createElement(Input, { className: `h-[50] mt-3 rounded-[50] border-gray-200 border ` }, /* @__PURE__ */ React__default.createElement(InputField, { placeholder: "Search", value: searchQuery, onChangeText: (text) => safeSend({
385
- type: Actions.SET_SEARCH_QUERY,
386
- data: {
387
- searchQuery: text
388
- }
389
- }) })), /* @__PURE__ */ React__default.createElement(Center, { className: "mt-6" }, /* @__PURE__ */ React__default.createElement(Ionicons, { name: "chatbubbles", size: 50 }), /* @__PURE__ */ React__default.createElement(Text, null, "You don't have any messages yet!")))), keyExtractor: (item, index) => "key" + index }));
231
+ }, ItemSeparatorComponent: React__default.useCallback(() => /* @__PURE__ */ React__default.createElement(Box, { className: "h-0.5 bg-gray-200" }), []), renderItem, ListFooterComponent, onEndReached: handleLoadMore, onEndReachedThreshold: 0.5, initialNumToRender: 5, maxToRenderPerBatch: 5, windowSize: 5, removeClippedSubviews: true, updateCellsBatchingPeriod: 100, getItemLayout: React__default.useCallback((data2, index) => ({
232
+ length: 80,
233
+ offset: 80 * index,
234
+ index
235
+ }), []), keyExtractor: React__default.useCallback((item) => `channel-${item.id}`, []), ListEmptyComponent }));
390
236
  };
391
237
  const Dialogs = React__default.memo(DialogsComponent);export{Dialogs};//# sourceMappingURL=Dialogs.js.map