@developer_tribe/react-native-comnyx 0.14.0 → 0.16.0

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 (213) hide show
  1. package/Comnyx.podspec +10 -2
  2. package/README.md +50 -0
  3. package/android/build.gradle +1 -0
  4. package/android/consumer-rules.pro +23 -0
  5. package/android/generated/java/com/comnyx/NativeComnyxSpec.java +46 -0
  6. package/android/generated/jni/RNComnyxSpec-generated.cpp +23 -1
  7. package/android/generated/jni/RNComnyxSpec.h +7 -0
  8. package/android/generated/jni/react/renderer/components/RNComnyxSpec/RNComnyxSpecJSI-generated.cpp +21 -0
  9. package/android/generated/jni/react/renderer/components/RNComnyxSpec/RNComnyxSpecJSI.h +70 -0
  10. package/android/src/main/AndroidManifest.xml +11 -1
  11. package/android/src/main/AndroidManifestNew.xml +11 -1
  12. package/android/src/main/java/com/comnyx/ComnyxMediaPickerModule.kt +105 -19
  13. package/android/src/main/java/com/comnyx/ComnyxModule.kt +7 -0
  14. package/android/src/main/java/com/comnyx/src/messaging/firebase/FirebaseMessagingService.kt +4 -6
  15. package/android/src/main/res/xml/comnyx_file_paths.xml +12 -0
  16. package/ios/APNService.swift +9 -9
  17. package/ios/Comnyx.swift +17 -8
  18. package/ios/ComnyxMediaPicker.m +6 -0
  19. package/ios/ComnyxMediaPicker.swift +106 -26
  20. package/ios/ComnyxMessaging.swift +2 -0
  21. package/ios/PrivacyInfo.xcprivacy +32 -0
  22. package/ios/comnyx_post_install.rb +25 -0
  23. package/ios/generated/RCTAppDependencyProvider.h +25 -0
  24. package/ios/generated/RCTAppDependencyProvider.mm +55 -0
  25. package/ios/generated/RCTModulesConformingToProtocolsProvider.h +18 -0
  26. package/ios/generated/RCTModulesConformingToProtocolsProvider.mm +33 -0
  27. package/ios/generated/RCTThirdPartyComponentsProvider.h +16 -0
  28. package/ios/generated/RCTThirdPartyComponentsProvider.mm +23 -0
  29. package/ios/generated/RNComnyxSpec/RNComnyxSpec-generated.mm +53 -0
  30. package/ios/generated/RNComnyxSpec/RNComnyxSpec.h +67 -0
  31. package/ios/generated/RNComnyxSpecJSI-generated.cpp +38 -0
  32. package/ios/generated/RNComnyxSpecJSI.h +89 -0
  33. package/ios/generated/ReactAppDependencyProvider.podspec +34 -0
  34. package/lib/commonjs/NativeComnyxMediaPicker.js +46 -6
  35. package/lib/commonjs/NativeComnyxMediaPicker.js.map +1 -1
  36. package/lib/commonjs/api/conversations.js +6 -6
  37. package/lib/commonjs/api/conversations.js.map +1 -1
  38. package/lib/commonjs/api/customers.js +3 -2
  39. package/lib/commonjs/api/customers.js.map +1 -1
  40. package/lib/commonjs/api/media.js +20 -6
  41. package/lib/commonjs/api/media.js.map +1 -1
  42. package/lib/commonjs/api/messages.js +3 -2
  43. package/lib/commonjs/api/messages.js.map +1 -1
  44. package/lib/commonjs/assets/gallery.png +0 -0
  45. package/lib/commonjs/assets/video-play.png +0 -0
  46. package/lib/commonjs/components/ChatList.js +93 -45
  47. package/lib/commonjs/components/ChatList.js.map +1 -1
  48. package/lib/commonjs/components/ComnyxErrorBoundary.js +92 -0
  49. package/lib/commonjs/components/ComnyxErrorBoundary.js.map +1 -0
  50. package/lib/commonjs/components/CustomerForm.js +2 -2
  51. package/lib/commonjs/components/CustomerForm.js.map +1 -1
  52. package/lib/commonjs/components/MediaMessageItem.js +4 -3
  53. package/lib/commonjs/components/MediaMessageItem.js.map +1 -1
  54. package/lib/commonjs/components/MediaPickerButton.js +211 -14
  55. package/lib/commonjs/components/MediaPickerButton.js.map +1 -1
  56. package/lib/commonjs/components/MediaViewerModal.js +7 -0
  57. package/lib/commonjs/components/MediaViewerModal.js.map +1 -1
  58. package/lib/commonjs/components/MessageInput.js +63 -13
  59. package/lib/commonjs/components/MessageInput.js.map +1 -1
  60. package/lib/commonjs/components/MessageItem.js +1 -2
  61. package/lib/commonjs/components/MessageItem.js.map +1 -1
  62. package/lib/commonjs/constants/translations.js +87 -116
  63. package/lib/commonjs/constants/translations.js.map +1 -1
  64. package/lib/commonjs/hooks/usePolling.js +25 -21
  65. package/lib/commonjs/hooks/usePolling.js.map +1 -1
  66. package/lib/commonjs/hooks/useThemeColors.js +12 -1
  67. package/lib/commonjs/hooks/useThemeColors.js.map +1 -1
  68. package/lib/commonjs/index.js.map +1 -1
  69. package/lib/commonjs/notifications/initializeNotifications.js +19 -16
  70. package/lib/commonjs/notifications/initializeNotifications.js.map +1 -1
  71. package/lib/commonjs/register/Accumulator.js +19 -6
  72. package/lib/commonjs/register/Accumulator.js.map +1 -1
  73. package/lib/commonjs/register/collectData.js +1 -1
  74. package/lib/commonjs/register/collectData.js.map +1 -1
  75. package/lib/commonjs/store/store.js +6 -0
  76. package/lib/commonjs/store/store.js.map +1 -1
  77. package/lib/commonjs/support/ComnyxSupport.js +60 -15
  78. package/lib/commonjs/support/ComnyxSupport.js.map +1 -1
  79. package/lib/commonjs/support/SupportConfigContext.js +24 -0
  80. package/lib/commonjs/support/SupportConfigContext.js.map +1 -0
  81. package/lib/commonjs/types/Theme.js +30 -2
  82. package/lib/commonjs/types/Theme.js.map +1 -1
  83. package/lib/commonjs/version.js +1 -1
  84. package/lib/module/NativeComnyxMediaPicker.js +43 -6
  85. package/lib/module/NativeComnyxMediaPicker.js.map +1 -1
  86. package/lib/module/api/conversations.js +6 -6
  87. package/lib/module/api/conversations.js.map +1 -1
  88. package/lib/module/api/customers.js +3 -2
  89. package/lib/module/api/customers.js.map +1 -1
  90. package/lib/module/api/media.js +21 -6
  91. package/lib/module/api/media.js.map +1 -1
  92. package/lib/module/api/messages.js +3 -2
  93. package/lib/module/api/messages.js.map +1 -1
  94. package/lib/module/assets/gallery.png +0 -0
  95. package/lib/module/assets/video-play.png +0 -0
  96. package/lib/module/components/ChatList.js +94 -46
  97. package/lib/module/components/ChatList.js.map +1 -1
  98. package/lib/module/components/ComnyxErrorBoundary.js +87 -0
  99. package/lib/module/components/ComnyxErrorBoundary.js.map +1 -0
  100. package/lib/module/components/CustomerForm.js +2 -2
  101. package/lib/module/components/CustomerForm.js.map +1 -1
  102. package/lib/module/components/MediaMessageItem.js +4 -3
  103. package/lib/module/components/MediaMessageItem.js.map +1 -1
  104. package/lib/module/components/MediaPickerButton.js +215 -18
  105. package/lib/module/components/MediaPickerButton.js.map +1 -1
  106. package/lib/module/components/MediaViewerModal.js +8 -1
  107. package/lib/module/components/MediaViewerModal.js.map +1 -1
  108. package/lib/module/components/MessageInput.js +64 -14
  109. package/lib/module/components/MessageInput.js.map +1 -1
  110. package/lib/module/components/MessageItem.js +1 -2
  111. package/lib/module/components/MessageItem.js.map +1 -1
  112. package/lib/module/constants/translations.js +87 -116
  113. package/lib/module/constants/translations.js.map +1 -1
  114. package/lib/module/hooks/usePolling.js +25 -21
  115. package/lib/module/hooks/usePolling.js.map +1 -1
  116. package/lib/module/hooks/useThemeColors.js +13 -2
  117. package/lib/module/hooks/useThemeColors.js.map +1 -1
  118. package/lib/module/index.js +0 -1
  119. package/lib/module/index.js.map +1 -1
  120. package/lib/module/notifications/initializeNotifications.js +19 -16
  121. package/lib/module/notifications/initializeNotifications.js.map +1 -1
  122. package/lib/module/register/Accumulator.js +19 -6
  123. package/lib/module/register/Accumulator.js.map +1 -1
  124. package/lib/module/register/collectData.js +1 -1
  125. package/lib/module/register/collectData.js.map +1 -1
  126. package/lib/module/store/store.js +6 -0
  127. package/lib/module/store/store.js.map +1 -1
  128. package/lib/module/support/ComnyxSupport.js +61 -16
  129. package/lib/module/support/ComnyxSupport.js.map +1 -1
  130. package/lib/module/support/SupportConfigContext.js +19 -0
  131. package/lib/module/support/SupportConfigContext.js.map +1 -0
  132. package/lib/module/types/Theme.js +30 -2
  133. package/lib/module/types/Theme.js.map +1 -1
  134. package/lib/module/version.js +1 -1
  135. package/lib/typescript/src/NativeComnyxMediaPicker.d.ts +11 -0
  136. package/lib/typescript/src/NativeComnyxMediaPicker.d.ts.map +1 -1
  137. package/lib/typescript/src/api/conversations.d.ts +2 -2
  138. package/lib/typescript/src/api/conversations.d.ts.map +1 -1
  139. package/lib/typescript/src/api/customers.d.ts +1 -1
  140. package/lib/typescript/src/api/customers.d.ts.map +1 -1
  141. package/lib/typescript/src/api/media.d.ts +3 -3
  142. package/lib/typescript/src/api/media.d.ts.map +1 -1
  143. package/lib/typescript/src/api/messages.d.ts +1 -1
  144. package/lib/typescript/src/api/messages.d.ts.map +1 -1
  145. package/lib/typescript/src/components/ChatList.d.ts.map +1 -1
  146. package/lib/typescript/src/components/ComnyxErrorBoundary.d.ts +18 -0
  147. package/lib/typescript/src/components/ComnyxErrorBoundary.d.ts.map +1 -0
  148. package/lib/typescript/src/components/MediaMessageItem.d.ts.map +1 -1
  149. package/lib/typescript/src/components/MediaPickerButton.d.ts.map +1 -1
  150. package/lib/typescript/src/components/MediaViewerModal.d.ts.map +1 -1
  151. package/lib/typescript/src/components/MessageInput.d.ts.map +1 -1
  152. package/lib/typescript/src/components/MessageItem.d.ts.map +1 -1
  153. package/lib/typescript/src/constants/translations.d.ts.map +1 -1
  154. package/lib/typescript/src/hooks/usePolling.d.ts.map +1 -1
  155. package/lib/typescript/src/hooks/useThemeColors.d.ts.map +1 -1
  156. package/lib/typescript/src/index.d.ts +2 -0
  157. package/lib/typescript/src/index.d.ts.map +1 -1
  158. package/lib/typescript/src/notifications/initializeNotifications.d.ts.map +1 -1
  159. package/lib/typescript/src/register/Accumulator.d.ts.map +1 -1
  160. package/lib/typescript/src/register/collectData.d.ts +4 -1
  161. package/lib/typescript/src/register/collectData.d.ts.map +1 -1
  162. package/lib/typescript/src/store/store.d.ts +6 -2
  163. package/lib/typescript/src/store/store.d.ts.map +1 -1
  164. package/lib/typescript/src/support/ComnyxSupport.d.ts +56 -2
  165. package/lib/typescript/src/support/ComnyxSupport.d.ts.map +1 -1
  166. package/lib/typescript/src/support/SupportConfigContext.d.ts +58 -0
  167. package/lib/typescript/src/support/SupportConfigContext.d.ts.map +1 -0
  168. package/lib/typescript/src/support/index.d.ts +1 -0
  169. package/lib/typescript/src/support/index.d.ts.map +1 -1
  170. package/lib/typescript/src/types/Conversation.d.ts +2 -2
  171. package/lib/typescript/src/types/Conversation.d.ts.map +1 -1
  172. package/lib/typescript/src/types/Customer.d.ts +1 -1
  173. package/lib/typescript/src/types/Customer.d.ts.map +1 -1
  174. package/lib/typescript/src/types/LocalizationKeys.d.ts +0 -1
  175. package/lib/typescript/src/types/LocalizationKeys.d.ts.map +1 -1
  176. package/lib/typescript/src/types/MessageResponse.d.ts +7 -4
  177. package/lib/typescript/src/types/MessageResponse.d.ts.map +1 -1
  178. package/lib/typescript/src/types/Theme.d.ts +26 -0
  179. package/lib/typescript/src/types/Theme.d.ts.map +1 -1
  180. package/lib/typescript/src/version.d.ts +1 -1
  181. package/package.json +12 -25
  182. package/src/NativeComnyxMediaPicker.ts +46 -7
  183. package/src/api/conversations.ts +6 -4
  184. package/src/api/customers.ts +3 -1
  185. package/src/api/media.ts +32 -10
  186. package/src/api/messages.ts +3 -1
  187. package/src/assets/gallery.png +0 -0
  188. package/src/assets/video-play.png +0 -0
  189. package/src/components/ChatList.tsx +115 -55
  190. package/src/components/ComnyxErrorBoundary.tsx +91 -0
  191. package/src/components/CustomerForm.tsx +2 -2
  192. package/src/components/MediaMessageItem.tsx +10 -3
  193. package/src/components/MediaPickerButton.tsx +238 -17
  194. package/src/components/MediaViewerModal.tsx +8 -1
  195. package/src/components/MessageInput.tsx +89 -16
  196. package/src/components/MessageItem.tsx +12 -14
  197. package/src/constants/translations.ts +87 -116
  198. package/src/hooks/usePolling.ts +21 -11
  199. package/src/hooks/useThemeColors.ts +11 -2
  200. package/src/index.ts +12 -0
  201. package/src/notifications/initializeNotifications.ts +22 -20
  202. package/src/register/Accumulator.ts +26 -9
  203. package/src/register/collectData.ts +10 -2
  204. package/src/store/store.ts +11 -3
  205. package/src/support/ComnyxSupport.tsx +128 -22
  206. package/src/support/SupportConfigContext.tsx +79 -0
  207. package/src/support/index.ts +7 -0
  208. package/src/types/Conversation.ts +2 -2
  209. package/src/types/Customer.ts +1 -2
  210. package/src/types/LocalizationKeys.ts +0 -1
  211. package/src/types/MessageResponse.ts +4 -4
  212. package/src/types/Theme.ts +38 -0
  213. package/src/version.ts +1 -1
@@ -6,7 +6,7 @@ import {
6
6
  StatusBar,
7
7
  useWindowDimensions,
8
8
  } from 'react-native';
9
- import { useState } from 'react';
9
+ import { useState, useEffect } from 'react';
10
10
  import { AppText } from './AppText';
11
11
  import { ScaledSheet } from './ScaledSheet';
12
12
  import { activeOpacity } from '../constants/activeOpacity';
@@ -29,6 +29,12 @@ export function MediaViewerModal({
29
29
  const [imageError, setImageError] = useState(false);
30
30
  const isVideo = mediaType === 'video';
31
31
  const displayUri = isVideo ? thumbnailUri || undefined : mediaUri;
32
+ // Reset error state when URI or visibility changes
33
+ useEffect(() => {
34
+ if (visible) {
35
+ setImageError(false);
36
+ }
37
+ }, [visible, mediaUri]);
32
38
 
33
39
  const handlePlayVideo = () => {
34
40
  if (mediaUri) {
@@ -61,6 +67,7 @@ export function MediaViewerModal({
61
67
  source={{ uri: displayUri }}
62
68
  style={{ width, height: height * 0.9 }}
63
69
  resizeMode="contain"
70
+ resizeMethod="resize"
64
71
  onError={() => setImageError(true)}
65
72
  />
66
73
  ) : (
@@ -5,7 +5,7 @@ import {
5
5
  TouchableOpacity,
6
6
  ScrollView,
7
7
  } from 'react-native';
8
- import { useState, useCallback } from 'react';
8
+ import { useState, useCallback, useEffect, useRef } from 'react';
9
9
  import { sendCustomerMessage } from '../api';
10
10
  import { getUploadUrl, uploadFileToS3, sendMediaMessage } from '../api';
11
11
  import { deleteTempFile } from '../NativeComnyxMediaPicker';
@@ -17,6 +17,7 @@ import { useIsRtl } from '../hooks/isRtl';
17
17
  import { useAppStore } from '../store/store';
18
18
  import { MediaPickerButton } from './MediaPickerButton';
19
19
  import type { MediaAsset } from '../types/MediaTypes';
20
+ import { useSupportConfig } from '../support/SupportConfigContext';
20
21
 
21
22
  const sendDark = require('../assets/arrow-right.png');
22
23
  const circleXIcon = require('../assets/x-circle.png');
@@ -34,6 +35,20 @@ export function MessageInput({
34
35
  const themeColors = useThemeColors();
35
36
  const localize = useLocalize();
36
37
  const isRtl = useIsRtl();
38
+ const { onBeforeSend } = useSupportConfig();
39
+
40
+ const uploadAbortRef = useRef<AbortController | null>(null);
41
+ const lifecycleAbortRef = useRef<AbortController | null>(null);
42
+ if (lifecycleAbortRef.current === null) {
43
+ lifecycleAbortRef.current = new AbortController();
44
+ }
45
+ useEffect(() => {
46
+ const controller = lifecycleAbortRef.current;
47
+ return () => {
48
+ uploadAbortRef.current?.abort();
49
+ controller?.abort();
50
+ };
51
+ }, []);
37
52
 
38
53
  const sendTextOnlyMessage = useCallback(() => {
39
54
  if (!value.trim()) return;
@@ -53,10 +68,14 @@ export function MessageInput({
53
68
  },
54
69
  ...(data ?? []),
55
70
  ]);
56
- sendCustomerMessage(customer.external_id as string, value, {
57
- fake: useAppStore.getState().fake,
58
- })
71
+ sendCustomerMessage(
72
+ customer.external_id as string,
73
+ value,
74
+ { fake: useAppStore.getState().fake },
75
+ lifecycleAbortRef.current?.signal
76
+ )
59
77
  .then((res) => {
78
+ if (lifecycleAbortRef.current?.signal.aborted) return;
60
79
  const data = useAppStore.getState().data;
61
80
  if (data) {
62
81
  const itemIndex = data.findIndex((item) => item.local_id === localId);
@@ -114,6 +133,7 @@ export function MessageInput({
114
133
  async (
115
134
  asset: MediaAsset,
116
135
  isFake: boolean,
136
+ signal: AbortSignal,
117
137
  onProgress?: (percentage: number) => void
118
138
  ): Promise<string> => {
119
139
  const presignResponse = await getUploadUrl(
@@ -124,9 +144,14 @@ export function MessageInput({
124
144
  const uploadUrl = presignResponse.data.url;
125
145
  const filePath = presignResponse.data.path;
126
146
 
127
- await uploadFileToS3(uploadUrl, asset.uri, asset.mimeType, onProgress, {
128
- fake: isFake,
129
- });
147
+ await uploadFileToS3(
148
+ uploadUrl,
149
+ asset.uri,
150
+ asset.mimeType,
151
+ onProgress,
152
+ { fake: isFake },
153
+ signal
154
+ );
130
155
 
131
156
  return isFake ? asset.uri : filePath;
132
157
  },
@@ -166,6 +191,10 @@ export function MessageInput({
166
191
  ]);
167
192
  scrollToBottom(false);
168
193
 
194
+ uploadAbortRef.current?.abort();
195
+ const controller = new AbortController();
196
+ uploadAbortRef.current = controller;
197
+
169
198
  try {
170
199
  const fileProgresses = new Array(assets.length).fill(0);
171
200
  let lastProgressUpdate = 0;
@@ -198,6 +227,7 @@ export function MessageInput({
198
227
  const path = await uploadSingleMedia(
199
228
  assets[i]!,
200
229
  isFake,
230
+ controller.signal,
201
231
  (percentage) => {
202
232
  fileProgresses[i] = percentage;
203
233
  updateOverallProgress();
@@ -211,7 +241,8 @@ export function MessageInput({
211
241
  uploadedPaths,
212
242
  assets[0]!.type,
213
243
  content,
214
- { fake: isFake }
244
+ { fake: isFake },
245
+ controller.signal
215
246
  );
216
247
 
217
248
  const currentData = useAppStore.getState().data;
@@ -265,6 +296,10 @@ export function MessageInput({
265
296
  }
266
297
  }
267
298
  console.error('[Comnyx] Media upload failed:', error);
299
+ } finally {
300
+ if (uploadAbortRef.current === controller) {
301
+ uploadAbortRef.current = null;
302
+ }
268
303
  }
269
304
  },
270
305
  [customer, scrollToBottom, uploadSingleMedia]
@@ -294,18 +329,45 @@ export function MessageInput({
294
329
  const handleSend = useCallback(async () => {
295
330
  if (isSending) return;
296
331
 
297
- if (pendingMedia.length > 0) {
298
- setIsSending(true);
332
+ const hasMedia = pendingMedia.length > 0;
333
+ const hasText = !!value.trim();
334
+ if (!hasMedia && !hasText) return;
335
+
336
+ if (onBeforeSend) {
337
+ try {
338
+ setIsSending(true);
339
+ await onBeforeSend({
340
+ content: value.trim(),
341
+ mediaCount: pendingMedia.length,
342
+ mediaTypes: pendingMedia.map((m) => m.type),
343
+ });
344
+ } catch (err) {
345
+ console.warn('[Comnyx] onBeforeSend cancelled the message:', err);
346
+ setIsSending(false);
347
+ return;
348
+ }
349
+ }
350
+
351
+ if (hasMedia) {
352
+ if (!onBeforeSend) setIsSending(true);
299
353
  const content = value.trim();
300
354
  const assets = [...pendingMedia];
301
355
  setPendingMedia([]);
302
356
  setValue('');
303
357
  await sendMediaMessages(assets, content);
304
358
  setIsSending(false);
305
- } else if (value.trim()) {
359
+ } else if (hasText) {
306
360
  sendTextOnlyMessage();
361
+ if (onBeforeSend) setIsSending(false);
307
362
  }
308
- }, [isSending, pendingMedia, value, sendMediaMessages, sendTextOnlyMessage]);
363
+ }, [
364
+ isSending,
365
+ pendingMedia,
366
+ value,
367
+ sendMediaMessages,
368
+ sendTextOnlyMessage,
369
+ onBeforeSend,
370
+ ]);
309
371
 
310
372
  const hasPendingMedia = pendingMedia.length > 0;
311
373
 
@@ -335,8 +397,18 @@ export function MessageInput({
335
397
  />
336
398
  {asset.type === 'video' && (
337
399
  <View style={styles.playIconOverlay}>
338
- <View style={styles.playIcon}>
339
- <View style={styles.playTriangle} />
400
+ <View
401
+ style={[
402
+ styles.playIcon,
403
+ { borderColor: themeColors.playIcon },
404
+ ]}
405
+ >
406
+ <View
407
+ style={[
408
+ styles.playTriangle,
409
+ { borderLeftColor: themeColors.playIcon },
410
+ ]}
411
+ />
340
412
  </View>
341
413
  </View>
342
414
  )}
@@ -375,6 +447,9 @@ export function MessageInput({
375
447
  onPress={handleSend}
376
448
  activeOpacity={activeOpacity}
377
449
  disabled={isSending}
450
+ accessibilityRole="button"
451
+ accessibilityLabel={localize('chat.messageInput.placeholder')}
452
+ accessibilityState={{ disabled: isSending, busy: isSending }}
378
453
  >
379
454
  <Image
380
455
  style={[
@@ -441,7 +516,6 @@ const styles = ScaledSheet.create({
441
516
  height: '22@vs',
442
517
  borderRadius: '11@vs',
443
518
  borderWidth: 1.5,
444
- borderColor: '#fff',
445
519
  justifyContent: 'center',
446
520
  alignItems: 'center',
447
521
  },
@@ -451,7 +525,6 @@ const styles = ScaledSheet.create({
451
525
  borderLeftWidth: '7@vs',
452
526
  borderTopWidth: '5@vs',
453
527
  borderBottomWidth: '5@vs',
454
- borderLeftColor: '#fff',
455
528
  borderTopColor: 'transparent',
456
529
  borderBottomColor: 'transparent',
457
530
  marginLeft: '2@s',
@@ -1,4 +1,11 @@
1
- import { View, Image, TouchableOpacity, Linking } from 'react-native';
1
+ import {
2
+ View,
3
+ Image,
4
+ TouchableOpacity,
5
+ Linking,
6
+ type NativeSyntheticEvent,
7
+ type TextLayoutEventData,
8
+ } from 'react-native';
2
9
  import { AppText } from './AppText';
3
10
  import type { AppConversationMessage } from '../types/Conversation';
4
11
  import { useThemeColors } from '../hooks/useThemeColors';
@@ -11,14 +18,6 @@ import { MediaMessageItem } from './MediaMessageItem';
11
18
  const clockIcon = require('../assets/iconamoon_clock-fill.png');
12
19
  const infoIcon = require('../assets/info-circle.png');
13
20
 
14
- interface TextLine {
15
- width: number;
16
- height: number;
17
- x: number;
18
- y: number;
19
- text: string;
20
- }
21
-
22
21
  interface MessageLayout {
23
22
  lines: number;
24
23
  lastLineWidth: number;
@@ -90,7 +89,7 @@ function TextMessageItem({
90
89
  }
91
90
  };
92
91
 
93
- const onTextLayout = (event: any) => {
92
+ const onTextLayout = (event: NativeSyntheticEvent<TextLayoutEventData>) => {
94
93
  const { lines } = event.nativeEvent;
95
94
 
96
95
  const numLines = lines.length;
@@ -99,9 +98,9 @@ function TextMessageItem({
99
98
 
100
99
  if (numLines >= 1) {
101
100
  // Get the width of the last line
102
- lastLineWidth = lines[numLines - 1].width;
101
+ lastLineWidth = lines[numLines - 1]!.width;
103
102
  // Use the widest line as the total width
104
- totalWidth = Math.max(...lines.map((line: TextLine) => line.width));
103
+ totalWidth = Math.max(...lines.map((line) => line.width));
105
104
  }
106
105
 
107
106
  layoutRef.current = {
@@ -183,9 +182,8 @@ function TextMessageItem({
183
182
  {
184
183
  regex:
185
184
  /https?:\/\/(?:[-\w.])+(?::[0-9]+)?(?:\/(?:[\w/_.])*(?:\?(?:[\w&=%.])*)?(?:#(?:[\w.])*)?)?/g,
186
- color: '#0066CC',
185
+ color: themeColors.link,
187
186
  navigate: (url) => {
188
- console.log('url', url);
189
187
  if (url) {
190
188
  Linking.openURL(url);
191
189
  }