datasync-blob 1.1.24 → 1.1.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.
@@ -20,87 +20,131 @@ class DsBlob extends _react.Component {
20
20
  this.debugging = false;
21
21
  }
22
22
 
23
- //-----------------------------------------------------------------------------------------------------------------------------------------
24
- reduceBase64Image = e => {
25
- let imageSource = e.path && e.path[0] || e.srcElement; //Safari compliancy
26
-
27
- alert("reduceBase64Image !");
28
- if (this.debugging) console.log("imageSource = ", imageSource);
29
- var canvas = document.createElement('canvas'),
30
- context,
31
- width = imageSource.width,
32
- height = imageSource.height;
33
-
34
- //Exact size props are set
35
- if (this.props.width && this.props.height) {
36
- //Check image size
37
- if (width > this.props.width || height > this.props.height) {
38
- alert("L'image est trop grande, le format requis est " + this.props.width + "x" + this.props.height);
39
- return;
23
+ //-----------------------------------------
24
+ /**
25
+ * PROTOTYPE : uploadToDatasyncCloud
26
+ * Purpose : Upload binary data to My Custom Cloud server using Datasync SncPushCloud endpoint and return the accessible URL for the uploaded file.
27
+ * @param base64Data
28
+ * @param fileName
29
+ */
30
+ uploadToDatasyncCloud = async pictureBlob => {
31
+ try {
32
+ const formData = new FormData();
33
+ let cloud_filename = pictureBlob.cloud_url_prefix.split('/').pop(); // Extract filename from cloud_url_prefix
34
+
35
+ console.log("Uploading to Datasync Cloud with filename:", cloud_filename);
36
+ formData.append('action', "syncPushCloud");
37
+ //formData.append('filename', `${CGUID()}.jpg`);
38
+ formData.append('filename', cloud_filename); // Extract filename from cloud_url_prefix
39
+
40
+ // Convert blob URL to actual binary data
41
+ let binaryString;
42
+ if (pictureBlob.isBlobUrl && pictureBlob.data.startsWith('blob:')) {
43
+ // Fetch the blob URL to get actual file content
44
+ console.log('Fetching blob URL:', pictureBlob.data);
45
+ const blobResponse = await fetch(pictureBlob.data);
46
+ const blob = await blobResponse.blob();
47
+
48
+ // Convert blob to ArrayBuffer then to Uint8Array
49
+ const arrayBuffer = await blob.arrayBuffer(); // Raw binary JPEG data
50
+ const uint8Array = new Uint8Array(arrayBuffer); // ← THIS CONTAINS THE GENUINE JPEG FILE BINARY DATA
51
+
52
+ // Convert to base64 string for transmission (chunked to avoid stack overflow)
53
+ let binaryStr = '';
54
+ const chunkSize = 8192; // Process in 8KB chunks to avoid stack overflow
55
+ for (let i = 0; i < uint8Array.length; i += chunkSize) {
56
+ const chunk = uint8Array.slice(i, i + chunkSize);
57
+ binaryStr += String.fromCharCode(...chunk);
58
+ }
59
+ binaryString = btoa(binaryStr); // ← THIS CONTAINS THE GENUINE JPEG FILE AS BASE64 STRING
60
+
61
+ console.log('Converted blob URL to binary data, size:', uint8Array.length);
62
+ } else if (Array.isArray(pictureBlob.binaryData)) {
63
+ // Convert Uint8Array or regular array to base64 string
64
+ const uint8Array = new Uint8Array(pictureBlob.binaryData);
65
+ let binaryStr = '';
66
+ const chunkSize = 8192;
67
+ for (let i = 0; i < uint8Array.length; i += chunkSize) {
68
+ const chunk = uint8Array.slice(i, i + chunkSize);
69
+ binaryStr += String.fromCharCode(...chunk);
70
+ }
71
+ binaryString = btoa(binaryStr);
72
+ } else if (pictureBlob.binaryData instanceof Uint8Array) {
73
+ // Already a Uint8Array, convert to base64
74
+ let binaryStr = '';
75
+ const chunkSize = 8192;
76
+ for (let i = 0; i < pictureBlob.binaryData.length; i += chunkSize) {
77
+ const chunk = pictureBlob.binaryData.slice(i, i + chunkSize);
78
+ binaryStr += String.fromCharCode(...chunk);
79
+ }
80
+ binaryString = btoa(binaryStr);
81
+ } else {
82
+ // Assume it's already a string
83
+ binaryString = pictureBlob.binaryData || "";
40
84
  }
85
+ formData.append('binary', binaryString);
86
+ console.log("binaryString ->", binaryString.substring(0, 100) + '...'); // Log the beginning of the base64 string for debugging
41
87
 
42
- //Check image size
43
- if (width < this.props.width || height < this.props.height) {
44
- alert("L'image est trop petite, le format requis est " + this.props.width + "x" + this.props.height);
45
- return;
88
+ const results = await fetch('http://localhost:8888/datasync-service/Sync.php', {
89
+ method: 'POST',
90
+ body: formData
91
+ });
92
+ if (!results.ok) {
93
+ throw new Error(`HTTP error! status: ${response.statusText}`);
94
+ }
95
+ let sync_push_cloud_response = await results.json();
96
+
97
+ // Try to parse as JSON
98
+ try {
99
+ if (!sync_push_cloud_response.state) throw new Error(`syncPushCloud returned error: ${sync_push_cloud_response.message}`);else console.log('syncPushCloud upload response:', sync_push_cloud_response.message);
100
+ return true; // Return true on successful upload
101
+ } catch (parseError) {
102
+ console.error('syncPushCloud : JSON parse error:', parseError);
103
+ throw new Error(`syncPushCloud raised error: ${parseError}`);
46
104
  }
105
+ } catch (error) {
106
+ if (true) {
107
+ console.error('syncPushCloud upload error details:', error);
108
+ }
109
+ throw error;
47
110
  }
111
+ };
48
112
 
49
- //Max size props are set
50
- if (this.props.maxWidth && this.props.maxHeight) {
51
- if (width > height) {
52
- //Check resize is enabled
53
- if (!this.props.reduceImage) {
54
- alert("L'image est trop large ! la largeur maximale est de " + this.props.maxWidth);
55
- return;
56
- }
57
- if (width > this.props.maxWidth) {
58
- height *= this.props.maxWidth / width;
59
- width = this.props.maxWidth;
60
- }
61
- } else {
62
- if (height > this.props.maxHeight) {
63
- //Check resize is enabled
64
- if (!this.props.reduceImage) {
65
- alert("L'image est trop haute, la hauteur maximale est de " + this.props.maxHeight);
66
- return;
113
+ //-----------------------------------------
114
+ convert_blob_picture_into_cloud_file = async pictureBlob => {
115
+ try {
116
+ console.log("Received pictureBlob in uploadPicture:cloud_url_prefix -> ", pictureBlob.cloud_url_prefix);
117
+ if (!pictureBlob || !pictureBlob.data) {
118
+ //Reset picture
119
+ this.setPicture("");
120
+ return;
121
+ }
122
+ if (pictureBlob.isBlobUrl && pictureBlob.data.startsWith('blob:') && pictureBlob.cloud_url_prefix) {
123
+ let updloadSucces = await this.uploadToDatasyncCloud(pictureBlob); // Upload the image to custom Datasync cloud
124
+ if (updloadSucces) {
125
+ //Clear the data URL to free memory since the image is now uploaded and accessible via cloud URL
126
+ if (pictureBlob.data && pictureBlob.data.startsWith('blob:')) {
127
+ URL.revokeObjectURL(pictureBlob.data);
67
128
  }
68
- width *= this.props.maxHeight / height;
69
- height = this.props.maxHeight;
129
+ this.setData(pictureBlob.cloud_url_prefix);
130
+ //inform parent component of the new cloud URL for the uploaded image
131
+ this.props.uploadPicture({
132
+ data: pictureBlob.cloud_url_prefix
133
+ });
134
+ } else {
135
+ console.error("Upload to Datasync cloud failed - no success response received");
136
+ throw new Error("Upload to Datasync cloud failed - no success response received");
70
137
  }
71
138
  }
72
- }
73
-
74
- //Build 2d picture
75
- canvas.width = width;
76
- canvas.height = height;
77
- context = canvas.getContext('2d');
78
- context.drawImage(imageSource, 0, 0, width, height);
79
-
80
- //Jpeg conversion
81
- let jpegCompressionRatio = this.props.jpegQuality && this.props.jpegQuality > 0 && this.props.jpegQuality < 1 ? this.props.jpegQuality : 1;
82
- let canvasData = canvas.toDataURL('image/jpg', jpegCompressionRatio); //Jpeg conversion
83
-
84
- if (this.debugging) console.log("jpegCompressionRatio->", jpegCompressionRatio, " canvasData.length = ", canvasData.length);
85
- const processedData = this.props.removebase64 ? canvasData ? canvasData.substring("data:image/png;base64".length) : "" : canvasData ? canvasData : "";
86
- this.setData(processedData);
87
- if (this.props.removebase64) {
88
- //remove base64 prefix if property is set
89
- this.props.uploadPicture({
90
- data: processedData
91
- });
92
- } else {
93
- //Keep base 64 prefix as it is
94
- this.props.uploadPicture({
95
- data: processedData
96
- });
139
+ } catch (error) {
140
+ console.error("Upload error:", error);
97
141
  }
98
142
  };
143
+
99
144
  //-----------------------------------------------------------------------------------------------------------------------------------------
100
- reduceBinaryImage = e => {
145
+ reduceBase64Image = e => {
101
146
  let imageSource = e.path && e.path[0] || e.srcElement; //Safari compliancy
102
147
 
103
- alert("reduceBinaryImage !");
104
148
  if (this.debugging) console.log("imageSource = ", imageSource);
105
149
  var canvas = document.createElement('canvas'),
106
150
  context,
@@ -147,102 +191,77 @@ class DsBlob extends _react.Component {
147
191
  }
148
192
  }
149
193
 
194
+ //Compute jpeg compression ratio
195
+ let jpegCompressionRatio = this.props.jpegQuality && this.props.jpegQuality > 0 && this.props.jpegQuality < 1 ? this.props.jpegQuality : 1;
196
+
150
197
  //Build 2d picture
151
198
  canvas.width = width;
152
199
  canvas.height = height;
153
200
  context = canvas.getContext('2d');
154
201
  context.drawImage(imageSource, 0, 0, width, height);
202
+ if (this.props.cloud_storage) {
203
+ canvas.toBlob(async blob => {
204
+ if (blob) {
205
+ console.log("Binary blob created, size:", blob.size);
206
+ if (this.debugging) console.log("jpegCompressionRatio->", jpegCompressionRatio, " blob.size = ", blob.size);
207
+
208
+ // Fallback: use blob URL for display but keep binary data
209
+ const blobUrl = URL.createObjectURL(blob);
210
+
211
+ // Convert blob to ArrayBuffer to maintain genuine binary data
212
+ const reader = new FileReader();
213
+ reader.onload = () => {
214
+ const binaryData = reader.result; // ArrayBuffer - genuine binary data
215
+ console.log("Fallback: Using binary data, size:", binaryData.byteLength);
216
+
217
+ //Call the upload callback with both blob URL for display and binary data for upload
218
+ this.convert_blob_picture_into_cloud_file({
219
+ data: blobUrl,
220
+ // For display in img tag
221
+ binaryData: binaryData,
222
+ // Genuine JPEG binary stream
223
+ cloud_url_prefix: this.props.cloud_url_prefix,
224
+ // Pass cloud URL prefix if needed for parent component
225
+ isBlobUrl: true // Flag to track blob URLs for cleanup
226
+ });
227
+ };
228
+ reader.readAsArrayBuffer(blob);
229
+ } else {
230
+ console.error("Failed to create blob from canvas");
231
+ }
232
+ }, 'image/jpeg', jpegCompressionRatio);
233
+ } else {
234
+ //Jpeg conversion
155
235
 
156
- //Binary conversion using toBlob to maintain binary output
157
- let jpegCompressionRatio = this.props.jpegQuality && this.props.jpegQuality > 0 && this.props.jpegQuality < 1 ? this.props.jpegQuality : 1;
158
- canvas.toBlob(async blob => {
159
- if (blob) {
160
- console.log("Binary blob created, size:", blob.size);
161
- if (this.debugging) console.log("jpegCompressionRatio->", jpegCompressionRatio, " blob.size = ", blob.size);
162
-
163
- // Fallback: use blob URL for display but keep binary data
164
- const blobUrl = URL.createObjectURL(blob);
165
-
166
- // Convert blob to ArrayBuffer to maintain genuine binary data
167
- const reader = new FileReader();
168
- reader.onload = () => {
169
- const binaryData = reader.result; // ArrayBuffer - genuine binary data
170
- console.log("Fallback: Using binary data, size:", binaryData.byteLength);
171
-
172
- // Store both display URL and binary data
173
- this.setData(blobUrl, binaryData);
174
- this.props.uploadPicture({
175
- data: blobUrl,
176
- // For display in img tag
177
- binaryData: binaryData,
178
- // Genuine JPEG binary stream
179
- cloud_url_prefix: this.props.cloud_url_prefix,
180
- // Pass cloud URL prefix if needed for parent component
181
- isBlobUrl: true // Flag to track blob URLs for cleanup
182
- });
183
- };
184
- reader.readAsArrayBuffer(blob);
185
- } else {
186
- console.error("Failed to create blob from canvas");
187
- }
188
- }, 'image/jpeg', jpegCompressionRatio);
236
+ let canvasData = canvas.toDataURL('image/jpg', jpegCompressionRatio); //Jpeg conversion
237
+
238
+ if (this.debugging) console.log("jpegCompressionRatio->", jpegCompressionRatio, " canvasData.length = ", canvasData.length);
239
+ const processedData = canvasData ? canvasData : "";
240
+ this.setData(processedData);
241
+
242
+ //Keep base 64 prefix as it is
243
+ this.props.uploadPicture({
244
+ data: processedData
245
+ });
246
+ }
189
247
  };
190
248
 
191
249
  //-----------------------------------------------------------------------------------------------------------------------------------------
192
250
  storeBase64ImageToImg = e => {
193
- var image = document.createElement('img');
194
- image.onload = this.reduceBase64Image;
251
+ var DOM_image = document.createElement('img');
252
+ DOM_image.onload = this.reduceBase64Image;
195
253
  console.log("storeBase64ImageToImg:e.currentTarget.result = ", e.currentTarget.result);
196
- alert("storeBase64ImageToImg !");
197
- image.src = e.currentTarget.result;
198
- };
199
-
200
- //-----------------------------------------------------------------------------------------------------------------------------------------
201
- storeBinaryImageToImg = e => {
202
- var image = document.createElement('img');
203
- //2Do DEBUG image.onload = this.reduceImage;
204
- console.log("storeBinaryImageToImg:e.currentTarget.result = ", e.currentTarget.result);
205
- alert("storeBinaryImageToImg !");
206
- // Convert ArrayBuffer to Blob URL since image.src cannot accept ArrayBuffer directly
207
- // Use the detected image type from the original file
208
- const imageType = this.currentImageType || 'image/jpeg'; // fallback to jpeg
209
- const blob = new Blob([e.currentTarget.result], {
210
- type: imageType
211
- });
212
- const blobUrl = URL.createObjectURL(blob);
213
- image.src = blobUrl;
214
-
215
- // Clean up blob URL after image loads to prevent memory leaks
216
- image.onload = loadEvent => {
217
- this.reduceBinaryImage(loadEvent);
218
- URL.revokeObjectURL(blobUrl);
219
- // Clear the stored image type
220
- this.currentImageType = null;
221
- };
254
+ DOM_image.src = e.currentTarget.result;
222
255
  };
223
256
 
224
257
  //-----------------------------------------------------------------------------------------------------------------------------------------
225
258
  readImageAsBase64 = async aPictureFile => {
226
259
  let _reader = new FileReader();
227
260
  console.log("readImageAsBase64:aPictureFile = ", aPictureFile);
228
- alert("readImageAsBase64 !");
229
261
  _reader.onload = this.storeBase64ImageToImg;
230
262
  _reader.readAsDataURL(aPictureFile); //The readAsDataURL() method of the FileReader interface is used to read the contents of the specified file's data as a base64 encoded string.
231
263
  };
232
264
 
233
- //-----------------------------------------------------------------------------------------------------------------------------------------
234
- readImageAsBinary = async aPictureFile => {
235
- let _reader = new FileReader();
236
- console.log("readImageAsBinary:aPictureFile = ", aPictureFile);
237
- alert("readImageAsBinary !");
238
-
239
- // Store the image type for use in storeBinaryImageToImg
240
- this.currentImageType = aPictureFile.type;
241
- console.log("Detected image type:", this.currentImageType);
242
- _reader.onload = this.storeBinaryImageToImg;
243
- _reader.readAsArrayBuffer(aPictureFile); //The readAsArrayBuffer() method reads the file as genuine binary content without base64 conversion.
244
- };
245
-
246
265
  //-----------------------------------------------------------------------------------------------------------------------------------------
247
266
  resetUpload = () => {
248
267
  // Clean up any blob URLs before resetting
@@ -260,7 +279,7 @@ class DsBlob extends _react.Component {
260
279
  cleanupBlobUrl = () => {
261
280
  // Only show alert if not in test environment
262
281
  if (typeof jest === 'undefined') {
263
- alert("cleanupBlobUrl !");
282
+ console.log("cleanupBlobUrl !");
264
283
  }
265
284
  // Revoke blob URL if it exists to prevent memory leaks
266
285
  if (this.state.data && this.state.data.startsWith('blob:')) {
@@ -318,11 +337,7 @@ class DsBlob extends _react.Component {
318
337
  if (errCount == errs.length) {
319
338
  //None new error occurs
320
339
  if (this.debugging) console.log("readImageAsBase64::", file.name);
321
- if (this.props.cloud_storage) {
322
- this.readImageAsBinary(file);
323
- } else {
324
- this.readImageAsBase64(file);
325
- }
340
+ this.readImageAsBase64(file);
326
341
  }
327
342
  });
328
343
  if (errs.length) {
@@ -345,8 +360,7 @@ class DsBlob extends _react.Component {
345
360
  }
346
361
 
347
362
  // Otherwise, treat as base64 and add appropriate prefix
348
- const prefix = this.props.removebase64 ? "data:image/png;base64," : "";
349
- return prefix + this.state.data;
363
+ return this.state.data;
350
364
  };
351
365
 
352
366
  //-----------------------------------------------------------------------------------------------------------------------------------------
@@ -356,7 +370,6 @@ class DsBlob extends _react.Component {
356
370
  return this.state.binaryData || this.props.binaryData || null;
357
371
  };
358
372
 
359
- //-----------------------------------------------------------------------------------------------------------------------------------------
360
373
  //-----------------------------------------------------------------------------------------------------------------------------------------
361
374
  // Data getter and setter methods for read-write access
362
375
  getData = () => {
@@ -464,7 +477,6 @@ DsBlob.propTypes = {
464
477
  // Image processing options
465
478
  reduceImage: _propTypes.default.bool,
466
479
  jpegQuality: _propTypes.default.number,
467
- removebase64: _propTypes.default.bool,
468
480
  // Cloud storage options
469
481
  cloud_storage: _propTypes.default.bool,
470
482
  cloud_url_prefix: _propTypes.default.string,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datasync-blob",
3
- "version": "1.1.24",
3
+ "version": "1.1.26",
4
4
  "description": "Datasync Blob component",
5
5
  "main": "./dist/components/DsBlob.js",
6
6
  "files": [