@searpent/react-image-annotate 2.0.52 → 2.0.53

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.
@@ -3,7 +3,7 @@ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
3
3
  import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
4
4
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread";
5
5
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
6
- import React, { useEffect, useReducer } from "react";
6
+ import React, { useCallback, useEffect, useReducer } from "react";
7
7
  import makeImmutable, { without } from "seamless-immutable";
8
8
  import intersection from "lodash/intersection";
9
9
  import MainLayout from "../MainLayout";
@@ -135,7 +135,8 @@ export var Annotator = function Annotator(_ref) {
135
135
  return i.lockedUntil;
136
136
  }).map(function (i) {
137
137
  return i.id;
138
- }))
138
+ })),
139
+ toSaveImage: null
139
140
  }))),
140
141
  _useReducer2 = _slicedToArray(_useReducer, 2),
141
142
  state = _useReducer2[0],
@@ -172,8 +173,15 @@ export var Annotator = function Annotator(_ref) {
172
173
  type: "ADD_GROUP",
173
174
  group: group
174
175
  });
175
- }; // trigger save and recalc
176
+ };
176
177
 
178
+ var handleRecalcClicked = useCallback(function (_ref2) {
179
+ var imageId = _ref2.imageId;
180
+ dispatchToReducer({
181
+ type: "RECALC_CLICKED",
182
+ imageId: imageId
183
+ });
184
+ }, [dispatchToReducer]); // detect on page change if anything changed, if so trigger save and recalc
177
185
 
178
186
  useEffect(function () {
179
187
  var selectedImage = state.selectedImage,
@@ -183,14 +191,40 @@ export var Annotator = function Annotator(_ref) {
183
191
  if ((lastAction === null || lastAction === void 0 ? void 0 : lastAction.type) === 'SELECT_IMAGE' && selectedImage !== previouslySelectedImage) {
184
192
  var _state$images$previou, _state$images$previou2;
185
193
 
194
+ // save if previously selected image has any changes
195
+ if (((_state$images$previou = state.images[previouslySelectedImage]) === null || _state$images$previou === void 0 ? void 0 : (_state$images$previou2 = _state$images$previou.saveableActions) === null || _state$images$previou2 === void 0 ? void 0 : _state$images$previou2.length) > 0) {
196
+ var _state$images$previou3, _state$images$previou4;
197
+
198
+ // decide wheather recalc is needed
199
+ var triggerRecalc = intersection(reacalcActionsEnum, state.images[previouslySelectedImage].saveableActions).length > 0; // decide whether album metadata should be updated
200
+
201
+ var toSaveMetadata = [];
202
+
203
+ if ((_state$images$previou3 = state.images[previouslySelectedImage]) === null || _state$images$previou3 === void 0 ? void 0 : (_state$images$previou4 = _state$images$previou3.saveableActions) === null || _state$images$previou4 === void 0 ? void 0 : _state$images$previou4.includes("UPDATE_ALBUM_METADATA")) {
204
+ toSaveMetadata = state.albumMetadata;
205
+ } // set this image to be saved
206
+
207
+
208
+ dispatchToReducer({
209
+ type: "SAVE_IMAGE",
210
+ image: _objectSpread({}, state.images[previouslySelectedImage]),
211
+ triggerRecalc: triggerRecalc,
212
+ toSaveMetadata: toSaveMetadata
213
+ });
214
+ }
215
+ }
216
+ }, [state.previouslySelectedImage, state.selectedImage, state.images, state, save]); // handle save of image
217
+
218
+ useEffect(function () {
219
+ if (state.toSaveImage !== null) {
186
220
  // metadata on album level
187
221
  var saveHandler =
188
222
  /*#__PURE__*/
189
223
  function () {
190
- var _ref2 = _asyncToGenerator(
224
+ var _ref3 = _asyncToGenerator(
191
225
  /*#__PURE__*/
192
226
  _regeneratorRuntime.mark(function _callee(image, triggerRecalc, albumMetadata) {
193
- var _ref3, lockedUntil;
227
+ var _ref4, lockedUntil;
194
228
 
195
229
  return _regeneratorRuntime.wrap(function _callee$(_context) {
196
230
  while (1) {
@@ -209,8 +243,8 @@ export var Annotator = function Annotator(_ref) {
209
243
  });
210
244
 
211
245
  case 4:
212
- _ref3 = _context.sent;
213
- lockedUntil = _ref3.lockedUntil;
246
+ _ref4 = _context.sent;
247
+ lockedUntil = _ref4.lockedUntil;
214
248
  dispatchToReducer({
215
249
  type: "IMAGE_UPDATE_SUCCESS",
216
250
  imageId: image.id,
@@ -237,28 +271,17 @@ export var Annotator = function Annotator(_ref) {
237
271
  }));
238
272
 
239
273
  return function saveHandler(_x, _x2, _x3) {
240
- return _ref2.apply(this, arguments);
274
+ return _ref3.apply(this, arguments);
241
275
  };
242
- }(); // save if previously selected image has any changes
243
-
244
-
245
- if (((_state$images$previou = state.images[previouslySelectedImage]) === null || _state$images$previou === void 0 ? void 0 : (_state$images$previou2 = _state$images$previou.saveableActions) === null || _state$images$previou2 === void 0 ? void 0 : _state$images$previou2.length) > 0) {
246
- var _state$images$previou3, _state$images$previou4;
247
-
248
- // decide wheather recalc is needed
249
- var triggerRecalc = intersection(reacalcActionsEnum, state.images[previouslySelectedImage].saveableActions).length > 0; // decide wheather album metadata should be updated
276
+ }();
250
277
 
251
- var toSaveMetadata = [];
252
-
253
- if ((_state$images$previou3 = state.images[previouslySelectedImage]) === null || _state$images$previou3 === void 0 ? void 0 : (_state$images$previou4 = _state$images$previou3.saveableActions) === null || _state$images$previou4 === void 0 ? void 0 : _state$images$previou4.includes("UPDATE_ALBUM_METADATA")) {
254
- toSaveMetadata = state.albumMetadata;
255
- } // save image
256
-
257
-
258
- saveHandler(_objectSpread({}, state.images[previouslySelectedImage]), triggerRecalc, toSaveMetadata);
259
- }
278
+ var _state$toSaveImage = state.toSaveImage,
279
+ image = _state$toSaveImage.image,
280
+ triggerRecalc = _state$toSaveImage.triggerRecalc,
281
+ toSaveMetadata = _state$toSaveImage.toSaveMetadata;
282
+ saveHandler(image, triggerRecalc, toSaveMetadata);
260
283
  }
261
- }, [state.previouslySelectedImage, state.selectedImage, state.images, state, save]); // polling of images
284
+ }, [save, state.toSaveImage]); // polling of images
262
285
 
263
286
  useEffect(function () {
264
287
  if (state.toPollImages.length > 0) {
@@ -273,7 +296,7 @@ export var Annotator = function Annotator(_ref) {
273
296
  /*#__PURE__*/
274
297
  _regeneratorRuntime.mark(function _callee2(fetchImage, imageId) {
275
298
  var tries,
276
- _ref4,
299
+ _ref5,
277
300
  image,
278
301
  _args2 = arguments;
279
302
 
@@ -301,8 +324,8 @@ export var Annotator = function Annotator(_ref) {
301
324
  });
302
325
 
303
326
  case 6:
304
- _ref4 = _context2.sent;
305
- image = _ref4.image;
327
+ _ref5 = _context2.sent;
328
+ image = _ref5.image;
306
329
 
307
330
  if (image.lockedUntil) {
308
331
  _context2.next = 11;
@@ -355,10 +378,10 @@ export var Annotator = function Annotator(_ref) {
355
378
  }, [onImagesChange, selectedImage]);
356
379
  if (!images && !videoSrc) return 'Missing required prop "images" or "videoSrc"';
357
380
 
358
- var _ref5 = state.imagesSavedAt < state.imagesUpdatedAt ? [true, true] : [false, false],
359
- _ref6 = _slicedToArray(_ref5, 2),
360
- recalcActive = _ref6[0],
361
- saveActive = _ref6[1];
381
+ var _ref6 = state.imagesSavedAt < state.imagesUpdatedAt ? [true, true] : [false, false],
382
+ _ref7 = _slicedToArray(_ref6, 2),
383
+ recalcActive = _ref7[0],
384
+ saveActive = _ref7[1];
362
385
 
363
386
  return React.createElement(SettingsProvider, {
364
387
  clsColors: clsColors,
@@ -387,7 +410,8 @@ export var Annotator = function Annotator(_ref) {
387
410
  saveActive: recalcActive,
388
411
  recalcActive: saveActive,
389
412
  onMetadataChange: handleMetadataChange,
390
- onAddGroup: handleAddGroup
413
+ onAddGroup: handleAddGroup,
414
+ onRecalcClick: handleRecalcClicked
391
415
  }));
392
416
  };
393
417
  export default Annotator;
@@ -1266,7 +1266,19 @@ export default (function (state, action) {
1266
1266
  // )
1267
1267
  }
1268
1268
 
1269
- case "IMAGE_UPDATE_INIT":
1269
+ case "SAVE_IMAGE":
1270
+ {
1271
+ var image = action.image,
1272
+ triggerRecalc = action.triggerRecalc,
1273
+ toSaveMetadata = action.toSaveMetadata;
1274
+ return setIn(state, ["toSaveImage"], {
1275
+ image: image,
1276
+ triggerRecalc: triggerRecalc,
1277
+ toSaveMetadata: toSaveMetadata
1278
+ });
1279
+ }
1280
+
1281
+ case "RECALC_CLICKED":
1270
1282
  {
1271
1283
  var imageId = action.imageId;
1272
1284
  var imageIdx = state.images.findIndex(function (i) {
@@ -1277,7 +1289,29 @@ export default (function (state, action) {
1277
1289
  throw new Error("failed to find index of image with id ".concat(imageId));
1278
1290
  }
1279
1291
 
1280
- return setIn(state, ["images", imageIdx], _objectSpread({}, state.images[imageIdx], {
1292
+ var _image = _objectSpread({}, state.images[imageIdx]);
1293
+
1294
+ return setIn(state, ["toSaveImage"], {
1295
+ image: _image,
1296
+ triggerRecalc: true,
1297
+ toSaveMetadata: []
1298
+ });
1299
+ }
1300
+
1301
+ case "IMAGE_UPDATE_INIT":
1302
+ {
1303
+ var _imageId = action.imageId;
1304
+
1305
+ var _imageIdx = state.images.findIndex(function (i) {
1306
+ return i.id === _imageId;
1307
+ });
1308
+
1309
+ if (_imageIdx < 0) {
1310
+ throw new Error("failed to find index of image with id ".concat(_imageId));
1311
+ }
1312
+
1313
+ state = setIn(state, ["toSaveImage"], null);
1314
+ return setIn(state, ["images", _imageIdx], _objectSpread({}, state.images[_imageIdx], {
1281
1315
  lockedUntil: defaultLockedUntil(),
1282
1316
  syncError: null,
1283
1317
  saveableActions: []
@@ -1286,23 +1320,23 @@ export default (function (state, action) {
1286
1320
 
1287
1321
  case "IMAGE_UPDATE_SUCCESS":
1288
1322
  {
1289
- var _imageId = action.imageId,
1323
+ var _imageId2 = action.imageId,
1290
1324
  lockedUntil = action.lockedUntil;
1291
1325
 
1292
- var _imageIdx = state.images.findIndex(function (i) {
1293
- return i.id === _imageId;
1326
+ var _imageIdx2 = state.images.findIndex(function (i) {
1327
+ return i.id === _imageId2;
1294
1328
  });
1295
1329
 
1296
- if (_imageIdx < 0) {
1297
- throw new Error("failed to find index of image with id ".concat(_imageId));
1330
+ if (_imageIdx2 < 0) {
1331
+ throw new Error("failed to find index of image with id ".concat(_imageId2));
1298
1332
  } // if there is lockedUntil set, it means we need to poll for updated
1299
1333
 
1300
1334
 
1301
1335
  if (lockedUntil) {
1302
- state = setIn(state, ["toPollImages"], uniq([].concat(_toConsumableArray(state.toPollImages), [_imageId])));
1336
+ state = setIn(state, ["toPollImages"], uniq([].concat(_toConsumableArray(state.toPollImages), [_imageId2])));
1303
1337
  }
1304
1338
 
1305
- return setIn(state, ["images", _imageIdx], _objectSpread({}, state.images[_imageIdx], {
1339
+ return setIn(state, ["images", _imageIdx2], _objectSpread({}, state.images[_imageIdx2], {
1306
1340
  lockedUntil: lockedUntil,
1307
1341
  syncError: null
1308
1342
  }));
@@ -1310,18 +1344,18 @@ export default (function (state, action) {
1310
1344
 
1311
1345
  case "IMAGE_UPDATE_FAIL":
1312
1346
  {
1313
- var _imageId2 = action.imageId,
1347
+ var _imageId3 = action.imageId,
1314
1348
  error = action.error;
1315
1349
 
1316
- var _imageIdx2 = state.images.findIndex(function (i) {
1317
- return i.id === _imageId2;
1350
+ var _imageIdx3 = state.images.findIndex(function (i) {
1351
+ return i.id === _imageId3;
1318
1352
  });
1319
1353
 
1320
- if (_imageIdx2 < 0) {
1321
- throw new Error("failed to find index of image with id ".concat(_imageId2));
1354
+ if (_imageIdx3 < 0) {
1355
+ throw new Error("failed to find index of image with id ".concat(_imageId3));
1322
1356
  }
1323
1357
 
1324
- return setIn(state, ["images", _imageIdx2], _objectSpread({}, state.images[_imageIdx2], {
1358
+ return setIn(state, ["images", _imageIdx3], _objectSpread({}, state.images[_imageIdx3], {
1325
1359
  lockedUntil: null,
1326
1360
  syncError: error
1327
1361
  }));
@@ -1337,35 +1371,35 @@ export default (function (state, action) {
1337
1371
 
1338
1372
  case "IMAGE_POLL_SUCCESS":
1339
1373
  {
1340
- var image = action.image;
1374
+ var _image2 = action.image;
1341
1375
 
1342
- var _imageIdx3 = state.images.findIndex(function (i) {
1343
- return i.id === image.id;
1376
+ var _imageIdx4 = state.images.findIndex(function (i) {
1377
+ return i.id === _image2.id;
1344
1378
  });
1345
1379
 
1346
- if (_imageIdx3 < 0) {
1347
- throw new Error("failed to find index of image with id ".concat(image.id));
1380
+ if (_imageIdx4 < 0) {
1381
+ throw new Error("failed to find index of image with id ".concat(_image2.id));
1348
1382
  }
1349
1383
 
1350
- return setIn(state, ["images", _imageIdx3], _objectSpread({}, state.images[_imageIdx3], {
1384
+ return setIn(state, ["images", _imageIdx4], _objectSpread({}, state.images[_imageIdx4], {
1351
1385
  lockedUntil: null,
1352
1386
  syncError: null
1353
- }, image));
1387
+ }, _image2));
1354
1388
  }
1355
1389
 
1356
1390
  case "IMAGE_POLL_TIMEOUT":
1357
1391
  {
1358
- var _imageId3 = action.imageId;
1392
+ var _imageId4 = action.imageId;
1359
1393
 
1360
- var _imageIdx4 = state.images.findIndex(function (i) {
1361
- return i.id === _imageId3;
1394
+ var _imageIdx5 = state.images.findIndex(function (i) {
1395
+ return i.id === _imageId4;
1362
1396
  });
1363
1397
 
1364
- if (_imageIdx4 < 0) {
1365
- throw new Error("failed to find index of image with id ".concat(_imageId3));
1398
+ if (_imageIdx5 < 0) {
1399
+ throw new Error("failed to find index of image with id ".concat(_imageId4));
1366
1400
  }
1367
1401
 
1368
- return setIn(state, ["images", _imageIdx4], _objectSpread({}, state.images[_imageIdx4], {
1402
+ return setIn(state, ["images", _imageIdx5], _objectSpread({}, state.images[_imageIdx5], {
1369
1403
  lockedUntil: null,
1370
1404
  syncError: new Error("polling timeout")
1371
1405
  }));
@@ -37,7 +37,9 @@ import regionsToBlocks from '../utils/regions-to-blocks';
37
37
  import PageSelector from "../PageSelector";
38
38
  import regionsGroups from '../utils/regions-groups';
39
39
  import RightSidebarItemsWrapper from './RightSidebarItemsWrapper';
40
- import Locker from '../Locker'; // import Fullscreen from "../Fullscreen"
40
+ import Locker from '../Locker';
41
+ import { reacalcActionsEnum } from "../utils/saveable-actions-enum";
42
+ import intersection from "lodash/intersection"; // import Fullscreen from "../Fullscreen"
41
43
 
42
44
  var emptyArr = [];
43
45
  var theme = createTheme();
@@ -126,7 +128,8 @@ export var MainLayout = function MainLayout(_ref5) {
126
128
  _ref5$saveActive = _ref5.saveActive,
127
129
  saveActive = _ref5$saveActive === void 0 ? false : _ref5$saveActive,
128
130
  onMetadataChange = _ref5.onMetadataChange,
129
- onAddGroup = _ref5.onAddGroup;
131
+ onAddGroup = _ref5.onAddGroup,
132
+ onRecalcClick = _ref5.onRecalcClick;
130
133
  var classes = useStyles();
131
134
  var settings = useSettings();
132
135
  var fullScreenHandle = useFullScreenHandle();
@@ -301,7 +304,8 @@ export var MainLayout = function MainLayout(_ref5) {
301
304
  })) === null || _i$metadata$find === void 0 ? void 0 : _i$metadata$find.value) || null,
302
305
  metadata: i.metadata || [],
303
306
  lockedUntil: i.lockedUntil,
304
- syncError: i.syncError || null
307
+ syncError: i.syncError || null,
308
+ isRecalcReady: intersection(reacalcActionsEnum, state.images[idx].saveableActions).length > 0
305
309
  };
306
310
  });
307
311
 
@@ -339,10 +343,9 @@ export var MainLayout = function MainLayout(_ref5) {
339
343
  }, showPageSelector && React.createElement(PageSelector, {
340
344
  pages: pages,
341
345
  onPageClick: handlePageClick,
342
- saveActive: saveActive,
343
- recalcActive: recalcActive,
344
346
  onMetadataChange: onMetadataChange,
345
- metadataConfigs: state.metadataConfigs || []
347
+ metadataConfigs: state.metadataConfigs || [],
348
+ onRecalcClick: onRecalcClick
346
349
  }), React.createElement(WorkspaceWrapper, null, React.createElement(Workspace, {
347
350
  style: {
348
351
  width: "auto"
@@ -14,11 +14,15 @@ function PageThumbnail(_ref) {
14
14
  metadata = _ref.metadata,
15
15
  showMetadata = _ref.showMetadata,
16
16
  imageIndex = _ref.imageIndex,
17
+ imageId = _ref.imageId,
17
18
  onMetadataChange = _ref.onMetadataChange,
18
19
  _ref$metadataConfigs = _ref.metadataConfigs,
19
20
  metadataConfigs = _ref$metadataConfigs === void 0 ? [] : _ref$metadataConfigs,
20
21
  isLocked = _ref.isLocked,
21
- error = _ref.error;
22
+ error = _ref.error,
23
+ onRecalcClick = _ref.onRecalcClick,
24
+ _ref$isRecalcReady = _ref.isRecalcReady,
25
+ isRecalcReady = _ref$isRecalcReady === void 0 ? false : _ref$isRecalcReady;
22
26
 
23
27
  var handleChange = function handleChange(e) {
24
28
  e.preventDefault();
@@ -32,6 +36,13 @@ function PageThumbnail(_ref) {
32
36
  });
33
37
  };
34
38
 
39
+ var handleRecalcClick = function handleRecalcClick(e) {
40
+ e.stopPropagation();
41
+ onRecalcClick({
42
+ imageId: imageId
43
+ });
44
+ };
45
+
35
46
  var pageNumber = metadata === null || metadata === void 0 ? void 0 : (_metadata$find = metadata.find) === null || _metadata$find === void 0 ? void 0 : (_metadata$find$call = _metadata$find.call(metadata, function (md) {
36
47
  return md.key === 'pageNumber';
37
48
  })) === null || _metadata$find$call === void 0 ? void 0 : _metadata$find$call.value;
@@ -47,7 +58,12 @@ function PageThumbnail(_ref) {
47
58
  errorMessage: error.message
48
59
  }), React.createElement("div", {
49
60
  className: "ps-page-thumbnail-image-wrapper"
50
- }, React.createElement("img", {
61
+ }, isRecalcReady && React.createElement("div", {
62
+ className: "ps-page-thumbnail-recalc-wrapper"
63
+ }, React.createElement("button", {
64
+ className: "recalc-button",
65
+ onClick: handleRecalcClick
66
+ }, "Extract")), React.createElement("img", {
51
67
  src: src,
52
68
  alt: "",
53
69
  className: "ps-page-thumbnail-image"
@@ -102,10 +118,9 @@ function isLocked(page) {
102
118
  function PageSelector(_ref3) {
103
119
  var pages = _ref3.pages,
104
120
  onPageClick = _ref3.onPageClick,
105
- recalcActive = _ref3.recalcActive,
106
- saveActive = _ref3.saveActive,
107
121
  onMetadataChange = _ref3.onMetadataChange,
108
- metadataConfigs = _ref3.metadataConfigs;
122
+ metadataConfigs = _ref3.metadataConfigs,
123
+ onRecalcClick = _ref3.onRecalcClick;
109
124
 
110
125
  var _useState = useState(false),
111
126
  _useState2 = _slicedToArray(_useState, 2),
@@ -148,8 +163,11 @@ function PageSelector(_ref3) {
148
163
  metadata: page.metadata,
149
164
  showMetadata: showMetadata,
150
165
  imageIndex: idx,
166
+ imageId: page.id,
151
167
  onMetadataChange: onMetadataChange,
152
- metadataConfigs: metadataConfigs
168
+ metadataConfigs: metadataConfigs,
169
+ onRecalcClick: onRecalcClick,
170
+ isRecalcReady: page.isRecalcReady
153
171
  });
154
172
  })));
155
173
  }
@@ -235,4 +235,30 @@ input:checked+.slider:before {
235
235
 
236
236
  .mr-2 {
237
237
  margin-right: 1rem;
238
+ }
239
+
240
+ .ps-page-thumbnail-recalc-wrapper {
241
+ width: 100%;
242
+ height: 100%;
243
+ background: linear-gradient(rgba(255, 255, 255, 0), #8898aa);
244
+ display: flex;
245
+ justify-content: center;
246
+ align-items: center;
247
+ }
248
+
249
+ .ps-page-thumbnail-recalc-wrapper>.recalc-button {
250
+ width: 80%;
251
+ height: 40%;
252
+ border: none;
253
+ background-image: linear-gradient(310deg, #377ceb, #a8b8d8);
254
+ color: white;
255
+ font-weight: 400;
256
+ border-radius: 8px !important;
257
+ transition: transform .2s;
258
+ }
259
+
260
+ .ps-page-thumbnail-recalc-wrapper>.recalc-button:hover {
261
+ cursor: pointer;
262
+ font-weight: 600;
263
+ transform: scale(1.15);
238
264
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@searpent/react-image-annotate",
3
- "version": "2.0.52",
3
+ "version": "2.0.53",
4
4
  "dependencies": {
5
5
  "@editorjs/editorjs": "^2.25.0",
6
6
  "@editorjs/paragraph": "^2.8.0",