@droppii-org/chat-mobile 0.2.24 → 0.2.26

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 (178) hide show
  1. package/lib/module/assets/images/btn_resend.png +0 -0
  2. package/lib/module/assets/images/index.js +2 -1
  3. package/lib/module/assets/images/index.js.map +1 -1
  4. package/lib/module/components/AttachmentPreview/FilePreview.js +1 -1
  5. package/lib/module/components/AttachmentPreview/FilePreview.js.map +1 -1
  6. package/lib/module/components/flows/inputButtons/index.js +3 -6
  7. package/lib/module/components/flows/inputButtons/index.js.map +1 -1
  8. package/lib/module/components/messages/MessageStatusIndicator.js +70 -0
  9. package/lib/module/components/messages/MessageStatusIndicator.js.map +1 -0
  10. package/lib/module/components/messages/fileMessage/index.js +1 -1
  11. package/lib/module/components/messages/fileMessage/index.js.map +1 -1
  12. package/lib/module/components/messages/imageMessage/index.js +60 -51
  13. package/lib/module/components/messages/imageMessage/index.js.map +1 -1
  14. package/lib/module/components/messages/linkMessage/index.js +17 -9
  15. package/lib/module/components/messages/linkMessage/index.js.map +1 -1
  16. package/lib/module/components/messages/mergedMessage/index.js +5 -8
  17. package/lib/module/components/messages/mergedMessage/index.js.map +1 -1
  18. package/lib/module/components/messages/styles.js +12 -0
  19. package/lib/module/components/messages/styles.js.map +1 -1
  20. package/lib/module/components/messages/textMessage/index.js +20 -9
  21. package/lib/module/components/messages/textMessage/index.js.map +1 -1
  22. package/lib/module/components/messages/videoMessage/index.js +7 -11
  23. package/lib/module/components/messages/videoMessage/index.js.map +1 -1
  24. package/lib/module/config/uploadLimits.js +1 -1
  25. package/lib/module/config/uploadLimits.js.map +1 -1
  26. package/lib/module/core/useChatListener.js +35 -4
  27. package/lib/module/core/useChatListener.js.map +1 -1
  28. package/lib/module/core/useUserListener.js +17 -7
  29. package/lib/module/core/useUserListener.js.map +1 -1
  30. package/lib/module/hooks/message/useSendMessage.js +62 -15
  31. package/lib/module/hooks/message/useSendMessage.js.map +1 -1
  32. package/lib/module/hooks/useChatCompose.js +39 -28
  33. package/lib/module/hooks/useChatCompose.js.map +1 -1
  34. package/lib/module/hooks/useChatMessages.js +39 -8
  35. package/lib/module/hooks/useChatMessages.js.map +1 -1
  36. package/lib/module/hooks/useFileAttachment.js +1 -1
  37. package/lib/module/hooks/useFileAttachment.js.map +1 -1
  38. package/lib/module/hooks/useFileDownload.js +1 -1
  39. package/lib/module/hooks/useFileDownload.js.map +1 -1
  40. package/lib/module/hooks/useImageAttachment.js +12 -3
  41. package/lib/module/hooks/useImageAttachment.js.map +1 -1
  42. package/lib/module/index.js +1 -0
  43. package/lib/module/index.js.map +1 -1
  44. package/lib/module/screens/chat-detail/ChatDetail.js +24 -1
  45. package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
  46. package/lib/module/screens/chat-detail/ChatListLegend.js +40 -28
  47. package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
  48. package/lib/module/screens/chat-detail/constants.js +3 -2
  49. package/lib/module/screens/chat-detail/constants.js.map +1 -1
  50. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +48 -15
  51. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
  52. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxMenu.js +98 -0
  53. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxMenu.js.map +1 -0
  54. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxOverlay.js +110 -0
  55. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxOverlay.js.map +1 -0
  56. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js +64 -0
  57. package/lib/module/screens/chat-detail/messageToolbox/MessageToolboxWrapper.js.map +1 -0
  58. package/lib/module/screens/chat-detail/messageToolbox/messageToolbox.utils.js +37 -0
  59. package/lib/module/screens/chat-detail/messageToolbox/messageToolbox.utils.js.map +1 -0
  60. package/lib/module/screens/chat-detail/messageToolbox/types.js +4 -0
  61. package/lib/module/screens/chat-detail/messageToolbox/types.js.map +1 -0
  62. package/lib/module/services/attachmentOrchestrator.js +34 -12
  63. package/lib/module/services/attachmentOrchestrator.js.map +1 -1
  64. package/lib/module/services/message.js +13 -5
  65. package/lib/module/services/message.js.map +1 -1
  66. package/lib/module/translation/resources/i18n.js +9 -3
  67. package/lib/module/translation/resources/i18n.js.map +1 -1
  68. package/lib/module/types/chat.js.map +1 -1
  69. package/lib/module/types/global.d.js +2 -0
  70. package/lib/module/types/global.d.js.map +1 -0
  71. package/lib/module/types/index.d.js +3 -0
  72. package/lib/module/types/index.d.js.map +1 -0
  73. package/lib/module/utils/UIUtils.js +37 -0
  74. package/lib/module/utils/UIUtils.js.map +1 -0
  75. package/lib/module/utils/ui.js +15 -13
  76. package/lib/module/utils/ui.js.map +1 -1
  77. package/lib/module/utils/videoThumbnailUpload.js +1 -1
  78. package/lib/module/utils/videoThumbnailUpload.js.map +1 -1
  79. package/lib/typescript/src/assets/images/index.d.ts +1 -0
  80. package/lib/typescript/src/assets/images/index.d.ts.map +1 -1
  81. package/lib/typescript/src/components/flows/inputButtons/index.d.ts.map +1 -1
  82. package/lib/typescript/src/components/messages/MessageStatusIndicator.d.ts +9 -0
  83. package/lib/typescript/src/components/messages/MessageStatusIndicator.d.ts.map +1 -0
  84. package/lib/typescript/src/components/messages/fileMessage/index.d.ts.map +1 -1
  85. package/lib/typescript/src/components/messages/imageMessage/index.d.ts.map +1 -1
  86. package/lib/typescript/src/components/messages/linkMessage/index.d.ts +3 -8
  87. package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -1
  88. package/lib/typescript/src/components/messages/mergedMessage/index.d.ts.map +1 -1
  89. package/lib/typescript/src/components/messages/styles.d.ts +15 -3
  90. package/lib/typescript/src/components/messages/styles.d.ts.map +1 -1
  91. package/lib/typescript/src/components/messages/textMessage/index.d.ts +2 -8
  92. package/lib/typescript/src/components/messages/textMessage/index.d.ts.map +1 -1
  93. package/lib/typescript/src/components/messages/videoMessage/index.d.ts.map +1 -1
  94. package/lib/typescript/src/core/useChatListener.d.ts.map +1 -1
  95. package/lib/typescript/src/core/useUserListener.d.ts.map +1 -1
  96. package/lib/typescript/src/hooks/message/useSendMessage.d.ts +2 -0
  97. package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
  98. package/lib/typescript/src/hooks/useChatCompose.d.ts.map +1 -1
  99. package/lib/typescript/src/hooks/useChatMessages.d.ts.map +1 -1
  100. package/lib/typescript/src/hooks/useImageAttachment.d.ts.map +1 -1
  101. package/lib/typescript/src/index.d.ts +1 -0
  102. package/lib/typescript/src/index.d.ts.map +1 -1
  103. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
  104. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts +1 -1
  105. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
  106. package/lib/typescript/src/screens/chat-detail/constants.d.ts +2 -2
  107. package/lib/typescript/src/screens/chat-detail/constants.d.ts.map +1 -1
  108. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +4 -5
  109. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
  110. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.d.ts +11 -0
  111. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.d.ts.map +1 -0
  112. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.d.ts +10 -0
  113. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.d.ts.map +1 -0
  114. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.d.ts +11 -0
  115. package/lib/typescript/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.d.ts.map +1 -0
  116. package/lib/typescript/src/screens/chat-detail/messageToolbox/messageToolbox.utils.d.ts +18 -0
  117. package/lib/typescript/src/screens/chat-detail/messageToolbox/messageToolbox.utils.d.ts.map +1 -0
  118. package/lib/typescript/src/screens/chat-detail/messageToolbox/types.d.ts +12 -0
  119. package/lib/typescript/src/screens/chat-detail/messageToolbox/types.d.ts.map +1 -0
  120. package/lib/typescript/src/screens/chat-detail/types.d.ts +2 -0
  121. package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
  122. package/lib/typescript/src/services/attachmentOrchestrator.d.ts.map +1 -1
  123. package/lib/typescript/src/services/message.d.ts +7 -0
  124. package/lib/typescript/src/services/message.d.ts.map +1 -1
  125. package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
  126. package/lib/typescript/src/types/chat.d.ts +11 -0
  127. package/lib/typescript/src/types/chat.d.ts.map +1 -1
  128. package/lib/typescript/src/utils/UIUtils.d.ts +4 -0
  129. package/lib/typescript/src/utils/UIUtils.d.ts.map +1 -0
  130. package/lib/typescript/src/utils/ui.d.ts +1 -12
  131. package/lib/typescript/src/utils/ui.d.ts.map +1 -1
  132. package/package.json +4 -2
  133. package/src/assets/images/btn_resend.png +0 -0
  134. package/src/assets/images/index.ts +1 -0
  135. package/src/components/AttachmentPreview/FilePreview.tsx +1 -1
  136. package/src/components/flows/inputButtons/index.tsx +3 -5
  137. package/src/components/messages/MessageStatusIndicator.tsx +82 -0
  138. package/src/components/messages/fileMessage/index.tsx +0 -2
  139. package/src/components/messages/imageMessage/index.tsx +72 -58
  140. package/src/components/messages/linkMessage/index.tsx +16 -21
  141. package/src/components/messages/mergedMessage/index.tsx +13 -18
  142. package/src/components/messages/styles.ts +12 -0
  143. package/src/components/messages/textMessage/index.tsx +20 -20
  144. package/src/components/messages/videoMessage/index.tsx +8 -11
  145. package/src/config/uploadLimits.ts +1 -1
  146. package/src/core/useChatListener.ts +38 -4
  147. package/src/core/useUserListener.ts +17 -7
  148. package/src/hooks/message/useSendMessage.ts +103 -24
  149. package/src/hooks/useChatCompose.ts +42 -33
  150. package/src/hooks/useChatMessages.ts +54 -10
  151. package/src/hooks/useFileAttachment.ts +1 -1
  152. package/src/hooks/useFileDownload.ts +1 -1
  153. package/src/hooks/useImageAttachment.ts +13 -5
  154. package/src/index.tsx +2 -0
  155. package/src/screens/chat-detail/ChatDetail.tsx +29 -0
  156. package/src/screens/chat-detail/ChatListLegend.tsx +45 -28
  157. package/src/screens/chat-detail/constants.ts +3 -2
  158. package/src/screens/chat-detail/legend/LegendChatMessage.tsx +60 -15
  159. package/src/screens/chat-detail/messageToolbox/MessageToolboxMenu.tsx +114 -0
  160. package/src/screens/chat-detail/messageToolbox/MessageToolboxOverlay.tsx +130 -0
  161. package/src/screens/chat-detail/messageToolbox/MessageToolboxWrapper.tsx +99 -0
  162. package/src/screens/chat-detail/messageToolbox/messageToolbox.utils.ts +56 -0
  163. package/src/screens/chat-detail/messageToolbox/types.ts +13 -0
  164. package/src/screens/chat-detail/types.ts +2 -0
  165. package/src/services/attachmentOrchestrator.ts +45 -21
  166. package/src/services/message.ts +21 -4
  167. package/src/translation/resources/i18n.ts +11 -3
  168. package/src/types/chat.ts +6 -0
  169. package/src/types/global.d.ts +299 -0
  170. package/src/types/index.d.ts +1 -0
  171. package/src/utils/UIUtils.ts +31 -0
  172. package/src/utils/ui.ts +20 -16
  173. package/src/utils/videoThumbnailUpload.ts +1 -1
  174. package/lib/module/hooks/useVideoAttachment.js +0 -251
  175. package/lib/module/hooks/useVideoAttachment.js.map +0 -1
  176. package/lib/typescript/src/hooks/useVideoAttachment.d.ts +0 -29
  177. package/lib/typescript/src/hooks/useVideoAttachment.d.ts.map +0 -1
  178. package/src/hooks/useVideoAttachment.ts +0 -334
@@ -1,334 +0,0 @@
1
- import { useCallback, useState } from 'react';
2
- import RNFS from 'react-native-fs';
3
- import DeviceUtils from '../utils/device';
4
- import UIUtils from '../utils/ui';
5
- import { trans } from '../translation';
6
- import { getMimeType } from '../utils/imageUtils';
7
- import { UPLOAD_LIMITS } from '../config/uploadLimits';
8
- import { ImageUploadAPI } from '../services/imageUpload';
9
- import VideoThumbnailUtil from '../utils/videoThumbnail';
10
-
11
- interface PickedVideo {
12
- path: string;
13
- filename?: string;
14
- size?: number;
15
- width?: number;
16
- height?: number;
17
- duration?: number;
18
- }
19
-
20
- interface VideoWithUploadStatus {
21
- type: 'video';
22
- video: PickedVideo;
23
- uploadProgress: number;
24
- error: string | null;
25
- isUploading: boolean;
26
- uploadedUrl?: string;
27
- thumbnailUrl?: string;
28
- thumbnailPath?: string;
29
- thumbnailSize?: number;
30
- }
31
-
32
- export interface UseVideoAttachmentReturn {
33
- selectedVideos: VideoWithUploadStatus[];
34
- isVideoPreviewVisible: boolean;
35
- handleVideoAttach: () => Promise<void>;
36
- handleVideoRemove: (index: number) => void;
37
- clearAllVideos: () => void;
38
- }
39
-
40
- export const useVideoAttachment = (): UseVideoAttachmentReturn => {
41
- const [selectedVideos, setSelectedVideos] = useState<VideoWithUploadStatus[]>(
42
- []
43
- );
44
- const [isVideoPreviewVisible, setIsVideoPreviewVisible] = useState(false);
45
-
46
- const updateVideoStatus = useCallback(
47
- (index: number, updates: Partial<Omit<VideoWithUploadStatus, 'video'>>) => {
48
- setSelectedVideos((prev) => {
49
- const newVideos = [...prev];
50
- if (newVideos[index]) {
51
- newVideos[index] = { ...newVideos[index], ...updates };
52
- }
53
- return newVideos;
54
- });
55
- },
56
- []
57
- );
58
-
59
- const uploadVideo = useCallback(
60
- async (index: number, video: PickedVideo) => {
61
- console.log('UploadVideo', 'Step 1: Starting upload for video', {
62
- index,
63
- });
64
- let cachedFilePath: string | null = null;
65
-
66
- try {
67
- console.log('UploadVideo', 'Step 2: Updating status to uploading...');
68
- updateVideoStatus(index, {
69
- isUploading: true,
70
- error: null,
71
- uploadProgress: 0,
72
- });
73
-
74
- try {
75
- console.log('UploadVideo', 'Step 3: Preparing file...', {
76
- originalPath: video.path,
77
- filename: video.filename,
78
- });
79
- const ext = video.filename?.split('.').pop() || 'mp4';
80
- const fileName = `temp-video-${Date.now()}-${index}.${ext}`;
81
- cachedFilePath = `${RNFS.DocumentDirectoryPath}/${fileName}`;
82
-
83
- console.log('UploadVideo', 'Step 4: Copying file to cache...', {
84
- from: video.path,
85
- to: cachedFilePath,
86
- });
87
- await RNFS.copyFile(video.path, cachedFilePath);
88
- console.log('UploadVideo', 'Step 5: File copied successfully');
89
- } catch (fileError: any) {
90
- console.error('UploadVideo', 'File copy error', fileError);
91
- throw new Error(
92
- `Failed to prepare file: ${fileError?.message || 'Unknown error'}`
93
- );
94
- }
95
-
96
- const filename = video.filename || 'video.mp4';
97
-
98
- const setProgress = (progress: number) => {
99
- try {
100
- console.log('UploadVideo', 'Progress', { percentage: progress });
101
- updateVideoStatus(index, { uploadProgress: progress });
102
- } catch (err) {
103
- console.error('UploadVideo', 'Progress update error', err);
104
- }
105
- };
106
-
107
- let uploadedVideo;
108
- try {
109
- console.log('UploadVideo', 'Step 6: Uploading to server...', {
110
- filename,
111
- size: video.size,
112
- duration: video.duration,
113
- });
114
- uploadedVideo = await ImageUploadAPI.uploadImageFile(
115
- {
116
- path: cachedFilePath || '',
117
- filename,
118
- size: video.size || 0,
119
- width: video.width || 0,
120
- height: video.height || 0,
121
- mime: getMimeType(filename),
122
- },
123
- setProgress
124
- );
125
- console.log('UploadVideo', 'Step 7: Upload successful!', {
126
- url: uploadedVideo?.url,
127
- });
128
- } catch (uploadError: any) {
129
- console.error('UploadVideo', 'Server upload error', uploadError);
130
- throw new Error(
131
- `Upload failed: ${uploadError?.message || 'Unknown error'}`
132
- );
133
- }
134
-
135
- if (!uploadedVideo?.url) {
136
- throw new Error('No URL returned from server');
137
- }
138
-
139
- console.log('UploadVideo', 'Step 8: Video upload complete');
140
-
141
- // Step 8.5: Generate and upload thumbnail (REQUIRED before ready to send)
142
- let thumbnailUrl: string | undefined;
143
- let thumbnailPath: string | undefined;
144
- let thumbnailSize: number | undefined;
145
-
146
- try {
147
- console.log('UploadVideo', 'Step 8.5a: Generating thumbnail...');
148
- const thumbnail = await VideoThumbnailUtil.generateThumbnail(
149
- video.path,
150
- { time: 1000, quality: 80 } // time in milliseconds (1 second)
151
- );
152
-
153
- if (!thumbnail) {
154
- throw new Error('Failed to generate thumbnail from video');
155
- }
156
-
157
- thumbnailPath = thumbnail.path;
158
- console.log('✅ [UploadVideo] THUMBNAIL PATH:', thumbnail.path);
159
- console.log('UploadVideo', 'Step 8.5b: Thumbnail generated', {
160
- path: thumbnail.path,
161
- width: thumbnail.width,
162
- height: thumbnail.height,
163
- });
164
-
165
- console.log('UploadVideo', 'Step 8.5c: Uploading thumbnail...');
166
- const uploadedThumbnail = await ImageUploadAPI.uploadImageFile(
167
- {
168
- path: thumbnail.path,
169
- filename: `thumb-${filename}`,
170
- size: 0,
171
- width: thumbnail.width || 320,
172
- height: thumbnail.height || 180,
173
- mime: 'image/jpeg',
174
- },
175
- (progress) => {
176
- console.log('UploadVideo', 'Thumbnail upload progress', {
177
- percentage: progress,
178
- });
179
- }
180
- );
181
-
182
- if (!uploadedThumbnail?.url) {
183
- throw new Error('Thumbnail URL not returned from server');
184
- }
185
-
186
- thumbnailUrl = uploadedThumbnail.url;
187
- thumbnailSize = uploadedThumbnail.size || 0;
188
- console.log('✅ [UploadVideo] THUMBNAIL URL READY:', thumbnailUrl);
189
- console.log('UploadVideo', 'Step 8.5d: Thumbnail uploaded', {
190
- url: thumbnailUrl,
191
- size: `${thumbnailSize} bytes`,
192
- });
193
- } catch (thumbError: any) {
194
- const errorMsg =
195
- thumbError?.message || 'Failed to generate/upload thumbnail';
196
- console.error('❌ [UploadVideo] THUMBNAIL ERROR:', errorMsg);
197
- throw new Error(errorMsg);
198
- }
199
-
200
- console.log('UploadVideo', 'Step 9: Preparing data...');
201
- updateVideoStatus(index, {
202
- isUploading: false,
203
- uploadProgress: 100,
204
- uploadedUrl: uploadedVideo.url,
205
- thumbnailUrl,
206
- thumbnailPath,
207
- thumbnailSize,
208
- });
209
-
210
- console.log(
211
- 'UploadVideo',
212
- 'Step 10: Ready to send - waiting for user confirmation'
213
- );
214
-
215
- console.log('UploadVideo', 'Step 11: Cleaning up cache files...');
216
- try {
217
- if (cachedFilePath) {
218
- await ImageUploadAPI.cleanupImageFile(cachedFilePath);
219
- }
220
- if (thumbnailPath) {
221
- await VideoThumbnailUtil.cleanupThumbnail(thumbnailPath);
222
- }
223
- } catch (cleanupError) {
224
- console.warn('UploadVideo', 'Cleanup warning', cleanupError);
225
- }
226
- console.log('UploadVideo', 'Step 12: COMPLETE ✓');
227
- } catch (error: any) {
228
- console.error('UploadVideo', 'ERROR', error);
229
- const errorMsg = error?.message || trans('chat:video_upload_failed');
230
- updateVideoStatus(index, {
231
- isUploading: false,
232
- error: errorMsg,
233
- });
234
-
235
- try {
236
- if (cachedFilePath) {
237
- await ImageUploadAPI.cleanupImageFile(cachedFilePath);
238
- }
239
- } catch (cleanupError) {
240
- console.warn('UploadVideo', 'Cleanup after error', cleanupError);
241
- }
242
-
243
- console.error('uploadVideo', 'Full error', error);
244
- }
245
- },
246
- [updateVideoStatus]
247
- );
248
-
249
- const handleVideoAttach = useCallback(async () => {
250
- console.log('VideoAttach', 'Step 1: User tapped video attachment button');
251
- try {
252
- console.log('VideoAttach', 'Step 2: Opening video picker...');
253
- const videos = await DeviceUtils.openVideoPicker();
254
-
255
- if (!videos || videos.length === 0) {
256
- console.log('VideoAttach', 'Step 3: User cancelled picker');
257
- return;
258
- }
259
-
260
- console.log('VideoAttach', 'Step 4: Videos picked', {
261
- count: videos.length,
262
- });
263
-
264
- const oversizedVideos = videos.filter(
265
- (vid) => (vid.size || 0) > UPLOAD_LIMITS.video
266
- );
267
-
268
- if (oversizedVideos.length > 0) {
269
- console.warn('VideoAttach', 'Step 5: Some videos too large', {
270
- count: oversizedVideos.length,
271
- maxSize: UPLOAD_LIMITS.video,
272
- });
273
- UIUtils.toast.open({
274
- title: trans('chat:video_too_large'),
275
- theme: 'danger',
276
- });
277
- const validVideos = videos.filter(
278
- (vid) => (vid.size || 0) <= UPLOAD_LIMITS.video
279
- );
280
- if (validVideos.length === 0) return;
281
- videos.splice(0, videos.length, ...validVideos);
282
- }
283
-
284
- console.log('VideoAttach', 'Step 6: Size validation passed');
285
- const startIndex = selectedVideos.length;
286
-
287
- console.log('VideoAttach', 'Step 7: Adding to preview list', {
288
- count: videos.length,
289
- startIndex,
290
- });
291
-
292
- setSelectedVideos((prev) => [
293
- ...prev,
294
- ...videos.map((video) => ({
295
- type: 'video' as const,
296
- video,
297
- uploadProgress: 0,
298
- error: null,
299
- isUploading: true,
300
- })),
301
- ]);
302
- setIsVideoPreviewVisible(true);
303
-
304
- console.log('VideoAttach', 'Step 8: Starting uploads...');
305
- await Promise.all(
306
- videos.map((video, offset) => uploadVideo(startIndex + offset, video))
307
- );
308
- } catch (error) {
309
- console.error('VideoAttach', 'ERROR', error);
310
- UIUtils.toast.open({
311
- title: trans('chat:video_pick_failed'),
312
- message: error instanceof Error ? error.message : 'Unknown error',
313
- theme: 'danger',
314
- });
315
- }
316
- }, [selectedVideos.length, uploadVideo]);
317
-
318
- const handleVideoRemove = useCallback((index: number) => {
319
- setSelectedVideos((prev) => prev.filter((_, i) => i !== index));
320
- }, []);
321
-
322
- const clearAllVideos = useCallback(() => {
323
- setSelectedVideos([]);
324
- setIsVideoPreviewVisible(false);
325
- }, []);
326
-
327
- return {
328
- selectedVideos,
329
- isVideoPreviewVisible,
330
- handleVideoAttach,
331
- handleVideoRemove,
332
- clearAllVideos,
333
- };
334
- };