box-annotations 4.0.0-beta.8 → 4.0.1-beta.1
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/README.md +7 -57
- package/dist/annotations.css +1 -1
- package/dist/annotations.js +1 -1
- package/i18n/bn-IN.js +6 -0
- package/i18n/bn-IN.properties +12 -0
- package/i18n/da-DK.js +6 -0
- package/i18n/da-DK.properties +12 -0
- package/i18n/de-DE.js +6 -0
- package/i18n/de-DE.properties +12 -0
- package/i18n/en-AU.js +6 -0
- package/i18n/en-AU.properties +12 -0
- package/i18n/en-CA.js +6 -0
- package/i18n/en-CA.properties +12 -0
- package/i18n/en-GB.js +6 -0
- package/i18n/en-GB.properties +12 -0
- package/i18n/en-US.js +6 -0
- package/i18n/en-US.properties +12 -0
- package/i18n/en-x-pseudo.js +16 -9
- package/i18n/en-x-pseudo.properties +23 -9
- package/i18n/es-419.js +6 -0
- package/i18n/es-419.properties +12 -0
- package/i18n/es-ES.js +6 -0
- package/i18n/es-ES.properties +12 -0
- package/i18n/fi-FI.js +6 -0
- package/i18n/fi-FI.properties +12 -0
- package/i18n/fr-CA.js +6 -0
- package/i18n/fr-CA.properties +12 -0
- package/i18n/fr-FR.js +6 -0
- package/i18n/fr-FR.properties +12 -0
- package/i18n/hi-IN.js +6 -0
- package/i18n/hi-IN.properties +12 -0
- package/i18n/it-IT.js +6 -0
- package/i18n/it-IT.properties +12 -0
- package/i18n/ja-JP.js +6 -0
- package/i18n/ja-JP.properties +12 -0
- package/i18n/json/src/components/Popups/messages.json +1 -1
- package/i18n/ko-KR.js +6 -0
- package/i18n/ko-KR.properties +12 -0
- package/i18n/nb-NO.js +6 -0
- package/i18n/nb-NO.properties +12 -0
- package/i18n/nl-NL.js +6 -0
- package/i18n/nl-NL.properties +12 -0
- package/i18n/pl-PL.js +6 -0
- package/i18n/pl-PL.properties +12 -0
- package/i18n/pt-BR.js +6 -0
- package/i18n/pt-BR.properties +12 -0
- package/i18n/ru-RU.js +6 -0
- package/i18n/ru-RU.properties +12 -0
- package/i18n/sv-SE.js +6 -0
- package/i18n/sv-SE.properties +12 -0
- package/i18n/tr-TR.js +6 -0
- package/i18n/tr-TR.properties +12 -0
- package/i18n/zh-CN.js +6 -0
- package/i18n/zh-CN.properties +12 -0
- package/i18n/zh-TW.js +6 -0
- package/i18n/zh-TW.properties +12 -0
- package/package.json +29 -29
- package/src/@types/events.ts +8 -2
- package/src/@types/global.ts +1 -0
- package/src/@types/model.ts +20 -7
- package/src/BoxAnnotations.ts +16 -2
- package/src/common/BaseAnnotator.scss +0 -1
- package/src/common/BaseAnnotator.ts +125 -19
- package/src/common/BaseManager.ts +67 -4
- package/src/common/DeselectListener.tsx +21 -0
- package/src/common/DeselectManager.tsx +30 -0
- package/src/common/useIsListInteractive.ts +10 -0
- package/src/common/useMountId.ts +14 -0
- package/src/common/useOutsideEvent.ts +9 -4
- package/src/common/usePrevious.ts +13 -0
- package/src/components/ItemList/ItemList.scss +7 -2
- package/src/components/ItemList/ItemList.tsx +45 -26
- package/src/components/ItemList/ItemRow.scss +19 -7
- package/src/components/ItemList/ItemRow.tsx +33 -12
- package/src/components/PointerCapture/PointerCapture.tsx +116 -0
- package/src/components/PointerCapture/index.ts +2 -0
- package/src/components/Popups/Popper.ts +1 -0
- package/src/components/Popups/PopupArrow.scss +91 -0
- package/src/components/Popups/PopupBase.scss +12 -81
- package/src/components/Popups/PopupBase.tsx +0 -1
- package/src/components/Popups/PopupCursor.tsx +1 -1
- package/src/components/Popups/PopupDrawingToolbar.scss +76 -0
- package/src/components/Popups/PopupDrawingToolbar.tsx +109 -0
- package/src/components/Popups/PopupHighlight.scss +39 -0
- package/src/components/Popups/PopupHighlight.tsx +97 -0
- package/src/components/Popups/PopupHighlightError.scss +23 -0
- package/src/components/Popups/PopupHighlightError.tsx +74 -0
- package/src/components/Popups/PopupList.scss +1 -4
- package/src/components/Popups/PopupList.tsx +2 -2
- package/src/components/Popups/PopupReply.tsx +51 -6
- package/src/components/Popups/messages.ts +30 -0
- package/src/components/ReplyField/ReplyField.scss +6 -1
- package/src/components/ReplyField/ReplyField.tsx +43 -42
- package/src/components/ReplyField/ReplyFieldContainer.tsx +2 -1
- package/src/components/ReplyForm/ReplyButton.tsx +38 -0
- package/src/components/ReplyForm/ReplyForm.scss +3 -0
- package/src/components/ReplyForm/ReplyForm.tsx +49 -12
- package/src/components/ReplyForm/ReplyFormContainer.tsx +6 -4
- package/src/constants.js +1 -8
- package/src/document/DocumentAnnotator.scss +15 -0
- package/src/document/DocumentAnnotator.ts +110 -53
- package/src/document/docUtil.ts +61 -0
- package/src/drawing/DecoratedDrawingPath.scss +9 -0
- package/src/drawing/DecoratedDrawingPath.tsx +43 -0
- package/src/drawing/DrawingAnnotations.scss +39 -0
- package/src/drawing/DrawingAnnotations.tsx +157 -0
- package/src/drawing/DrawingAnnotationsContainer.tsx +66 -0
- package/src/drawing/DrawingCreator.scss +9 -0
- package/src/drawing/DrawingCreator.tsx +183 -0
- package/src/drawing/DrawingCursor.ts +23 -0
- package/src/drawing/DrawingList.tsx +60 -0
- package/src/drawing/DrawingManager.tsx +15 -0
- package/src/drawing/DrawingPath.tsx +17 -0
- package/src/drawing/DrawingPathGroup.tsx +52 -0
- package/src/drawing/DrawingSVG.tsx +34 -0
- package/src/drawing/DrawingSVGGroup.tsx +23 -0
- package/src/drawing/DrawingTarget.scss +11 -0
- package/src/drawing/DrawingTarget.tsx +100 -0
- package/src/drawing/SVGFilterContext.js +5 -0
- package/src/drawing/actions.ts +48 -0
- package/src/drawing/drawingUtil.ts +106 -0
- package/src/drawing/index.ts +2 -0
- package/src/highlight/HighlightAnnotations.scss +12 -0
- package/src/highlight/HighlightAnnotations.tsx +144 -0
- package/src/highlight/HighlightCanvas.scss +9 -0
- package/src/highlight/HighlightCanvas.tsx +109 -0
- package/src/highlight/HighlightContainer.tsx +64 -0
- package/src/highlight/HighlightCreator.scss +12 -0
- package/src/highlight/HighlightCreatorManager.ts +79 -0
- package/src/highlight/HighlightList.scss +13 -0
- package/src/highlight/HighlightList.tsx +92 -0
- package/src/highlight/HighlightListener.ts +37 -0
- package/src/highlight/HighlightManager.tsx +15 -0
- package/src/highlight/HighlightSvg.scss +7 -0
- package/src/highlight/HighlightSvg.tsx +18 -0
- package/src/highlight/HighlightTarget.scss +5 -0
- package/src/highlight/HighlightTarget.tsx +106 -0
- package/src/highlight/actions.ts +36 -0
- package/src/highlight/highlightUtil.ts +143 -0
- package/src/highlight/index.ts +4 -0
- package/src/image/ImageAnnotator.scss +20 -0
- package/src/image/ImageAnnotator.ts +137 -0
- package/src/polyfill.ts +19 -0
- package/src/popup/PopupContainer.tsx +50 -0
- package/src/popup/PopupLayer.scss +3 -0
- package/src/popup/PopupLayer.tsx +103 -0
- package/src/popup/PopupManager.tsx +15 -0
- package/src/region/RegionAnnotation.scss +4 -0
- package/src/region/RegionAnnotation.tsx +15 -16
- package/src/region/RegionAnnotations.scss +1 -15
- package/src/region/RegionAnnotations.tsx +14 -115
- package/src/region/RegionAnnotationsContainer.tsx +24 -0
- package/src/region/RegionCreation.scss +17 -0
- package/src/region/RegionCreation.tsx +79 -0
- package/src/region/RegionCreationContainer.tsx +43 -0
- package/src/region/RegionCreationManager.tsx +15 -0
- package/src/region/RegionCreator.scss +9 -2
- package/src/region/RegionCreator.tsx +50 -71
- package/src/region/RegionList.tsx +8 -12
- package/src/region/RegionManager.tsx +7 -39
- package/src/region/RegionRect.scss +41 -9
- package/src/region/RegionRect.tsx +9 -3
- package/src/region/index.ts +1 -0
- package/src/region/regionUtil.ts +1 -8
- package/src/region/transformUtil.ts +28 -0
- package/src/store/annotations/actions.ts +1 -0
- package/src/store/annotations/reducer.ts +9 -2
- package/src/store/annotations/selectors.ts +1 -0
- package/src/store/annotations/types.ts +1 -0
- package/src/store/common/actions.ts +1 -0
- package/src/store/common/reducer.ts +16 -10
- package/src/store/common/selectors.ts +1 -0
- package/src/store/common/types.ts +3 -0
- package/src/store/createRootReducer.ts +4 -0
- package/src/store/creator/actions.ts +2 -0
- package/src/store/creator/reducer.ts +22 -3
- package/src/store/creator/selectors.ts +9 -1
- package/src/store/creator/types.ts +18 -3
- package/src/store/drawing/actions.ts +10 -0
- package/src/store/drawing/index.ts +4 -0
- package/src/store/drawing/reducer.ts +50 -0
- package/src/store/drawing/selectors.ts +9 -0
- package/src/store/drawing/types.ts +7 -0
- package/src/store/eventing/active.ts +4 -2
- package/src/store/eventing/fetch.ts +8 -0
- package/src/store/eventing/init.ts +14 -0
- package/src/store/eventing/middleware.ts +21 -3
- package/src/store/eventing/mode.ts +7 -0
- package/src/store/eventing/staged.ts +56 -0
- package/src/store/eventing/status.ts +19 -0
- package/src/store/highlight/actions.ts +106 -0
- package/src/store/highlight/index.ts +4 -0
- package/src/store/highlight/reducer.ts +37 -0
- package/src/store/highlight/selectors.ts +12 -0
- package/src/store/highlight/types.ts +14 -0
- package/src/store/index.ts +2 -0
- package/src/store/options/actions.ts +2 -0
- package/src/store/options/reducer.ts +17 -1
- package/src/store/options/selectors.ts +8 -0
- package/src/store/options/types.ts +5 -0
- package/src/store/types.ts +5 -1
- package/src/store/users/actions.ts +3 -2
- package/src/utils/resin.ts +22 -0
- package/src/utils/rotate.ts +131 -0
- package/src/utils/scroll.ts +45 -0
- package/src/utils/util.ts +3 -0
- package/src/region/RegionContainer.tsx +0 -49
- package/src/utils/polyfill.js +0 -161
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bdlBoxBlue } from 'box-ui-elements/es/styles/variables';
|
|
2
|
+
import { createReducer } from '@reduxjs/toolkit';
|
|
2
3
|
import { CommonState, Mode } from './types';
|
|
3
|
-
import { toggleAnnotationModeAction } from './actions';
|
|
4
|
+
import { setColorAction, toggleAnnotationModeAction } from './actions';
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
);
|
|
6
|
+
export const initialState = {
|
|
7
|
+
color: bdlBoxBlue,
|
|
8
|
+
mode: Mode.NONE,
|
|
9
|
+
};
|
|
10
10
|
|
|
11
|
-
export default
|
|
12
|
-
|
|
13
|
-
})
|
|
11
|
+
export default createReducer<CommonState>(initialState, builder =>
|
|
12
|
+
builder
|
|
13
|
+
.addCase(setColorAction, (state, { payload }) => {
|
|
14
|
+
state.color = payload;
|
|
15
|
+
})
|
|
16
|
+
.addCase(toggleAnnotationModeAction, (state, { payload }) => {
|
|
17
|
+
state.mode = payload;
|
|
18
|
+
}),
|
|
19
|
+
);
|
|
@@ -2,6 +2,8 @@ import { combineReducers, Reducer } from 'redux';
|
|
|
2
2
|
import { annotationsReducer } from './annotations';
|
|
3
3
|
import { commonReducer } from './common';
|
|
4
4
|
import { creatorReducer } from './creator';
|
|
5
|
+
import { drawingReducer } from './drawing';
|
|
6
|
+
import { highlightReducer } from './highlight';
|
|
5
7
|
import { optionsReducer } from './options';
|
|
6
8
|
import { usersReducer } from './users';
|
|
7
9
|
|
|
@@ -10,6 +12,8 @@ const createRootReducer = (): Reducer =>
|
|
|
10
12
|
annotations: annotationsReducer,
|
|
11
13
|
common: commonReducer,
|
|
12
14
|
creator: creatorReducer,
|
|
15
|
+
drawing: drawingReducer,
|
|
16
|
+
highlight: highlightReducer,
|
|
13
17
|
options: optionsReducer,
|
|
14
18
|
users: usersReducer,
|
|
15
19
|
});
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createAction } from '@reduxjs/toolkit';
|
|
2
2
|
import { CreatorItem, CreatorStatus } from './types';
|
|
3
3
|
|
|
4
|
+
export const resetCreatorAction = createAction('RESET_CREATOR');
|
|
4
5
|
export const setCursorAction = createAction<number>('SET_CREATOR_CURSOR');
|
|
5
6
|
export const setMessageAction = createAction<string>('SET_CREATOR_MESSAGE');
|
|
7
|
+
export const setReferenceIdAction = createAction<string>('SET_CREATOR_REFERENCE_ID');
|
|
6
8
|
export const setStagedAction = createAction<CreatorItem | null>('SET_CREATOR_STAGED');
|
|
7
9
|
export const setStatusAction = createAction<CreatorStatus>('SET_CREATOR_STATUS');
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { createReducer } from '@reduxjs/toolkit';
|
|
2
|
-
import { CreatorState, CreatorStatus } from './types';
|
|
3
2
|
import { createAnnotationAction } from '../annotations';
|
|
4
|
-
import {
|
|
3
|
+
import { CreatorState, CreatorStatus } from './types';
|
|
4
|
+
import {
|
|
5
|
+
resetCreatorAction,
|
|
6
|
+
setCursorAction,
|
|
7
|
+
setMessageAction,
|
|
8
|
+
setReferenceIdAction,
|
|
9
|
+
setStagedAction,
|
|
10
|
+
setStatusAction,
|
|
11
|
+
} from './actions';
|
|
12
|
+
import { toggleAnnotationModeAction } from '../common';
|
|
5
13
|
|
|
6
14
|
export const initialState = {
|
|
7
15
|
cursor: 0,
|
|
8
16
|
error: null,
|
|
9
17
|
message: '',
|
|
18
|
+
referenceId: null,
|
|
10
19
|
staged: null,
|
|
11
20
|
status: CreatorStatus.init,
|
|
12
21
|
};
|
|
@@ -22,9 +31,18 @@ export default createReducer<CreatorState>(initialState, builder =>
|
|
|
22
31
|
state.error = error;
|
|
23
32
|
state.status = CreatorStatus.rejected;
|
|
24
33
|
})
|
|
34
|
+
.addCase(resetCreatorAction, state => {
|
|
35
|
+
state.message = '';
|
|
36
|
+
state.referenceId = null;
|
|
37
|
+
state.staged = null;
|
|
38
|
+
state.status = CreatorStatus.init;
|
|
39
|
+
})
|
|
25
40
|
.addCase(setMessageAction, (state, { payload }) => {
|
|
26
41
|
state.message = payload;
|
|
27
42
|
})
|
|
43
|
+
.addCase(setReferenceIdAction, (state, { payload }) => {
|
|
44
|
+
state.referenceId = payload;
|
|
45
|
+
})
|
|
28
46
|
.addCase(setStagedAction, (state, { payload }) => {
|
|
29
47
|
state.staged = payload;
|
|
30
48
|
})
|
|
@@ -33,5 +51,6 @@ export default createReducer<CreatorState>(initialState, builder =>
|
|
|
33
51
|
})
|
|
34
52
|
.addCase(setCursorAction, (state, { payload }) => {
|
|
35
53
|
state.cursor = payload;
|
|
36
|
-
})
|
|
54
|
+
})
|
|
55
|
+
.addCase(toggleAnnotationModeAction, () => initialState),
|
|
37
56
|
);
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { AppState } from '../types';
|
|
2
|
-
import { CreatorItem, CreatorStatus } from './types';
|
|
2
|
+
import { CreatorItem, CreatorItemDrawing, CreatorItemHighlight, CreatorItemRegion, CreatorStatus } from './types';
|
|
3
3
|
|
|
4
4
|
type State = Pick<AppState, 'creator'>;
|
|
5
5
|
|
|
6
6
|
export const getCreatorCursor = (state: State): number => state.creator.cursor;
|
|
7
7
|
export const getCreatorMessage = (state: State): string => state.creator.message;
|
|
8
|
+
export const getCreatorReferenceId = (state: State): string | null => state.creator.referenceId;
|
|
8
9
|
export const getCreatorStaged = (state: State): CreatorItem | null => state.creator.staged;
|
|
9
10
|
export const getCreatorStagedForLocation = (state: State, location: number): CreatorItem | null => {
|
|
10
11
|
const staged = getCreatorStaged(state);
|
|
11
12
|
return staged && staged.location === location ? staged : null;
|
|
12
13
|
};
|
|
13
14
|
export const getCreatorStatus = (state: State): CreatorStatus => state.creator.status;
|
|
15
|
+
|
|
16
|
+
export const isCreatorStagedDrawing = (staged: CreatorItem | null): staged is CreatorItemDrawing =>
|
|
17
|
+
(staged as CreatorItemDrawing)?.pathGroups !== undefined;
|
|
18
|
+
export const isCreatorStagedHighlight = (staged: CreatorItem | null): staged is CreatorItemHighlight =>
|
|
19
|
+
(staged as CreatorItemHighlight)?.shapes !== undefined;
|
|
20
|
+
export const isCreatorStagedRegion = (staged: CreatorItem | null): staged is CreatorItemRegion =>
|
|
21
|
+
(staged as CreatorItemRegion)?.shape !== undefined;
|
|
@@ -1,21 +1,36 @@
|
|
|
1
|
-
import { Rect, SerializedError } from '../../@types';
|
|
1
|
+
import { PathGroup, Rect, SerializedError } from '../../@types';
|
|
2
2
|
|
|
3
3
|
export enum CreatorStatus {
|
|
4
4
|
init = 'init',
|
|
5
5
|
pending = 'pending',
|
|
6
6
|
rejected = 'rejected',
|
|
7
7
|
staged = 'staged',
|
|
8
|
+
started = 'started',
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
export type
|
|
11
|
+
export type CreatorItemBase = {
|
|
11
12
|
location: number;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type CreatorItemRegion = CreatorItemBase & {
|
|
12
16
|
shape: Rect;
|
|
13
17
|
};
|
|
14
18
|
|
|
19
|
+
export type CreatorItemHighlight = CreatorItemBase & {
|
|
20
|
+
shapes: Rect[];
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type CreatorItemDrawing = CreatorItemBase & {
|
|
24
|
+
pathGroups: Array<PathGroup>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type CreatorItem = CreatorItemRegion | CreatorItemHighlight | CreatorItemDrawing | null;
|
|
28
|
+
|
|
15
29
|
export type CreatorState = {
|
|
16
30
|
cursor: number;
|
|
17
31
|
error: SerializedError | null;
|
|
18
32
|
message: string;
|
|
19
|
-
|
|
33
|
+
referenceId: string | null;
|
|
34
|
+
staged: CreatorItem;
|
|
20
35
|
status: CreatorStatus;
|
|
21
36
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createAction } from '@reduxjs/toolkit';
|
|
2
|
+
import { addClientIds } from '../../drawing/drawingUtil';
|
|
3
|
+
|
|
4
|
+
export const addDrawingPathGroupAction = createAction('ADD_DRAWING_PATH_GROUP', pathGroup => ({
|
|
5
|
+
payload: addClientIds(pathGroup),
|
|
6
|
+
}));
|
|
7
|
+
export const redoDrawingPathGroupAction = createAction('REDO_DRAWING_PATH_GROUP');
|
|
8
|
+
export const resetDrawingAction = createAction('RESET_DRAWING');
|
|
9
|
+
export const setDrawingLocationAction = createAction<number>('SET_DRAWING_LOCATION');
|
|
10
|
+
export const undoDrawingPathGroupAction = createAction('UNDO_DRAWING_PATH_GROUP');
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createReducer } from '@reduxjs/toolkit';
|
|
2
|
+
import { createAnnotationAction } from '../annotations';
|
|
3
|
+
import { toggleAnnotationModeAction } from '../common';
|
|
4
|
+
import { resetCreatorAction } from '../creator';
|
|
5
|
+
import {
|
|
6
|
+
addDrawingPathGroupAction,
|
|
7
|
+
redoDrawingPathGroupAction,
|
|
8
|
+
resetDrawingAction,
|
|
9
|
+
setDrawingLocationAction,
|
|
10
|
+
undoDrawingPathGroupAction,
|
|
11
|
+
} from './actions';
|
|
12
|
+
import { DrawingState } from './types';
|
|
13
|
+
|
|
14
|
+
export const initialState = {
|
|
15
|
+
drawnPathGroups: [],
|
|
16
|
+
location: 0,
|
|
17
|
+
stashedPathGroups: [],
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default createReducer<DrawingState>(initialState, builder =>
|
|
21
|
+
builder
|
|
22
|
+
.addCase(createAnnotationAction.fulfilled, () => initialState)
|
|
23
|
+
.addCase(addDrawingPathGroupAction, (state, { payload }) => {
|
|
24
|
+
state.drawnPathGroups.push(payload);
|
|
25
|
+
state.stashedPathGroups = [];
|
|
26
|
+
})
|
|
27
|
+
.addCase(redoDrawingPathGroupAction, state => {
|
|
28
|
+
const pathGroup = state.stashedPathGroups.pop();
|
|
29
|
+
|
|
30
|
+
if (pathGroup) {
|
|
31
|
+
state.drawnPathGroups.push(pathGroup);
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
.addCase(resetCreatorAction, () => initialState) // Needed for when `PopupReply` is cancelled
|
|
35
|
+
.addCase(resetDrawingAction, () => initialState)
|
|
36
|
+
.addCase(setDrawingLocationAction, (state, { payload }) => {
|
|
37
|
+
if (state.location !== payload) {
|
|
38
|
+
state.location = payload;
|
|
39
|
+
state.drawnPathGroups = [];
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
.addCase(toggleAnnotationModeAction, () => initialState)
|
|
43
|
+
.addCase(undoDrawingPathGroupAction, state => {
|
|
44
|
+
const pathGroup = state.drawnPathGroups.pop();
|
|
45
|
+
|
|
46
|
+
if (pathGroup) {
|
|
47
|
+
state.stashedPathGroups.push(pathGroup);
|
|
48
|
+
}
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PathGroup } from '../../@types';
|
|
2
|
+
import { AppState } from '../types';
|
|
3
|
+
|
|
4
|
+
type State = Pick<AppState, 'drawing'>;
|
|
5
|
+
|
|
6
|
+
export const getDrawingDrawnPathGroupsForLocation = (state: State, location: number): Array<PathGroup> =>
|
|
7
|
+
state.drawing.location === location ? state.drawing.drawnPathGroups : [];
|
|
8
|
+
export const getStashedDrawnPathGroupsForLocation = (state: State, location: number): Array<PathGroup> =>
|
|
9
|
+
state.drawing.location === location ? state.drawing.stashedPathGroups : [];
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import eventManager from '../../common/EventManager';
|
|
2
2
|
import { AppState } from '../types';
|
|
3
|
-
import { getActiveAnnotationId } from '../annotations';
|
|
4
3
|
import { Event } from '../../@types';
|
|
4
|
+
import { getActiveAnnotationId } from '../annotations';
|
|
5
|
+
import { getFileVersionId } from '../options';
|
|
5
6
|
|
|
6
7
|
const handleActiveAnnotationEvents = (prevState: AppState, nextState: AppState): void => {
|
|
7
8
|
const prevActiveAnnotationId = getActiveAnnotationId(prevState);
|
|
8
9
|
const nextActiveAnnotationId = getActiveAnnotationId(nextState);
|
|
10
|
+
const fileVersionId = getFileVersionId(nextState);
|
|
9
11
|
|
|
10
12
|
if (prevActiveAnnotationId !== nextActiveAnnotationId) {
|
|
11
|
-
eventManager.emit(Event.ACTIVE_CHANGE, nextActiveAnnotationId);
|
|
13
|
+
eventManager.emit(Event.ACTIVE_CHANGE, { annotationId: nextActiveAnnotationId, fileVersionId });
|
|
12
14
|
}
|
|
13
15
|
};
|
|
14
16
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import eventManager from '../../common/EventManager';
|
|
2
|
+
import { AppState } from '../types';
|
|
3
|
+
import { AsyncAction } from './types';
|
|
4
|
+
import { Event } from '../../@types';
|
|
5
|
+
|
|
6
|
+
export const handleFetchErrorEvents = (prevState: AppState, nextState: AppState, action: AsyncAction): void => {
|
|
7
|
+
eventManager.emit(Event.ANNOTATION_FETCH_ERROR, action);
|
|
8
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import eventManager from '../../common/EventManager';
|
|
2
|
+
import { AppState } from '../types';
|
|
3
|
+
import { Event } from '../../@types';
|
|
4
|
+
import { getAnnotations, getIsInitialized } from '../annotations';
|
|
5
|
+
|
|
6
|
+
export const handleAnnotationsInitialized = (prevState: AppState, nextState: AppState): void => {
|
|
7
|
+
const prevIsInitialized = getIsInitialized(prevState);
|
|
8
|
+
const nextIsInitialized = getIsInitialized(nextState);
|
|
9
|
+
|
|
10
|
+
// Only emit an event the first time the library is initialized/rendered
|
|
11
|
+
if (prevIsInitialized !== nextIsInitialized && nextIsInitialized) {
|
|
12
|
+
eventManager.emit(Event.ANNOTATIONS_INITIALIZED, { annotations: getAnnotations(nextState) });
|
|
13
|
+
}
|
|
14
|
+
};
|
|
@@ -1,16 +1,34 @@
|
|
|
1
1
|
import noop from 'lodash/noop';
|
|
2
2
|
import { Action, Dispatch, Middleware, MiddlewareAPI } from '@reduxjs/toolkit';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
createAnnotationAction,
|
|
5
|
+
fetchAnnotationsAction,
|
|
6
|
+
setActiveAnnotationIdAction,
|
|
7
|
+
setIsInitialized,
|
|
8
|
+
} from '../annotations/actions';
|
|
9
|
+
import { EventHandlerMap } from './types';
|
|
4
10
|
import { handleActiveAnnotationEvents } from './active';
|
|
11
|
+
import { handleAnnotationsInitialized } from './init';
|
|
5
12
|
import { handleCreateErrorEvents, handleCreatePendingEvents, handleCreateSuccessEvents } from './create';
|
|
6
|
-
import {
|
|
13
|
+
import { handleFetchErrorEvents } from './fetch';
|
|
14
|
+
import { handleResetCreatorAction, handleSetStagedAction } from './staged';
|
|
15
|
+
import { handleSetStatusAction } from './status';
|
|
16
|
+
import { handleToggleAnnotationModeAction } from './mode';
|
|
17
|
+
import { resetCreatorAction, setStagedAction, setStatusAction } from '../creator';
|
|
18
|
+
import { toggleAnnotationModeAction } from '../common/actions';
|
|
7
19
|
|
|
8
20
|
// Array of event handlers based on redux action. To add handling for new events add an entry keyed by action
|
|
9
21
|
const eventHandlers: EventHandlerMap = {
|
|
10
|
-
[createAnnotationAction.pending.toString()]: handleCreatePendingEvents,
|
|
11
22
|
[createAnnotationAction.fulfilled.toString()]: handleCreateSuccessEvents,
|
|
23
|
+
[createAnnotationAction.pending.toString()]: handleCreatePendingEvents,
|
|
12
24
|
[createAnnotationAction.rejected.toString()]: handleCreateErrorEvents,
|
|
25
|
+
[fetchAnnotationsAction.rejected.toString()]: handleFetchErrorEvents,
|
|
26
|
+
[resetCreatorAction.toString()]: handleResetCreatorAction,
|
|
13
27
|
[setActiveAnnotationIdAction.toString()]: handleActiveAnnotationEvents,
|
|
28
|
+
[setIsInitialized.toString()]: handleAnnotationsInitialized,
|
|
29
|
+
[setStagedAction.toString()]: handleSetStagedAction,
|
|
30
|
+
[setStatusAction.toString()]: handleSetStatusAction,
|
|
31
|
+
[toggleAnnotationModeAction.toString()]: handleToggleAnnotationModeAction,
|
|
14
32
|
};
|
|
15
33
|
|
|
16
34
|
function getEventingMiddleware(handlers: EventHandlerMap = eventHandlers): Middleware {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import eventManager from '../../common/EventManager';
|
|
2
|
+
import { AppState } from '../types';
|
|
3
|
+
import { Event } from '../../@types';
|
|
4
|
+
|
|
5
|
+
export const handleToggleAnnotationModeAction = (prevState: AppState, nextState: AppState): void => {
|
|
6
|
+
eventManager.emit(Event.ANNOTATIONS_MODE_CHANGE, { mode: nextState.common.mode });
|
|
7
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import eventManager from '../../common/EventManager';
|
|
2
|
+
import { AppState } from '../types';
|
|
3
|
+
import { CreatorItem, getCreatorStaged, isCreatorStagedHighlight, isCreatorStagedRegion } from '../creator';
|
|
4
|
+
import { Event } from '../../@types';
|
|
5
|
+
|
|
6
|
+
type Status = 'create' | 'update' | 'cancel';
|
|
7
|
+
|
|
8
|
+
type Type = 'highlight' | 'region';
|
|
9
|
+
|
|
10
|
+
export const getStatus = (prevStaged: CreatorItem, nextStaged: CreatorItem): Status | null => {
|
|
11
|
+
let status: Status | null = null;
|
|
12
|
+
|
|
13
|
+
if (prevStaged === null && nextStaged !== null) {
|
|
14
|
+
status = 'create';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (prevStaged !== null) {
|
|
18
|
+
status = nextStaged === null ? 'cancel' : 'update';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return status;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const getType = (staged: CreatorItem): Type | null => {
|
|
25
|
+
let type: Type | null = null;
|
|
26
|
+
|
|
27
|
+
if (isCreatorStagedRegion(staged)) {
|
|
28
|
+
type = 'region';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (isCreatorStagedHighlight(staged)) {
|
|
32
|
+
type = 'highlight';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return type;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const handleSetStagedAction = (prevState: AppState, nextState: AppState): void => {
|
|
39
|
+
const prevStaged = getCreatorStaged(prevState);
|
|
40
|
+
const nextStaged = getCreatorStaged(nextState);
|
|
41
|
+
const status = getStatus(prevStaged, nextStaged);
|
|
42
|
+
const type = getType(prevStaged) || getType(nextStaged);
|
|
43
|
+
|
|
44
|
+
if (!status || !type) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
eventManager.emit(Event.CREATOR_STAGED_CHANGE, { type, status });
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const handleResetCreatorAction = (prevState: AppState): void => {
|
|
52
|
+
const prevStaged = getCreatorStaged(prevState);
|
|
53
|
+
const type = getType(prevStaged);
|
|
54
|
+
|
|
55
|
+
eventManager.emit(Event.CREATOR_STAGED_CHANGE, { type, status: 'cancel' });
|
|
56
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import eventManager from '../../common/EventManager';
|
|
2
|
+
import { AppState } from '../types';
|
|
3
|
+
import { Event } from '../../@types';
|
|
4
|
+
import { getAnnotationMode } from '../common';
|
|
5
|
+
import { getCreatorStatus } from '../creator';
|
|
6
|
+
|
|
7
|
+
export const handleSetStatusAction = (prevState: AppState, nextState: AppState): void => {
|
|
8
|
+
const prevStatus = getCreatorStatus(prevState);
|
|
9
|
+
const nextStatus = getCreatorStatus(nextState);
|
|
10
|
+
|
|
11
|
+
if (prevStatus === nextStatus) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
eventManager.emit(Event.CREATOR_STATUS_CHANGE, {
|
|
16
|
+
status: nextStatus,
|
|
17
|
+
type: getAnnotationMode(nextState),
|
|
18
|
+
});
|
|
19
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { createAction } from '@reduxjs/toolkit';
|
|
2
|
+
import { combineRects } from '../../highlight/highlightUtil';
|
|
3
|
+
import { SelectionItem } from './types';
|
|
4
|
+
import { Shape } from '../../@types';
|
|
5
|
+
|
|
6
|
+
export type SelectionArg = {
|
|
7
|
+
containerRect: DOMRect;
|
|
8
|
+
hasError?: boolean;
|
|
9
|
+
location: number;
|
|
10
|
+
range: Range;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type Payload = {
|
|
14
|
+
payload: SelectionItem | null;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
declare global {
|
|
18
|
+
interface Document {
|
|
19
|
+
createNodeIterator(
|
|
20
|
+
root: Node,
|
|
21
|
+
whatToShow?: number,
|
|
22
|
+
filter?: NodeFilter | Function,
|
|
23
|
+
entityReferenceExpansion?: boolean,
|
|
24
|
+
): NodeIterator;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const getClientRects = (range: Range): DOMRect[] => {
|
|
29
|
+
const iterator = document.createNodeIterator(
|
|
30
|
+
range.commonAncestorContainer,
|
|
31
|
+
NodeFilter.SHOW_ALL,
|
|
32
|
+
function acceptNode() {
|
|
33
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
34
|
+
},
|
|
35
|
+
false,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const newRange = document.createRange();
|
|
39
|
+
const rects = [];
|
|
40
|
+
let currentNode = iterator.nextNode();
|
|
41
|
+
while (currentNode) {
|
|
42
|
+
if (rects.length === 0 && currentNode !== range.startContainer) {
|
|
43
|
+
currentNode = iterator.nextNode();
|
|
44
|
+
// eslint-disable-next-line no-continue
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Only highlight Text nodes
|
|
49
|
+
if (currentNode.nodeType === Node.TEXT_NODE) {
|
|
50
|
+
newRange.selectNodeContents(currentNode);
|
|
51
|
+
if (currentNode === range.startContainer) {
|
|
52
|
+
newRange.setStart(currentNode, range.startOffset);
|
|
53
|
+
}
|
|
54
|
+
if (currentNode === range.endContainer) {
|
|
55
|
+
newRange.setEnd(currentNode, range.endOffset);
|
|
56
|
+
}
|
|
57
|
+
rects.push(newRange.getBoundingClientRect());
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (currentNode === range.endContainer) {
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
currentNode = iterator.nextNode();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return rects;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const getShape = ({ height, left, top, width }: DOMRect): Shape => ({
|
|
71
|
+
height,
|
|
72
|
+
width,
|
|
73
|
+
x: left,
|
|
74
|
+
y: top,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
export const setSelectionAction = createAction(
|
|
78
|
+
'SET_SELECTION',
|
|
79
|
+
(arg: SelectionArg | null): Payload => {
|
|
80
|
+
if (!arg) {
|
|
81
|
+
return {
|
|
82
|
+
payload: null,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const { containerRect, hasError, location, range } = arg;
|
|
87
|
+
|
|
88
|
+
let rects = Array.from(range.getClientRects());
|
|
89
|
+
// getClientRects on IE/Edge might return 0 rects
|
|
90
|
+
if (!rects.length) {
|
|
91
|
+
rects = getClientRects(range);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
payload: {
|
|
96
|
+
containerRect: getShape(containerRect),
|
|
97
|
+
hasError,
|
|
98
|
+
location,
|
|
99
|
+
rects: combineRects(rects.map(getShape)),
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
export const setIsPromotingAction = createAction<boolean>('SET_IS_PROMOTING');
|
|
106
|
+
export const setIsSelectingAction = createAction<boolean>('SET_IS_SELECTING');
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createReducer } from '@reduxjs/toolkit';
|
|
2
|
+
import { createAnnotationAction } from '../annotations';
|
|
3
|
+
import { HighlightState } from './types';
|
|
4
|
+
import { resetCreatorAction, setStatusAction } from '../creator';
|
|
5
|
+
import { setIsPromotingAction, setIsSelectingAction, setSelectionAction } from './actions';
|
|
6
|
+
import { toggleAnnotationModeAction } from '../common';
|
|
7
|
+
|
|
8
|
+
export const initialState = {
|
|
9
|
+
isPromoting: false,
|
|
10
|
+
isSelecting: false,
|
|
11
|
+
selection: null,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default createReducer<HighlightState>(initialState, builder =>
|
|
15
|
+
builder
|
|
16
|
+
.addCase(setIsPromotingAction, (state, { payload }) => {
|
|
17
|
+
state.isPromoting = payload;
|
|
18
|
+
})
|
|
19
|
+
.addCase(setIsSelectingAction, (state, { payload }) => {
|
|
20
|
+
state.isSelecting = payload;
|
|
21
|
+
})
|
|
22
|
+
.addCase(setSelectionAction, (state, { payload }) => {
|
|
23
|
+
state.selection = payload;
|
|
24
|
+
})
|
|
25
|
+
.addCase(createAnnotationAction.fulfilled, state => {
|
|
26
|
+
state.isPromoting = false;
|
|
27
|
+
})
|
|
28
|
+
.addCase(resetCreatorAction, state => {
|
|
29
|
+
state.isPromoting = false;
|
|
30
|
+
})
|
|
31
|
+
.addCase(toggleAnnotationModeAction, state => {
|
|
32
|
+
state.isPromoting = false;
|
|
33
|
+
})
|
|
34
|
+
.addCase(setStatusAction, state => {
|
|
35
|
+
state.selection = null;
|
|
36
|
+
}),
|
|
37
|
+
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AppState } from '../types';
|
|
2
|
+
import { SelectionItem } from './types';
|
|
3
|
+
|
|
4
|
+
type State = Pick<AppState, 'highlight'>;
|
|
5
|
+
|
|
6
|
+
export const getIsPromoting = (state: State): boolean => state.highlight.isPromoting;
|
|
7
|
+
export const getIsSelecting = (state: State): boolean => state.highlight.isSelecting;
|
|
8
|
+
export const getSelection = (state: State): SelectionItem | null => state.highlight.selection;
|
|
9
|
+
export const getSelectionForLocation = (state: State, location: number): SelectionItem | null => {
|
|
10
|
+
const selection = getSelection(state);
|
|
11
|
+
return selection && selection.location === location ? selection : null;
|
|
12
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Shape } from '../../@types';
|
|
2
|
+
|
|
3
|
+
export type HighlightState = {
|
|
4
|
+
isPromoting: boolean;
|
|
5
|
+
isSelecting: boolean;
|
|
6
|
+
selection: SelectionItem | null;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type SelectionItem = {
|
|
10
|
+
containerRect: Shape;
|
|
11
|
+
hasError?: boolean;
|
|
12
|
+
location: number;
|
|
13
|
+
rects: Array<Shape>;
|
|
14
|
+
};
|
package/src/store/index.ts
CHANGED
|
@@ -4,3 +4,5 @@ import { Permissions } from '../../@types';
|
|
|
4
4
|
export const setFileIdAction = createAction<string | null>('SET_FIlE_ID');
|
|
5
5
|
export const setFileVersionIdAction = createAction<string | null>('SET_FILE_VERSION_ID');
|
|
6
6
|
export const setPermissionsAction = createAction<Permissions>('SET_PERMISSIONS');
|
|
7
|
+
export const setRotationAction = createAction<number>('SET_ROTATION');
|
|
8
|
+
export const setScaleAction = createAction<number>('SET_SCALE');
|