@searpent/react-image-annotate 2.0.48 → 2.0.49
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/Annotator/exampleImages.js +41 -0
- package/Annotator/examplePhotos.js +6 -3
- package/Annotator/index.js +187 -31
- package/Annotator/reducers/general-reducer.js +123 -0
- package/Errorer/index.js +11 -0
- package/MainLayout/index.js +6 -6
- package/PageSelector/index.js +21 -6
- package/package.json +1 -1
- package/utils/default-locked-until.js +6 -0
- package/utils/photosToImages.js +2 -1
- package/utils/saveable-actions-enum.js +3 -0
- package/utils/sleep.js +7 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
var mockedImage = {
|
|
2
|
+
"id": "NA",
|
|
3
|
+
"src": "https://www.gannett-cdn.com/presto/2022/01/12/NJDN/8088720b-446d-4693-be62-4dfdf1c3046f-DailyNewsSaturday.jpg?width=660&height=1253&fit=crop&format=pjpg&auto=webp",
|
|
4
|
+
"thumbnail": "https://www.gannett-cdn.com/presto/2022/01/12/NJDN/8088720b-446d-4693-be62-4dfdf1c3046f-DailyNewsSaturday.jpg?width=660&height=1253&fit=crop&format=pjpg&auto=webp",
|
|
5
|
+
"name": "https://www.gannett-cdn.com/presto/2022/01/12/NJDN/8088720b-446d-4693-be62-4dfdf1c3046f-DailyNewsSaturday.jpg?width=660&height=1253&fit=crop&format=pjpg&auto=webp",
|
|
6
|
+
"regions": [{
|
|
7
|
+
"id": "346807698131517440",
|
|
8
|
+
"type": "box",
|
|
9
|
+
"visible": true,
|
|
10
|
+
"cls": "title",
|
|
11
|
+
"highlighted": false,
|
|
12
|
+
"groupHighlighted": false,
|
|
13
|
+
"x": 0.5189794,
|
|
14
|
+
"y": 0.043963477,
|
|
15
|
+
"w": 0.46070240000000007,
|
|
16
|
+
"h": 0.13752678299999999,
|
|
17
|
+
"groupId": "0",
|
|
18
|
+
"text": "komerční příloha čtvrtek 29. dubna 2021 Robotické sekačky na trávu - nový pohled na sekání trávy"
|
|
19
|
+
}, {
|
|
20
|
+
"id": "346807698131517441",
|
|
21
|
+
"type": "box",
|
|
22
|
+
"visible": true,
|
|
23
|
+
"cls": "subtitle",
|
|
24
|
+
"highlighted": false,
|
|
25
|
+
"groupHighlighted": false,
|
|
26
|
+
"x": 0.51976687,
|
|
27
|
+
"y": 0.17134483,
|
|
28
|
+
"w": 0.18034333000000002,
|
|
29
|
+
"h": 0.10370872999999997,
|
|
30
|
+
"groupId": "0",
|
|
31
|
+
"text": "Udržet trávník v perfektním stavu, znamená věnovat mu ohromné množství času a cítit se neustále odpovědný za jeho stav. Znamená to nepopulární, mnohdy obtížnou, časově náročnou práci a také starost o likvidaci zahradního odpadu. Dobrou zprávou je, že robotická sekačka na trávu všechny tyto věci obstará za Vás."
|
|
32
|
+
}],
|
|
33
|
+
"metadata": [{
|
|
34
|
+
"key": "page",
|
|
35
|
+
"value": "66"
|
|
36
|
+
}, {
|
|
37
|
+
"key": "mockedBy",
|
|
38
|
+
"value": "artificial server"
|
|
39
|
+
}]
|
|
40
|
+
};
|
|
41
|
+
export default [mockedImage];
|
|
@@ -777,7 +777,8 @@ var examplePhotos = [{
|
|
|
777
777
|
}, {
|
|
778
778
|
"key": "mutation",
|
|
779
779
|
"value": "hřensko"
|
|
780
|
-
}]
|
|
780
|
+
}],
|
|
781
|
+
"lockedUntil": ""
|
|
781
782
|
}, {
|
|
782
783
|
"id": "431fc636-d6d1-4e20-a35b-cc7a201c1833",
|
|
783
784
|
"fullsize": {
|
|
@@ -1328,7 +1329,8 @@ var examplePhotos = [{
|
|
|
1328
1329
|
"metadata": [{
|
|
1329
1330
|
"key": "pageNumber",
|
|
1330
1331
|
"value": "2"
|
|
1331
|
-
}]
|
|
1332
|
+
}],
|
|
1333
|
+
"lockedUntil": "2020-01-18T11:35:00.000Z"
|
|
1332
1334
|
}, {
|
|
1333
1335
|
"id": "45f79ec8-fd2e-4ad8-82f6-007a2eec2b97",
|
|
1334
1336
|
"fullsize": {
|
|
@@ -2047,7 +2049,8 @@ var examplePhotos = [{
|
|
|
2047
2049
|
"metadata": [{
|
|
2048
2050
|
"key": "pageNumber",
|
|
2049
2051
|
"value": "3"
|
|
2050
|
-
}]
|
|
2052
|
+
}],
|
|
2053
|
+
"lockedUntil": ""
|
|
2051
2054
|
}, {
|
|
2052
2055
|
"id": "5494ea75-ec1b-4513-b23b-0b2eaa29b576",
|
|
2053
2056
|
"fullsize": {
|
package/Annotator/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread";
|
|
|
4
4
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
5
5
|
import React, { useEffect, useReducer } from "react";
|
|
6
6
|
import makeImmutable, { without } from "seamless-immutable";
|
|
7
|
+
import intersection from "lodash/intersection";
|
|
7
8
|
import MainLayout from "../MainLayout";
|
|
8
9
|
import SettingsProvider from "../SettingsProvider";
|
|
9
10
|
import combineReducers from "./reducers/combine-reducers.js";
|
|
@@ -13,6 +14,8 @@ import historyHandler from "./reducers/history-handler.js";
|
|
|
13
14
|
import imageReducer from "./reducers/image-reducer.js";
|
|
14
15
|
import useEventCallback from "use-event-callback";
|
|
15
16
|
import videoReducer from "./reducers/video-reducer.js";
|
|
17
|
+
import { reacalcActionsEnum } from "../utils/saveable-actions-enum";
|
|
18
|
+
import sleep from '../utils/sleep';
|
|
16
19
|
export var Annotator = function Annotator(_ref) {
|
|
17
20
|
var images = _ref.images,
|
|
18
21
|
allowedArea = _ref.allowedArea,
|
|
@@ -79,8 +82,10 @@ export var Annotator = function Annotator(_ref) {
|
|
|
79
82
|
onSelectedImageChange = _ref.onSelectedImageChange,
|
|
80
83
|
albumMetadata = _ref.albumMetadata,
|
|
81
84
|
metadataConfigs = _ref.metadataConfigs,
|
|
82
|
-
_ref$
|
|
83
|
-
|
|
85
|
+
_ref$save = _ref.save,
|
|
86
|
+
save = _ref$save === void 0 ? function () {} : _ref$save,
|
|
87
|
+
_ref$fetchImage = _ref.fetchImage,
|
|
88
|
+
fetchImage = _ref$fetchImage === void 0 ? function () {} : _ref$fetchImage;
|
|
84
89
|
|
|
85
90
|
if (typeof selectedImage === "string") {
|
|
86
91
|
selectedImage = (images || []).findIndex(function (img) {
|
|
@@ -126,7 +131,8 @@ export var Annotator = function Annotator(_ref) {
|
|
|
126
131
|
imagesUpdatedAt: null,
|
|
127
132
|
imagesSavedAt: null,
|
|
128
133
|
albumMetadata: albumMetadata,
|
|
129
|
-
metadataConfigs: metadataConfigs
|
|
134
|
+
metadataConfigs: metadataConfigs,
|
|
135
|
+
toPollImages: []
|
|
130
136
|
}))),
|
|
131
137
|
_useReducer2 = _slicedToArray(_useReducer, 2),
|
|
132
138
|
state = _useReducer2[0],
|
|
@@ -255,39 +261,190 @@ export var Annotator = function Annotator(_ref) {
|
|
|
255
261
|
type: "ADD_GROUP",
|
|
256
262
|
group: group
|
|
257
263
|
});
|
|
258
|
-
}; // trigger
|
|
264
|
+
}; // trigger save and recalc
|
|
259
265
|
|
|
260
266
|
|
|
261
267
|
useEffect(function () {
|
|
262
|
-
var
|
|
268
|
+
var selectedImage = state.selectedImage,
|
|
269
|
+
previouslySelectedImage = state.previouslySelectedImage,
|
|
270
|
+
lastAction = state.lastAction;
|
|
263
271
|
|
|
264
|
-
|
|
272
|
+
if ((lastAction === null || lastAction === void 0 ? void 0 : lastAction.type) === 'SELECT_IMAGE' && selectedImage !== previouslySelectedImage) {
|
|
273
|
+
var _state$images$previou, _state$images$previou2;
|
|
265
274
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
275
|
+
// metadata on album level
|
|
276
|
+
var saveHandler =
|
|
277
|
+
/*#__PURE__*/
|
|
278
|
+
function () {
|
|
279
|
+
var _ref4 = _asyncToGenerator(
|
|
280
|
+
/*#__PURE__*/
|
|
281
|
+
_regeneratorRuntime.mark(function _callee3(image, triggerRecalc, albumMetadata) {
|
|
282
|
+
var _ref5, lockedUntil;
|
|
283
|
+
|
|
284
|
+
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
285
|
+
while (1) {
|
|
286
|
+
switch (_context3.prev = _context3.next) {
|
|
287
|
+
case 0:
|
|
288
|
+
dispatchToReducer({
|
|
289
|
+
type: "IMAGE_UPDATE_INIT",
|
|
290
|
+
imageId: image.id
|
|
291
|
+
});
|
|
292
|
+
_context3.prev = 1;
|
|
293
|
+
_context3.next = 4;
|
|
294
|
+
return save({
|
|
295
|
+
image: image,
|
|
296
|
+
triggerRecalc: triggerRecalc,
|
|
297
|
+
albumMetadata: albumMetadata
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
case 4:
|
|
301
|
+
_ref5 = _context3.sent;
|
|
302
|
+
lockedUntil = _ref5.lockedUntil;
|
|
303
|
+
dispatchToReducer({
|
|
304
|
+
type: "IMAGE_UPDATE_SUCCESS",
|
|
305
|
+
imageId: image.id,
|
|
306
|
+
lockedUntil: lockedUntil
|
|
307
|
+
});
|
|
308
|
+
_context3.next = 12;
|
|
309
|
+
break;
|
|
310
|
+
|
|
311
|
+
case 9:
|
|
312
|
+
_context3.prev = 9;
|
|
313
|
+
_context3.t0 = _context3["catch"](1);
|
|
314
|
+
dispatchToReducer({
|
|
315
|
+
type: "IMAGE_UPDATE_FAIL",
|
|
316
|
+
imageId: image.id,
|
|
317
|
+
error: _context3.t0
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
case 12:
|
|
321
|
+
case "end":
|
|
322
|
+
return _context3.stop();
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}, _callee3, null, [[1, 9]]);
|
|
326
|
+
}));
|
|
327
|
+
|
|
328
|
+
return function saveHandler(_x3, _x4, _x5) {
|
|
329
|
+
return _ref4.apply(this, arguments);
|
|
330
|
+
};
|
|
331
|
+
}(); // save if previously selected image has any changes
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
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) {
|
|
335
|
+
var _state$images$previou3, _state$images$previou4;
|
|
336
|
+
|
|
337
|
+
// decide wheather recalc is needed
|
|
338
|
+
var triggerRecalc = intersection(reacalcActionsEnum, state.images[previouslySelectedImage].saveableActions).length > 0; // decide wheather album metadata should be updated
|
|
339
|
+
|
|
340
|
+
var toSaveMetadata = [];
|
|
341
|
+
|
|
342
|
+
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")) {
|
|
343
|
+
toSaveMetadata = state.albumMetadata;
|
|
344
|
+
} // save image
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
saveHandler(_objectSpread({}, state.images[previouslySelectedImage]), triggerRecalc, toSaveMetadata);
|
|
348
|
+
}
|
|
274
349
|
}
|
|
275
|
-
}, [state.previouslySelectedImage, state.selectedImage,
|
|
350
|
+
}, [state.previouslySelectedImage, state.selectedImage, state.images, state, save]); // polling of images
|
|
276
351
|
|
|
277
352
|
useEffect(function () {
|
|
278
|
-
if (
|
|
279
|
-
|
|
280
|
-
|
|
353
|
+
if (state.toPollImages.length > 0) {
|
|
354
|
+
var polledImages = state.toPollImages.reduce(function (acc, imageId) {
|
|
355
|
+
function pollImage(_x6, _x7) {
|
|
356
|
+
return _pollImage.apply(this, arguments);
|
|
357
|
+
} // make recursive calling of polling function
|
|
358
|
+
|
|
281
359
|
|
|
282
|
-
|
|
283
|
-
|
|
360
|
+
function _pollImage() {
|
|
361
|
+
_pollImage = _asyncToGenerator(
|
|
362
|
+
/*#__PURE__*/
|
|
363
|
+
_regeneratorRuntime.mark(function _callee4(fetchImage, imageId) {
|
|
364
|
+
var tries,
|
|
365
|
+
_ref6,
|
|
366
|
+
image,
|
|
367
|
+
_args4 = arguments;
|
|
368
|
+
|
|
369
|
+
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
|
|
370
|
+
while (1) {
|
|
371
|
+
switch (_context4.prev = _context4.next) {
|
|
372
|
+
case 0:
|
|
373
|
+
tries = _args4.length > 2 && _args4[2] !== undefined ? _args4[2] : 5;
|
|
374
|
+
|
|
375
|
+
if (!(tries === 0)) {
|
|
376
|
+
_context4.next = 4;
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
dispatchToReducer({
|
|
381
|
+
type: "IMAGE_POLL_TIMEOUT",
|
|
382
|
+
imageId: imageId
|
|
383
|
+
});
|
|
384
|
+
return _context4.abrupt("return");
|
|
385
|
+
|
|
386
|
+
case 4:
|
|
387
|
+
_context4.next = 6;
|
|
388
|
+
return fetchImage({
|
|
389
|
+
imageId: imageId
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
case 6:
|
|
393
|
+
_ref6 = _context4.sent;
|
|
394
|
+
image = _ref6.image;
|
|
395
|
+
|
|
396
|
+
if (image.lockedUntil) {
|
|
397
|
+
_context4.next = 11;
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
dispatchToReducer({
|
|
402
|
+
type: "IMAGE_POLL_SUCCESS",
|
|
403
|
+
image: image
|
|
404
|
+
});
|
|
405
|
+
return _context4.abrupt("return");
|
|
406
|
+
|
|
407
|
+
case 11:
|
|
408
|
+
_context4.next = 13;
|
|
409
|
+
return sleep(5000);
|
|
410
|
+
|
|
411
|
+
case 13:
|
|
412
|
+
_context4.next = 15;
|
|
413
|
+
return pollImage(fetchImage, imageId, tries - 1);
|
|
414
|
+
|
|
415
|
+
case 15:
|
|
416
|
+
return _context4.abrupt("return", _context4.sent);
|
|
417
|
+
|
|
418
|
+
case 16:
|
|
419
|
+
case "end":
|
|
420
|
+
return _context4.stop();
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}, _callee4);
|
|
424
|
+
}));
|
|
425
|
+
return _pollImage.apply(this, arguments);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
pollImage(fetchImage, imageId, 10);
|
|
429
|
+
return imageId;
|
|
430
|
+
}, []);
|
|
431
|
+
dispatchToReducer({
|
|
432
|
+
type: "IMAGE_POLL_INIT",
|
|
433
|
+
imageIds: polledImages
|
|
434
|
+
});
|
|
284
435
|
}
|
|
436
|
+
}, [fetchImage, state.toPollImages]); // // TODO: delete this when work done
|
|
437
|
+
// useEffect(() => {
|
|
438
|
+
// if (!state.lastAction || !["BEGIN_BOX_TRANSFORM", "CHANGE_REGION", "DELETE_REGION", "DELETE_SELECTED_REGION", "UPDATE_METADATA", "SELECT_CLASSIFICATION"].includes(state.lastAction.type)) { return }
|
|
439
|
+
// if (onImagesChange) {
|
|
440
|
+
// onImagesChange(state.images)
|
|
441
|
+
// }
|
|
442
|
+
// dispatchToReducer({
|
|
443
|
+
// type: "IMAGES_UPDATED",
|
|
444
|
+
// updatedAt: new Date()
|
|
445
|
+
// })
|
|
446
|
+
// }, [onImagesChange, state.images, state.lastAction])
|
|
285
447
|
|
|
286
|
-
dispatchToReducer({
|
|
287
|
-
type: "IMAGES_UPDATED",
|
|
288
|
-
updatedAt: new Date()
|
|
289
|
-
});
|
|
290
|
-
}, [onImagesChange, state.images, state.lastAction]);
|
|
291
448
|
useEffect(function () {
|
|
292
449
|
if (selectedImage === undefined) return;
|
|
293
450
|
dispatchToReducer({
|
|
@@ -298,10 +455,10 @@ export var Annotator = function Annotator(_ref) {
|
|
|
298
455
|
}, [onImagesChange, selectedImage]);
|
|
299
456
|
if (!images && !videoSrc) return 'Missing required prop "images" or "videoSrc"';
|
|
300
457
|
|
|
301
|
-
var
|
|
302
|
-
|
|
303
|
-
recalcActive =
|
|
304
|
-
saveActive =
|
|
458
|
+
var _ref7 = state.imagesSavedAt < state.imagesUpdatedAt ? [true, true] : [false, false],
|
|
459
|
+
_ref8 = _slicedToArray(_ref7, 2),
|
|
460
|
+
recalcActive = _ref8[0],
|
|
461
|
+
saveActive = _ref8[1];
|
|
305
462
|
|
|
306
463
|
return React.createElement(SettingsProvider, {
|
|
307
464
|
clsColors: clsColors,
|
|
@@ -332,8 +489,7 @@ export var Annotator = function Annotator(_ref) {
|
|
|
332
489
|
saveActive: recalcActive,
|
|
333
490
|
recalcActive: saveActive,
|
|
334
491
|
onMetadataChange: handleMetadataChange,
|
|
335
|
-
onAddGroup: handleAddGroup
|
|
336
|
-
lockedImages: lockedImages
|
|
492
|
+
onAddGroup: handleAddGroup
|
|
337
493
|
}));
|
|
338
494
|
};
|
|
339
495
|
export default Annotator;
|
|
@@ -5,6 +5,7 @@ import { moveRegion } from "../../ImageCanvas/region-tools.js";
|
|
|
5
5
|
import { getIn, setIn, updateIn } from "seamless-immutable";
|
|
6
6
|
import moment from "moment";
|
|
7
7
|
import isEqual from "lodash/isEqual";
|
|
8
|
+
import uniq from "lodash/uniq";
|
|
8
9
|
import getActiveImage from "./get-active-image";
|
|
9
10
|
import { saveToHistory } from "./history-handler.js";
|
|
10
11
|
import colors from "../../colors";
|
|
@@ -16,6 +17,7 @@ import setInLocalStorage from "../../utils/set-in-local-storage";
|
|
|
16
17
|
import onlyUnique from "../../utils/filter-only-unique";
|
|
17
18
|
import regionsGroups from '../../utils/regions-groups';
|
|
18
19
|
import nextGroupId from "../../utils/next-group-id";
|
|
20
|
+
import defaultLockedUntil from "../../utils/default-locked-until";
|
|
19
21
|
|
|
20
22
|
var getRandomId = function getRandomId() {
|
|
21
23
|
return Math.random().toString().split(".")[1];
|
|
@@ -107,6 +109,11 @@ export default (function (state, action) {
|
|
|
107
109
|
}));
|
|
108
110
|
};
|
|
109
111
|
|
|
112
|
+
var addSaveableAction = function addSaveableAction(state, action) {
|
|
113
|
+
if (currentImageIndex === null) return state;
|
|
114
|
+
return setIn(state, [].concat(_toConsumableArray(pathToActiveImage), ["saveableActions"]), [].concat(_toConsumableArray(activeImage.saveableActions || []), [action]));
|
|
115
|
+
};
|
|
116
|
+
|
|
110
117
|
var setNewImage = function setNewImage(img, index) {
|
|
111
118
|
var _ref = typeof img === "object" ? img : {
|
|
112
119
|
src: img
|
|
@@ -151,6 +158,7 @@ export default (function (state, action) {
|
|
|
151
158
|
state = setIn(state, [].concat(_toConsumableArray(pathToActiveImage), ["regions"]), newRegions);
|
|
152
159
|
}
|
|
153
160
|
|
|
161
|
+
state = addSaveableAction(state, "SELECT_CLASSIFICATION");
|
|
154
162
|
return setIn(state, ["selectedCls"], action.cls);
|
|
155
163
|
}
|
|
156
164
|
|
|
@@ -178,6 +186,7 @@ export default (function (state, action) {
|
|
|
178
186
|
state = saveToHistory(state, "Change Region Comment");
|
|
179
187
|
}
|
|
180
188
|
|
|
189
|
+
state = addSaveableAction(state, "CHANGE_REGION");
|
|
181
190
|
return setIn(state, [].concat(_toConsumableArray(pathToActiveImage), ["regions", regionIndex]), action.region);
|
|
182
191
|
}
|
|
183
192
|
|
|
@@ -846,11 +855,13 @@ export default (function (state, action) {
|
|
|
846
855
|
|
|
847
856
|
if (state.mode.isNew) {
|
|
848
857
|
if (Math.abs(state.mode.original.x - _x2) < 0.002 || Math.abs(state.mode.original.y - _y2) < 0.002) {
|
|
858
|
+
state = addSaveableAction(state, "MOUSE_UP_RESIZE_BOX");
|
|
849
859
|
return setIn(modifyRegion(state.mode.regionId, null), ["mode"], null);
|
|
850
860
|
}
|
|
851
861
|
}
|
|
852
862
|
|
|
853
863
|
if (state.mode.editLabelEditorAfter) {
|
|
864
|
+
state = addSaveableAction(state, "MOUSE_UP_RESIZE_BOX");
|
|
854
865
|
return _objectSpread({}, modifyRegion(state.mode.regionId, {
|
|
855
866
|
editingLabels: true
|
|
856
867
|
}), {
|
|
@@ -863,6 +874,7 @@ export default (function (state, action) {
|
|
|
863
874
|
case "RESIZE_KEYPOINTS":
|
|
864
875
|
case "MOVE_POLYGON_POINT":
|
|
865
876
|
{
|
|
877
|
+
state = addSaveableAction(state, "MOUSE_UP_MOVE_REGION");
|
|
866
878
|
return _objectSpread({}, state, {
|
|
867
879
|
mode: null
|
|
868
880
|
});
|
|
@@ -965,6 +977,7 @@ export default (function (state, action) {
|
|
|
965
977
|
|
|
966
978
|
if (_regionIndex18 === null) return state;
|
|
967
979
|
state = saveToHistory(state, "Delete region");
|
|
980
|
+
state = addSaveableAction(state, "DELETE_REGION");
|
|
968
981
|
return setIn(state, [].concat(_toConsumableArray(pathToActiveImage), ["regions"]), (activeImage.regions || []).filter(function (r) {
|
|
969
982
|
return r.id !== action.region.id;
|
|
970
983
|
}));
|
|
@@ -975,6 +988,7 @@ export default (function (state, action) {
|
|
|
975
988
|
var _groupId = action.groupId;
|
|
976
989
|
if (_groupId === null || _groupId === undefined) return state;
|
|
977
990
|
state = saveToHistory(state, "Delete group");
|
|
991
|
+
state = addSaveableAction(state, "DELETE_GROUP");
|
|
978
992
|
return setIn(state, [].concat(_toConsumableArray(pathToActiveImage), ["regions"]), (activeImage.regions || []).filter(function (r) {
|
|
979
993
|
return r.groupId !== _groupId;
|
|
980
994
|
}));
|
|
@@ -1141,6 +1155,7 @@ export default (function (state, action) {
|
|
|
1141
1155
|
});
|
|
1142
1156
|
}); // TODO: add mutation of order and deletion of regions - SI-1967
|
|
1143
1157
|
|
|
1158
|
+
state = addSaveableAction(state, "UPDATE_REGIONS");
|
|
1144
1159
|
return setIn(state, ["images", imageIndex, "regions"], updatedRegions);
|
|
1145
1160
|
}
|
|
1146
1161
|
|
|
@@ -1182,6 +1197,7 @@ export default (function (state, action) {
|
|
|
1182
1197
|
return state;
|
|
1183
1198
|
}
|
|
1184
1199
|
|
|
1200
|
+
state = addSaveableAction(state, "UPDATE_ALBUM_METADATA");
|
|
1185
1201
|
return setIn(state, ["albumMetadata", metadataIndex], {
|
|
1186
1202
|
key: name,
|
|
1187
1203
|
value: value
|
|
@@ -1214,6 +1230,7 @@ export default (function (state, action) {
|
|
|
1214
1230
|
}
|
|
1215
1231
|
|
|
1216
1232
|
articleMetadata[toBeUpdatedMetadataIdx].value = value;
|
|
1233
|
+
state = addSaveableAction(state, "UPDATE_METADATA");
|
|
1217
1234
|
return setIn(state, ["images", _imageIndex, "regions", articleMetadataRegionIdx], _objectSpread({}, articleRegionToUpdate, {
|
|
1218
1235
|
text: JSON.stringify(articleMetadata)
|
|
1219
1236
|
}));
|
|
@@ -1229,6 +1246,7 @@ export default (function (state, action) {
|
|
|
1229
1246
|
return state;
|
|
1230
1247
|
}
|
|
1231
1248
|
|
|
1249
|
+
state = addSaveableAction(state, "UPDATE_METADATA");
|
|
1232
1250
|
return setIn(state, ["images", _imageIndex, "metadata", _metadataIndex], {
|
|
1233
1251
|
key: name,
|
|
1234
1252
|
value: value
|
|
@@ -1248,6 +1266,111 @@ export default (function (state, action) {
|
|
|
1248
1266
|
// )
|
|
1249
1267
|
}
|
|
1250
1268
|
|
|
1269
|
+
case "IMAGE_UPDATE_INIT":
|
|
1270
|
+
{
|
|
1271
|
+
var imageId = action.imageId;
|
|
1272
|
+
var imageIdx = state.images.findIndex(function (i) {
|
|
1273
|
+
return i.id === imageId;
|
|
1274
|
+
});
|
|
1275
|
+
|
|
1276
|
+
if (imageIdx < 0) {
|
|
1277
|
+
throw new Error("failed to find index of image with id ".concat(imageId));
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
return setIn(state, ["images", imageIdx], _objectSpread({}, state.images[imageIdx], {
|
|
1281
|
+
lockedUntil: defaultLockedUntil(),
|
|
1282
|
+
syncError: null,
|
|
1283
|
+
saveableActions: []
|
|
1284
|
+
}));
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
case "IMAGE_UPDATE_SUCCESS":
|
|
1288
|
+
{
|
|
1289
|
+
var _imageId = action.imageId,
|
|
1290
|
+
lockedUntil = action.lockedUntil;
|
|
1291
|
+
|
|
1292
|
+
var _imageIdx = state.images.findIndex(function (i) {
|
|
1293
|
+
return i.id === _imageId;
|
|
1294
|
+
});
|
|
1295
|
+
|
|
1296
|
+
if (_imageIdx < 0) {
|
|
1297
|
+
throw new Error("failed to find index of image with id ".concat(_imageId));
|
|
1298
|
+
} // if there is lockedUntil set, it means we need to poll for updated
|
|
1299
|
+
|
|
1300
|
+
|
|
1301
|
+
if (lockedUntil) {
|
|
1302
|
+
state = setIn(state, ["toPollImages"], uniq([].concat(_toConsumableArray(state.toPollImages), [_imageId])));
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
return setIn(state, ["images", _imageIdx], _objectSpread({}, state.images[_imageIdx], {
|
|
1306
|
+
lockedUntil: lockedUntil,
|
|
1307
|
+
syncError: null
|
|
1308
|
+
}));
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
case "IMAGE_UPDATE_FAIL":
|
|
1312
|
+
{
|
|
1313
|
+
var _imageId2 = action.imageId,
|
|
1314
|
+
error = action.error;
|
|
1315
|
+
|
|
1316
|
+
var _imageIdx2 = state.images.findIndex(function (i) {
|
|
1317
|
+
return i.id === _imageId2;
|
|
1318
|
+
});
|
|
1319
|
+
|
|
1320
|
+
if (_imageIdx2 < 0) {
|
|
1321
|
+
throw new Error("failed to find index of image with id ".concat(_imageId2));
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
return setIn(state, ["images", _imageIdx2], _objectSpread({}, state.images[_imageIdx2], {
|
|
1325
|
+
lockedUntil: null,
|
|
1326
|
+
syncError: error
|
|
1327
|
+
}));
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
case "IMAGE_POLL_INIT":
|
|
1331
|
+
{
|
|
1332
|
+
var imageIds = action.imageIds;
|
|
1333
|
+
return setIn(state, ["toPollImages"], state.toPollImages.filter(function (i) {
|
|
1334
|
+
return !imageIds.includes(i);
|
|
1335
|
+
}));
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
case "IMAGE_POLL_SUCCESS":
|
|
1339
|
+
{
|
|
1340
|
+
var image = action.image;
|
|
1341
|
+
|
|
1342
|
+
var _imageIdx3 = state.images.findIndex(function (i) {
|
|
1343
|
+
return i.id === image.id;
|
|
1344
|
+
});
|
|
1345
|
+
|
|
1346
|
+
if (_imageIdx3 < 0) {
|
|
1347
|
+
throw new Error("failed to find index of image with id ".concat(image.id));
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
return setIn(state, ["images", _imageIdx3], _objectSpread({}, state.images[_imageIdx3], {
|
|
1351
|
+
lockedUntil: null,
|
|
1352
|
+
syncError: null
|
|
1353
|
+
}, image));
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
case "IMAGE_POLL_TIMEOUT":
|
|
1357
|
+
{
|
|
1358
|
+
var _imageId3 = action.imageId;
|
|
1359
|
+
|
|
1360
|
+
var _imageIdx4 = state.images.findIndex(function (i) {
|
|
1361
|
+
return i.id === _imageId3;
|
|
1362
|
+
});
|
|
1363
|
+
|
|
1364
|
+
if (_imageIdx4 < 0) {
|
|
1365
|
+
throw new Error("failed to find index of image with id ".concat(_imageId3));
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
return setIn(state, ["images", _imageIdx4], _objectSpread({}, state.images[_imageIdx4], {
|
|
1369
|
+
lockedUntil: null,
|
|
1370
|
+
syncError: new Error("polling timeout")
|
|
1371
|
+
}));
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1251
1374
|
default:
|
|
1252
1375
|
break;
|
|
1253
1376
|
}
|
package/Errorer/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ErrorIcon from '@mui/icons-material/Error';
|
|
3
|
+
import './errorer.css';
|
|
4
|
+
|
|
5
|
+
function Errorer() {
|
|
6
|
+
return React.createElement("div", {
|
|
7
|
+
className: "errorer"
|
|
8
|
+
}, React.createElement(ErrorIcon, null));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default Errorer;
|
package/MainLayout/index.js
CHANGED
|
@@ -85,7 +85,7 @@ var EditorWrapper = styled("div")(function (_ref4) {
|
|
|
85
85
|
};
|
|
86
86
|
});
|
|
87
87
|
export var MainLayout = function MainLayout(_ref5) {
|
|
88
|
-
var _state$images$state$s, _state$images$state$s2
|
|
88
|
+
var _state$images$state$s, _state$images$state$s2;
|
|
89
89
|
|
|
90
90
|
var state = _ref5.state,
|
|
91
91
|
dispatch = _ref5.dispatch,
|
|
@@ -130,8 +130,7 @@ export var MainLayout = function MainLayout(_ref5) {
|
|
|
130
130
|
_ref5$saveActive = _ref5.saveActive,
|
|
131
131
|
saveActive = _ref5$saveActive === void 0 ? false : _ref5$saveActive,
|
|
132
132
|
onMetadataChange = _ref5.onMetadataChange,
|
|
133
|
-
onAddGroup = _ref5.onAddGroup
|
|
134
|
-
lockedImages = _ref5.lockedImages;
|
|
133
|
+
onAddGroup = _ref5.onAddGroup;
|
|
135
134
|
var classes = useStyles();
|
|
136
135
|
var settings = useSettings();
|
|
137
136
|
var fullScreenHandle = useFullScreenHandle();
|
|
@@ -304,7 +303,9 @@ export var MainLayout = function MainLayout(_ref5) {
|
|
|
304
303
|
pageNumber: (i === null || i === void 0 ? void 0 : (_i$metadata = i.metadata) === null || _i$metadata === void 0 ? void 0 : (_i$metadata$find = _i$metadata.find(function (md) {
|
|
305
304
|
return md.key === "pageNumber";
|
|
306
305
|
})) === null || _i$metadata$find === void 0 ? void 0 : _i$metadata$find.value) || null,
|
|
307
|
-
metadata: i.metadata || []
|
|
306
|
+
metadata: i.metadata || [],
|
|
307
|
+
lockedUntil: i.lockedUntil,
|
|
308
|
+
syncError: i.syncError || null
|
|
308
309
|
};
|
|
309
310
|
});
|
|
310
311
|
|
|
@@ -315,7 +316,7 @@ export var MainLayout = function MainLayout(_ref5) {
|
|
|
315
316
|
});
|
|
316
317
|
};
|
|
317
318
|
|
|
318
|
-
var isSelectedImageLocked =
|
|
319
|
+
var isSelectedImageLocked = false;
|
|
319
320
|
return React.createElement(ThemeProvider, {
|
|
320
321
|
theme: theme
|
|
321
322
|
}, React.createElement(FullScreenContainer, null, React.createElement(FullScreen, {
|
|
@@ -341,7 +342,6 @@ export var MainLayout = function MainLayout(_ref5) {
|
|
|
341
342
|
}
|
|
342
343
|
}, showPageSelector && React.createElement(PageSelector, {
|
|
343
344
|
pages: pages,
|
|
344
|
-
lockedImages: lockedImages,
|
|
345
345
|
onPageClick: handlePageClick,
|
|
346
346
|
onRecalc: onRecalc,
|
|
347
347
|
onSave: onSave,
|
package/PageSelector/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import React, { useState } from 'react';
|
|
|
3
3
|
import classnames from "classnames";
|
|
4
4
|
import './page-selector.css';
|
|
5
5
|
import Locker from '../Locker';
|
|
6
|
+
import Errorer from '../Errorer';
|
|
6
7
|
|
|
7
8
|
function PageThumbnail(_ref) {
|
|
8
9
|
var _metadata$find, _metadata$find$call;
|
|
@@ -16,7 +17,8 @@ function PageThumbnail(_ref) {
|
|
|
16
17
|
onMetadataChange = _ref.onMetadataChange,
|
|
17
18
|
_ref$metadataConfigs = _ref.metadataConfigs,
|
|
18
19
|
metadataConfigs = _ref$metadataConfigs === void 0 ? [] : _ref$metadataConfigs,
|
|
19
|
-
isLocked = _ref.isLocked
|
|
20
|
+
isLocked = _ref.isLocked,
|
|
21
|
+
error = _ref.error;
|
|
20
22
|
|
|
21
23
|
var handleChange = function handleChange(e) {
|
|
22
24
|
e.preventDefault();
|
|
@@ -41,7 +43,9 @@ function PageThumbnail(_ref) {
|
|
|
41
43
|
'ps-page-thumbnail-disabled': isLocked
|
|
42
44
|
}),
|
|
43
45
|
onClick: onClick
|
|
44
|
-
}, isLocked && React.createElement(Locker, null), React.createElement(
|
|
46
|
+
}, isLocked && React.createElement(Locker, null), error && React.createElement(Errorer, {
|
|
47
|
+
errorMessage: error.message
|
|
48
|
+
}), React.createElement("div", {
|
|
45
49
|
className: "ps-page-thumbnail-image-wrapper"
|
|
46
50
|
}, React.createElement("img", {
|
|
47
51
|
src: src,
|
|
@@ -83,6 +87,18 @@ function PageThumbnail(_ref) {
|
|
|
83
87
|
})));
|
|
84
88
|
}
|
|
85
89
|
|
|
90
|
+
function isLocked(page) {
|
|
91
|
+
var _Date$parse;
|
|
92
|
+
|
|
93
|
+
var lockedUntil = page.lockedUntil; // needs to be defined and greater than current time
|
|
94
|
+
|
|
95
|
+
if (((_Date$parse = Date.parse(lockedUntil)) === null || _Date$parse === void 0 ? void 0 : _Date$parse.valueOf()) > new Date().valueOf()) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
|
|
86
102
|
function PageSelector(_ref3) {
|
|
87
103
|
var pages = _ref3.pages,
|
|
88
104
|
onPageClick = _ref3.onPageClick,
|
|
@@ -91,9 +107,7 @@ function PageSelector(_ref3) {
|
|
|
91
107
|
recalcActive = _ref3.recalcActive,
|
|
92
108
|
saveActive = _ref3.saveActive,
|
|
93
109
|
onMetadataChange = _ref3.onMetadataChange,
|
|
94
|
-
metadataConfigs = _ref3.metadataConfigs
|
|
95
|
-
_ref3$lockedImages = _ref3.lockedImages,
|
|
96
|
-
lockedImages = _ref3$lockedImages === void 0 ? [] : _ref3$lockedImages;
|
|
110
|
+
metadataConfigs = _ref3.metadataConfigs;
|
|
97
111
|
|
|
98
112
|
var _useState = useState(false),
|
|
99
113
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -134,7 +148,8 @@ function PageSelector(_ref3) {
|
|
|
134
148
|
}, pages.map(function (page, idx) {
|
|
135
149
|
return React.createElement(PageThumbnail, {
|
|
136
150
|
key: "".concat(page.id),
|
|
137
|
-
isLocked:
|
|
151
|
+
isLocked: isLocked(page),
|
|
152
|
+
error: page.syncError,
|
|
138
153
|
src: page.src,
|
|
139
154
|
isActive: page.isActive,
|
|
140
155
|
onClick: function onClick() {
|
package/package.json
CHANGED
package/utils/photosToImages.js
CHANGED
|
@@ -76,7 +76,8 @@ function photosToImages(photos) {
|
|
|
76
76
|
thumbnail: photo.thumbnail.key,
|
|
77
77
|
name: photo.fullsize.key,
|
|
78
78
|
regions: modelResultsToRegions(photo.modelResults.v1),
|
|
79
|
-
metadata: photo.metadata
|
|
79
|
+
metadata: photo.metadata,
|
|
80
|
+
lockedUntil: photo.lockedUntil
|
|
80
81
|
};
|
|
81
82
|
});
|
|
82
83
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var reacalcActionsEnum = ["MOUSE_UP_RESIZE_BOX", "DELETE_REGION", "DELETE_GROUP", "MOUSE_UP_MOVE_REGION"];
|
|
2
|
+
var saveableActionsEnum = [reacalcActionsEnum, "SELECT_CLASSIFICATION", "CHANGE_REGION", "UPDATE_REGIONS", "UPDATE_METADATA", "UPDATE_ALBUM_METADATA"];
|
|
3
|
+
export { saveableActionsEnum, reacalcActionsEnum };
|