@teamnhz/rn-ui-toolkit 1.2.1 โ†’ 1.2.3

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,9 +1,8 @@
1
1
  import React from "react";
2
2
  type Props = {
3
3
  mediaType: "photo" | "video";
4
- isMultiSelect?: boolean;
5
- onSuccess: (res: any) => void;
6
4
  visible: boolean;
5
+ onSuccess: (res: any) => void;
7
6
  onClose: () => void;
8
7
  enableCompression?: boolean;
9
8
  };
@@ -7,25 +7,38 @@ import { Image as ImageCompressor, Video as VideoCompressor, } from "react-nativ
7
7
  import { cameraPermissions, galleryPermissions, checkMicroPhonePermission, } from "../../utils/permissions";
8
8
  import { Colors, Images, Scale, Typography } from "../../styles";
9
9
  //--------------------------------------
10
- // ๐ŸŸฆ FORMAT RESPONSE (single standard)
10
+ // ๐ŸŸฆ FORMAT PATH (always file:// format)
11
11
  //--------------------------------------
12
12
  const normalizePath = (p) => {
13
13
  if (!p)
14
14
  return "";
15
15
  return p.startsWith("file://") ? p : `file://${p}`;
16
16
  };
17
- const buildResponse = (raw, compressed) => {
18
- return {
19
- path: normalizePath(compressed || raw?.path || raw?.uri),
20
- originalPath: normalizePath(raw?.path || raw?.uri),
21
- fileName: raw?.fileName || "",
22
- type: raw?.type || "",
23
- duration: raw?.duration || undefined,
24
- };
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
25
  };
26
- const ImagePicker = ({ mediaType, onSuccess, visible, onClose, enableCompression = true, }) => {
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, }) => {
27
40
  //--------------------------------------
28
- // ๐ŸŸฆ SEND RAW (loading true)
41
+ // SEND RAW (loader ON)
29
42
  //--------------------------------------
30
43
  const sendRaw = (raw) => {
31
44
  onSuccess({
@@ -34,16 +47,17 @@ const ImagePicker = ({ mediaType, onSuccess, visible, onClose, enableCompression
34
47
  });
35
48
  };
36
49
  //--------------------------------------
37
- // ๐ŸŸฆ SEND FINAL COMPRESSED
50
+ // SEND FINAL (loader OFF)
38
51
  //--------------------------------------
39
- const sendFinal = (raw, compressedPath) => {
52
+ const sendFinal = (raw, compressed) => {
40
53
  onSuccess({
41
54
  loading: false,
42
- data: buildResponse(raw, compressedPath),
55
+ data: buildResponse(raw, compressed),
43
56
  });
57
+ resetInternalState();
44
58
  };
45
59
  //--------------------------------------
46
- // ๐ŸŸฆ COMPRESS IMAGE
60
+ // COMPRESS IMAGE
47
61
  //--------------------------------------
48
62
  const compressImage = async (path) => {
49
63
  try {
@@ -57,7 +71,7 @@ const ImagePicker = ({ mediaType, onSuccess, visible, onClose, enableCompression
57
71
  }
58
72
  };
59
73
  //--------------------------------------
60
- // ๐ŸŸฆ COMPRESS VIDEO
74
+ // COMPRESS VIDEO
61
75
  //--------------------------------------
62
76
  const compressVideo = async (uri) => {
63
77
  try {
@@ -70,13 +84,14 @@ const ImagePicker = ({ mediaType, onSuccess, visible, onClose, enableCompression
70
84
  }
71
85
  };
72
86
  //--------------------------------------
73
- // ๐ŸŸฆ TAKE PHOTO / VIDEO FROM CAMERA
87
+ // CAMERA HANDLER
74
88
  //--------------------------------------
75
89
  const handleCamera = async () => {
90
+ onClose(); // ๐Ÿ”ฅ CLOSE FIRST (best UX)
76
91
  await cameraPermissions(async (granted) => {
77
92
  if (!granted)
78
93
  return;
79
- // PHOTO FROM CAMERA
94
+ // PHOTO
80
95
  if (mediaType === "photo") {
81
96
  try {
82
97
  const img = await ImageCropPicker.openCamera({
@@ -90,10 +105,10 @@ const ImagePicker = ({ mediaType, onSuccess, visible, onClose, enableCompression
90
105
  sendFinal(img, compressed);
91
106
  }
92
107
  catch (e) {
93
- console.log("Camera Photo Error", e);
108
+ console.log("Camera Photo Error:", e);
94
109
  }
95
110
  }
96
- // VIDEO FROM CAMERA
111
+ // VIDEO
97
112
  else {
98
113
  const mic = await checkMicroPhonePermission();
99
114
  if (!mic)
@@ -112,13 +127,14 @@ const ImagePicker = ({ mediaType, onSuccess, visible, onClose, enableCompression
112
127
  });
113
128
  };
114
129
  //--------------------------------------
115
- // ๐ŸŸฆ PICK FROM GALLERY
130
+ // GALLERY HANDLER
116
131
  //--------------------------------------
117
132
  const handleGallery = async () => {
133
+ onClose(); // ๐Ÿ”ฅ CLOSE IMMEDIATELY
118
134
  await galleryPermissions(async (granted) => {
119
135
  if (!granted)
120
136
  return;
121
- // PHOTO FROM GALLERY (CROP PICKER)
137
+ // PHOTO (Crop Picker)
122
138
  if (mediaType === "photo") {
123
139
  try {
124
140
  const img = await ImageCropPicker.openPicker({
@@ -132,10 +148,10 @@ const ImagePicker = ({ mediaType, onSuccess, visible, onClose, enableCompression
132
148
  sendFinal(img, compressed);
133
149
  }
134
150
  catch (e) {
135
- console.log("Gallery Photo Error", e);
151
+ console.log("Gallery Photo Error:", e);
136
152
  }
137
153
  }
138
- // VIDEO FROM GALLERY
154
+ // VIDEO
139
155
  else {
140
156
  launchImageLibrary({ mediaType: "video" }, async (res) => {
141
157
  const raw = res?.assets?.[0];
@@ -151,6 +167,8 @@ const ImagePicker = ({ mediaType, onSuccess, visible, onClose, enableCompression
151
167
  });
152
168
  };
153
169
  //--------------------------------------
170
+ // RETURN UI
171
+ //--------------------------------------
154
172
  return (React.createElement(BottomSheet, { visible: visible, onClose: onClose, height: 230 },
155
173
  React.createElement(View, { style: styles.container },
156
174
  React.createElement(TouchableOpacity, { style: styles.row, onPress: handleCamera },
@@ -166,10 +184,23 @@ const ImagePicker = ({ mediaType, onSuccess, visible, onClose, enableCompression
166
184
  React.createElement(Text, { style: styles.text }, "Cancel")))));
167
185
  };
168
186
  export default ImagePicker;
187
+ //--------------------------------------
188
+ // STYLES
189
+ //--------------------------------------
169
190
  const styles = StyleSheet.create({
170
191
  container: { flex: 1, padding: 16 },
171
- row: { flexDirection: "row", alignItems: "center" },
172
- text: { ...Typography.style.standardU(), color: Colors.white },
192
+ row: {
193
+ flexDirection: "row",
194
+ 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
+ },
173
204
  icon: {
174
205
  width: Scale.moderateScale(20),
175
206
  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.1",
3
+ "version": "1.2.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [