@tradly/asset 1.0.12 → 1.0.14

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 (72) hide show
  1. package/README.md +257 -13
  2. package/dist/components/FileUpload.js +8 -247
  3. package/dist/components/FileUpload.native.js +13 -0
  4. package/dist/components/Icons.js +10 -33
  5. package/dist/components/Icons.native.js +16 -0
  6. package/dist/components/ImagesSkeleton.js +7 -15
  7. package/dist/components/ImagesSkeleton.native.js +13 -0
  8. package/dist/components/MediaGallery.js +8 -148
  9. package/dist/components/MediaGallery.native.js +13 -0
  10. package/dist/components/MediaPopup.js +8 -99
  11. package/dist/components/MediaPopup.native.js +13 -0
  12. package/dist/components/MediaTab.js +7 -180
  13. package/dist/components/MediaTab.native.js +13 -0
  14. package/dist/components/Pagination.js +8 -136
  15. package/dist/components/Pagination.native.js +13 -0
  16. package/dist/components/VideosGallery.js +8 -148
  17. package/dist/components/VideosGallery.native.js +13 -0
  18. package/dist/core/MediaApiService.js +396 -0
  19. package/dist/esm/components/FileUpload.js +1 -246
  20. package/dist/esm/components/FileUpload.native.js +1 -0
  21. package/dist/esm/components/Icons.js +1 -32
  22. package/dist/esm/components/Icons.native.js +1 -0
  23. package/dist/esm/components/ImagesSkeleton.js +1 -14
  24. package/dist/esm/components/ImagesSkeleton.native.js +1 -0
  25. package/dist/esm/components/MediaGallery.js +1 -144
  26. package/dist/esm/components/MediaGallery.native.js +1 -0
  27. package/dist/esm/components/MediaPopup.js +1 -97
  28. package/dist/esm/components/MediaPopup.native.js +1 -0
  29. package/dist/esm/components/MediaTab.js +1 -177
  30. package/dist/esm/components/MediaTab.native.js +1 -0
  31. package/dist/esm/components/Pagination.js +1 -134
  32. package/dist/esm/components/Pagination.native.js +1 -0
  33. package/dist/esm/components/VideosGallery.js +1 -144
  34. package/dist/esm/components/VideosGallery.native.js +1 -0
  35. package/dist/esm/core/MediaApiService.js +390 -0
  36. package/dist/esm/index.js +1 -1
  37. package/dist/esm/native/FileUpload.native.js +298 -0
  38. package/dist/esm/native/Icons.native.js +51 -0
  39. package/dist/esm/native/ImagesSkeleton.native.js +45 -0
  40. package/dist/esm/native/MediaGallery.native.js +221 -0
  41. package/dist/esm/native/MediaPopup.native.js +151 -0
  42. package/dist/esm/native/MediaTab.native.js +175 -0
  43. package/dist/esm/native/Pagination.native.js +186 -0
  44. package/dist/esm/native/VideosGallery.native.js +233 -0
  45. package/dist/esm/services/apiService.js +1 -372
  46. package/dist/esm/web/FileUpload.web.js +253 -0
  47. package/dist/esm/web/Icons.web.js +32 -0
  48. package/dist/esm/web/ImagesSkeleton.web.js +14 -0
  49. package/dist/esm/web/MediaGallery.web.js +144 -0
  50. package/dist/esm/web/MediaPopup.web.js +97 -0
  51. package/dist/esm/web/MediaTab.web.js +177 -0
  52. package/dist/esm/web/Pagination.web.js +134 -0
  53. package/dist/esm/web/VideosGallery.web.js +144 -0
  54. package/dist/index.js +2 -2
  55. package/dist/native/FileUpload.native.js +304 -0
  56. package/dist/native/Icons.native.js +59 -0
  57. package/dist/native/ImagesSkeleton.native.js +52 -0
  58. package/dist/native/MediaGallery.native.js +230 -0
  59. package/dist/native/MediaPopup.native.js +158 -0
  60. package/dist/native/MediaTab.native.js +184 -0
  61. package/dist/native/Pagination.native.js +193 -0
  62. package/dist/native/VideosGallery.native.js +241 -0
  63. package/dist/services/apiService.js +2 -372
  64. package/dist/web/FileUpload.web.js +259 -0
  65. package/dist/web/Icons.web.js +39 -0
  66. package/dist/web/ImagesSkeleton.web.js +21 -0
  67. package/dist/web/MediaGallery.web.js +153 -0
  68. package/dist/web/MediaPopup.web.js +104 -0
  69. package/dist/web/MediaTab.web.js +186 -0
  70. package/dist/web/Pagination.web.js +141 -0
  71. package/dist/web/VideosGallery.web.js +153 -0
  72. package/package.json +4 -3
@@ -0,0 +1,298 @@
1
+ function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
2
+ function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
3
+ function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
4
+ function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
5
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
6
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
8
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
9
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
10
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
11
+ import React, { useState } from "react";
12
+ import { View, Text, TouchableOpacity, StyleSheet, Alert, ActivityIndicator } from "react-native";
13
+ import { CameraIcon } from "./Icons.native";
14
+
15
+ /**
16
+ * FileUpload component for React Native
17
+ *
18
+ * USAGE EXAMPLES:
19
+ *
20
+ * 1. Using react-native-image-picker:
21
+ * import { launchImageLibrary } from 'react-native-image-picker'
22
+ *
23
+ * <MediaPopup
24
+ * picker={(options) => {
25
+ * return new Promise((resolve) => {
26
+ * launchImageLibrary(options, (response) => {
27
+ * resolve(response.assets || [])
28
+ * })
29
+ * })
30
+ * }}
31
+ * ...
32
+ * />
33
+ *
34
+ * 2. Using expo-image-picker:
35
+ * import * as ImagePicker from 'expo-image-picker'
36
+ *
37
+ * <MediaPopup
38
+ * picker={async (options) => {
39
+ * const result = await ImagePicker.launchImageLibraryAsync({
40
+ * mediaTypes: options.mediaType === 'photo' ? ImagePicker.MediaTypeOptions.Images
41
+ * : options.mediaType === 'video' ? ImagePicker.MediaTypeOptions.Videos
42
+ * : ImagePicker.MediaTypeOptions.All,
43
+ * allowsMultipleSelection: options.allowsMultiple,
44
+ * quality: options.quality,
45
+ * })
46
+ * return result.assets || []
47
+ * }}
48
+ * ...
49
+ * />
50
+ *
51
+ * 3. Custom picker options:
52
+ * <MediaPopup
53
+ * picker={...}
54
+ * pickerOptions={(accept) => ({
55
+ * mediaType: accept?.includes('image') ? 'photo' : 'video',
56
+ * quality: 0.9,
57
+ * allowsMultiple: true,
58
+ * // Add any other options your picker library supports
59
+ * })}
60
+ * ...
61
+ * />
62
+ *
63
+ * @param {Function} picker - REQUIRED: Your file picker function
64
+ * Should accept options and return a promise that resolves with an array of file objects
65
+ * Each file object should have: { uri, type/mimeType, fileName/name }
66
+ *
67
+ * @param {Function} pickerOptions - Optional: Function to generate picker options based on accept type
68
+ * Default: { mediaType: 'photo' | 'video' | 'mixed', quality: 0.8, allowsMultiple: true }
69
+ */
70
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
71
+ var FileUpload = function FileUpload(_ref) {
72
+ var loadMedia = _ref.loadMedia,
73
+ accept = _ref.accept,
74
+ title = _ref.title,
75
+ apiService = _ref.apiService,
76
+ onUploadStart = _ref.onUploadStart,
77
+ onUploadComplete = _ref.onUploadComplete,
78
+ onUploadError = _ref.onUploadError,
79
+ picker = _ref.picker,
80
+ pickerOptions = _ref.pickerOptions,
81
+ containerStyle = _ref.containerStyle,
82
+ buttonStyle = _ref.buttonStyle,
83
+ iconContainerStyle = _ref.iconContainerStyle,
84
+ titleStyle = _ref.titleStyle,
85
+ loadingStyle = _ref.loadingStyle;
86
+ var _useState = useState(false),
87
+ _useState2 = _slicedToArray(_useState, 2),
88
+ isLoading = _useState2[0],
89
+ setISLoading = _useState2[1];
90
+ var _useState3 = useState(0),
91
+ _useState4 = _slicedToArray(_useState3, 2),
92
+ uploadProgress = _useState4[0],
93
+ setUploadProgress = _useState4[1];
94
+
95
+ // Convert file picker result to File-like object for apiService
96
+ var convertToFile = function convertToFile(pickerResult) {
97
+ // Picker typically returns: { uri, type, fileName, fileSize, width, height }
98
+ // We need to create a File-like object that apiService.uploadMedia expects
99
+ // For React Native, we'll use the URI directly and let uploadMedia handle it
100
+
101
+ return {
102
+ uri: pickerResult.uri,
103
+ name: pickerResult.fileName || pickerResult.uri.split("/").pop() || "image.jpg",
104
+ type: pickerResult.type || pickerResult.mimeType || "image/jpeg",
105
+ // Keep original picker result for potential use
106
+ _pickerResult: pickerResult
107
+ };
108
+ };
109
+ var uploadFiles = /*#__PURE__*/function () {
110
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(fileList) {
111
+ var filesToUpload, uploadedUrls, _t;
112
+ return _regenerator().w(function (_context) {
113
+ while (1) switch (_context.p = _context.n) {
114
+ case 0:
115
+ if (onUploadStart) {
116
+ onUploadStart(fileList);
117
+ }
118
+ setISLoading(true);
119
+ setUploadProgress(0);
120
+ _context.p = 1;
121
+ // Convert picker results to File-like objects
122
+ filesToUpload = fileList.map(convertToFile); // Use the API service to upload files
123
+ // Note: uploadMedia will need to handle React Native file URIs
124
+ _context.n = 2;
125
+ return apiService.uploadMedia(filesToUpload, apiService.authKey);
126
+ case 2:
127
+ uploadedUrls = _context.v;
128
+ if (onUploadComplete) {
129
+ onUploadComplete(uploadedUrls);
130
+ }
131
+ setUploadProgress(0);
132
+ if (loadMedia) {
133
+ loadMedia();
134
+ }
135
+ _context.n = 4;
136
+ break;
137
+ case 3:
138
+ _context.p = 3;
139
+ _t = _context.v;
140
+ console.error("Upload error:", _t);
141
+ if (onUploadError) {
142
+ onUploadError(_t);
143
+ }
144
+ Alert.alert("Upload Error", _t.message || "Failed to upload file");
145
+ case 4:
146
+ _context.p = 4;
147
+ setISLoading(false);
148
+ return _context.f(4);
149
+ case 5:
150
+ return _context.a(2);
151
+ }
152
+ }, _callee, null, [[1, 3, 4, 5]]);
153
+ }));
154
+ return function uploadFiles(_x) {
155
+ return _ref2.apply(this, arguments);
156
+ };
157
+ }();
158
+ var handlePickFile = /*#__PURE__*/function () {
159
+ var _ref3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
160
+ var options, isImage, isVideo, result, assets, _error$message, _t2;
161
+ return _regenerator().w(function (_context2) {
162
+ while (1) switch (_context2.p = _context2.n) {
163
+ case 0:
164
+ if (picker) {
165
+ _context2.n = 1;
166
+ break;
167
+ }
168
+ Alert.alert("File Picker Not Configured", "Please provide a picker function prop. See FileUpload.native.jsx documentation for examples.", [{
169
+ text: "OK"
170
+ }]);
171
+ return _context2.a(2);
172
+ case 1:
173
+ _context2.p = 1;
174
+ // Generate picker options based on accept type
175
+
176
+ if (pickerOptions && typeof pickerOptions === "function") {
177
+ options = pickerOptions(accept);
178
+ } else {
179
+ // Default options
180
+ isImage = accept === null || accept === void 0 ? void 0 : accept.includes("image");
181
+ isVideo = accept === null || accept === void 0 ? void 0 : accept.includes("video");
182
+ options = {
183
+ mediaType: isImage ? "photo" : isVideo ? "video" : "mixed",
184
+ quality: 0.8,
185
+ allowsMultiple: true
186
+ };
187
+ }
188
+
189
+ // Call the picker function provided by the app
190
+ _context2.n = 2;
191
+ return picker(options);
192
+ case 2:
193
+ result = _context2.v;
194
+ // Handle different picker response formats
195
+ // react-native-image-picker: { assets: [...] }
196
+ // expo-image-picker: { assets: [...] }
197
+ // Custom: could be array directly or { assets: [...] }
198
+ assets = Array.isArray(result) ? result : (result === null || result === void 0 ? void 0 : result.assets) || result || [];
199
+ if (!(assets && assets.length > 0)) {
200
+ _context2.n = 3;
201
+ break;
202
+ }
203
+ _context2.n = 3;
204
+ return uploadFiles(assets);
205
+ case 3:
206
+ _context2.n = 6;
207
+ break;
208
+ case 4:
209
+ _context2.p = 4;
210
+ _t2 = _context2.v;
211
+ console.error("Error picking file:", _t2);
212
+ if (!(_t2.code === "E_PICKER_CANCELLED" || (_error$message = _t2.message) !== null && _error$message !== void 0 && _error$message.includes("cancel"))) {
213
+ _context2.n = 5;
214
+ break;
215
+ }
216
+ return _context2.a(2);
217
+ case 5:
218
+ Alert.alert("Error", _t2.message || "Failed to pick file");
219
+ case 6:
220
+ return _context2.a(2);
221
+ }
222
+ }, _callee2, null, [[1, 4]]);
223
+ }));
224
+ return function handlePickFile() {
225
+ return _ref3.apply(this, arguments);
226
+ };
227
+ }();
228
+ if (isLoading) {
229
+ return /*#__PURE__*/_jsxs(View, {
230
+ style: [styles.loadingContainer, loadingStyle],
231
+ children: [/*#__PURE__*/_jsx(ActivityIndicator, {
232
+ size: "small",
233
+ color: "#3B3269"
234
+ }), /*#__PURE__*/_jsx(Text, {
235
+ style: styles.loadingText,
236
+ children: "Uploading..."
237
+ })]
238
+ });
239
+ }
240
+ return /*#__PURE__*/_jsx(View, {
241
+ style: [styles.container, containerStyle],
242
+ children: /*#__PURE__*/_jsxs(TouchableOpacity, {
243
+ onPress: handlePickFile,
244
+ style: [styles.button, buttonStyle],
245
+ disabled: isLoading,
246
+ children: [/*#__PURE__*/_jsx(View, {
247
+ style: [styles.iconContainer, iconContainerStyle],
248
+ children: /*#__PURE__*/_jsx(CameraIcon, {})
249
+ }), /*#__PURE__*/_jsx(Text, {
250
+ style: [styles.title, titleStyle],
251
+ children: title
252
+ })]
253
+ })
254
+ });
255
+ };
256
+ var styles = StyleSheet.create({
257
+ container: {
258
+ width: "100%",
259
+ height: 160
260
+ },
261
+ button: {
262
+ width: "100%",
263
+ height: "100%",
264
+ flexDirection: "column",
265
+ justifyContent: "center",
266
+ alignItems: "center",
267
+ borderWidth: 1,
268
+ borderColor: "#3B3269",
269
+ borderStyle: "dashed",
270
+ borderRadius: 8,
271
+ backgroundColor: "#FFFFFF"
272
+ },
273
+ iconContainer: {
274
+ padding: 10,
275
+ backgroundColor: "#3B3269",
276
+ borderRadius: 20,
277
+ marginBottom: 8
278
+ },
279
+ title: {
280
+ fontSize: 14,
281
+ color: "#000000",
282
+ marginTop: 8
283
+ },
284
+ loadingContainer: {
285
+ width: "100%",
286
+ height: 160,
287
+ justifyContent: "center",
288
+ alignItems: "center",
289
+ backgroundColor: "#E5E5E5",
290
+ borderRadius: 8
291
+ },
292
+ loadingText: {
293
+ marginTop: 8,
294
+ fontSize: 14,
295
+ color: "#666666"
296
+ }
297
+ });
298
+ export default FileUpload;
@@ -0,0 +1,51 @@
1
+ import React from 'react';
2
+ import { View, Text, StyleSheet } from 'react-native';
3
+ // Note: For better icons, you can use react-native-svg or react-native-vector-icons
4
+ // This is a simple implementation using Text/View
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ export var CloseIcon = function CloseIcon(_ref) {
7
+ var _ref$size = _ref.size,
8
+ size = _ref$size === void 0 ? 32 : _ref$size,
9
+ _ref$color = _ref.color,
10
+ color = _ref$color === void 0 ? '#000000' : _ref$color;
11
+ return /*#__PURE__*/_jsx(View, {
12
+ style: [styles.closeIcon, {
13
+ width: size,
14
+ height: size
15
+ }],
16
+ children: /*#__PURE__*/_jsx(Text, {
17
+ style: [styles.closeIconText, {
18
+ color: color,
19
+ fontSize: size * 0.6
20
+ }],
21
+ children: "\u2715"
22
+ })
23
+ });
24
+ };
25
+ export var CameraIcon = function CameraIcon() {
26
+ return /*#__PURE__*/_jsx(View, {
27
+ style: styles.cameraIcon,
28
+ children: /*#__PURE__*/_jsx(Text, {
29
+ style: styles.cameraIconText,
30
+ children: "\uD83D\uDCF7"
31
+ })
32
+ });
33
+ };
34
+ var styles = StyleSheet.create({
35
+ closeIcon: {
36
+ justifyContent: 'center',
37
+ alignItems: 'center'
38
+ },
39
+ closeIconText: {
40
+ fontWeight: 'bold'
41
+ },
42
+ cameraIcon: {
43
+ width: 22,
44
+ height: 18,
45
+ justifyContent: 'center',
46
+ alignItems: 'center'
47
+ },
48
+ cameraIconText: {
49
+ fontSize: 18
50
+ }
51
+ });
@@ -0,0 +1,45 @@
1
+ import React from 'react';
2
+ import { View, StyleSheet, Dimensions, ActivityIndicator } from 'react-native';
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ var _Dimensions$get = Dimensions.get('window'),
5
+ SCREEN_WIDTH = _Dimensions$get.width;
6
+ var NUM_COLUMNS = 3;
7
+ var ITEM_MARGIN = 8;
8
+ var ITEM_SIZE = (SCREEN_WIDTH - 40 - ITEM_MARGIN * (NUM_COLUMNS - 1) * 2) / NUM_COLUMNS;
9
+ var ImagesSkeleton = function ImagesSkeleton(_ref) {
10
+ var _ref$per_page = _ref.per_page,
11
+ per_page = _ref$per_page === void 0 ? 30 : _ref$per_page;
12
+ var skeletonItems = [];
13
+ for (var i = 0; i < per_page; i++) {
14
+ skeletonItems.push(/*#__PURE__*/_jsx(View, {
15
+ style: [styles.skeletonItem, {
16
+ width: ITEM_SIZE,
17
+ height: ITEM_SIZE,
18
+ margin: ITEM_MARGIN
19
+ }],
20
+ children: /*#__PURE__*/_jsx(ActivityIndicator, {
21
+ size: "small",
22
+ color: "#3B3269"
23
+ })
24
+ }, i));
25
+ }
26
+ return /*#__PURE__*/_jsx(View, {
27
+ style: styles.container,
28
+ children: skeletonItems
29
+ });
30
+ };
31
+ var styles = StyleSheet.create({
32
+ container: {
33
+ flexDirection: 'row',
34
+ flexWrap: 'wrap',
35
+ padding: 4
36
+ },
37
+ skeletonItem: {
38
+ backgroundColor: '#E5E5E5',
39
+ borderRadius: 8,
40
+ justifyContent: 'center',
41
+ alignItems: 'center',
42
+ opacity: 0.3
43
+ }
44
+ });
45
+ export default ImagesSkeleton;
@@ -0,0 +1,221 @@
1
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
2
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
4
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
5
+ function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
6
+ function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
7
+ function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
8
+ function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
9
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
10
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
11
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
12
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
13
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
14
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
15
+ import React, { useState, useEffect } from 'react';
16
+ import { View, FlatList, Image, TouchableOpacity, StyleSheet, Dimensions } from 'react-native';
17
+ import FileUpload from './FileUpload.native';
18
+ import ImagesSkeleton from './ImagesSkeleton.native';
19
+ import Pagination from './Pagination.native';
20
+ import { jsx as _jsx } from "react/jsx-runtime";
21
+ var _Dimensions$get = Dimensions.get('window'),
22
+ SCREEN_WIDTH = _Dimensions$get.width;
23
+ var NUM_COLUMNS = 3;
24
+ var ITEM_MARGIN = 8;
25
+ var ITEM_SIZE = (SCREEN_WIDTH - 40 - ITEM_MARGIN * (NUM_COLUMNS - 1) * 2) / NUM_COLUMNS; // 40 = padding, adjust for margins
26
+
27
+ var IMAGE_MIME_TYPES = ['image/png', 'image/jpeg', 'image/webp', 'image/svg+xml', 'image/gif', 'image/avif', 'image/x-icon', 'image/vnd.microsoft.icon', 'image/heic', 'image/heif'];
28
+ var ImagesGallery = function ImagesGallery(_ref) {
29
+ var update_data = _ref.update_data,
30
+ closePopup = _ref.closePopup,
31
+ apiService = _ref.apiService,
32
+ onError = _ref.onError,
33
+ picker = _ref.picker,
34
+ pickerOptions = _ref.pickerOptions,
35
+ containerStyle = _ref.containerStyle,
36
+ gridStyle = _ref.gridStyle,
37
+ imageItemStyle = _ref.imageItemStyle,
38
+ paginationContainerStyle = _ref.paginationContainerStyle;
39
+ var _useState = useState([]),
40
+ _useState2 = _slicedToArray(_useState, 2),
41
+ images = _useState2[0],
42
+ setImages = _useState2[1];
43
+ var _useState3 = useState(0),
44
+ _useState4 = _slicedToArray(_useState3, 2),
45
+ total_count = _useState4[0],
46
+ setTotalCount = _useState4[1];
47
+ var _useState5 = useState(1),
48
+ _useState6 = _slicedToArray(_useState5, 2),
49
+ currentPage = _useState6[0],
50
+ setCurrentPage = _useState6[1];
51
+ var _useState7 = useState(false),
52
+ _useState8 = _slicedToArray(_useState7, 2),
53
+ isLoading = _useState8[0],
54
+ setISLoading = _useState8[1];
55
+
56
+ // Fetch images
57
+ useEffect(function () {
58
+ loadMedia();
59
+ }, []);
60
+ var loadMedia = /*#__PURE__*/function () {
61
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
62
+ var page_number,
63
+ _response$data,
64
+ _response$data2,
65
+ response,
66
+ mediaData,
67
+ count,
68
+ _args = arguments,
69
+ _t;
70
+ return _regenerator().w(function (_context) {
71
+ while (1) switch (_context.p = _context.n) {
72
+ case 0:
73
+ page_number = _args.length > 0 && _args[0] !== undefined ? _args[0] : 1;
74
+ _context.p = 1;
75
+ _context.n = 2;
76
+ return apiService.fetchMedia({
77
+ mimeTypes: IMAGE_MIME_TYPES,
78
+ page: page_number,
79
+ setISLoading: setISLoading,
80
+ isLoading: isLoading
81
+ });
82
+ case 2:
83
+ response = _context.v;
84
+ // Handle different response formats
85
+ mediaData = (response === null || response === void 0 ? void 0 : response.media) || (response === null || response === void 0 || (_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.media) || (response === null || response === void 0 ? void 0 : response.data) || response || [];
86
+ count = (response === null || response === void 0 ? void 0 : response.count) || (response === null || response === void 0 || (_response$data2 = response.data) === null || _response$data2 === void 0 ? void 0 : _response$data2.count) || (response === null || response === void 0 ? void 0 : response.total) || 0;
87
+ setImages(Array.isArray(mediaData) ? mediaData : []);
88
+ setTotalCount(count);
89
+ setCurrentPage(page_number);
90
+ _context.n = 4;
91
+ break;
92
+ case 3:
93
+ _context.p = 3;
94
+ _t = _context.v;
95
+ console.error('Error loading media:', _t);
96
+ if (onError) {
97
+ onError(_t);
98
+ }
99
+ case 4:
100
+ return _context.a(2);
101
+ }
102
+ }, _callee, null, [[1, 3]]);
103
+ }));
104
+ return function loadMedia() {
105
+ return _ref2.apply(this, arguments);
106
+ };
107
+ }();
108
+ var handleImageClick = function handleImageClick(image) {
109
+ if (update_data) {
110
+ update_data(image.url || image);
111
+ }
112
+ if (closePopup) {
113
+ closePopup();
114
+ }
115
+ };
116
+ var renderItem = function renderItem(_ref3) {
117
+ var item = _ref3.item,
118
+ index = _ref3.index;
119
+ // First item is the upload button
120
+ if (index === 0) {
121
+ return /*#__PURE__*/_jsx(View, {
122
+ style: [styles.uploadContainer, {
123
+ width: ITEM_SIZE,
124
+ height: ITEM_SIZE
125
+ }],
126
+ children: /*#__PURE__*/_jsx(FileUpload, {
127
+ loadMedia: loadMedia,
128
+ accept: "image/*",
129
+ title: "Add Image",
130
+ apiService: apiService,
131
+ onUploadError: onError,
132
+ picker: picker,
133
+ pickerOptions: pickerOptions
134
+ })
135
+ });
136
+ }
137
+ var image = images[index - 1];
138
+ var imageUrl = typeof image === 'string' ? image : image.url;
139
+ var imageKey = image.id || image.url || index;
140
+ return /*#__PURE__*/_jsx(TouchableOpacity, {
141
+ onPress: function onPress() {
142
+ return handleImageClick(image);
143
+ },
144
+ style: [styles.imageItem, {
145
+ width: ITEM_SIZE,
146
+ height: ITEM_SIZE
147
+ }, imageItemStyle],
148
+ children: /*#__PURE__*/_jsx(Image, {
149
+ source: {
150
+ uri: imageUrl
151
+ },
152
+ style: styles.image,
153
+ resizeMode: "cover"
154
+ })
155
+ });
156
+ };
157
+ var data = isLoading ? [] : [{
158
+ type: 'upload'
159
+ }].concat(_toConsumableArray(images));
160
+ return /*#__PURE__*/_jsx(View, {
161
+ style: [styles.container, containerStyle],
162
+ children: isLoading ? /*#__PURE__*/_jsx(ImagesSkeleton, {}) : /*#__PURE__*/_jsx(FlatList, {
163
+ data: data,
164
+ renderItem: renderItem,
165
+ keyExtractor: function keyExtractor(item, index) {
166
+ if (index === 0) return 'upload';
167
+ var image = images[index - 1];
168
+ return image.id || image.url || "image-".concat(index);
169
+ },
170
+ numColumns: NUM_COLUMNS,
171
+ contentContainerStyle: [styles.grid, gridStyle],
172
+ showsVerticalScrollIndicator: false,
173
+ ListFooterComponent: total_count > 0 ? /*#__PURE__*/_jsx(View, {
174
+ style: [styles.paginationContainer, paginationContainerStyle],
175
+ children: /*#__PURE__*/_jsx(Pagination, {
176
+ nextPage: function nextPage(value) {
177
+ return loadMedia(value);
178
+ },
179
+ pageCount: Math.ceil(total_count / 30),
180
+ current_page: currentPage
181
+ })
182
+ }) : null
183
+ })
184
+ });
185
+ };
186
+ var styles = StyleSheet.create({
187
+ container: {
188
+ flex: 1
189
+ },
190
+ grid: {
191
+ padding: 4
192
+ },
193
+ uploadContainer: {
194
+ margin: ITEM_MARGIN
195
+ },
196
+ imageItem: {
197
+ margin: ITEM_MARGIN,
198
+ borderRadius: 8,
199
+ overflow: 'hidden',
200
+ backgroundColor: '#FFFFFF',
201
+ shadowColor: '#000',
202
+ shadowOffset: {
203
+ width: 0,
204
+ height: 2
205
+ },
206
+ shadowOpacity: 0.1,
207
+ shadowRadius: 3.84,
208
+ elevation: 5
209
+ },
210
+ image: {
211
+ width: '100%',
212
+ height: '100%'
213
+ },
214
+ paginationContainer: {
215
+ paddingVertical: 16,
216
+ paddingHorizontal: 8,
217
+ backgroundColor: '#F5F5F5',
218
+ marginTop: 8
219
+ }
220
+ });
221
+ export default ImagesGallery;