box-annotations 5.3.0 → 5.3.1-beta.0

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.
Files changed (94) hide show
  1. package/dist/annotations.css +1 -1
  2. package/dist/annotations.js +1 -1
  3. package/dist/annotations.js.LICENSE.txt +0 -9
  4. package/i18n/bn-IN.js +6 -0
  5. package/i18n/bn-IN.properties +12 -0
  6. package/i18n/da-DK.js +6 -0
  7. package/i18n/da-DK.properties +12 -0
  8. package/i18n/de-DE.js +6 -0
  9. package/i18n/de-DE.properties +12 -0
  10. package/i18n/en-AU.js +6 -0
  11. package/i18n/en-AU.properties +12 -0
  12. package/i18n/en-CA.js +6 -0
  13. package/i18n/en-CA.properties +12 -0
  14. package/i18n/en-GB.js +6 -0
  15. package/i18n/en-GB.properties +12 -0
  16. package/i18n/es-419.js +6 -0
  17. package/i18n/es-419.properties +12 -0
  18. package/i18n/es-ES.js +6 -0
  19. package/i18n/es-ES.properties +12 -0
  20. package/i18n/fi-FI.js +6 -0
  21. package/i18n/fi-FI.properties +12 -0
  22. package/i18n/fr-CA.js +6 -0
  23. package/i18n/fr-CA.properties +12 -0
  24. package/i18n/fr-FR.js +6 -0
  25. package/i18n/fr-FR.properties +12 -0
  26. package/i18n/hi-IN.js +6 -0
  27. package/i18n/hi-IN.properties +12 -0
  28. package/i18n/it-IT.js +6 -0
  29. package/i18n/it-IT.properties +12 -0
  30. package/i18n/ja-JP.js +7 -1
  31. package/i18n/ja-JP.properties +13 -1
  32. package/i18n/ko-KR.js +6 -0
  33. package/i18n/ko-KR.properties +12 -0
  34. package/i18n/nb-NO.js +6 -0
  35. package/i18n/nb-NO.properties +12 -0
  36. package/i18n/nl-NL.js +6 -0
  37. package/i18n/nl-NL.properties +12 -0
  38. package/i18n/pl-PL.js +6 -0
  39. package/i18n/pl-PL.properties +12 -0
  40. package/i18n/pt-BR.js +6 -0
  41. package/i18n/pt-BR.properties +12 -0
  42. package/i18n/ru-RU.js +6 -0
  43. package/i18n/ru-RU.properties +12 -0
  44. package/i18n/sv-SE.js +6 -0
  45. package/i18n/sv-SE.properties +12 -0
  46. package/i18n/tr-TR.js +6 -0
  47. package/i18n/tr-TR.properties +12 -0
  48. package/i18n/zh-CN.js +6 -0
  49. package/i18n/zh-CN.properties +12 -0
  50. package/i18n/zh-TW.js +6 -0
  51. package/i18n/zh-TW.properties +12 -0
  52. package/package.json +23 -22
  53. package/src/BoxAnnotations.ts +1 -1
  54. package/src/adapters/threadedAnnotationsAdapters.ts +10 -2
  55. package/src/boundingBoxHighlight/BoundingBoxHighlightContainer.tsx +4 -1
  56. package/src/common/BaseAnnotator.scss +1 -1
  57. package/src/common/DeselectListener.tsx +1 -1
  58. package/src/components/BoundingBoxHighlight/BoundingBoxHighlightNav.scss +3 -3
  59. package/src/components/BoundingBoxHighlight/BoundingBoxHighlightRect.scss +11 -6
  60. package/src/components/Popups/PopupBase.scss +2 -2
  61. package/src/components/Popups/PopupDrawingToolbar.scss +4 -4
  62. package/src/components/Popups/PopupList.scss +1 -1
  63. package/src/components/Popups/PopupV2.scss +2 -2
  64. package/src/components/Popups/PopupV2.tsx +30 -43
  65. package/src/components/ReplyForm/ReplyForm.tsx +1 -8
  66. package/src/constants.ts +2 -3
  67. package/src/document/DocumentAnnotator.ts +28 -5
  68. package/src/document/docUtil.ts +7 -1
  69. package/src/drawing/DrawingAnnotations.tsx +24 -24
  70. package/src/drawing/DrawingCursor.ts +2 -1
  71. package/src/drawing/DrawingManager.tsx +9 -1
  72. package/src/highlight/HighlightAnnotations.tsx +23 -22
  73. package/src/highlight/HighlightCreator.scss +9 -2
  74. package/src/media/MediaAnnotator.ts +38 -16
  75. package/src/popup/PopupLayer.tsx +1 -5
  76. package/src/region/RegionAnnotations.tsx +2 -3
  77. package/src/region/RegionCreation.tsx +4 -1
  78. package/src/region/RegionCreationManager.tsx +8 -1
  79. package/src/region/RegionCreator.scss +9 -3
  80. package/src/region/RegionManager.tsx +8 -1
  81. package/src/region/RegionRect.scss +17 -9
  82. package/src/store/annotations/actions.ts +86 -104
  83. package/src/store/annotations/reducer.ts +4 -4
  84. package/src/store/creator/selectors.ts +6 -6
  85. package/src/store/eventing/create.ts +4 -2
  86. package/src/store/eventing/delete.ts +4 -5
  87. package/src/store/eventing/middleware.ts +13 -11
  88. package/src/store/eventing/replyCreate.ts +6 -10
  89. package/src/store/eventing/replyDelete.ts +5 -9
  90. package/src/store/eventing/replyUpdate.ts +6 -10
  91. package/src/store/eventing/update.ts +5 -6
  92. package/src/store/highlight/actions.ts +43 -41
  93. package/src/test-utils/videoAnnotations.tsx +11 -11
  94. package/src/utils/useVideoTiming.ts +9 -13
@@ -2,7 +2,7 @@
2
2
 
3
3
  $ba-RegionRect-color: $bdl-yellorange;
4
4
  $ba-RegionRect-bgColor--default: rgba($ba-RegionRect-color, 0); // Default color uses zero alpha value for transition
5
- $ba-RegionRect-bgColor--hover: rgba($ba-RegionRect-color, .1);
5
+ $ba-RegionRect-bgColor--hover: rgba($ba-RegionRect-color, 0.1);
6
6
  $ba-RegionRect-bgColor--active: rgba($ba-RegionRect-color, 0);
7
7
  $ba-RegionRect-transitionDelay: 25ms;
8
8
  $ba-RegionRect-transitionDuration: 200ms;
@@ -21,29 +21,37 @@ $ba-RegionRect-transitionDuration: 200ms;
21
21
 
22
22
  &::after {
23
23
  position: absolute;
24
- top: $border-size-outer;
25
- right: $border-size-outer;
26
- bottom: $border-size-outer;
27
- left: $border-size-outer;
24
+ inset: $border-size-outer;
28
25
  display: block;
29
26
  background-color: $ba-RegionRect-bgColor--default;
30
27
  border-radius: $border-radius;
31
- box-shadow: 0 0 0 $border-size-inner rgba($white, 1), 0 0 0 $border-size-outer rgba($ba-RegionRect-color, .6), 0 0 0 0 rgba(0, 0, 0, 0);
32
- transition: background-color $ba-RegionRect-transitionDuration ease, box-shadow $ba-RegionRect-transitionDuration ease;
28
+ box-shadow:
29
+ 0 0 0 $border-size-inner rgba($white, 1),
30
+ 0 0 0 $border-size-outer rgba($ba-RegionRect-color, 0.6),
31
+ 0 0 0 0 rgb(0 0 0 / 0%);
32
+ transition:
33
+ background-color $ba-RegionRect-transitionDuration ease,
34
+ box-shadow $ba-RegionRect-transitionDuration ease;
33
35
  content: '';
34
36
  }
35
37
 
36
38
  &:hover {
37
39
  &::after {
38
40
  background-color: $ba-RegionRect-bgColor--hover;
39
- box-shadow: 0 0 0 $border-size-inner rgba($white, 1), 0 0 0 $border-size-outer rgba($ba-RegionRect-color, 1), 0 8px 16px 0 rgba(0, 0, 0, .1);
41
+ box-shadow:
42
+ 0 0 0 $border-size-inner rgba($white, 1),
43
+ 0 0 0 $border-size-outer rgba($ba-RegionRect-color, 1),
44
+ 0 8px 16px 0 rgb(0 0 0 / 10%);
40
45
  }
41
46
  }
42
47
 
43
48
  &.is-active {
44
49
  &::after {
45
50
  background-color: $ba-RegionRect-bgColor--active;
46
- box-shadow: 0 0 0 $border-size-inner rgba($ba-RegionRect-color, 1), 0 0 0 $border-size-outer rgba($ba-RegionRect-color, 1), 0 8px 52px 0 rgba(0, 0, 0, .2);
51
+ box-shadow:
52
+ 0 0 0 $border-size-inner rgba($ba-RegionRect-color, 1),
53
+ 0 0 0 $border-size-outer rgba($ba-RegionRect-color, 1),
54
+ 0 8px 52px 0 rgb(0 0 0 / 20%);
47
55
  transition-delay: $ba-RegionRect-transitionDelay;
48
56
  }
49
57
  }
@@ -53,27 +53,24 @@ export const createReplyAction = createAsyncThunk<
53
53
  { annotationId: string; reply: Reply },
54
54
  { annotationId: string; message: string },
55
55
  AppThunkAPI
56
- >(
57
- 'CREATE_REPLY',
58
- async ({ annotationId, message }, { extra, getState, signal }) => {
59
- const client = extra.api.getAnnotationsAPI();
60
- const state = getState();
61
- const fileId = getFileId(state);
62
- const filePermissions = getPermissions(state);
63
- const annotation = getAnnotation(state, annotationId);
64
- const permissions = { ...filePermissions, ...annotation?.permissions };
56
+ >('CREATE_REPLY', async ({ annotationId, message }, { extra, getState, signal }) => {
57
+ const client = extra.api.getAnnotationsAPI();
58
+ const state = getState();
59
+ const fileId = getFileId(state);
60
+ const filePermissions = getPermissions(state);
61
+ const annotation = getAnnotation(state, annotationId);
62
+ const permissions = { ...filePermissions, ...annotation?.permissions };
65
63
 
66
- signal.addEventListener('abort', () => {
67
- client.destroy();
68
- });
64
+ signal.addEventListener('abort', () => {
65
+ client.destroy();
66
+ });
69
67
 
70
- const reply = await new Promise<Reply>((resolve, reject) => {
71
- client.createAnnotationReply(fileId, annotationId, permissions, message, resolve, reject);
72
- });
68
+ const reply = await new Promise<Reply>((resolve, reject) => {
69
+ client.createAnnotationReply(fileId, annotationId, permissions, message, resolve, reject);
70
+ });
73
71
 
74
- return { annotationId, reply };
75
- },
76
- );
72
+ return { annotationId, reply };
73
+ });
77
74
 
78
75
  export const deleteAnnotationAction = createAsyncThunk<string, string, AppThunkAPI>(
79
76
  'DELETE_ANNOTATION',
@@ -101,97 +98,88 @@ export const updateAnnotationAction = createAsyncThunk<
101
98
  Annotation,
102
99
  { annotationId: string; payload: { message?: string; status?: string } },
103
100
  AppThunkAPI
104
- >(
105
- 'UPDATE_ANNOTATION',
106
- async ({ annotationId, payload }, { extra, getState, signal }) => {
107
- const client = extra.api.getAnnotationsAPI();
108
- const state = getState();
109
- const fileId = getFileId(state);
110
- const filePermissions = getPermissions(state);
111
- const existingAnnotation = getAnnotation(state, annotationId);
112
- const permissions = { ...filePermissions, ...existingAnnotation?.permissions };
113
-
114
- signal.addEventListener('abort', () => {
115
- client.destroy();
116
- });
117
-
118
- return new Promise<Annotation>((resolve, reject) => {
119
- client.updateAnnotation(fileId, annotationId, permissions, payload, resolve, reject);
120
- });
121
- },
122
- );
101
+ >('UPDATE_ANNOTATION', async ({ annotationId, payload }, { extra, getState, signal }) => {
102
+ const client = extra.api.getAnnotationsAPI();
103
+ const state = getState();
104
+ const fileId = getFileId(state);
105
+ const filePermissions = getPermissions(state);
106
+ const existingAnnotation = getAnnotation(state, annotationId);
107
+ const permissions = { ...filePermissions, ...existingAnnotation?.permissions };
108
+
109
+ signal.addEventListener('abort', () => {
110
+ client.destroy();
111
+ });
112
+
113
+ return new Promise<Annotation>((resolve, reject) => {
114
+ client.updateAnnotation(fileId, annotationId, permissions, payload, resolve, reject);
115
+ });
116
+ });
123
117
 
124
118
  export const updateReplyAction = createAsyncThunk<
125
119
  { annotationId: string; reply: Reply },
126
120
  { annotationId: string; replyId: string; payload: { message?: string; status?: string } },
127
121
  AppThunkAPI
128
- >(
129
- 'UPDATE_REPLY',
130
- async ({ annotationId, replyId, payload }, { extra, getState, signal }) => {
131
- const client = extra.api.getThreadedCommentsAPI();
132
- const state = getState();
133
- const fileId = getFileId(state);
134
- const annotation = getAnnotation(state, annotationId);
135
- const reply = annotation?.replies?.find(r => r.id === replyId);
136
-
137
- if (!reply) {
138
- throw new Error(`updateReplyAction: reply ${replyId} not found on annotation ${annotationId}`);
139
- }
140
-
141
- signal.addEventListener('abort', () => {
142
- client.destroy();
122
+ >('UPDATE_REPLY', async ({ annotationId, replyId, payload }, { extra, getState, signal }) => {
123
+ const client = extra.api.getThreadedCommentsAPI();
124
+ const state = getState();
125
+ const fileId = getFileId(state);
126
+ const annotation = getAnnotation(state, annotationId);
127
+ const reply = annotation?.replies?.find(r => r.id === replyId);
128
+
129
+ if (!reply) {
130
+ throw new Error(`updateReplyAction: reply ${replyId} not found on annotation ${annotationId}`);
131
+ }
132
+
133
+ signal.addEventListener('abort', () => {
134
+ client.destroy();
135
+ });
136
+
137
+ const updated = await new Promise<Reply>((resolve, reject) => {
138
+ client.updateComment({
139
+ commentId: replyId,
140
+ errorCallback: reject,
141
+ fileId,
142
+ message: payload.message,
143
+ permissions: reply.permissions ?? {},
144
+ status: payload.status,
145
+ successCallback: resolve,
143
146
  });
147
+ });
144
148
 
145
- const updated = await new Promise<Reply>((resolve, reject) => {
146
- client.updateComment({
147
- commentId: replyId,
148
- errorCallback: reject,
149
- fileId,
150
- message: payload.message,
151
- permissions: reply.permissions ?? {},
152
- status: payload.status,
153
- successCallback: resolve,
154
- });
155
- });
156
-
157
- return { annotationId, reply: updated };
158
- },
159
- );
149
+ return { annotationId, reply: updated };
150
+ });
160
151
 
161
152
  export const deleteReplyAction = createAsyncThunk<
162
153
  { annotationId: string; replyId: string },
163
154
  { annotationId: string; replyId: string },
164
155
  AppThunkAPI
165
- >(
166
- 'DELETE_REPLY',
167
- async ({ annotationId, replyId }, { extra, getState, signal }) => {
168
- const client = extra.api.getThreadedCommentsAPI();
169
- const state = getState();
170
- const fileId = getFileId(state);
171
- const annotation = getAnnotation(state, annotationId);
172
- const reply = annotation?.replies?.find(r => r.id === replyId);
173
-
174
- if (!reply) {
175
- throw new Error(`deleteReplyAction: reply ${replyId} not found on annotation ${annotationId}`);
176
- }
177
-
178
- signal.addEventListener('abort', () => {
179
- client.destroy();
180
- });
181
-
182
- await new Promise<void>((resolve, reject) => {
183
- client.deleteComment({
184
- commentId: replyId,
185
- errorCallback: reject,
186
- fileId,
187
- permissions: reply.permissions ?? {},
188
- successCallback: resolve,
189
- });
156
+ >('DELETE_REPLY', async ({ annotationId, replyId }, { extra, getState, signal }) => {
157
+ const client = extra.api.getThreadedCommentsAPI();
158
+ const state = getState();
159
+ const fileId = getFileId(state);
160
+ const annotation = getAnnotation(state, annotationId);
161
+ const reply = annotation?.replies?.find(r => r.id === replyId);
162
+
163
+ if (!reply) {
164
+ throw new Error(`deleteReplyAction: reply ${replyId} not found on annotation ${annotationId}`);
165
+ }
166
+
167
+ signal.addEventListener('abort', () => {
168
+ client.destroy();
169
+ });
170
+
171
+ await new Promise<void>((resolve, reject) => {
172
+ client.deleteComment({
173
+ commentId: replyId,
174
+ errorCallback: reject,
175
+ fileId,
176
+ permissions: reply.permissions ?? {},
177
+ successCallback: resolve,
190
178
  });
179
+ });
191
180
 
192
- return { annotationId, replyId };
193
- },
194
- );
181
+ return { annotationId, replyId };
182
+ });
195
183
 
196
184
  export type SidebarAnnotationUpdatePayload = Partial<Annotation> & { id: string };
197
185
  export type SidebarReplyMutationPayload = { annotationId: string; reply: Reply };
@@ -200,15 +188,9 @@ export type SidebarReplyDeletePayload = { annotationId: string; replyId: string
200
188
  export const applySidebarAnnotationUpdateAction = createAction<SidebarAnnotationUpdatePayload>(
201
189
  'APPLY_SIDEBAR_ANNOTATION_UPDATE',
202
190
  );
203
- export const applySidebarReplyCreateAction = createAction<SidebarReplyMutationPayload>(
204
- 'APPLY_SIDEBAR_REPLY_CREATE',
205
- );
206
- export const applySidebarReplyDeleteAction = createAction<SidebarReplyDeletePayload>(
207
- 'APPLY_SIDEBAR_REPLY_DELETE',
208
- );
209
- export const applySidebarReplyUpdateAction = createAction<SidebarReplyMutationPayload>(
210
- 'APPLY_SIDEBAR_REPLY_UPDATE',
211
- );
191
+ export const applySidebarReplyCreateAction = createAction<SidebarReplyMutationPayload>('APPLY_SIDEBAR_REPLY_CREATE');
192
+ export const applySidebarReplyDeleteAction = createAction<SidebarReplyDeletePayload>('APPLY_SIDEBAR_REPLY_DELETE');
193
+ export const applySidebarReplyUpdateAction = createAction<SidebarReplyMutationPayload>('APPLY_SIDEBAR_REPLY_UPDATE');
212
194
 
213
195
  export const removeAnnotationAction = createAction<string>('REMOVE_ANNOTATION');
214
196
  export const setActiveAnnotationIdAction = createAction<string | null>('SET_ACTIVE_ANNOTATION_ID');
@@ -37,7 +37,9 @@ const annotationsAllIds = createReducer<AnnotationsState['allIds']>([], builder
37
37
  .addCase(createAnnotationAction.fulfilled, (state, { payload: { id } }) => {
38
38
  state.push(id);
39
39
  })
40
- .addCase(deleteAnnotationAction.fulfilled, (state, { payload: id }) => state.filter(annotationId => annotationId !== id))
40
+ .addCase(deleteAnnotationAction.fulfilled, (state, { payload: id }) =>
41
+ state.filter(annotationId => annotationId !== id),
42
+ )
41
43
  .addCase(removeAnnotationAction, (state, { payload: id }) => state.filter(annotationId => annotationId !== id))
42
44
  .addCase(fetchAnnotationsAction.fulfilled, (state, { payload }) => {
43
45
  payload.entries.forEach(({ id }) => state.indexOf(id) === -1 && state.push(id));
@@ -67,9 +69,7 @@ const annotationsById = createReducer<AnnotationsState['byId']>({}, builder =>
67
69
  .addCase(updateReplyAction.fulfilled, (state, { payload: { annotationId, reply } }) => {
68
70
  const annotation = state[annotationId];
69
71
  if (annotation && annotation.replies) {
70
- annotation.replies = annotation.replies.map(existing =>
71
- existing.id === reply.id ? reply : existing,
72
- );
72
+ annotation.replies = annotation.replies.map(existing => (existing.id === reply.id ? reply : existing));
73
73
  }
74
74
  })
75
75
  .addCase(deleteReplyAction.fulfilled, (state, { payload: { annotationId, replyId } }) => {
@@ -11,13 +11,13 @@ export const getCreatorStaged = (state: State): CreatorItem | null => state.crea
11
11
  export const getCreatorStagedForLocation = (state: State, location: number): CreatorItem | null => {
12
12
  const staged = getCreatorStaged(state);
13
13
  // The location is typically a page and this selector was originally meant to only return the staged annotation
14
- // (those that have been drawn but not saved) that belong to the page specified by the location. For documents,
15
- // the annotator creates new sets of managers(highlights, drawings, regions) for each page with the current
16
- // page number being the location e.g. page 4 of 10. This selector prevents a staged annotation from staying on
17
- // the screen when a user navigates to a different page. By default, the location value for managers is 1 which is
14
+ // (those that have been drawn but not saved) that belong to the page specified by the location. For documents,
15
+ // the annotator creates new sets of managers(highlights, drawings, regions) for each page with the current
16
+ // page number being the location e.g. page 4 of 10. This selector prevents a staged annotation from staying on
17
+ // the screen when a user navigates to a different page. By default, the location value for managers is 1 which is
18
18
  // why this selector works for images. Video annotations will not work this way because they reference a timestamp, not a page,
19
- // and the drawing canvas is the video player which has no pages. In this case, we just need to get the staged annotation and do the
20
- // locaton check for MEDIA_LOCATION_INDEX. The MEDIA_LOCATION_INDEX is a special value, set in the manager, that is used to indicate that
19
+ // and the drawing canvas is the video player which has no pages. In this case, we just need to get the staged annotation and do the
20
+ // locaton check for MEDIA_LOCATION_INDEX. The MEDIA_LOCATION_INDEX is a special value, set in the manager, that is used to indicate that
21
21
  // the this is actually a staged video annotation with a timestamp as its location.
22
22
  if (location === MEDIA_LOCATION_INDEX) {
23
23
  return staged;
@@ -15,8 +15,10 @@ const emitCreateEvent = (action: AsyncAction<NewAnnotation, Annotation>, status:
15
15
  });
16
16
  };
17
17
 
18
- const createHandler = (status: Status) => (prevState: AppState, nextState: AppState, action: AsyncAction): void =>
19
- emitCreateEvent(action as AsyncAction<NewAnnotation, Annotation>, status);
18
+ const createHandler =
19
+ (status: Status) =>
20
+ (prevState: AppState, nextState: AppState, action: AsyncAction): void =>
21
+ emitCreateEvent(action as AsyncAction<NewAnnotation, Annotation>, status);
20
22
 
21
23
  const handleCreateErrorEvents = createHandler(Status.ERROR);
22
24
  const handleCreatePendingEvents = createHandler(Status.PENDING);
@@ -14,11 +14,10 @@ const emitDeleteEvent = (action: AsyncAction<string, string>, status: Status): v
14
14
  });
15
15
  };
16
16
 
17
- const deleteHandler = (status: Status) => (
18
- _prev: AppState,
19
- _next: AppState,
20
- action: AsyncAction,
21
- ): void => emitDeleteEvent(action as AsyncAction<string, string>, status);
17
+ const deleteHandler =
18
+ (status: Status) =>
19
+ (_prev: AppState, _next: AppState, action: AsyncAction): void =>
20
+ emitDeleteEvent(action as AsyncAction<string, string>, status);
22
21
 
23
22
  const handleDeleteErrorEvents = deleteHandler(Status.ERROR);
24
23
  const handleDeletePendingEvents = deleteHandler(Status.PENDING);
@@ -71,19 +71,21 @@ export const eventHandlers: EventHandlerMap = {
71
71
  };
72
72
 
73
73
  function getEventingMiddleware(handlers: EventHandlerMap = eventHandlers): Middleware {
74
- return (store: MiddlewareAPI) => (next: Dispatch) => (action: Action): Action => {
75
- const { type } = action;
76
- // Retrieve the prevState as well as the nextState after the action has modified the state in order
77
- // to pass all that information to the event handler
78
- const prevState = store.getState();
79
- const result = next(action);
80
- const nextState = store.getState();
74
+ return (store: MiddlewareAPI) =>
75
+ (next: Dispatch) =>
76
+ (action: Action): Action => {
77
+ const { type } = action;
78
+ // Retrieve the prevState as well as the nextState after the action has modified the state in order
79
+ // to pass all that information to the event handler
80
+ const prevState = store.getState();
81
+ const result = next(action);
82
+ const nextState = store.getState();
81
83
 
82
- const handler = handlers[type] || noop;
83
- handler(prevState, nextState, action);
84
+ const handler = handlers[type] || noop;
85
+ handler(prevState, nextState, action);
84
86
 
85
- return result;
86
- };
87
+ return result;
88
+ };
87
89
  }
88
90
 
89
91
  export default getEventingMiddleware;
@@ -1,15 +1,12 @@
1
1
  import eventManager from '../../common/EventManager';
2
- import { Reply , Event } from '../../@types';
2
+ import { Reply, Event } from '../../@types';
3
3
  import { AppState } from '../types';
4
4
  import { AsyncAction, Status } from './types';
5
5
 
6
6
  type ReplyCreateArg = { annotationId: string; message: string };
7
7
  type ReplyCreatePayload = { annotationId: string; reply: Reply };
8
8
 
9
- const emitReplyCreateEvent = (
10
- action: AsyncAction<ReplyCreateArg, ReplyCreatePayload>,
11
- status: Status,
12
- ): void => {
9
+ const emitReplyCreateEvent = (action: AsyncAction<ReplyCreateArg, ReplyCreatePayload>, status: Status): void => {
13
10
  const { error, meta: { arg, requestId } = {}, payload } = action;
14
11
  if (status === Status.SUCCESS && !payload?.reply) return;
15
12
  const annotationId = payload?.annotationId ?? arg?.annotationId;
@@ -21,11 +18,10 @@ const emitReplyCreateEvent = (
21
18
  });
22
19
  };
23
20
 
24
- const replyCreateHandler = (status: Status) => (
25
- _prev: AppState,
26
- _next: AppState,
27
- action: AsyncAction,
28
- ): void => emitReplyCreateEvent(action as AsyncAction<ReplyCreateArg, ReplyCreatePayload>, status);
21
+ const replyCreateHandler =
22
+ (status: Status) =>
23
+ (_prev: AppState, _next: AppState, action: AsyncAction): void =>
24
+ emitReplyCreateEvent(action as AsyncAction<ReplyCreateArg, ReplyCreatePayload>, status);
29
25
 
30
26
  const handleReplyCreateErrorEvents = replyCreateHandler(Status.ERROR);
31
27
  const handleReplyCreatePendingEvents = replyCreateHandler(Status.PENDING);
@@ -6,10 +6,7 @@ import { Event } from '../../@types';
6
6
  type ReplyDeleteArg = { annotationId: string; replyId: string };
7
7
  type ReplyDeletePayload = { annotationId: string; replyId: string };
8
8
 
9
- const emitReplyDeleteEvent = (
10
- action: AsyncAction<ReplyDeleteArg, ReplyDeletePayload>,
11
- status: Status,
12
- ): void => {
9
+ const emitReplyDeleteEvent = (action: AsyncAction<ReplyDeleteArg, ReplyDeletePayload>, status: Status): void => {
13
10
  const { error, meta: { arg, requestId } = {}, payload } = action;
14
11
  if (status === Status.SUCCESS && !payload) return;
15
12
  const annotationId = payload?.annotationId ?? arg?.annotationId;
@@ -22,11 +19,10 @@ const emitReplyDeleteEvent = (
22
19
  });
23
20
  };
24
21
 
25
- const replyDeleteHandler = (status: Status) => (
26
- _prev: AppState,
27
- _next: AppState,
28
- action: AsyncAction,
29
- ): void => emitReplyDeleteEvent(action as AsyncAction<ReplyDeleteArg, ReplyDeletePayload>, status);
22
+ const replyDeleteHandler =
23
+ (status: Status) =>
24
+ (_prev: AppState, _next: AppState, action: AsyncAction): void =>
25
+ emitReplyDeleteEvent(action as AsyncAction<ReplyDeleteArg, ReplyDeletePayload>, status);
30
26
 
31
27
  const handleReplyDeleteErrorEvents = replyDeleteHandler(Status.ERROR);
32
28
  const handleReplyDeletePendingEvents = replyDeleteHandler(Status.PENDING);
@@ -1,5 +1,5 @@
1
1
  import eventManager from '../../common/EventManager';
2
- import { Reply , Event } from '../../@types';
2
+ import { Reply, Event } from '../../@types';
3
3
  import { AppState } from '../types';
4
4
  import { AsyncAction, Status } from './types';
5
5
 
@@ -10,10 +10,7 @@ type ReplyUpdateArg = {
10
10
  };
11
11
  type ReplyUpdatePayload = { annotationId: string; reply: Reply };
12
12
 
13
- const emitReplyUpdateEvent = (
14
- action: AsyncAction<ReplyUpdateArg, ReplyUpdatePayload>,
15
- status: Status,
16
- ): void => {
13
+ const emitReplyUpdateEvent = (action: AsyncAction<ReplyUpdateArg, ReplyUpdatePayload>, status: Status): void => {
17
14
  const { error, meta: { arg, requestId } = {}, payload } = action;
18
15
  if (status === Status.SUCCESS && !payload?.reply) return;
19
16
  const annotationId = payload?.annotationId ?? arg?.annotationId;
@@ -26,11 +23,10 @@ const emitReplyUpdateEvent = (
26
23
  });
27
24
  };
28
25
 
29
- const replyUpdateHandler = (status: Status) => (
30
- _prev: AppState,
31
- _next: AppState,
32
- action: AsyncAction,
33
- ): void => emitReplyUpdateEvent(action as AsyncAction<ReplyUpdateArg, ReplyUpdatePayload>, status);
26
+ const replyUpdateHandler =
27
+ (status: Status) =>
28
+ (_prev: AppState, _next: AppState, action: AsyncAction): void =>
29
+ emitReplyUpdateEvent(action as AsyncAction<ReplyUpdateArg, ReplyUpdatePayload>, status);
34
30
 
35
31
  const handleReplyUpdateErrorEvents = replyUpdateHandler(Status.ERROR);
36
32
  const handleReplyUpdatePendingEvents = replyUpdateHandler(Status.PENDING);
@@ -1,5 +1,5 @@
1
1
  import eventManager from '../../common/EventManager';
2
- import { Annotation , Event } from '../../@types';
2
+ import { Annotation, Event } from '../../@types';
3
3
  import { AppState } from '../types';
4
4
  import { AsyncAction, Status } from './types';
5
5
 
@@ -16,11 +16,10 @@ const emitUpdateEvent = (action: AsyncAction<UpdateArg, Annotation>, status: Sta
16
16
  });
17
17
  };
18
18
 
19
- const updateHandler = (status: Status) => (
20
- _prev: AppState,
21
- _next: AppState,
22
- action: AsyncAction,
23
- ): void => emitUpdateEvent(action as AsyncAction<UpdateArg, Annotation>, status);
19
+ const updateHandler =
20
+ (status: Status) =>
21
+ (_prev: AppState, _next: AppState, action: AsyncAction): void =>
22
+ emitUpdateEvent(action as AsyncAction<UpdateArg, Annotation>, status);
24
23
 
25
24
  const handleUpdateErrorEvents = updateHandler(Status.ERROR);
26
25
  const handleUpdatePendingEvents = updateHandler(Status.PENDING);
@@ -77,59 +77,61 @@ export const getShape = ({ height, left, top, width }: DOMRect): Shape => ({
77
77
  y: top,
78
78
  });
79
79
 
80
- export const setSelectionAction = createAction(
81
- 'SET_SELECTION',
82
- (arg: SelectionArg | null): Payload => {
83
- if (!arg) {
84
- return {
85
- payload: null,
86
- };
87
- }
88
-
89
- const { containerEl, containerRect, hasError, location, range, rotation } = arg;
80
+ export const setSelectionAction = createAction('SET_SELECTION', (arg: SelectionArg | null): Payload => {
81
+ if (!arg) {
82
+ return {
83
+ payload: null,
84
+ };
85
+ }
90
86
 
91
- let rects = Array.from(range.getClientRects());
92
- // getClientRects on IE/Edge might return 0 rects
93
- if (!rects.length) {
94
- rects = getClientRects(range);
95
- }
87
+ const { containerEl, containerRect, hasError, location, range, rotation } = arg;
96
88
 
97
- const screenShapes = rects.map(getShape);
98
-
99
- if (rotation && containerEl) {
100
- // Convert screen rects to element-local coordinates
101
- const localRects = screenShapes.map(shape => {
102
- const [lx1, ly1] = getElementLocalPosition(shape.x, shape.y, containerEl, rotation);
103
- const [lx2, ly2] = getElementLocalPosition(shape.x + shape.width, shape.y + shape.height, containerEl, rotation);
104
- return {
105
- x: Math.min(lx1, lx2),
106
- y: Math.min(ly1, ly2),
107
- width: Math.abs(lx2 - lx1),
108
- height: Math.abs(ly2 - ly1),
109
- };
110
- });
89
+ let rects = Array.from(range.getClientRects());
90
+ // getClientRects on IE/Edge might return 0 rects
91
+ if (!rects.length) {
92
+ rects = getClientRects(range);
93
+ }
111
94
 
95
+ const screenShapes = rects.map(getShape);
96
+
97
+ if (rotation && containerEl) {
98
+ // Convert screen rects to element-local coordinates
99
+ const localRects = screenShapes.map(shape => {
100
+ const [lx1, ly1] = getElementLocalPosition(shape.x, shape.y, containerEl, rotation);
101
+ const [lx2, ly2] = getElementLocalPosition(
102
+ shape.x + shape.width,
103
+ shape.y + shape.height,
104
+ containerEl,
105
+ rotation,
106
+ );
112
107
  return {
113
- payload: {
114
- containerRect: { x: 0, y: 0, width: containerEl.offsetWidth, height: containerEl.offsetHeight },
115
- hasError,
116
- location,
117
- popupRect: getBoundingRect(screenShapes),
118
- rects: combineRects(localRects),
119
- },
108
+ x: Math.min(lx1, lx2),
109
+ y: Math.min(ly1, ly2),
110
+ width: Math.abs(lx2 - lx1),
111
+ height: Math.abs(ly2 - ly1),
120
112
  };
121
- }
113
+ });
122
114
 
123
115
  return {
124
116
  payload: {
125
- containerRect: getShape(containerRect),
117
+ containerRect: { x: 0, y: 0, width: containerEl.offsetWidth, height: containerEl.offsetHeight },
126
118
  hasError,
127
119
  location,
128
- rects: combineRects(screenShapes),
120
+ popupRect: getBoundingRect(screenShapes),
121
+ rects: combineRects(localRects),
129
122
  },
130
123
  };
131
- },
132
- );
124
+ }
125
+
126
+ return {
127
+ payload: {
128
+ containerRect: getShape(containerRect),
129
+ hasError,
130
+ location,
131
+ rects: combineRects(screenShapes),
132
+ },
133
+ };
134
+ });
133
135
 
134
136
  export const setIsPromotingAction = createAction<boolean>('SET_IS_PROMOTING');
135
137
  export const setIsSelectingAction = createAction<boolean>('SET_IS_SELECTING');