datasync-blob 1.1.12 → 1.1.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.
- package/dist/components/DsBlob.js +237 -0
- package/package.json +21 -11
- package/dist/DsBlob.js +0 -206
- package/dist/types/DsBlob.d.ts +0 -49
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DsBlob = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
9
|
+
class DsBlob extends _react.Component {
|
|
10
|
+
constructor(props) {
|
|
11
|
+
super(props);
|
|
12
|
+
this.state = {
|
|
13
|
+
hover_input: false,
|
|
14
|
+
hover_image: false
|
|
15
|
+
};
|
|
16
|
+
this.debugging = false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
20
|
+
reduceImage = e => {
|
|
21
|
+
let imageSource = e.path && e.path[0] || e.srcElement; //Safari compliancy
|
|
22
|
+
|
|
23
|
+
if (this.debugging) console.log("imageSource = ", imageSource);
|
|
24
|
+
var canvas = document.createElement('canvas'),
|
|
25
|
+
context,
|
|
26
|
+
width = imageSource.width,
|
|
27
|
+
height = imageSource.height;
|
|
28
|
+
|
|
29
|
+
//Exact size props are set
|
|
30
|
+
if (this.props.width && this.props.height) {
|
|
31
|
+
//Check image size
|
|
32
|
+
if (width > this.props.width || height > this.props.height) {
|
|
33
|
+
alert("L'image est trop grande, le format requis est " + this.props.width + "x" + this.props.height);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
//Check image size
|
|
38
|
+
if (width < this.props.width || height < this.props.height) {
|
|
39
|
+
alert("L'image est trop petite, le format requis est " + this.props.width + "x" + this.props.height);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//Max size props are set
|
|
45
|
+
if (this.props.maxWidth && this.props.maxHeight) {
|
|
46
|
+
if (width > height) {
|
|
47
|
+
//Check resize is enabled
|
|
48
|
+
if (!this.props.reduceImage) {
|
|
49
|
+
alert("L'image est trop large ! la largeur maximale est de " + this.props.maxWidth);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (width > this.props.maxWidth) {
|
|
53
|
+
height *= this.props.maxWidth / width;
|
|
54
|
+
width = this.props.maxWidth;
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
if (height > this.props.maxHeight) {
|
|
58
|
+
//Check resize is enabled
|
|
59
|
+
if (!this.props.reduceImage) {
|
|
60
|
+
alert("L'image est trop haute, la hauteur maximale est de " + this.props.maxHeight);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
width *= this.props.maxHeight / height;
|
|
64
|
+
height = this.props.maxHeight;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
//Build 2d picture
|
|
70
|
+
canvas.width = width;
|
|
71
|
+
canvas.height = height;
|
|
72
|
+
context = canvas.getContext('2d');
|
|
73
|
+
context.drawImage(imageSource, 0, 0, width, height);
|
|
74
|
+
|
|
75
|
+
//Jpeg conversion
|
|
76
|
+
let jpegCompressionRatio = this.props.jpegQuality && this.props.jpegQuality > 0 && this.props.jpegQuality < 1 ? this.props.jpegQuality : 1;
|
|
77
|
+
let canvasData = canvas.toDataURL('image/jpg', jpegCompressionRatio); //Jpeg conversion
|
|
78
|
+
|
|
79
|
+
if (this.debugging) console.log("jpegCompressionRatio->", jpegCompressionRatio, " canvasData.length = ", canvasData.length);
|
|
80
|
+
if (this.props.removebase64) {
|
|
81
|
+
//remove base64 prefix if property is set
|
|
82
|
+
this.props.uploadPicture({
|
|
83
|
+
data: canvasData ? canvasData.substring("data:image/png;base64".length) : "",
|
|
84
|
+
item_id: this.props.item_id
|
|
85
|
+
});
|
|
86
|
+
} else {
|
|
87
|
+
//Keep base 64 prefix as it is
|
|
88
|
+
this.props.uploadPicture({
|
|
89
|
+
data: canvasData ? canvasData : "",
|
|
90
|
+
item_id: this.props.item_id
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
96
|
+
storeImageToImg = e => {
|
|
97
|
+
var image = document.createElement('img');
|
|
98
|
+
image.onload = this.reduceImage;
|
|
99
|
+
image.src = e.currentTarget.result;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
103
|
+
readImageAsBase64 = async aPictureFile => {
|
|
104
|
+
let _reader = new FileReader();
|
|
105
|
+
alert("readImageAsBase64 !");
|
|
106
|
+
_reader.onload = this.storeImageToImg;
|
|
107
|
+
_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.
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
111
|
+
readImageAsBinary = async aPictureFile => {
|
|
112
|
+
let _reader = new FileReader();
|
|
113
|
+
alert("readImageAsBinary !");
|
|
114
|
+
_reader.onload = this.storeImageToImg;
|
|
115
|
+
_reader.readAsArrayBuffer(aPictureFile); //The readAsArrayBuffer() method reads the file as genuine binary content without base64 conversion.
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
119
|
+
resetUpload = () => {
|
|
120
|
+
this.props.uploadPicture({
|
|
121
|
+
data: "",
|
|
122
|
+
item_id: this.props.item_id
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
127
|
+
onInputChange = e => {
|
|
128
|
+
const errs = [];
|
|
129
|
+
const files = Array.from(e.target.files);
|
|
130
|
+
const types = ['image/png', 'image/jpeg', 'image/gif'];
|
|
131
|
+
const _1Mo = 1024 * 1024;
|
|
132
|
+
const SizeLimit = 9;
|
|
133
|
+
|
|
134
|
+
//Reset input cache value - to assure trigger if user select the same file again
|
|
135
|
+
e.target.value = null;
|
|
136
|
+
if (this.debugging) console.log("onInputChange");
|
|
137
|
+
if (files.length > 1) {
|
|
138
|
+
const msg = 'Pas plus d\'une image à la fois';
|
|
139
|
+
alert(msg);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
files.forEach((file, i) => {
|
|
143
|
+
let errCount = errs.length;
|
|
144
|
+
if (types.every(type => file.type !== type)) {
|
|
145
|
+
errs.push(`'${file.type}' : format non supporté`);
|
|
146
|
+
}
|
|
147
|
+
if (file.size > SizeLimit * _1Mo) {
|
|
148
|
+
errs.push(`'${file.name}' image trop volumineuse (max:${SizeLimit}Méga-octets)`);
|
|
149
|
+
}
|
|
150
|
+
if (this.debugging) console.log(`errCount = ${errCount} vs errs.length = ${errs.length}`);
|
|
151
|
+
if (errCount == errs.length) {
|
|
152
|
+
//None new error occurs
|
|
153
|
+
if (this.debugging) console.log("readImageAsBase64::", file.name);
|
|
154
|
+
if (this.props.cloud_storage) {
|
|
155
|
+
this.readImageAsBinary(file);
|
|
156
|
+
} else {
|
|
157
|
+
this.readImageAsBase64(file);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
if (errs.length) {
|
|
162
|
+
return errs.forEach(err => alert(err));
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
render() {
|
|
166
|
+
const upload_picture_label = {
|
|
167
|
+
cursor: "pointer"
|
|
168
|
+
};
|
|
169
|
+
const upload_picture_label_input = {
|
|
170
|
+
opacity: "0",
|
|
171
|
+
width: "0px",
|
|
172
|
+
height: "0px"
|
|
173
|
+
};
|
|
174
|
+
const div_show_image_hover = {
|
|
175
|
+
position: "relative",
|
|
176
|
+
margin: "0px",
|
|
177
|
+
opacity: "0.5"
|
|
178
|
+
};
|
|
179
|
+
const div_show_image = {
|
|
180
|
+
position: "relative",
|
|
181
|
+
margin: "0px"
|
|
182
|
+
};
|
|
183
|
+
const div_show_image_hover_input = {
|
|
184
|
+
display: "block",
|
|
185
|
+
top: "0px",
|
|
186
|
+
left: "0px",
|
|
187
|
+
position: "absolute"
|
|
188
|
+
};
|
|
189
|
+
const div_show_image_input = {
|
|
190
|
+
position: "absolute",
|
|
191
|
+
display: "none",
|
|
192
|
+
cursor: "pointer"
|
|
193
|
+
};
|
|
194
|
+
return /*#__PURE__*/_react.default.createElement("div", null, !this.props.data && /*#__PURE__*/_react.default.createElement("label", {
|
|
195
|
+
id: "upload-picture-label",
|
|
196
|
+
className: this.props.buttonStyle,
|
|
197
|
+
style: upload_picture_label
|
|
198
|
+
}, this.props.Caption, /*#__PURE__*/_react.default.createElement("input", {
|
|
199
|
+
style: upload_picture_label_input,
|
|
200
|
+
id: "nested-input",
|
|
201
|
+
type: "file",
|
|
202
|
+
accept: "image/*",
|
|
203
|
+
onChange: this.onInputChange,
|
|
204
|
+
multiple: true
|
|
205
|
+
})), this.props.data && this.props.data.length > 0 && /*#__PURE__*/_react.default.createElement("div", {
|
|
206
|
+
class: "show-image",
|
|
207
|
+
style: div_show_image,
|
|
208
|
+
onMouseOver: () => {
|
|
209
|
+
this.setState({
|
|
210
|
+
hover_input: true,
|
|
211
|
+
hover_image: true
|
|
212
|
+
}, () => {
|
|
213
|
+
if (this.debugging) console.log("onMouseOver");
|
|
214
|
+
});
|
|
215
|
+
},
|
|
216
|
+
onMouseLeave: () => {
|
|
217
|
+
this.setState({
|
|
218
|
+
hover_input: false,
|
|
219
|
+
hover_image: false
|
|
220
|
+
}, () => {
|
|
221
|
+
if (this.debugging) console.log("onMouseLeave");
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}, /*#__PURE__*/_react.default.createElement("img", {
|
|
225
|
+
style: this.state.hover_image ? div_show_image_hover : div_show_image,
|
|
226
|
+
src: this.props.removebase64 ? "data:image/png;base64" : "" + this.props.data,
|
|
227
|
+
className: this.props.pictureStyle
|
|
228
|
+
}), !this.props.readOnly && /*#__PURE__*/_react.default.createElement("input", {
|
|
229
|
+
style: this.state.hover_input ? div_show_image_hover_input : div_show_image_input,
|
|
230
|
+
className: "btn btn-primary delete",
|
|
231
|
+
type: "button",
|
|
232
|
+
value: "Effacer",
|
|
233
|
+
onClick: this.resetUpload
|
|
234
|
+
})));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
exports.DsBlob = DsBlob;
|
package/package.json
CHANGED
|
@@ -1,31 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "datasync-blob",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.14",
|
|
4
4
|
"description": "Datasync Blob component",
|
|
5
|
-
"main": "dist/DsBlob.js",
|
|
6
|
-
"module": "dist/DsBlob.js",
|
|
7
|
-
"types": "dist/types/DsBlob.d.ts",
|
|
5
|
+
"main": "./dist/components/DsBlob.js",
|
|
8
6
|
"files": [
|
|
9
|
-
"dist"
|
|
7
|
+
"./dist"
|
|
10
8
|
],
|
|
11
9
|
"repository": {
|
|
12
10
|
"type": "git",
|
|
13
|
-
"url": "https://github.com/pmabiala/datasync-blob.git"
|
|
11
|
+
"url": "git+https://github.com/pmabiala/datasync-blob.git"
|
|
14
12
|
},
|
|
15
13
|
"bugs": {
|
|
16
14
|
"url": "https://github.com/pmabiala/datasync-blob.git/issues",
|
|
17
15
|
"email": "pmabiala@me.com"
|
|
18
16
|
},
|
|
19
17
|
"devDependencies": {
|
|
20
|
-
"@
|
|
21
|
-
"@
|
|
22
|
-
"
|
|
18
|
+
"@babel/cli": "^7.24.1",
|
|
19
|
+
"@babel/core": "^7.24.4",
|
|
20
|
+
"@babel/preset-env": "^7.24.4",
|
|
21
|
+
"@babel/preset-react": "^7.24.1",
|
|
22
|
+
"@testing-library/react": "^14.2.2",
|
|
23
|
+
"javascript-obfuscator": "^4.1.1",
|
|
24
|
+
"jest": "^29.7.0",
|
|
25
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
26
|
+
"jest-transform-css": "^6.0.1",
|
|
27
|
+
"react": "^18.2.0",
|
|
28
|
+
"react-pdf": "^7.7.1",
|
|
29
|
+
"webpack": "^5.99.9",
|
|
30
|
+
"webpack-cli": "^6.0.1",
|
|
31
|
+
"webpack-node-externals": "^3.0.0",
|
|
32
|
+
"webpack-obfuscator": "^3.5.1"
|
|
23
33
|
},
|
|
24
34
|
"peerDependencies": {
|
|
25
|
-
"react": "^
|
|
35
|
+
"react": "^ 18.2.0"
|
|
26
36
|
},
|
|
27
37
|
"scripts": {
|
|
28
|
-
"
|
|
38
|
+
"build_old": "rm -r dist && babel src -d dist --ignore src/**/*.test.jsx && npm run copy-files",
|
|
29
39
|
"build": "rm -r dist && babel src -d dist --ignore src/**/*.test.jsx && npm run copy-files && webpack --config webpack.config.js",
|
|
30
40
|
"copy-files": "cp ./src/*.css dist/",
|
|
31
41
|
"test": "jest --config jest.config.json"
|
package/dist/DsBlob.js
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
-
import { Component } from "react";
|
|
12
|
-
const error_tables = [
|
|
13
|
-
{ error_code: "IMAGE_TOO_LARGE", error_definition: "Image dimensions exceed maximum allowed size" },
|
|
14
|
-
{ error_code: "IMAGE_TOO_SMALL", error_definition: "Image dimensions are below minimum required size" },
|
|
15
|
-
{ error_code: "MULTIPLE_FILES", error_definition: "Multiple files selected when only one is allowed" },
|
|
16
|
-
{ error_code: "UNSUPPORTED_FORMAT", error_definition: "File format is not supported" },
|
|
17
|
-
{ error_code: "SOURCE_FILE_TOO_BIG", error_definition: "Source File size exceeds maximum allowed limit" },
|
|
18
|
-
{ error_code: "TARGET_FILE_TOO_BIG", error_definition: "Target File size exceeds maximum allowed limit" }
|
|
19
|
-
];
|
|
20
|
-
export class DsBlob extends Component {
|
|
21
|
-
constructor(props) {
|
|
22
|
-
super(props);
|
|
23
|
-
this.handleError = (errorCode, message) => {
|
|
24
|
-
const errorDef = error_tables.find(err => err.error_code === errorCode);
|
|
25
|
-
const errorObject = {
|
|
26
|
-
error_code: errorCode,
|
|
27
|
-
error_definition: (errorDef === null || errorDef === void 0 ? void 0 : errorDef.error_definition) || "Unknown error",
|
|
28
|
-
message: message
|
|
29
|
-
};
|
|
30
|
-
if (this.props.onErrorHandler) {
|
|
31
|
-
this.props.onErrorHandler(errorObject);
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
// Fallback to alert if no error handler provided
|
|
35
|
-
alert(message);
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
39
|
-
this.reduceImage = (e) => {
|
|
40
|
-
var _a, _b, _c, _d, _e, _f;
|
|
41
|
-
let imageSource = (e.path && e.path[0]) || e.srcElement; //Safari compliancy
|
|
42
|
-
if (this.props.debugging) {
|
|
43
|
-
console.log("imageSource = ", imageSource);
|
|
44
|
-
console.log(`props.width : ${this.props.width} props.height : ${this.props.height}`);
|
|
45
|
-
console.log(`props.maxWidth : ${this.props.maxWidth} props.maxHeight : ${this.props.maxHeight}`);
|
|
46
|
-
}
|
|
47
|
-
var canvas = document.createElement('canvas'), context, width = imageSource.width, height = imageSource.height;
|
|
48
|
-
//Exact size props are set
|
|
49
|
-
if (this.props.width || this.props.height) {
|
|
50
|
-
//Check image size
|
|
51
|
-
if (this.props.debugging)
|
|
52
|
-
console.log(`checking exact image size ${this.props.width} x ${this.props.height}`);
|
|
53
|
-
const targetWidth = (_a = this.props.width) !== null && _a !== void 0 ? _a : width;
|
|
54
|
-
const targetHeight = (_b = this.props.height) !== null && _b !== void 0 ? _b : height;
|
|
55
|
-
if (width > targetWidth || height > targetHeight) {
|
|
56
|
-
this.handleError("IMAGE_TOO_LARGE", "L'image est trop grande, le format requis est " + this.props.width + "x" + this.props.height);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
if (width < targetWidth || height < targetHeight) {
|
|
60
|
-
this.handleError("IMAGE_TOO_SMALL", "L'image est trop petite, le format requis est " + this.props.width + "x" + this.props.height);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
//Max size props are set
|
|
65
|
-
let sourceX = 0, sourceY = 0, sourceWidth = imageSource.width, sourceHeight = imageSource.height;
|
|
66
|
-
let cropMode = false;
|
|
67
|
-
//this.props.maxWidth && this.props.maxHeight are always defined now at least with default 80 x 60 pixels values
|
|
68
|
-
if (this.props.reduceImage) {
|
|
69
|
-
//pictures is just resampled to fit in maxWidth and maxHeight
|
|
70
|
-
const maxW = (_c = this.props.maxWidth) !== null && _c !== void 0 ? _c : 80;
|
|
71
|
-
const maxH = (_d = this.props.maxHeight) !== null && _d !== void 0 ? _d : 60;
|
|
72
|
-
const scaleX = maxW / width;
|
|
73
|
-
const scaleY = maxH / height;
|
|
74
|
-
const scale = Math.min(scaleX, scaleY); // Use smaller scale to fit within bounds
|
|
75
|
-
if (this.props.debugging)
|
|
76
|
-
console.log(`Resizing to fit ${maxW} x ${maxH}`);
|
|
77
|
-
// Calculate new dimensions that fit within bounds
|
|
78
|
-
width = width * scale;
|
|
79
|
-
height = height * scale;
|
|
80
|
-
// Use original image dimensions for drawing (no cropping)
|
|
81
|
-
sourceWidth = imageSource.width;
|
|
82
|
-
sourceHeight = imageSource.height;
|
|
83
|
-
sourceX = 0;
|
|
84
|
-
sourceY = 0;
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
// Crop image to fit exactly maxWidth x maxHeight
|
|
88
|
-
const maxW = (_e = this.props.maxWidth) !== null && _e !== void 0 ? _e : 80;
|
|
89
|
-
const maxH = (_f = this.props.maxHeight) !== null && _f !== void 0 ? _f : 60;
|
|
90
|
-
const scaleX = maxW / width;
|
|
91
|
-
const scaleY = maxH / height;
|
|
92
|
-
const scale = Math.max(scaleX, scaleY); // Use larger scale to fill area completely
|
|
93
|
-
if (this.props.debugging)
|
|
94
|
-
console.log(`Cropping to ${maxW} x ${maxH}`);
|
|
95
|
-
// Calculate source crop dimensions (centered crop)
|
|
96
|
-
sourceWidth = maxW / scale;
|
|
97
|
-
sourceHeight = maxH / scale;
|
|
98
|
-
sourceX = (imageSource.width - sourceWidth) / 2;
|
|
99
|
-
sourceY = (imageSource.height - sourceHeight) / 2;
|
|
100
|
-
width = this.props.maxWidth;
|
|
101
|
-
height = this.props.maxHeight;
|
|
102
|
-
cropMode = true;
|
|
103
|
-
}
|
|
104
|
-
//Build 2d picture
|
|
105
|
-
canvas.width = width;
|
|
106
|
-
canvas.height = height;
|
|
107
|
-
context = canvas.getContext('2d');
|
|
108
|
-
if (cropMode) {
|
|
109
|
-
// Draw cropped image
|
|
110
|
-
context.drawImage(imageSource, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, width, height);
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
// Draw scaled image (original behavior)
|
|
114
|
-
context.drawImage(imageSource, 0, 0, width, height);
|
|
115
|
-
}
|
|
116
|
-
//Jpeg conversion
|
|
117
|
-
let jpegCompressionRatio = (this.props.jpegQuality && this.props.jpegQuality > 0 && this.props.jpegQuality < 1) ? this.props.jpegQuality : 1;
|
|
118
|
-
let canvasData = canvas.toDataURL('image/jpg', jpegCompressionRatio); //Jpeg conversion
|
|
119
|
-
if (this.props.debugging)
|
|
120
|
-
console.log("jpegCompressionRatio->", jpegCompressionRatio, " canvasData.length = ", canvasData.length, " canvasData.length in Ko = ", canvasData.length / 1024);
|
|
121
|
-
//Check canvasData length
|
|
122
|
-
let l_int_max_Kilo_bytes_weight = this.props.maxKBytes ? this.props.maxKBytes : 400;
|
|
123
|
-
if ((canvasData.length / 1024) > l_int_max_Kilo_bytes_weight) {
|
|
124
|
-
this.handleError("TARGET_FILE_TOO_BIG", `L'image excède le poids maximum de ${l_int_max_Kilo_bytes_weight} k-octets`);
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
if (this.props.removebase64) {
|
|
128
|
-
//remove base64 prefix if property is set
|
|
129
|
-
this.props.uploadPicture({ data: canvasData ? canvasData.substring("data:image/png;base64".length) : "", item_id: this.props.item_id });
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
//Keep base 64 prefix as it is
|
|
133
|
-
this.props.uploadPicture({ data: canvasData ? canvasData : "", item_id: this.props.item_id });
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
137
|
-
this.storeImageToImg = (e) => {
|
|
138
|
-
var image = document.createElement('img');
|
|
139
|
-
image.onload = this.reduceImage;
|
|
140
|
-
image.src = e.currentTarget.result;
|
|
141
|
-
};
|
|
142
|
-
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
143
|
-
this.readImage = (aPictureFile) => __awaiter(this, void 0, void 0, function* () {
|
|
144
|
-
let _reader = new FileReader();
|
|
145
|
-
_reader.onload = this.storeImageToImg;
|
|
146
|
-
_reader.readAsDataURL(aPictureFile);
|
|
147
|
-
});
|
|
148
|
-
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
149
|
-
this.resetUpload = () => {
|
|
150
|
-
this.props.uploadPicture({ data: "", item_id: this.props.item_id });
|
|
151
|
-
};
|
|
152
|
-
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
153
|
-
this.onInputChange = (e) => {
|
|
154
|
-
const errs = [];
|
|
155
|
-
const files = Array.from(e.target.files || []);
|
|
156
|
-
const types = ['image/png', 'image/jpeg', 'image/gif', 'image/svg', 'image/svg+xml', 'image/webp'];
|
|
157
|
-
const _1Mo = 1024 * 1024;
|
|
158
|
-
const SizeLimit = 1;
|
|
159
|
-
//Reset input cache value - to assure trigger if user select the same file again
|
|
160
|
-
e.target.value = "";
|
|
161
|
-
if (this.props.debugging)
|
|
162
|
-
console.log("onInputChange");
|
|
163
|
-
if (files.length > 1) {
|
|
164
|
-
this.handleError("MULTIPLE_FILES", 'Pas plus d\'une image à la fois');
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
files.forEach((file, i) => {
|
|
168
|
-
let errCount = errs.length;
|
|
169
|
-
if (types.every(type => file.type !== type)) {
|
|
170
|
-
this.handleError("UNSUPPORTED_FORMAT", `'${file.type}' : format non supporté !`);
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
if (file.size > (SizeLimit * _1Mo)) {
|
|
174
|
-
this.handleError("FILE_TOO_BIG", `'${file.name}' image trop volumineuse (max:${SizeLimit}Méga-octets)`);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
if (this.props.debugging)
|
|
178
|
-
console.log(`errCount = ${errCount} vs errs.length = ${errs.length}`);
|
|
179
|
-
if (errCount == errs.length) { //None new error occurs
|
|
180
|
-
if (this.props.debugging)
|
|
181
|
-
console.log("readImage::", file.name);
|
|
182
|
-
this.readImage(file);
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
if (errs.length) {
|
|
186
|
-
return errs.forEach(err => alert(err));
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
this.state = { hover_input: false, hover_image: false };
|
|
190
|
-
}
|
|
191
|
-
render() {
|
|
192
|
-
// Styles moved to external CSS file: DsBlob.css
|
|
193
|
-
return (_jsxs("div", { children: [(!this.props.data) &&
|
|
194
|
-
_jsxs("label", { id: "upload-picture-label", className: `upload-picture-label ${this.props.buttonStyle}`, children: [this.props.Caption, _jsx("input", { className: "upload-picture-label-input", id: "nested-input", type: "file", accept: "image/*", onChange: this.onInputChange, multiple: true })] }), (this.props.data && this.props.data.length > 0) &&
|
|
195
|
-
_jsxs("div", { className: "show-image", onMouseOver: () => { this.setState({ hover_input: true, hover_image: true }, () => { if (this.props.debugging)
|
|
196
|
-
console.log("onMouseOver"); }); }, onMouseLeave: () => { this.setState({ hover_input: false, hover_image: false }, () => { if (this.props.debugging)
|
|
197
|
-
console.log("onMouseLeave"); }); }, children: [_jsx("img", { className: `${this.state.hover_image ? "div-show-image-hover" : "div-show-image"} ${this.props.pictureStyle}`, src: (this.props.removebase64) ? "data:image/png;base64" : "" + this.props.data, alt: this.props.Caption || "uploaded image" }), !this.props.readOnly &&
|
|
198
|
-
_jsx("input", { className: `btn btn-primary delete ${this.state.hover_input ? "div-show-image-hover-input" : "div-show-image-input"}`, type: "button", value: "Effacer", onClick: this.resetUpload })] })] }));
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
DsBlob.defaultProps = {
|
|
202
|
-
maxKBytes: 400,
|
|
203
|
-
maxWidth: 80,
|
|
204
|
-
maxHeight: 60,
|
|
205
|
-
debugging: false
|
|
206
|
-
};
|
package/dist/types/DsBlob.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { Component, ChangeEvent } from "react";
|
|
2
|
-
interface ErrorObject {
|
|
3
|
-
error_code: string;
|
|
4
|
-
error_definition: string;
|
|
5
|
-
message: string;
|
|
6
|
-
}
|
|
7
|
-
interface DsBlobProps {
|
|
8
|
-
width?: number;
|
|
9
|
-
height?: number;
|
|
10
|
-
maxWidth?: number;
|
|
11
|
-
maxHeight?: number;
|
|
12
|
-
maxKBytes?: number;
|
|
13
|
-
reduceImage?: boolean;
|
|
14
|
-
jpegQuality?: number;
|
|
15
|
-
removebase64?: boolean;
|
|
16
|
-
uploadPicture: (data: {
|
|
17
|
-
data: string;
|
|
18
|
-
item_id: any;
|
|
19
|
-
}) => void;
|
|
20
|
-
onErrorHandler?: (errorObject: ErrorObject) => void;
|
|
21
|
-
item_id: any;
|
|
22
|
-
data?: string;
|
|
23
|
-
buttonStyle?: string;
|
|
24
|
-
Caption?: string;
|
|
25
|
-
pictureStyle?: string;
|
|
26
|
-
readOnly?: boolean;
|
|
27
|
-
debugging?: boolean;
|
|
28
|
-
}
|
|
29
|
-
interface DsBlobState {
|
|
30
|
-
hover_input: boolean;
|
|
31
|
-
hover_image: boolean;
|
|
32
|
-
}
|
|
33
|
-
export declare class DsBlob extends Component<DsBlobProps, DsBlobState> {
|
|
34
|
-
static defaultProps: {
|
|
35
|
-
maxKBytes: number;
|
|
36
|
-
maxWidth: number;
|
|
37
|
-
maxHeight: number;
|
|
38
|
-
debugging: boolean;
|
|
39
|
-
};
|
|
40
|
-
constructor(props: DsBlobProps);
|
|
41
|
-
private handleError;
|
|
42
|
-
reduceImage: (e: Event) => void;
|
|
43
|
-
storeImageToImg: (e: ProgressEvent<FileReader>) => void;
|
|
44
|
-
readImage: (aPictureFile: File) => Promise<void>;
|
|
45
|
-
resetUpload: () => void;
|
|
46
|
-
onInputChange: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
47
|
-
render(): import("react/jsx-runtime").JSX.Element;
|
|
48
|
-
}
|
|
49
|
-
export {};
|