@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.
- package/CHANGELOG.md +96 -0
- package/lib/compute.js +2 -3
- package/lib/compute.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/queries/inboxQueries.js +65 -0
- package/lib/queries/inboxQueries.js.map +1 -0
- package/lib/routes.json +2 -3
- package/lib/screens/inbox/DialogMessages.js +1 -1
- package/lib/screens/inbox/DialogMessages.js.map +1 -1
- package/lib/screens/inbox/DialogThreadMessages.js +4 -8
- package/lib/screens/inbox/DialogThreadMessages.js.map +1 -1
- package/lib/screens/inbox/DialogThreads.js +57 -12
- package/lib/screens/inbox/DialogThreads.js.map +1 -1
- package/lib/screens/inbox/Inbox.js +1 -1
- package/lib/screens/inbox/Inbox.js.map +1 -1
- package/lib/screens/inbox/components/CachedImage/consts.js +1 -1
- package/lib/screens/inbox/components/CachedImage/consts.js.map +1 -1
- package/lib/screens/inbox/components/CachedImage/index.js +168 -46
- package/lib/screens/inbox/components/CachedImage/index.js.map +1 -1
- package/lib/screens/inbox/components/DialogItem.js +169 -0
- package/lib/screens/inbox/components/DialogItem.js.map +1 -0
- package/lib/screens/inbox/components/GiftedChatInboxComponent.js +313 -0
- package/lib/screens/inbox/components/GiftedChatInboxComponent.js.map +1 -0
- package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +147 -31
- package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
- package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js +6 -1
- package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js.map +1 -1
- package/lib/screens/inbox/components/SubscriptionHandler.js +24 -0
- package/lib/screens/inbox/components/SubscriptionHandler.js.map +1 -0
- package/lib/screens/inbox/components/ThreadsViewItem.js +66 -55
- package/lib/screens/inbox/components/ThreadsViewItem.js.map +1 -1
- package/lib/screens/inbox/config/config.js +2 -2
- package/lib/screens/inbox/config/config.js.map +1 -1
- package/lib/screens/inbox/containers/ConversationView.js +1111 -434
- package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
- package/lib/screens/inbox/containers/Dialogs.js +193 -80
- package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
- package/lib/screens/inbox/containers/ThreadConversationView.js +725 -216
- 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/useInboxMessages.js +31 -0
- package/lib/screens/inbox/hooks/useInboxMessages.js.map +1 -0
- 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 +4 -4
- package/src/compute.ts +5 -6
- package/src/index.ts +2 -0
- package/src/navigation/InboxNavigation.tsx +3 -3
- package/src/queries/inboxQueries.ts +299 -0
- package/src/queries/index.d.ts +2 -0
- package/src/queries/index.ts +1 -0
- package/src/screens/inbox/DialogMessages.tsx +1 -1
- package/src/screens/inbox/DialogThreadMessages.tsx +7 -14
- package/src/screens/inbox/DialogThreads.tsx +55 -61
- package/src/screens/inbox/Inbox.tsx +1 -1
- package/src/screens/inbox/components/Actionsheet.tsx +30 -0
- package/src/screens/inbox/components/CachedImage/consts.ts +4 -3
- package/src/screens/inbox/components/CachedImage/index.tsx +232 -61
- package/src/screens/inbox/components/DialogItem.tsx +306 -0
- package/src/screens/inbox/components/DialogsHeader.tsx +6 -13
- package/src/screens/inbox/components/DialogsListItem.tsx +262 -198
- package/src/screens/inbox/components/ExpandableInput.tsx +460 -0
- package/src/screens/inbox/components/ExpandableInputActionSheet.tsx +518 -0
- package/src/screens/inbox/components/GiftedChatInboxComponent.tsx +411 -0
- package/src/screens/inbox/components/ServiceDialogsListItem.tsx +337 -194
- package/src/screens/inbox/components/SlackInput.tsx +23 -0
- package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +233 -23
- package/src/screens/inbox/components/SlackMessageContainer/SlackMessage.tsx +1 -1
- package/src/screens/inbox/components/SmartLoader.tsx +61 -0
- package/src/screens/inbox/components/SubscriptionHandler.tsx +41 -0
- package/src/screens/inbox/components/SupportServiceDialogsListItem.tsx +53 -55
- package/src/screens/inbox/components/ThreadsViewItem.tsx +178 -285
- package/src/screens/inbox/components/workflow/dialogs-list-item-xstate.ts +145 -0
- package/src/screens/inbox/components/workflow/service-dialogs-list-item-xstate.ts +159 -0
- package/src/screens/inbox/config/config.ts +2 -2
- package/src/screens/inbox/containers/ConversationView.tsx +1843 -702
- package/src/screens/inbox/containers/ConversationView.tsx.bk +1467 -0
- package/src/screens/inbox/containers/Dialogs.tsx +402 -204
- package/src/screens/inbox/containers/SupportServiceDialogs.tsx +4 -4
- package/src/screens/inbox/containers/ThreadConversationView.tsx +1350 -319
- package/src/screens/inbox/containers/ThreadsView.tsx +105 -193
- package/src/screens/inbox/containers/workflow/apollo/handleResult.ts +20 -0
- package/src/screens/inbox/containers/workflow/conversation-xstate.ts +313 -0
- package/src/screens/inbox/containers/workflow/dialogs-xstate.ts +196 -0
- package/src/screens/inbox/containers/workflow/thread-conversation-xstate.ts +401 -0
- package/src/screens/inbox/hooks/useInboxMessages.ts +34 -0
- 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
- package/tsconfig.json +11 -54
- package/lib/screens/inbox/components/DialogsListItem.js +0 -171
- package/lib/screens/inbox/components/DialogsListItem.js.map +0 -1
- package/lib/screens/inbox/components/ServiceDialogsListItem.js +0 -171
- package/lib/screens/inbox/components/ServiceDialogsListItem.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React__default,{useState,useRef,useEffect}from'react';import {Image}from'react-native';import*as FileSystem from'expo-file-system';import {IMAGE_CACHE_FOLDER}from'./consts.js';var __defProp = Object.defineProperty;
|
|
1
|
+
import React__default,{useState,useRef,useCallback,useEffect,useMemo}from'react';import {View,Text,Image}from'react-native';import*as FileSystem from'expo-file-system';import {IMAGE_CACHE_FOLDER}from'./consts.js';var __defProp = Object.defineProperty;
|
|
2
2
|
var __defProps = Object.defineProperties;
|
|
3
3
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
@@ -17,73 +17,195 @@ var __spreadValues = (a, b) => {
|
|
|
17
17
|
return a;
|
|
18
18
|
};
|
|
19
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
var __objRest = (source, exclude) => {
|
|
21
|
+
var target = {};
|
|
22
|
+
for (var prop in source)
|
|
23
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
24
|
+
target[prop] = source[prop];
|
|
25
|
+
if (source != null && __getOwnPropSymbols)
|
|
26
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
27
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
28
|
+
target[prop] = source[prop];
|
|
29
|
+
}
|
|
30
|
+
return target;
|
|
31
|
+
};
|
|
32
|
+
const downloadTracker = /* @__PURE__ */ new Map();
|
|
33
|
+
const ensureCacheDirectory = async () => {
|
|
34
|
+
try {
|
|
35
|
+
const dirInfo = await FileSystem.getInfoAsync(IMAGE_CACHE_FOLDER);
|
|
36
|
+
if (!dirInfo.exists) {
|
|
37
|
+
await FileSystem.makeDirectoryAsync(IMAGE_CACHE_FOLDER, {
|
|
38
|
+
intermediates: true
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
} catch (error) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const validateImageUri = (uri) => {
|
|
47
|
+
if (!uri)
|
|
48
|
+
return null;
|
|
49
|
+
uri = uri.trim();
|
|
50
|
+
try {
|
|
51
|
+
new URL(uri);
|
|
52
|
+
} catch (e) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return uri;
|
|
56
|
+
};
|
|
57
|
+
const CachedImage = React__default.memo((props) => {
|
|
58
|
+
const _a = props, {
|
|
22
59
|
source,
|
|
23
60
|
cacheKey,
|
|
24
|
-
placeholderContent
|
|
25
|
-
|
|
61
|
+
placeholderContent,
|
|
62
|
+
style,
|
|
63
|
+
resizeMode,
|
|
64
|
+
alt
|
|
65
|
+
} = _a, restProps = __objRest(_a, [
|
|
66
|
+
"source",
|
|
67
|
+
"cacheKey",
|
|
68
|
+
"placeholderContent",
|
|
69
|
+
"style",
|
|
70
|
+
"resizeMode",
|
|
71
|
+
"alt"
|
|
72
|
+
]);
|
|
26
73
|
const {
|
|
27
|
-
uri,
|
|
74
|
+
uri: originalUri,
|
|
28
75
|
headers,
|
|
29
|
-
expiresIn
|
|
76
|
+
expiresIn = 86400
|
|
30
77
|
} = source;
|
|
78
|
+
const uri = validateImageUri(originalUri);
|
|
31
79
|
const fileURI = `${IMAGE_CACHE_FOLDER}${cacheKey}`;
|
|
32
|
-
const [imgUri, setImgUri] = useState(
|
|
80
|
+
const [imgUri, setImgUri] = useState(null);
|
|
81
|
+
const [loadError, setLoadError] = useState(false);
|
|
82
|
+
const [useFallbackUri, setUseFallbackUri] = useState(false);
|
|
83
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
33
84
|
const componentIsMounted = useRef(true);
|
|
85
|
+
const hasAttemptedLoad = useRef(false);
|
|
34
86
|
const requestOption = headers ? {
|
|
35
87
|
headers
|
|
36
88
|
} : {};
|
|
37
|
-
const
|
|
89
|
+
const downloadCallback = useCallback((downloadProgress) => {
|
|
90
|
+
var _a2;
|
|
38
91
|
if (componentIsMounted.current === false) {
|
|
39
|
-
|
|
92
|
+
downloadTracker.delete(cacheKey);
|
|
93
|
+
(_a2 = downloadResumableRef.current) == null ? void 0 : _a2.pauseAsync();
|
|
40
94
|
FileSystem.deleteAsync(fileURI, {
|
|
41
95
|
idempotent: true
|
|
42
96
|
});
|
|
43
97
|
}
|
|
44
|
-
};
|
|
45
|
-
const downloadResumableRef = useRef(FileSystem.createDownloadResumable(uri, fileURI, requestOption,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}, []);
|
|
52
|
-
const loadImage = async () => {
|
|
98
|
+
}, [fileURI, cacheKey]);
|
|
99
|
+
const downloadResumableRef = useRef(uri ? FileSystem.createDownloadResumable(uri, fileURI, requestOption, downloadCallback) : null);
|
|
100
|
+
const loadImage = useCallback(async () => {
|
|
101
|
+
if (!uri || hasAttemptedLoad.current)
|
|
102
|
+
return;
|
|
103
|
+
hasAttemptedLoad.current = true;
|
|
104
|
+
setIsLoading(true);
|
|
53
105
|
try {
|
|
106
|
+
if (downloadTracker.has(cacheKey)) {
|
|
107
|
+
await downloadTracker.get(cacheKey);
|
|
108
|
+
if (componentIsMounted.current) {
|
|
109
|
+
setImgUri(fileURI);
|
|
110
|
+
setIsLoading(false);
|
|
111
|
+
}
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
54
114
|
const metadata = await FileSystem.getInfoAsync(fileURI);
|
|
55
115
|
const expired = expiresIn && new Date().getTime() / 1e3 - (metadata == null ? void 0 : metadata.modificationTime) > expiresIn;
|
|
56
116
|
if (!metadata.exists || (metadata == null ? void 0 : metadata.size) === 0 || expired) {
|
|
57
|
-
if (componentIsMounted.current)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
117
|
+
if (!componentIsMounted.current)
|
|
118
|
+
return;
|
|
119
|
+
if (expired && metadata.exists) {
|
|
120
|
+
await FileSystem.deleteAsync(fileURI, {
|
|
121
|
+
idempotent: true
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (!uri) {
|
|
125
|
+
setLoadError(true);
|
|
126
|
+
setIsLoading(false);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (!downloadResumableRef.current) {
|
|
130
|
+
setUseFallbackUri(true);
|
|
131
|
+
setImgUri(uri);
|
|
132
|
+
setIsLoading(false);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
const downloadPromise = downloadResumableRef.current.downloadAsync();
|
|
137
|
+
downloadTracker.set(cacheKey, downloadPromise);
|
|
138
|
+
const response = await downloadPromise;
|
|
139
|
+
downloadTracker.delete(cacheKey);
|
|
140
|
+
if (componentIsMounted.current) {
|
|
141
|
+
if (response && response.status === 200) {
|
|
142
|
+
setImgUri(fileURI);
|
|
143
|
+
} else {
|
|
144
|
+
setUseFallbackUri(true);
|
|
145
|
+
setImgUri(uri);
|
|
146
|
+
FileSystem.deleteAsync(fileURI, {
|
|
147
|
+
idempotent: true
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
setIsLoading(false);
|
|
68
151
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
152
|
+
} catch (downloadError) {
|
|
153
|
+
downloadTracker.delete(cacheKey);
|
|
154
|
+
if (componentIsMounted.current) {
|
|
155
|
+
setUseFallbackUri(true);
|
|
156
|
+
setImgUri(uri);
|
|
157
|
+
setIsLoading(false);
|
|
73
158
|
}
|
|
74
159
|
}
|
|
160
|
+
} else {
|
|
161
|
+
setImgUri(fileURI);
|
|
162
|
+
setIsLoading(false);
|
|
75
163
|
}
|
|
76
164
|
} catch (err) {
|
|
165
|
+
if (componentIsMounted.current) {
|
|
166
|
+
setUseFallbackUri(true);
|
|
167
|
+
setImgUri(uri);
|
|
168
|
+
setIsLoading(false);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}, [uri, fileURI, cacheKey, expiresIn]);
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
const setup = async () => {
|
|
174
|
+
const directoryExists = await ensureCacheDirectory();
|
|
175
|
+
if (directoryExists && uri) {
|
|
176
|
+
loadImage();
|
|
177
|
+
} else {
|
|
178
|
+
setLoadError(true);
|
|
179
|
+
setIsLoading(false);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
setup();
|
|
183
|
+
return () => {
|
|
184
|
+
componentIsMounted.current = false;
|
|
185
|
+
};
|
|
186
|
+
}, [uri, loadImage]);
|
|
187
|
+
const defaultPlaceholder = useMemo(() => /* @__PURE__ */ React__default.createElement(View, { style: [{
|
|
188
|
+
width: "100%",
|
|
189
|
+
height: "100%",
|
|
190
|
+
backgroundColor: "#e1e1e1",
|
|
191
|
+
justifyContent: "center",
|
|
192
|
+
alignItems: "center",
|
|
193
|
+
borderRadius: 3
|
|
194
|
+
}, style] }, /* @__PURE__ */ React__default.createElement(Text, null, "Image not available")), [style]);
|
|
195
|
+
if (isLoading || loadError || !imgUri) {
|
|
196
|
+
return placeholderContent || defaultPlaceholder;
|
|
197
|
+
}
|
|
198
|
+
return /* @__PURE__ */ React__default.createElement(Image, __spreadProps(__spreadValues({}, restProps), { style, source: __spreadProps(__spreadValues({}, source), {
|
|
199
|
+
uri: useFallbackUri ? uri : imgUri
|
|
200
|
+
}), resizeMode, onError: (e) => {
|
|
201
|
+
if (useFallbackUri) {
|
|
202
|
+
setLoadError(true);
|
|
203
|
+
setImgUri(null);
|
|
204
|
+
} else {
|
|
205
|
+
setUseFallbackUri(true);
|
|
206
|
+
setImgUri(uri);
|
|
77
207
|
}
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
Image,
|
|
83
|
-
__spreadProps(__spreadValues({}, props), {
|
|
84
|
-
source: __spreadProps(__spreadValues({}, source), {
|
|
85
|
-
uri: imgUri
|
|
86
|
-
})
|
|
87
|
-
})
|
|
88
|
-
);
|
|
89
|
-
};export{CachedImage as default};//# sourceMappingURL=index.js.map
|
|
208
|
+
} }));
|
|
209
|
+
}, (prevProps, nextProps) => {
|
|
210
|
+
return prevProps.cacheKey === nextProps.cacheKey && prevProps.source.uri === nextProps.source.uri && prevProps.style === nextProps.style;
|
|
211
|
+
});export{CachedImage as default};//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../src/screens/inbox/components/CachedImage/index.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef } from 'react';\nimport { Image } from 'react-native';\n// import { Image } from \"react-native\"\nimport * as FileSystem from 'expo-file-system';\n\nimport * as CONST from './consts';\n\nconst CachedImage = (props: any) => {\n const { source, cacheKey, placeholderContent } = props;\n const { uri, headers, expiresIn } = source;\n const fileURI = `${CONST.IMAGE_CACHE_FOLDER}${cacheKey}`;\n\n const [imgUri, setImgUri] = useState<any>(fileURI);\n\n const componentIsMounted = useRef(true);\n const requestOption = headers ? { headers } : {};\n\n const _callback = (downloadProgress: any) => {\n if (componentIsMounted.current === false) {\n downloadResumableRef.current.pauseAsync();\n FileSystem.deleteAsync(fileURI, { idempotent: true }); // delete file locally if it was not downloaded properly\n }\n };\n\n const downloadResumableRef = useRef(FileSystem.createDownloadResumable(uri, fileURI, requestOption, _callback));\n\n useEffect(() => {\n loadImage();\n return () => {\n componentIsMounted.current = false;\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n const loadImage = async () => {\n try {\n // Use the cached image if it exists\n const metadata: any = await FileSystem.getInfoAsync(fileURI);\n const expired = expiresIn && new Date().getTime() / 1000 - metadata?.modificationTime > expiresIn;\n // console.log({expiresIn, expired})\n\n // console.log({modificationTime: metadata.modificationTime, currentTime: new Date().getTime() / 1000})\n // console.log({metadata})\n if (!metadata.exists || metadata?.size === 0 || expired) {\n if (componentIsMounted.current) {\n setImgUri(null);\n\n if (expired) {\n await FileSystem.deleteAsync(fileURI, { idempotent: true });\n }\n // download to cache\n setImgUri(null);\n\n const response: any = await downloadResumableRef.current.downloadAsync();\n if (componentIsMounted.current && response.status === 200) {\n setImgUri(`${fileURI}?`); // deep clone to force re-render\n }\n if (response.status !== 200) {\n FileSystem.deleteAsync(fileURI, { idempotent: true }); // delete file locally if it was not downloaded properly\n }\n }\n }\n } catch (err) {\n // console.log({ err })\n }\n };\n // console.log({placeholderContent})\n if (!imgUri) return placeholderContent || null;\n\n return (\n <Image\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...props}\n source={{\n ...source,\n uri: imgUri,\n }}\n />\n );\n};\n\nexport const CacheManager = {\n addToCache: async ({ file, key }: any) => {\n await FileSystem.copyAsync({\n from: file,\n to: `${CONST.IMAGE_CACHE_FOLDER}${key}`,\n });\n // const uri = await FileSystem.getContentUriAsync(`${CONST.IMAGE_CACHE_FOLDER}${key}`)\n // return uri\n const uri = await CacheManager.getCachedUri({ key });\n return uri;\n },\n\n getCachedUri: async ({ key }: any) => {\n const uri = await FileSystem.getContentUriAsync(`${CONST.IMAGE_CACHE_FOLDER}${key}`);\n return uri;\n },\n\n downloadAsync: async ({ uri, key, options }: any) => {\n return await FileSystem.downloadAsync(uri, `${CONST.IMAGE_CACHE_FOLDER}${key}`, options);\n },\n};\n\nexport default CachedImage;\n"],"names":["CONST.IMAGE_CACHE_FOLDER","React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../src/screens/inbox/components/CachedImage/index.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef, useMemo, useCallback } from 'react';\nimport { Image, View, Text } from 'react-native';\n// import { Image } from \"react-native\"\nimport * as FileSystem from 'expo-file-system';\n\nimport * as CONST from './consts';\n\n// Global download tracking to prevent duplicate downloads\nconst downloadTracker = new Map();\n\n// Ensure the cache directory exists\nconst ensureCacheDirectory = async () => {\n try {\n const dirInfo = await FileSystem.getInfoAsync(CONST.IMAGE_CACHE_FOLDER);\n if (!dirInfo.exists) {\n // console.log('Creating cache directory:', CONST.IMAGE_CACHE_FOLDER);\n await FileSystem.makeDirectoryAsync(CONST.IMAGE_CACHE_FOLDER, { intermediates: true });\n }\n return true;\n } catch (error) {\n // console.error('Failed to create cache directory:', error);\n return false;\n }\n};\n\n// Validate and sanitize the image URL\nconst validateImageUri = (uri: string): string | null => {\n if (!uri) return null;\n\n // Trim whitespace\n uri = uri.trim();\n\n // Check if it's a valid URL format\n try {\n new URL(uri);\n } catch (e) {\n // console.log('Invalid URL format:', uri);\n return null;\n }\n\n // Add more validation as needed for your specific case\n return uri;\n};\n\nconst CachedImage = React.memo(\n (props: any) => {\n const { source, cacheKey, placeholderContent, style, resizeMode, alt, ...restProps } = props;\n const { uri: originalUri, headers, expiresIn = 86400 } = source;\n\n // Validate and sanitize the URI\n const uri = validateImageUri(originalUri);\n const fileURI = `${CONST.IMAGE_CACHE_FOLDER}${cacheKey}`;\n\n const [imgUri, setImgUri] = useState<string | null>(null);\n const [loadError, setLoadError] = useState<boolean>(false);\n const [useFallbackUri, setUseFallbackUri] = useState<boolean>(false);\n const [isLoading, setIsLoading] = useState<boolean>(true);\n\n const componentIsMounted = useRef(true);\n const hasAttemptedLoad = useRef(false);\n const requestOption = headers ? { headers } : {};\n\n // Create a memoized download callback\n const downloadCallback = useCallback(\n (downloadProgress: any) => {\n if (componentIsMounted.current === false) {\n downloadTracker.delete(cacheKey);\n downloadResumableRef.current?.pauseAsync();\n FileSystem.deleteAsync(fileURI, { idempotent: true });\n }\n },\n [fileURI, cacheKey],\n );\n\n // Create a memoized download resumable\n const downloadResumableRef = useRef(\n uri ? FileSystem.createDownloadResumable(uri, fileURI, requestOption, downloadCallback) : null,\n );\n\n // Memoized load image function to avoid recreating on every render\n const loadImage = useCallback(async () => {\n if (!uri || hasAttemptedLoad.current) return;\n\n hasAttemptedLoad.current = true;\n setIsLoading(true);\n\n try {\n // Check if this image is already being downloaded\n if (downloadTracker.has(cacheKey)) {\n // Wait for the existing download to complete\n await downloadTracker.get(cacheKey);\n if (componentIsMounted.current) {\n setImgUri(fileURI);\n setIsLoading(false);\n }\n return;\n }\n\n // Use the cached image if it exists\n const metadata: any = await FileSystem.getInfoAsync(fileURI);\n const expired = expiresIn && new Date().getTime() / 1000 - metadata?.modificationTime > expiresIn;\n\n if (!metadata.exists || metadata?.size === 0 || expired) {\n if (!componentIsMounted.current) return;\n\n if (expired && metadata.exists) {\n await FileSystem.deleteAsync(fileURI, { idempotent: true });\n }\n\n if (!uri) {\n setLoadError(true);\n setIsLoading(false);\n return;\n }\n\n if (!downloadResumableRef.current) {\n setUseFallbackUri(true);\n setImgUri(uri);\n setIsLoading(false);\n return;\n }\n\n try {\n // Record this download in the global tracker\n const downloadPromise = downloadResumableRef.current.downloadAsync();\n downloadTracker.set(cacheKey, downloadPromise);\n\n const response: any = await downloadPromise;\n\n // Remove from tracker when done\n downloadTracker.delete(cacheKey);\n\n if (componentIsMounted.current) {\n if (response && response.status === 200) {\n setImgUri(fileURI);\n } else {\n setUseFallbackUri(true);\n setImgUri(uri);\n FileSystem.deleteAsync(fileURI, { idempotent: true });\n }\n setIsLoading(false);\n }\n } catch (downloadError) {\n downloadTracker.delete(cacheKey);\n if (componentIsMounted.current) {\n setUseFallbackUri(true);\n setImgUri(uri);\n setIsLoading(false);\n }\n }\n } else {\n // Use cached version\n setImgUri(fileURI);\n setIsLoading(false);\n }\n } catch (err) {\n if (componentIsMounted.current) {\n setUseFallbackUri(true);\n setImgUri(uri);\n setIsLoading(false);\n }\n }\n }, [uri, fileURI, cacheKey, expiresIn]);\n\n // Setup effect\n useEffect(() => {\n const setup = async () => {\n const directoryExists = await ensureCacheDirectory();\n if (directoryExists && uri) {\n loadImage();\n } else {\n setLoadError(true);\n setIsLoading(false);\n }\n };\n\n setup();\n\n return () => {\n componentIsMounted.current = false;\n };\n }, [uri, loadImage]);\n\n // Default placeholder\n const defaultPlaceholder = useMemo(\n () => (\n <View\n style={[\n {\n width: '100%',\n height: '100%',\n backgroundColor: '#e1e1e1',\n justifyContent: 'center',\n alignItems: 'center',\n borderRadius: 3,\n },\n style,\n ]}\n >\n <Text>Image not available</Text>\n </View>\n ),\n [style],\n );\n\n // Show placeholder while loading or if there's an error\n if (isLoading || loadError || !imgUri) {\n return placeholderContent || defaultPlaceholder;\n }\n\n // Actual image component\n return (\n <Image\n {...restProps}\n style={style}\n source={{\n ...source,\n uri: useFallbackUri ? uri : imgUri,\n }}\n resizeMode={resizeMode}\n onError={(e) => {\n if (useFallbackUri) {\n setLoadError(true);\n setImgUri(null);\n } else {\n setUseFallbackUri(true);\n setImgUri(uri);\n }\n }}\n />\n );\n },\n (prevProps, nextProps) => {\n // Custom comparison function for memoization\n return (\n prevProps.cacheKey === nextProps.cacheKey &&\n prevProps.source.uri === nextProps.source.uri &&\n prevProps.style === nextProps.style\n );\n },\n);\n\nexport const CacheManager = {\n addToCache: async ({ file, key }: any) => {\n await ensureCacheDirectory();\n await FileSystem.copyAsync({\n from: file,\n to: `${CONST.IMAGE_CACHE_FOLDER}${key}`,\n });\n const uri = await CacheManager.getCachedUri({ key });\n return uri;\n },\n\n getCachedUri: async ({ key }: any) => {\n const uri = await FileSystem.getContentUriAsync(`${CONST.IMAGE_CACHE_FOLDER}${key}`);\n return uri;\n },\n\n downloadAsync: async ({ uri, key, options }: any) => {\n await ensureCacheDirectory();\n return await FileSystem.downloadAsync(uri, `${CONST.IMAGE_CACHE_FOLDER}${key}`, options);\n },\n\n clearCache: async () => {\n try {\n await FileSystem.deleteAsync(CONST.IMAGE_CACHE_FOLDER, { idempotent: true });\n await ensureCacheDirectory();\n } catch (error) {\n console.error('Error clearing cache:', error);\n }\n },\n};\n\nexport default CachedImage;\n"],"names":["CONST.IMAGE_CACHE_FOLDER","React","_a"],"mappings":"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"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import React__default,{useRef,useState,useMemo,useEffect,useCallback}from'react';import {Pressable,HStack,Box,Avatar,AvatarFallbackText,AvatarImage,AvatarGroup,AvatarBadge,Text}from'@admin-layout/gluestack-ui-mobile';import {isToday,isYesterday,format}from'date-fns';import {useFocusEffect}from'@react-navigation/native';import {RoomType}from'common';import {startCase}from'lodash-es';import colors from'tailwindcss/colors';const safeDate = (dateValue) => {
|
|
2
|
+
if (!dateValue)
|
|
3
|
+
return null;
|
|
4
|
+
try {
|
|
5
|
+
const date = new Date(dateValue);
|
|
6
|
+
if (isNaN(date.getTime())) {
|
|
7
|
+
console.warn("Invalid date value detected:", dateValue);
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
return date;
|
|
11
|
+
} catch (error) {
|
|
12
|
+
console.warn("Error creating date from value:", dateValue, error);
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const createdAtText = (value) => {
|
|
17
|
+
if (!value)
|
|
18
|
+
return "";
|
|
19
|
+
const date = safeDate(value);
|
|
20
|
+
if (!date)
|
|
21
|
+
return "";
|
|
22
|
+
if (isToday(date))
|
|
23
|
+
return "Today";
|
|
24
|
+
if (isYesterday(date))
|
|
25
|
+
return "Yesterday";
|
|
26
|
+
return format(date, "MMM dd, yyyy");
|
|
27
|
+
};
|
|
28
|
+
const LastMessageComponent = ({
|
|
29
|
+
title,
|
|
30
|
+
lastMessage,
|
|
31
|
+
isServiceChannel = false
|
|
32
|
+
}) => {
|
|
33
|
+
var _a, _b, _c, _d, _e;
|
|
34
|
+
const count = 30;
|
|
35
|
+
const channelTitle = (title == null ? void 0 : title.slice(0, count)) + ((title == null ? void 0 : title.length) > count ? "..." : "") || "";
|
|
36
|
+
let displayMessage = "No messages yet";
|
|
37
|
+
if (lastMessage) {
|
|
38
|
+
const hasFileAttachments = ((_b = (_a = lastMessage.files) == null ? void 0 : _a.data) == null ? void 0 : _b.length) > 0;
|
|
39
|
+
const isImageMessage = ((_c = lastMessage.message) == null ? void 0 : _c.includes("<img")) || ((_d = lastMessage.message) == null ? void 0 : _d.includes("[Image]")) || ((_e = lastMessage.message) == null ? void 0 : _e.includes("![")) || /\.(jpeg|jpg|gif|png|bmp|webp)/i.test(lastMessage.message || "") && ((lastMessage.message || "").includes("http") || (lastMessage.message || "").includes("/images/"));
|
|
40
|
+
if (hasFileAttachments) {
|
|
41
|
+
displayMessage = "\u{1F4CE} File attachment";
|
|
42
|
+
} else if (isImageMessage) {
|
|
43
|
+
displayMessage = "[Image]";
|
|
44
|
+
} else if (lastMessage.message && lastMessage.message.trim() !== "") {
|
|
45
|
+
displayMessage = lastMessage.message;
|
|
46
|
+
} else {
|
|
47
|
+
displayMessage = "(Empty message)";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const displayDate = (lastMessage == null ? void 0 : lastMessage.createdAt) ? createdAtText(lastMessage.createdAt) : (lastMessage == null ? void 0 : lastMessage.updatedAt) ? createdAtText(lastMessage.updatedAt) : "";
|
|
51
|
+
return /* @__PURE__ */ React__default.createElement(HStack, { space: "sm", className: "flex-1 justify-between" }, /* @__PURE__ */ React__default.createElement(Box, { className: "flex-[0.8]" }, /* @__PURE__ */ React__default.createElement(Text, { color: colors.gray[600], className: "text-base text-wrap flex-wrap font-semibold" }, channelTitle), /* @__PURE__ */ React__default.createElement(Text, { color: colors.gray[600], numberOfLines: 1 }, displayMessage)), /* @__PURE__ */ React__default.createElement(Box, { className: "flex-[0.2]" }, /* @__PURE__ */ React__default.createElement(Text, { color: colors.gray[500] }, displayDate)));
|
|
52
|
+
};
|
|
53
|
+
const DialogItemComponent = function DialogItem2({
|
|
54
|
+
currentUser,
|
|
55
|
+
channel,
|
|
56
|
+
onOpen
|
|
57
|
+
}) {
|
|
58
|
+
const isMountedRef = useRef(true);
|
|
59
|
+
const [title, setTitle] = useState("");
|
|
60
|
+
const [subscriptionsTimestamp, setSubscriptionsTimestamp] = useState(Date.now());
|
|
61
|
+
const isServiceChannel = (channel == null ? void 0 : channel.type) === RoomType.Service;
|
|
62
|
+
const lastMessage = channel == null ? void 0 : channel.lastMessage;
|
|
63
|
+
const creatorAndMembersId = useMemo(() => {
|
|
64
|
+
var _a, _b, _c, _d, _e, _f;
|
|
65
|
+
if (!isServiceChannel || !(channel == null ? void 0 : channel.members))
|
|
66
|
+
return null;
|
|
67
|
+
const membersIds = (_c = (_b = (_a = channel == null ? void 0 : channel.members) == null ? void 0 : _a.filter((m) => {
|
|
68
|
+
var _a2;
|
|
69
|
+
return m !== null && ((_a2 = m == null ? void 0 : m.user) == null ? void 0 : _a2.id) !== (currentUser == null ? void 0 : currentUser.id);
|
|
70
|
+
})) == null ? void 0 : _b.map((mu) => {
|
|
71
|
+
var _a2;
|
|
72
|
+
return (_a2 = mu == null ? void 0 : mu.user) == null ? void 0 : _a2.id;
|
|
73
|
+
})) != null ? _c : [];
|
|
74
|
+
const creatorId = (_d = channel == null ? void 0 : channel.creator) == null ? void 0 : _d.id;
|
|
75
|
+
const mergedIds = (_e = [].concat(membersIds, creatorId)) != null ? _e : [];
|
|
76
|
+
return (_f = mergedIds == null ? void 0 : mergedIds.filter((m, pos) => (mergedIds == null ? void 0 : mergedIds.indexOf(m)) === pos)) != null ? _f : [];
|
|
77
|
+
}, [isServiceChannel, channel, currentUser]);
|
|
78
|
+
const postParentId = useMemo(() => {
|
|
79
|
+
var _a;
|
|
80
|
+
if (!isServiceChannel || !(creatorAndMembersId == null ? void 0 : creatorAndMembersId.length))
|
|
81
|
+
return null;
|
|
82
|
+
return (creatorAndMembersId == null ? void 0 : creatorAndMembersId.length) && (creatorAndMembersId == null ? void 0 : creatorAndMembersId.includes(currentUser == null ? void 0 : currentUser.id)) ? null : (lastMessage == null ? void 0 : lastMessage.parentId) ? lastMessage == null ? void 0 : lastMessage.parentId : (_a = lastMessage == null ? void 0 : lastMessage.id) != null ? _a : 0;
|
|
83
|
+
}, [isServiceChannel, creatorAndMembersId, lastMessage, currentUser]);
|
|
84
|
+
const channelMembers = useMemo(() => {
|
|
85
|
+
var _a, _b, _c;
|
|
86
|
+
if (isServiceChannel)
|
|
87
|
+
return [];
|
|
88
|
+
return (_c = (_b = (_a = channel == null ? void 0 : channel.members) == null ? void 0 : _a.filter((ch) => {
|
|
89
|
+
var _a2, _b2;
|
|
90
|
+
return ((_a2 = ch == null ? void 0 : ch.user) == null ? void 0 : _a2.id) !== (currentUser == null ? void 0 : currentUser.id) && ((_b2 = ch == null ? void 0 : ch.user) == null ? void 0 : _b2.__typename) === "UserAccount";
|
|
91
|
+
})) == null ? void 0 : _b.map((m) => m == null ? void 0 : m.user)) != null ? _c : [];
|
|
92
|
+
}, [isServiceChannel, currentUser == null ? void 0 : currentUser.id, channel == null ? void 0 : channel.members]);
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
var _a, _b;
|
|
95
|
+
if (!isServiceChannel && channelMembers.length > 0 && isMountedRef.current) {
|
|
96
|
+
const titleString = ((_b = (_a = channelMembers == null ? void 0 : channelMembers.map((u) => `${(u == null ? void 0 : u.givenName) || ""} ${(u == null ? void 0 : u.familyName) || ""}`.trim())) == null ? void 0 : _a.filter(Boolean)) == null ? void 0 : _b.join(", ")) || "";
|
|
97
|
+
setTitle(titleString);
|
|
98
|
+
} else if (isServiceChannel && (channel == null ? void 0 : channel.title)) {
|
|
99
|
+
setTitle(channel.title);
|
|
100
|
+
}
|
|
101
|
+
}, [isServiceChannel, channelMembers, channel == null ? void 0 : channel.title]);
|
|
102
|
+
const displayTitle = useMemo(() => {
|
|
103
|
+
const length = 30;
|
|
104
|
+
const titleToUse = isServiceChannel ? (channel == null ? void 0 : channel.title) || "" : title;
|
|
105
|
+
return titleToUse.length > length ? titleToUse.substring(0, length - 3) + "..." : titleToUse;
|
|
106
|
+
}, [isServiceChannel, channel == null ? void 0 : channel.title, title]);
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
isMountedRef.current = true;
|
|
109
|
+
return () => {
|
|
110
|
+
isMountedRef.current = false;
|
|
111
|
+
};
|
|
112
|
+
}, []);
|
|
113
|
+
useFocusEffect(useCallback(() => {
|
|
114
|
+
if (!(channel == null ? void 0 : channel.id))
|
|
115
|
+
return;
|
|
116
|
+
console.log(`DialogItem focused for ${isServiceChannel ? "service" : "direct"} channel:`, channel == null ? void 0 : channel.id);
|
|
117
|
+
if (isServiceChannel) {
|
|
118
|
+
setSubscriptionsTimestamp(Date.now());
|
|
119
|
+
}
|
|
120
|
+
}, [channel == null ? void 0 : channel.id, isServiceChannel]));
|
|
121
|
+
const handlePress = useCallback(() => {
|
|
122
|
+
if (isServiceChannel) {
|
|
123
|
+
onOpen(channel == null ? void 0 : channel.id, displayTitle, postParentId);
|
|
124
|
+
} else {
|
|
125
|
+
onOpen(channel == null ? void 0 : channel.id, displayTitle);
|
|
126
|
+
}
|
|
127
|
+
}, [isServiceChannel, channel == null ? void 0 : channel.id, displayTitle, postParentId, onOpen]);
|
|
128
|
+
const renderAvatar = () => {
|
|
129
|
+
var _a, _b, _c, _d;
|
|
130
|
+
if (isServiceChannel) {
|
|
131
|
+
return /* @__PURE__ */ React__default.createElement(Avatar, { key: "service-channels-key-" + (channel == null ? void 0 : channel.id), size: "sm", className: "bg-transparent top-0 right-0 z-[1]" }, /* @__PURE__ */ React__default.createElement(AvatarFallbackText, null, startCase((_b = (_a = channel == null ? void 0 : channel.creator) == null ? void 0 : _a.username) == null ? void 0 : _b.charAt(0))), /* @__PURE__ */ React__default.createElement(AvatarImage, { alt: "user image", style: {
|
|
132
|
+
borderRadius: 6,
|
|
133
|
+
borderWidth: 2,
|
|
134
|
+
borderColor: "#fff"
|
|
135
|
+
}, source: {
|
|
136
|
+
uri: (_c = channel == null ? void 0 : channel.creator) == null ? void 0 : _c.picture
|
|
137
|
+
} }));
|
|
138
|
+
}
|
|
139
|
+
return /* @__PURE__ */ React__default.createElement(AvatarGroup, null, channelMembers && (channelMembers == null ? void 0 : channelMembers.length) > 0 && ((_d = channelMembers == null ? void 0 : channelMembers.slice(0, 1)) == null ? void 0 : _d.map((ch, i) => {
|
|
140
|
+
var _a2;
|
|
141
|
+
return /* @__PURE__ */ React__default.createElement(Avatar, { key: "dialogs-list-" + i, size: "sm", className: `bg-transparent top-[${i === 1 ? "4" : "0"}] right-[${i === 1 ? "-2" : "0"}] z-[${i === 1 ? 5 : 1}]` }, /* @__PURE__ */ React__default.createElement(AvatarFallbackText, null, startCase((_a2 = ch == null ? void 0 : ch.username) == null ? void 0 : _a2.charAt(0))), (channelMembers == null ? void 0 : channelMembers.length) > 1 && /* @__PURE__ */ React__default.createElement(AvatarBadge, { style: {
|
|
142
|
+
width: "100%",
|
|
143
|
+
height: "100%",
|
|
144
|
+
backgroundColor: "#e5e7eb",
|
|
145
|
+
borderRadius: 5
|
|
146
|
+
}, className: "items-center justify-center bg-gray-200 rounded-md" }, /* @__PURE__ */ React__default.createElement(Text, { style: {
|
|
147
|
+
fontSize: 12,
|
|
148
|
+
fontWeight: "bold",
|
|
149
|
+
color: "#000"
|
|
150
|
+
} }, channelMembers == null ? void 0 : channelMembers.length)), (channelMembers == null ? void 0 : channelMembers.length) === 1 && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(AvatarImage, { alt: "user image", style: {
|
|
151
|
+
borderRadius: 6,
|
|
152
|
+
borderWidth: 2,
|
|
153
|
+
borderColor: "#fff"
|
|
154
|
+
}, source: {
|
|
155
|
+
uri: ch == null ? void 0 : ch.picture
|
|
156
|
+
} }), /* @__PURE__ */ React__default.createElement(AvatarBadge, { style: {
|
|
157
|
+
width: 10,
|
|
158
|
+
height: 10
|
|
159
|
+
} })));
|
|
160
|
+
})));
|
|
161
|
+
};
|
|
162
|
+
return /* @__PURE__ */ React__default.createElement(Pressable, { onPress: handlePress, className: "flex-1 border-gray-200 rounded-md dark:border-gray-600 dark:bg-gray-700", style: {
|
|
163
|
+
borderBottomWidth: 1,
|
|
164
|
+
borderColor: "#e5e7eb",
|
|
165
|
+
marginVertical: 0,
|
|
166
|
+
paddingHorizontal: isServiceChannel ? 2 : 10
|
|
167
|
+
} }, /* @__PURE__ */ React__default.createElement(HStack, { space: "md", className: "flex-1 w-[100%] py-3 items-center" }, /* @__PURE__ */ React__default.createElement(Box, { className: "flex-[0.1] items-start pl-3" }, renderAvatar()), /* @__PURE__ */ React__default.createElement(Box, { className: "flex-1" }, /* @__PURE__ */ React__default.createElement(LastMessageComponent, { key: isServiceChannel ? `service-channel-${channel == null ? void 0 : channel.id}-${subscriptionsTimestamp}` : `last-msg-${(lastMessage == null ? void 0 : lastMessage.id) || "none"}-${channelMembers.length}`, title: displayTitle, lastMessage, isServiceChannel }))));
|
|
168
|
+
};
|
|
169
|
+
const DialogItem = React__default.memo(DialogItemComponent);export{DialogItem,DialogItemComponent};//# sourceMappingURL=DialogItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DialogItem.js","sources":["../../../../src/screens/inbox/components/DialogItem.tsx"],"sourcesContent":["import React, { useMemo, useState, useCallback, useRef, useEffect } from 'react';\nimport {\n Text,\n Pressable,\n HStack,\n Box,\n AvatarGroup,\n Avatar,\n AvatarFallbackText,\n AvatarImage,\n AvatarBadge,\n} from '@admin-layout/gluestack-ui-mobile';\nimport { format, isToday, isYesterday } from 'date-fns';\nimport { useFocusEffect } from '@react-navigation/native';\nimport { IChannel, IUserAccount, RoomType } from 'common';\nimport { startCase } from 'lodash-es';\nimport colors from 'tailwindcss/colors';\n\n// Helper function to safely create a Date object\nconst safeDate = (dateValue: any): Date | null => {\n if (!dateValue) return null;\n\n try {\n const date = new Date(dateValue);\n if (isNaN(date.getTime())) {\n console.warn('Invalid date value detected:', dateValue);\n return null;\n }\n return date;\n } catch (error) {\n console.warn('Error creating date from value:', dateValue, error);\n return null;\n }\n};\n\nconst createdAtText = (value: string): string => {\n if (!value) return '';\n const date = safeDate(value);\n if (!date) return '';\n\n if (isToday(date)) return 'Today';\n if (isYesterday(date)) return 'Yesterday';\n return format(date, 'MMM dd, yyyy');\n};\n\nexport interface IDialogListChannel extends IChannel {\n users: IUserAccount[];\n}\n\nexport interface IDialogItemProps {\n currentUser?: any;\n channel?: any;\n onOpen: (id: any, title: any, postParentId?: any) => void;\n}\n\ninterface LastMessageComponentProps {\n title: string;\n lastMessage: any;\n isServiceChannel?: boolean;\n}\n\n// LastMessage component that works for both direct and service channels\nconst LastMessageComponent: React.FC<LastMessageComponentProps> = ({\n title,\n lastMessage,\n isServiceChannel = false,\n}) => {\n const count = 30;\n const channelTitle = title?.slice(0, count) + (title?.length > count ? '...' : '') || '';\n\n let displayMessage = 'No messages yet';\n\n if (lastMessage) {\n const hasFileAttachments = lastMessage.files?.data?.length > 0;\n const isImageMessage =\n lastMessage.message?.includes('<img') ||\n lastMessage.message?.includes('[Image]') ||\n lastMessage.message?.includes('![') ||\n (/\\.(jpeg|jpg|gif|png|bmp|webp)/i.test(lastMessage.message || '') &&\n ((lastMessage.message || '').includes('http') || (lastMessage.message || '').includes('/images/')));\n\n if (hasFileAttachments) {\n displayMessage = '📎 File attachment';\n } else if (isImageMessage) {\n displayMessage = '[Image]';\n } else if (lastMessage.message && lastMessage.message.trim() !== '') {\n displayMessage = lastMessage.message;\n } else {\n displayMessage = '(Empty message)';\n }\n }\n\n const displayDate = lastMessage?.createdAt\n ? createdAtText(lastMessage.createdAt)\n : lastMessage?.updatedAt\n ? createdAtText(lastMessage.updatedAt)\n : '';\n\n return (\n <HStack space={'sm'} className=\"flex-1 justify-between\">\n <Box className=\"flex-[0.8]\">\n <Text color={colors.gray[600]} className=\"text-base text-wrap flex-wrap font-semibold\">\n {channelTitle}\n </Text>\n <Text color={colors.gray[600]} numberOfLines={1}>\n {displayMessage}\n </Text>\n </Box>\n\n <Box className=\"flex-[0.2]\">\n <Text color={colors.gray[500]}>{displayDate}</Text>\n </Box>\n </HStack>\n );\n};\n\nexport const DialogItemComponent: React.FC<IDialogItemProps> = function DialogItem({ currentUser, channel, onOpen }) {\n const isMountedRef = useRef(true);\n const [title, setTitle] = useState('');\n const [subscriptionsTimestamp, setSubscriptionsTimestamp] = useState(Date.now());\n\n const isServiceChannel = channel?.type === RoomType.Service;\n\n // Use channel.lastMessage instead of computing it\n const lastMessage = channel?.lastMessage;\n\n // Service channel specific calculations\n const creatorAndMembersId = useMemo(() => {\n if (!isServiceChannel || !channel?.members) return null;\n const membersIds: any =\n channel?.members\n ?.filter((m: any) => m !== null && m?.user?.id !== currentUser?.id)\n ?.map((mu: any) => mu?.user?.id) ?? [];\n const creatorId: any = channel?.creator?.id;\n const mergedIds: any = [].concat(membersIds, creatorId) ?? [];\n return mergedIds?.filter((m: any, pos: any) => mergedIds?.indexOf(m) === pos) ?? [];\n }, [isServiceChannel, channel, currentUser]);\n\n const postParentId = useMemo(() => {\n if (!isServiceChannel || !creatorAndMembersId?.length) return null;\n return creatorAndMembersId?.length && creatorAndMembersId?.includes(currentUser?.id)\n ? null\n : lastMessage?.parentId\n ? lastMessage?.parentId\n : lastMessage?.id ?? 0;\n }, [isServiceChannel, creatorAndMembersId, lastMessage, currentUser]);\n\n // Channel members computation for direct channels\n const channelMembers = useMemo(() => {\n if (isServiceChannel) return [];\n return (\n channel?.members\n ?.filter((ch: any) => ch?.user?.id !== currentUser?.id && ch?.user?.__typename === 'UserAccount')\n ?.map((m: any) => m?.user) ?? []\n );\n }, [isServiceChannel, currentUser?.id, channel?.members]);\n\n // Set title when channel members change (for direct channels)\n useEffect(() => {\n if (!isServiceChannel && channelMembers.length > 0 && isMountedRef.current) {\n const titleString =\n channelMembers\n ?.map((u: any) => `${u?.givenName || ''} ${u?.familyName || ''}`.trim())\n ?.filter(Boolean)\n ?.join(', ') || '';\n setTitle(titleString);\n } else if (isServiceChannel && channel?.title) {\n setTitle(channel.title);\n }\n }, [isServiceChannel, channelMembers, channel?.title]);\n\n // Compute display title\n const displayTitle = useMemo(() => {\n const length = 30;\n const titleToUse = isServiceChannel ? channel?.title || '' : title;\n return titleToUse.length > length ? titleToUse.substring(0, length - 3) + '...' : titleToUse;\n }, [isServiceChannel, channel?.title, title]);\n\n // Set mounted state on mount/unmount\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n // Focus effect handling\n useFocusEffect(\n useCallback(() => {\n if (!channel?.id) return;\n\n console.log(`DialogItem focused for ${isServiceChannel ? 'service' : 'direct'} channel:`, channel?.id);\n\n if (isServiceChannel) {\n setSubscriptionsTimestamp(Date.now());\n }\n }, [channel?.id, isServiceChannel]),\n );\n\n // Handle press based on channel type\n const handlePress = useCallback(() => {\n if (isServiceChannel) {\n onOpen(channel?.id, displayTitle, postParentId);\n } else {\n onOpen(channel?.id, displayTitle);\n }\n }, [isServiceChannel, channel?.id, displayTitle, postParentId, onOpen]);\n\n // Render avatar based on channel type\n const renderAvatar = () => {\n if (isServiceChannel) {\n return (\n <Avatar\n key={'service-channels-key-' + channel?.id}\n size={'sm'}\n className=\"bg-transparent top-0 right-0 z-[1]\"\n >\n <AvatarFallbackText>{startCase(channel?.creator?.username?.charAt(0))}</AvatarFallbackText>\n <AvatarImage\n alt=\"user image\"\n style={{ borderRadius: 6, borderWidth: 2, borderColor: '#fff' }}\n source={{\n uri: channel?.creator?.picture,\n }}\n />\n </Avatar>\n );\n }\n\n return (\n <AvatarGroup>\n {channelMembers &&\n channelMembers?.length > 0 &&\n channelMembers?.slice(0, 1)?.map((ch: any, i: number) => (\n <Avatar\n key={'dialogs-list-' + i}\n size={'sm'}\n className={`bg-transparent top-[${i === 1 ? '4' : '0'}] right-[${\n i === 1 ? '-2' : '0'\n }] z-[${i === 1 ? 5 : 1}]`}\n >\n <AvatarFallbackText>{startCase(ch?.username?.charAt(0))}</AvatarFallbackText>\n {channelMembers?.length > 1 && (\n <AvatarBadge\n style={{\n width: '100%',\n height: '100%',\n backgroundColor: '#e5e7eb',\n borderRadius: 5,\n }}\n className=\"items-center justify-center bg-gray-200 rounded-md\"\n >\n <Text style={{ fontSize: 12, fontWeight: 'bold', color: '#000' }}>\n {channelMembers?.length}\n </Text>\n </AvatarBadge>\n )}\n {channelMembers?.length === 1 && (\n <>\n <AvatarImage\n alt=\"user image\"\n style={{ borderRadius: 6, borderWidth: 2, borderColor: '#fff' }}\n source={{\n uri: ch?.picture,\n }}\n />\n <AvatarBadge style={{ width: 10, height: 10 }} />\n </>\n )}\n </Avatar>\n ))}\n </AvatarGroup>\n );\n };\n\n return (\n <Pressable\n onPress={handlePress}\n className=\"flex-1 border-gray-200 rounded-md dark:border-gray-600 dark:bg-gray-700\"\n style={{\n borderBottomWidth: 1,\n borderColor: '#e5e7eb',\n marginVertical: 0,\n paddingHorizontal: isServiceChannel ? 2 : 10,\n }}\n >\n <HStack space={'md'} className=\"flex-1 w-[100%] py-3 items-center\">\n <Box className=\"flex-[0.1] items-start pl-3\">{renderAvatar()}</Box>\n <Box className=\"flex-1\">\n <LastMessageComponent\n key={\n isServiceChannel\n ? `service-channel-${channel?.id}-${subscriptionsTimestamp}`\n : `last-msg-${lastMessage?.id || 'none'}-${channelMembers.length}`\n }\n title={displayTitle}\n lastMessage={lastMessage}\n isServiceChannel={isServiceChannel}\n />\n </Box>\n </HStack>\n </Pressable>\n );\n};\n\nexport const DialogItem = React.memo(DialogItemComponent);\n"],"names":["React","DialogItem","_a","_b"],"mappings":"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"}
|