Skip to content

Commit 0f41c4b

Browse files
committed
move isMutexAcquired to store
1 parent 5e96e38 commit 0f41c4b

File tree

6 files changed

+63
-41
lines changed

6 files changed

+63
-41
lines changed

frontend/javascripts/viewer/default_state.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ const defaultState: WebknossosState = {
178178
contributors: [],
179179
othersMayEdit: false,
180180
blockedByUser: null,
181+
isMutexAcquired: false,
181182
annotationLayers: [],
182183
version: 0,
183184
earliestAccessibleVersion: 0,

frontend/javascripts/viewer/model/actions/annotation_actions.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export type EditAnnotationLayerAction = ReturnType<typeof editAnnotationLayerAct
5252
export type SetAnnotationDescriptionAction = ReturnType<typeof setAnnotationDescriptionAction>;
5353
type SetAnnotationAllowUpdateAction = ReturnType<typeof setAnnotationAllowUpdateAction>;
5454
type SetBlockedByUserAction = ReturnType<typeof setBlockedByUserAction>;
55+
export type SetIsMutexAcquiredAction = ReturnType<typeof setIsMutexAcquiredAction>;
5556
type SetUserBoundingBoxesAction = ReturnType<typeof setUserBoundingBoxesAction>;
5657
type FinishedResizingUserBoundingBoxAction = ReturnType<
5758
typeof finishedResizingUserBoundingBoxAction
@@ -87,6 +88,7 @@ export type AnnotationActionTypes =
8788
| SetAnnotationDescriptionAction
8889
| SetAnnotationAllowUpdateAction
8990
| SetBlockedByUserAction
91+
| SetIsMutexAcquiredAction
9092
| SetUserBoundingBoxesAction
9193
| ChangeUserBoundingBoxAction
9294
| FinishedResizingUserBoundingBoxAction
@@ -176,6 +178,12 @@ export const setBlockedByUserAction = (blockedByUser: APIUserCompact | null | un
176178
blockedByUser,
177179
}) as const;
178180

181+
export const setIsMutexAcquiredAction = (isMutexAcquired: boolean) =>
182+
({
183+
type: "SET_IS_MUTEX_ACQUIRED",
184+
isMutexAcquired,
185+
}) as const;
186+
179187
// Strictly speaking this is no annotation action but a tracing action, as the boundingBox is saved with
180188
// the tracing, hence no ANNOTATION in the action type.
181189
export const setUserBoundingBoxesAction = (userBoundingBoxes: Array<UserBoundingBox>) =>

frontend/javascripts/viewer/model/reducers/annotation_reducer.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,13 @@ function AnnotationReducer(state: WebknossosState, action: Action): WebknossosSt
137137
});
138138
}
139139

140+
case "SET_IS_MUTEX_ACQUIRED": {
141+
const { isMutexAcquired } = action;
142+
return updateKey(state, "annotation", {
143+
isMutexAcquired,
144+
});
145+
}
146+
140147
case "SET_USER_BOUNDING_BOXES": {
141148
return updateUserBoundingBoxes(state, action.userBoundingBoxes);
142149
}

frontend/javascripts/viewer/model/reducers/reducer_helpers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ export function convertServerAnnotationToFrontendAnnotation(
156156
othersMayEdit,
157157
annotationLayers,
158158
blockedByUser: null,
159+
isMutexAcquired: false,
159160
};
160161
}
161162

frontend/javascripts/viewer/model/sagas/saving/save_mutex_saga.tsx

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import Toast from "libs/toast";
44
import messages from "messages";
55
import React from "react";
66
import { call, cancel, cancelled, delay, fork, put, retry, takeEvery } from "typed-redux-saga";
7-
import type { APIUserCompact } from "types/api_types";
87
import {
8+
type SetIsMutexAcquiredAction,
99
type SetOthersMayEditForAnnotationAction,
1010
setAnnotationAllowUpdateAction,
1111
setBlockedByUserAction,
12+
setIsMutexAcquiredAction,
1213
} from "viewer/model/actions/annotation_actions";
1314
import type { Saga } from "viewer/model/sagas/effect-generators";
1415
import { select } from "viewer/model/sagas/effect-generators";
@@ -25,12 +26,16 @@ const DISABLE_EAGER_MUTEX_ACQUISITION = true;
2526
type MutexLogicState = {
2627
isInitialRequest: boolean;
2728
doesHaveMutexFromBeginning: boolean;
28-
doesHaveMutex: boolean;
2929
shallTryAcquireMutex: boolean;
3030
};
3131

32+
function* getDoesHaveMutex(): Saga<boolean> {
33+
return yield* select((state) => state.annotation.isMutexAcquired);
34+
}
35+
3236
export function* acquireAnnotationMutexMaybe(): Saga<void> {
3337
yield* call(ensureWkReady);
38+
yield* fork(watchMutexStateChanges);
3439
if (DISABLE_EAGER_MUTEX_ACQUISITION) {
3540
return;
3641
}
@@ -43,7 +48,6 @@ export function* acquireAnnotationMutexMaybe(): Saga<void> {
4348
const mutexLogicState: MutexLogicState = {
4449
isInitialRequest: true,
4550
doesHaveMutexFromBeginning: false,
46-
doesHaveMutex: false,
4751
shallTryAcquireMutex: othersMayEdit,
4852
};
4953

@@ -97,14 +101,11 @@ function* tryAcquireMutexContinuously(mutexLogicState: MutexLogicState): Saga<vo
97101
mutexLogicState.doesHaveMutexFromBeginning = false;
98102
yield* put(setAnnotationAllowUpdateAction(false));
99103
}
100-
if (canEdit) {
101-
yield* put(setBlockedByUserAction(activeUser));
102-
} else {
103-
yield* put(setBlockedByUserAction(blockedByUser));
104-
}
105-
if (canEdit !== mutexLogicState.doesHaveMutex || mutexLogicState.isInitialRequest) {
106-
mutexLogicState.doesHaveMutex = canEdit;
107-
onMutexStateChanged(mutexLogicState.isInitialRequest, canEdit, blockedByUser);
104+
105+
yield* put(setBlockedByUserAction(canEdit ? activeUser : blockedByUser));
106+
107+
if (canEdit !== (yield* call(getDoesHaveMutex)) || mutexLogicState.isInitialRequest) {
108+
yield* put(setIsMutexAcquiredAction(canEdit));
108109
}
109110
} catch (error) {
110111
if (process.env.IS_TESTING) {
@@ -120,9 +121,8 @@ function* tryAcquireMutexContinuously(mutexLogicState: MutexLogicState): Saga<vo
120121
yield* put(setBlockedByUserAction(undefined));
121122
yield* put(setAnnotationAllowUpdateAction(false));
122123
mutexLogicState.doesHaveMutexFromBeginning = false;
123-
if (mutexLogicState.doesHaveMutex || mutexLogicState.isInitialRequest) {
124-
onMutexStateChanged(mutexLogicState.isInitialRequest, false, null);
125-
mutexLogicState.doesHaveMutex = false;
124+
if ((yield* call(getDoesHaveMutex)) || mutexLogicState.isInitialRequest) {
125+
yield* put(setIsMutexAcquiredAction(false));
126126
}
127127
}
128128
}
@@ -131,31 +131,35 @@ function* tryAcquireMutexContinuously(mutexLogicState: MutexLogicState): Saga<vo
131131
}
132132
}
133133

134-
// todop: this should automatically react to store changes / actions. there could be a "SET_MUTEX_INFO" action
135-
function onMutexStateChanged(
136-
isInitialRequest: boolean,
137-
canEdit: boolean,
138-
blockedByUser: APIUserCompact | null | undefined,
139-
) {
140-
if (canEdit) {
141-
Toast.close(MUTEX_NOT_ACQUIRED_KEY);
142-
if (!isInitialRequest) {
143-
const message = (
144-
<React.Fragment>
145-
{messages["annotation.acquiringMutexSucceeded"]}" "
146-
<Button onClick={() => location.reload()}>Reload the annotation</Button>
147-
</React.Fragment>
148-
);
149-
Toast.success(message, { sticky: true, key: MUTEX_ACQUIRED_KEY });
150-
}
151-
} else {
152-
Toast.close(MUTEX_ACQUIRED_KEY);
153-
const message =
154-
blockedByUser != null
155-
? messages["annotation.acquiringMutexFailed"]({
156-
userName: `${blockedByUser.firstName} ${blockedByUser.lastName}`,
157-
})
158-
: messages["annotation.acquiringMutexFailed.noUser"];
159-
Toast.warning(message, { sticky: true, key: MUTEX_NOT_ACQUIRED_KEY });
160-
}
134+
function* watchMutexStateChanges(): Saga<void> {
135+
// todop: wrong?
136+
let isInitialRequest = true;
137+
yield* takeEvery(
138+
"SET_IS_MUTEX_ACQUIRED",
139+
function* ({ isMutexAcquired }: SetIsMutexAcquiredAction) {
140+
if (isMutexAcquired) {
141+
Toast.close(MUTEX_NOT_ACQUIRED_KEY);
142+
if (!isInitialRequest) {
143+
const message = (
144+
<React.Fragment>
145+
{messages["annotation.acquiringMutexSucceeded"]}" "
146+
<Button onClick={() => location.reload()}>Reload the annotation</Button>
147+
</React.Fragment>
148+
);
149+
Toast.success(message, { sticky: true, key: MUTEX_ACQUIRED_KEY });
150+
}
151+
} else {
152+
Toast.close(MUTEX_ACQUIRED_KEY);
153+
const blockedByUser = yield* select((state) => state.annotation.blockedByUser);
154+
const message =
155+
blockedByUser != null
156+
? messages["annotation.acquiringMutexFailed"]({
157+
userName: `${blockedByUser.firstName} ${blockedByUser.lastName}`,
158+
})
159+
: messages["annotation.acquiringMutexFailed.noUser"];
160+
Toast.warning(message, { sticky: true, key: MUTEX_NOT_ACQUIRED_KEY });
161+
}
162+
isInitialRequest = false;
163+
},
164+
);
161165
}

frontend/javascripts/viewer/store.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ export type Annotation = {
146146
readonly othersMayEdit: boolean;
147147
readonly blockedByUser: APIUserCompact | null | undefined;
148148
readonly isLockedByOwner: boolean;
149+
readonly isMutexAcquired: boolean;
149150
};
150151
type TracingBase = {
151152
readonly createdTimestamp: number;

0 commit comments

Comments
 (0)