@teamnhz/rn-ui-toolkit 1.2.3 → 1.2.5

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.
@@ -1,6 +1,6 @@
1
1
  import React, { useState } from "react";
2
2
  import { ActivityIndicator } from "react-native";
3
- import FastImage from "react-native-fast-image";
3
+ import FastImage from "@d11/react-native-fast-image";
4
4
  const Image = (props) => {
5
5
  const [isLoading, setIsLoading] = useState(props?.isLoading || false);
6
6
  return (React.createElement(React.Fragment, null,
@@ -1,10 +1,18 @@
1
1
  import React from "react";
2
2
  type Props = {
3
3
  mediaType: "photo" | "video";
4
+ isMultiSelect?: boolean;
5
+ onSuccess: (data: any) => void;
4
6
  visible: boolean;
5
- onSuccess: (res: any) => void;
6
7
  onClose: () => void;
7
8
  enableCompression?: boolean;
9
+ imageCompressionOptions?: {
10
+ maxWidth?: number;
11
+ quality?: number;
12
+ };
13
+ videoCompressionOptions?: {
14
+ compressionMethod?: "auto" | "manual";
15
+ };
8
16
  };
9
17
  declare const ImagePicker: React.FC<Props>;
10
18
  export default ImagePicker;
@@ -1,174 +1,498 @@
1
- import React from "react";
2
- import { View, Text, TouchableOpacity, StyleSheet, Image, } from "react-native";
1
+ // // import React, { useCallback } from "react";
2
+ // // import {
3
+ // // View,
4
+ // // Text,
5
+ // // TouchableOpacity,
6
+ // // StyleSheet,
7
+ // // Image,
8
+ // // Alert,
9
+ // // ViewStyle,
10
+ // // TextStyle,
11
+ // // ImageStyle,
12
+ // // } from "react-native";
13
+ // // import { BottomSheet, Dividers } from "../index";
14
+ // // import { launchCamera, launchImageLibrary } from "react-native-image-picker";
15
+ // // import ImageCropPicker from "react-native-image-crop-picker";
16
+ // // import { Colors, Images, Scale, Typography } from "../../styles";
17
+ // // type StyleProps = {
18
+ // // containerStyle?: ViewStyle;
19
+ // // rowStyle?: ViewStyle;
20
+ // // textStyle?: TextStyle;
21
+ // // iconStyle?: ImageStyle;
22
+ // // };
23
+ // // type Props = {
24
+ // // mediaType: "photo" | "video";
25
+ // // isMultiSelect?: boolean;
26
+ // // onSuccess: (data: any) => void;
27
+ // // visible: boolean;
28
+ // // onClose: () => void;
29
+ // // } & StyleProps;
30
+ // // const ImagePicker: React.FC<Props> = ({
31
+ // // mediaType,
32
+ // // isMultiSelect = false,
33
+ // // onSuccess,
34
+ // // visible,
35
+ // // onClose,
36
+ // // containerStyle,
37
+ // // rowStyle,
38
+ // // textStyle,
39
+ // // iconStyle,
40
+ // // }) => {
41
+ // // const onComplete = useCallback(
42
+ // // (data: any) => {
43
+ // // onSuccess(data);
44
+ // // onClose();
45
+ // // },
46
+ // // [onSuccess, onClose]
47
+ // // );
48
+ // // const onCamera = () => {
49
+ // // if (mediaType === "photo") {
50
+ // // if (isMultiSelect) {
51
+ // // ImageCropPicker.openCamera({ mediaType: "photo" })
52
+ // // .then((response) => onComplete([response]))
53
+ // // .catch(() => {});
54
+ // // } else {
55
+ // // ImageCropPicker.openCamera({ mediaType: "photo" })
56
+ // // .then((response) =>
57
+ // // ImageCropPicker.openCropper({
58
+ // // path: response?.path,
59
+ // // width: response?.width,
60
+ // // height: response?.height,
61
+ // // mediaType: "photo",
62
+ // // freeStyleCropEnabled: true,
63
+ // // }).then(onComplete)
64
+ // // )
65
+ // // .catch(() => {});
66
+ // // }
67
+ // // } else {
68
+ // // launchCamera({ mediaType: "video" }, (response) => {
69
+ // // if (response?.assets) {
70
+ // // onComplete({
71
+ // // path: response.assets[0]?.uri,
72
+ // // duration: response.assets[0]?.duration,
73
+ // // });
74
+ // // }
75
+ // // });
76
+ // // }
77
+ // // };
78
+ // // const onGallery = () => {
79
+ // // if (mediaType === "photo") {
80
+ // // if (isMultiSelect) {
81
+ // // ImageCropPicker.openPicker({
82
+ // // mediaType: "photo",
83
+ // // multiple: true,
84
+ // // maxFiles: 5,
85
+ // // })
86
+ // // .then((images) => {
87
+ // // if (images.length > 5) {
88
+ // // Alert.alert(
89
+ // // "Limit Exceeded",
90
+ // // "You can only select up to 5 images."
91
+ // // );
92
+ // // } else {
93
+ // // onComplete(images);
94
+ // // }
95
+ // // })
96
+ // // .catch(() => {});
97
+ // // } else {
98
+ // // ImageCropPicker.openPicker({ mediaType: "photo" })
99
+ // // .then((response) =>
100
+ // // ImageCropPicker.openCropper({
101
+ // // path: response?.path,
102
+ // // width: response?.width,
103
+ // // height: response?.height,
104
+ // // mediaType: "photo",
105
+ // // freeStyleCropEnabled: true,
106
+ // // }).then(onComplete)
107
+ // // )
108
+ // // .catch(() => {});
109
+ // // }
110
+ // // } else {
111
+ // // launchImageLibrary({ mediaType: "video" }, (result) => {
112
+ // // if (result?.assets) {
113
+ // // onComplete({
114
+ // // path: result.assets[0]?.uri,
115
+ // // duration: result.assets[0]?.duration,
116
+ // // });
117
+ // // }
118
+ // // });
119
+ // // }
120
+ // // };
121
+ // // return (
122
+ // // <BottomSheet visible={visible} onClose={onClose} height={230}>
123
+ // // <View style={[styles.container, containerStyle]}>
124
+ // // {/* Camera */}
125
+ // // <TouchableOpacity style={[styles.row, rowStyle]} onPress={onCamera}>
126
+ // // <Image source={Images.video_icon} style={[styles.icon, iconStyle]} />
127
+ // // <Text style={[styles.text, textStyle]}>Camera</Text>
128
+ // // </TouchableOpacity>
129
+ // // <Dividers small />
130
+ // // {/* Gallery */}
131
+ // // <TouchableOpacity style={[styles.row, rowStyle]} onPress={onGallery}>
132
+ // // <Image source={Images.image_icon} style={[styles.icon, iconStyle]} />
133
+ // // <Text style={[styles.text, textStyle]}>Gallery</Text>
134
+ // // </TouchableOpacity>
135
+ // // <Dividers small />
136
+ // // {/* Cancel */}
137
+ // // <TouchableOpacity style={[styles.row, rowStyle]} onPress={onClose}>
138
+ // // <Image source={Images.cancel} style={[styles.icon, iconStyle]} />
139
+ // // <Text style={[styles.text, textStyle]}>Cancel</Text>
140
+ // // </TouchableOpacity>
141
+ // // </View>
142
+ // // </BottomSheet>
143
+ // // );
144
+ // // };
145
+ // // export default ImagePicker;
146
+ // // const styles = StyleSheet.create({
147
+ // // container: { flex: 1, padding: 16 },
148
+ // // row: {
149
+ // // flexDirection: "row",
150
+ // // alignItems: "center",
151
+ // // },
152
+ // // text: { ...Typography.style.standardU(), color: Colors.white },
153
+ // // icon: {
154
+ // // width: Scale.moderateScale(20),
155
+ // // height: Scale.moderateScale(20),
156
+ // // marginRight: 10,
157
+ // // tintColor: Colors.white,
158
+ // // },
159
+ // // });
160
+ // import React, { useCallback } from "react";
161
+ // import {
162
+ // View,
163
+ // Text,
164
+ // TouchableOpacity,
165
+ // StyleSheet,
166
+ // Image,
167
+ // Alert,
168
+ // } from "react-native";
169
+ // import { BottomSheet, Dividers } from "../index";
170
+ // import { launchCamera, launchImageLibrary } from "react-native-image-picker";
171
+ // import ImageCropPicker from "react-native-image-crop-picker";
172
+ // import { Colors, Images, Scale, Typography } from "../../styles";
173
+ // // 👇 Import your permission utilities
174
+ // import {
175
+ // cameraPermissions,
176
+ // galleryPermissions,
177
+ // } from "../../utils/permissions"; // ✅ Make sure path is correct
178
+ // type Props = {
179
+ // mediaType: "photo" | "video";
180
+ // isMultiSelect?: boolean;
181
+ // onSuccess: (data: any) => void;
182
+ // visible: boolean;
183
+ // onClose: () => void;
184
+ // };
185
+ // const ImagePicker: React.FC<Props> = ({
186
+ // mediaType,
187
+ // isMultiSelect = false,
188
+ // onSuccess,
189
+ // visible,
190
+ // onClose,
191
+ // }) => {
192
+ // // ✅ Success handler
193
+ // const onComplete = useCallback(
194
+ // (data: any) => {
195
+ // onSuccess(data);
196
+ // onClose();
197
+ // },
198
+ // [onSuccess, onClose]
199
+ // );
200
+ // // ✅ CAMERA HANDLER with permission check
201
+ // const handleCamera = async () => {
202
+ // await cameraPermissions(async (granted: boolean) => {
203
+ // if (!granted) return; // ❌ Permission denied, handled by your alert
204
+ // if (mediaType === "photo") {
205
+ // if (isMultiSelect) {
206
+ // // single capture, multiple not supported directly from camera
207
+ // ImageCropPicker.openCamera({ mediaType: "photo" })
208
+ // .then((response) => onComplete([response]))
209
+ // .catch(() => {});
210
+ // } else {
211
+ // ImageCropPicker.openCamera({ mediaType: "photo" })
212
+ // .then((response) =>
213
+ // ImageCropPicker.openCropper({
214
+ // path: response?.path,
215
+ // width: response?.width,
216
+ // height: response?.height,
217
+ // mediaType: "photo",
218
+ // freeStyleCropEnabled: true,
219
+ // }).then(onComplete)
220
+ // )
221
+ // .catch(() => {});
222
+ // }
223
+ // } else {
224
+ // // 🎥 VIDEO CAPTURE
225
+ // launchCamera({ mediaType: "video" }, (response) => {
226
+ // if (response?.assets?.length) {
227
+ // onComplete({
228
+ // path: response.assets[0]?.uri,
229
+ // duration: response.assets[0]?.duration,
230
+ // });
231
+ // }
232
+ // });
233
+ // }
234
+ // });
235
+ // };
236
+ // // ✅ GALLERY HANDLER with permission check
237
+ // const handleGallery = async () => {
238
+ // await galleryPermissions(async (granted: boolean) => {
239
+ // if (!granted) return; // ❌ Permission denied, handled by your alert
240
+ // if (mediaType === "photo") {
241
+ // if (isMultiSelect) {
242
+ // ImageCropPicker.openPicker({
243
+ // mediaType: "photo",
244
+ // multiple: true,
245
+ // maxFiles: 5,
246
+ // })
247
+ // .then((images) => {
248
+ // if (images.length > 5) {
249
+ // Alert.alert(
250
+ // "Limit Exceeded",
251
+ // "You can only select up to 5 images."
252
+ // );
253
+ // } else {
254
+ // onComplete(images);
255
+ // }
256
+ // })
257
+ // .catch(() => {});
258
+ // } else {
259
+ // ImageCropPicker.openPicker({ mediaType: "photo" })
260
+ // .then((response) =>
261
+ // ImageCropPicker.openCropper({
262
+ // path: response?.path,
263
+ // width: response?.width,
264
+ // height: response?.height,
265
+ // mediaType: "photo",
266
+ // freeStyleCropEnabled: true,
267
+ // }).then(onComplete)
268
+ // )
269
+ // .catch(() => {});
270
+ // }
271
+ // } else {
272
+ // // 🎥 VIDEO FROM GALLERY
273
+ // launchImageLibrary({ mediaType: "video" }, (result) => {
274
+ // if (result?.assets?.length) {
275
+ // onComplete({
276
+ // path: result.assets[0]?.uri,
277
+ // duration: result.assets[0]?.duration,
278
+ // });
279
+ // }
280
+ // });
281
+ // }
282
+ // });
283
+ // };
284
+ // return (
285
+ // <BottomSheet visible={visible} onClose={onClose} height={230}>
286
+ // <View style={styles.container}>
287
+ // {/* 📸 Camera */}
288
+ // <TouchableOpacity style={styles.row} onPress={handleCamera}>
289
+ // <Image source={Images.video_icon} style={styles.icon} />
290
+ // <Text style={styles.text}>Camera</Text>
291
+ // </TouchableOpacity>
292
+ // <Dividers small />
293
+ // {/* 🖼️ Gallery */}
294
+ // <TouchableOpacity style={styles.row} onPress={handleGallery}>
295
+ // <Image source={Images.image_icon} style={styles.icon} />
296
+ // <Text style={styles.text}>Gallery</Text>
297
+ // </TouchableOpacity>
298
+ // <Dividers small />
299
+ // {/* ❌ Cancel */}
300
+ // <TouchableOpacity style={styles.row} onPress={onClose}>
301
+ // <Image source={Images.cancel} style={styles.icon} />
302
+ // <Text style={styles.text}>Cancel</Text>
303
+ // </TouchableOpacity>
304
+ // </View>
305
+ // </BottomSheet>
306
+ // );
307
+ // };
308
+ // export default ImagePicker;
309
+ // const styles = StyleSheet.create({
310
+ // container: { flex: 1, padding: 16 },
311
+ // row: {
312
+ // flexDirection: "row",
313
+ // alignItems: "center",
314
+ // },
315
+ // text: { ...Typography.style.standardU(), color: Colors.white },
316
+ // icon: {
317
+ // width: Scale.moderateScale(20),
318
+ // height: Scale.moderateScale(20),
319
+ // marginRight: 10,
320
+ // tintColor: Colors.white,
321
+ // },
322
+ // });
323
+ import React, { useCallback } from "react";
324
+ import { View, Text, TouchableOpacity, StyleSheet, Image, Alert, } from "react-native";
3
325
  import { BottomSheet, Dividers } from "../index";
4
326
  import { launchCamera, launchImageLibrary } from "react-native-image-picker";
5
327
  import ImageCropPicker from "react-native-image-crop-picker";
6
328
  import { Image as ImageCompressor, Video as VideoCompressor, } from "react-native-compressor";
7
- import { cameraPermissions, galleryPermissions, checkMicroPhonePermission, } from "../../utils/permissions";
329
+ import RNFS from "react-native-fs";
8
330
  import { Colors, Images, Scale, Typography } from "../../styles";
9
- //--------------------------------------
10
- // 🟦 FORMAT PATH (always file:// format)
11
- //--------------------------------------
12
- const normalizePath = (p) => {
13
- if (!p)
14
- return "";
15
- return p.startsWith("file://") ? p : `file://${p}`;
16
- };
17
- const resetInternalState = () => {
18
- try {
19
- ImageCropPicker.clean().catch(() => { });
20
- ImageCropPicker.cleanSingle && ImageCropPicker.cleanSingle().catch(() => { });
21
- }
22
- catch { }
23
- // 🧹 If you stored something in ref or state in future
24
- // you can reset here too.
25
- };
26
- //--------------------------------------
27
- // 🟦 FINAL RESPONSE FORMAT
28
- //--------------------------------------
29
- const buildResponse = (raw, compressed) => ({
30
- path: normalizePath(compressed || raw?.path || raw?.uri),
31
- originalPath: normalizePath(raw?.path || raw?.uri),
32
- fileName: raw?.fileName || "",
33
- type: raw?.type || "",
34
- duration: raw?.duration || undefined,
35
- });
36
- //--------------------------------------
37
- // 🟦 MAIN COMPONENT
38
- //--------------------------------------
39
- const ImagePicker = ({ mediaType, visible, onSuccess, onClose, enableCompression = true, }) => {
40
- //--------------------------------------
41
- // SEND RAW (loader ON)
42
- //--------------------------------------
43
- const sendRaw = (raw) => {
44
- onSuccess({
45
- loading: true,
46
- data: buildResponse(raw),
47
- });
48
- };
49
- //--------------------------------------
50
- // SEND FINAL (loader OFF)
51
- //--------------------------------------
52
- const sendFinal = (raw, compressed) => {
53
- onSuccess({
54
- loading: false,
55
- data: buildResponse(raw, compressed),
56
- });
57
- resetInternalState();
58
- };
59
- //--------------------------------------
60
- // COMPRESS IMAGE
61
- //--------------------------------------
62
- const compressImage = async (path) => {
331
+ // Import your permission utilities
332
+ import { cameraPermissions, galleryPermissions, checkMicroPhonePermission, } from "../../utils/permissions";
333
+ const ImagePicker = ({ mediaType, isMultiSelect = false, onSuccess, visible, onClose, enableCompression = true, imageCompressionOptions = { maxWidth: 1080, quality: 0.7 }, videoCompressionOptions = { compressionMethod: "auto" }, }) => {
334
+ // Success handler
335
+ const onComplete = useCallback((data) => {
336
+ onSuccess(data);
337
+ onClose();
338
+ }, [onSuccess, onClose]);
339
+ // Helper: Compress Image
340
+ const compressImage = async (imagePath) => {
341
+ if (!enableCompression)
342
+ return imagePath;
63
343
  try {
64
- return await ImageCompressor.compress(path, {
65
- maxWidth: 1080,
66
- quality: 0.7,
344
+ const compressedImage = await ImageCompressor.compress(imagePath, {
345
+ maxWidth: imageCompressionOptions.maxWidth,
346
+ quality: imageCompressionOptions.quality,
67
347
  });
348
+ // Log compressed size (optional)
349
+ const stats = await RNFS.stat(compressedImage.replace("file://", ""));
350
+ const sizeInMB = stats.size / (1024 * 1024);
351
+ console.log("Compressed Image Size (MB):", sizeInMB);
352
+ return compressedImage;
68
353
  }
69
- catch {
70
- return path;
354
+ catch (error) {
355
+ console.error("Image compression error:", error);
356
+ return imagePath; // Return original if compression fails
71
357
  }
72
358
  };
73
- //--------------------------------------
74
- // COMPRESS VIDEO
75
- //--------------------------------------
76
- const compressVideo = async (uri) => {
359
+ // Helper: Compress Video
360
+ const compressVideo = async (videoUri) => {
361
+ if (!enableCompression)
362
+ return videoUri;
77
363
  try {
78
- return await VideoCompressor.compress(uri, {
79
- compressionMethod: "auto",
364
+ const compressedVideo = await VideoCompressor.compress(videoUri, {
365
+ compressionMethod: videoCompressionOptions.compressionMethod,
80
366
  });
367
+ // Log compressed size (optional)
368
+ const stats = await RNFS.stat(compressedVideo.replace("file://", ""));
369
+ const sizeInMB = stats.size / (1024 * 1024);
370
+ console.log("Compressed Video Size (MB):", sizeInMB);
371
+ return compressedVideo;
81
372
  }
82
- catch {
83
- return uri;
373
+ catch (error) {
374
+ console.error("Video compression error:", error);
375
+ return videoUri; // Return original if compression fails
84
376
  }
85
377
  };
86
- //--------------------------------------
87
- // CAMERA HANDLER
88
- //--------------------------------------
378
+ // CAMERA HANDLER with permission check and compression
89
379
  const handleCamera = async () => {
90
- onClose(); // 🔥 CLOSE FIRST (best UX)
91
380
  await cameraPermissions(async (granted) => {
92
381
  if (!granted)
93
382
  return;
94
- // PHOTO
95
383
  if (mediaType === "photo") {
96
384
  try {
97
- const img = await ImageCropPicker.openCamera({
385
+ const response = await ImageCropPicker.openCamera({
98
386
  mediaType: "photo",
99
- cropping: true,
100
387
  });
101
- sendRaw(img);
102
- const compressed = enableCompression
103
- ? await compressImage(img.path)
104
- : img.path;
105
- sendFinal(img, compressed);
388
+ if (isMultiSelect) {
389
+ // Single capture for multi-select mode
390
+ const compressedPath = await compressImage(response.path);
391
+ onComplete([{ ...response, path: compressedPath }]);
392
+ }
393
+ else {
394
+ // Crop and compress single image
395
+ const cropped = await ImageCropPicker.openCropper({
396
+ path: response?.path,
397
+ width: response?.width,
398
+ height: response?.height,
399
+ mediaType: "photo",
400
+ freeStyleCropEnabled: true,
401
+ });
402
+ const compressedPath = await compressImage(cropped.path);
403
+ onComplete({ ...cropped, path: compressedPath });
404
+ }
106
405
  }
107
- catch (e) {
108
- console.log("Camera Photo Error:", e);
406
+ catch (error) {
407
+ console.log("Camera cancelled or error:", error);
109
408
  }
110
409
  }
111
- // VIDEO
112
410
  else {
113
- const mic = await checkMicroPhonePermission();
114
- if (!mic)
411
+ // VIDEO CAPTURE - check microphone permission first
412
+ const micPermission = await checkMicroPhonePermission();
413
+ if (!micPermission) {
414
+ Alert.alert("Microphone Permission Required", "Please enable microphone access to record videos.");
115
415
  return;
116
- launchCamera({ mediaType: "video" }, async (res) => {
117
- const raw = res?.assets?.[0];
118
- if (!raw)
119
- return;
120
- sendRaw(raw);
121
- const compressed = enableCompression
122
- ? await compressVideo(raw.uri)
123
- : raw.uri;
124
- sendFinal(raw, compressed);
416
+ }
417
+ launchCamera({
418
+ mediaType: "video",
419
+ durationLimit: 60,
420
+ videoQuality: "high",
421
+ }, async (response) => {
422
+ if (response?.assets?.length) {
423
+ const videoUri = response.assets[0]?.uri;
424
+ const compressedPath = await compressVideo(videoUri);
425
+ onComplete({
426
+ path: compressedPath,
427
+ duration: response.assets[0]?.duration,
428
+ });
429
+ }
125
430
  });
126
431
  }
127
432
  });
128
433
  };
129
- //--------------------------------------
130
- // GALLERY HANDLER
131
- //--------------------------------------
434
+ // GALLERY HANDLER with permission check and compression
132
435
  const handleGallery = async () => {
133
- onClose(); // 🔥 CLOSE IMMEDIATELY
134
436
  await galleryPermissions(async (granted) => {
135
437
  if (!granted)
136
438
  return;
137
- // PHOTO (Crop Picker)
138
439
  if (mediaType === "photo") {
139
440
  try {
140
- const img = await ImageCropPicker.openPicker({
141
- mediaType: "photo",
142
- cropping: true,
143
- });
144
- sendRaw(img);
145
- const compressed = enableCompression
146
- ? await compressImage(img.path)
147
- : img.path;
148
- sendFinal(img, compressed);
441
+ if (isMultiSelect) {
442
+ const images = await ImageCropPicker.openPicker({
443
+ mediaType: "photo",
444
+ multiple: true,
445
+ maxFiles: 5,
446
+ });
447
+ if (images.length > 5) {
448
+ Alert.alert("Limit Exceeded", "You can only select up to 5 images.");
449
+ return;
450
+ }
451
+ // Compress multiple images
452
+ const compressedImages = await Promise.all(images.map(async (img) => ({
453
+ ...img,
454
+ path: await compressImage(img.path),
455
+ })));
456
+ onComplete(compressedImages);
457
+ }
458
+ else {
459
+ // Single image with crop
460
+ const response = await ImageCropPicker.openPicker({
461
+ mediaType: "photo",
462
+ });
463
+ const cropped = await ImageCropPicker.openCropper({
464
+ path: response?.path,
465
+ width: response?.width,
466
+ height: response?.height,
467
+ mediaType: "photo",
468
+ freeStyleCropEnabled: true,
469
+ });
470
+ const compressedPath = await compressImage(cropped.path);
471
+ onComplete({ ...cropped, path: compressedPath });
472
+ }
149
473
  }
150
- catch (e) {
151
- console.log("Gallery Photo Error:", e);
474
+ catch (error) {
475
+ console.log("Gallery cancelled or error:", error);
152
476
  }
153
477
  }
154
- // VIDEO
155
478
  else {
156
- launchImageLibrary({ mediaType: "video" }, async (res) => {
157
- const raw = res?.assets?.[0];
158
- if (!raw)
159
- return;
160
- sendRaw(raw);
161
- const compressed = enableCompression
162
- ? await compressVideo(raw.uri)
163
- : raw.uri;
164
- sendFinal(raw, compressed);
479
+ // VIDEO FROM GALLERY
480
+ launchImageLibrary({
481
+ mediaType: "video",
482
+ assetRepresentationMode: "current",
483
+ }, async (result) => {
484
+ if (result?.assets?.length) {
485
+ const videoUri = result.assets[0]?.uri;
486
+ const compressedPath = await compressVideo(videoUri);
487
+ onComplete({
488
+ path: compressedPath,
489
+ duration: result.assets[0]?.duration,
490
+ });
491
+ }
165
492
  });
166
493
  }
167
494
  });
168
495
  };
169
- //--------------------------------------
170
- // RETURN UI
171
- //--------------------------------------
172
496
  return (React.createElement(BottomSheet, { visible: visible, onClose: onClose, height: 230 },
173
497
  React.createElement(View, { style: styles.container },
174
498
  React.createElement(TouchableOpacity, { style: styles.row, onPress: handleCamera },
@@ -184,23 +508,13 @@ const ImagePicker = ({ mediaType, visible, onSuccess, onClose, enableCompression
184
508
  React.createElement(Text, { style: styles.text }, "Cancel")))));
185
509
  };
186
510
  export default ImagePicker;
187
- //--------------------------------------
188
- // STYLES
189
- //--------------------------------------
190
511
  const styles = StyleSheet.create({
191
512
  container: { flex: 1, padding: 16 },
192
513
  row: {
193
514
  flexDirection: "row",
194
515
  alignItems: "center",
195
- justifyContent: "center",
196
- paddingVertical: 14,
197
- },
198
- text: {
199
- ...Typography.style.standardU(),
200
- color: Colors.white,
201
- marginLeft: 10,
202
- textAlign: "center",
203
516
  },
517
+ text: { ...Typography.style.standardU(), color: Colors.white },
204
518
  icon: {
205
519
  width: Scale.moderateScale(20),
206
520
  height: Scale.moderateScale(20),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamnhz/rn-ui-toolkit",
3
- "version": "1.2.3",
3
+ "version": "1.2.5",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -20,7 +20,7 @@
20
20
  "react-native-date-picker": "^5.0.13",
21
21
  "react-native-element-dropdown": "^2.12.4",
22
22
  "react-native-elements": "^3.4.3",
23
- "react-native-fast-image": "^8.6.3",
23
+ "@d11/react-native-fast-image": "^8.12.0",
24
24
  "react-native-gesture-handler": "^2.26.0",
25
25
  "react-native-image-crop-picker": "^0.42.0",
26
26
  "react-native-image-picker": "^8.2.0",