From b15633f8d4cdc31a74b4c27a1851a3b7ca4f3c18 Mon Sep 17 00:00:00 2001 From: Jim O'Donnell Date: Thu, 15 Feb 2024 16:31:16 +0000 Subject: [PATCH] refactor: automatically sync drawing annotations - Add an `annotation.actualTask` view to drawing tasks and transcription tasks. - Add an `autorun` listener which observes `self.actualTask.marks` for changes, and updates the annotation value. - Remove the manual `annotation.update(newValue)` when a new mark is drawn. This might be a more robust fix for problems where the classification is not updated properly after a change to a drawing tool. It should keep drawing annotations in sync with their corresponding drawing tools. --- .../InteractionLayer/InteractionLayer.js | 2 -- .../tasks/drawing/models/DrawingAnnotation.js | 22 +++++++++++++++---- .../models/TranscriptionAnnotation.js | 20 ++++++++++++++--- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/InteractionLayer/InteractionLayer.js b/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/InteractionLayer/InteractionLayer.js index 9ce8625585c..9c826b1b93a 100644 --- a/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/InteractionLayer/InteractionLayer.js +++ b/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/InteractionLayer/InteractionLayer.js @@ -104,8 +104,6 @@ function InteractionLayer({ mark.setSubTaskVisibility(false) // Add a time value for tools that care about time. For most tools, this value is ignored. mark.setVideoTime(timeStamp, duration) - const markIDs = marks.map((mark) => mark.id) - annotation.update([...markIDs, mark.id]) } function onPointerDown(event) { diff --git a/packages/lib-classifier/src/plugins/tasks/drawing/models/DrawingAnnotation.js b/packages/lib-classifier/src/plugins/tasks/drawing/models/DrawingAnnotation.js index 908afd700f4..7f98675d615 100644 --- a/packages/lib-classifier/src/plugins/tasks/drawing/models/DrawingAnnotation.js +++ b/packages/lib-classifier/src/plugins/tasks/drawing/models/DrawingAnnotation.js @@ -1,4 +1,5 @@ -import { getRoot, getSnapshot, resolveIdentifier, types } from 'mobx-state-tree' +import { autorun } from 'mobx' +import { addDisposer, getRoot, getSnapshot, resolveIdentifier, types } from 'mobx-state-tree' import DrawingTask from './DrawingTask' import Annotation from '../../models/Annotation' import * as markTypes from '@plugins/drawingTools/models/marks' @@ -11,11 +12,14 @@ const Drawing = types.model('Drawing', { value: types.array(types.safeReference(GenericMark)) }) .views(self => ({ - toSnapshot () { + get actualTask() { + return resolveIdentifier(DrawingTask, getRoot(self), self.task) + }, + + toSnapshot() { const snapshot = getSnapshot(self) // resolve mark references (IDs) in the snapshot to mark snapshots - const actualTask = resolveIdentifier(DrawingTask, getRoot(self), self.task) - const value = actualTask.marks.map(mark => getSnapshot(mark)) + const value = self.actualTask.marks.map(mark => getSnapshot(mark)) const drawingSnapshot = Object.assign({}, snapshot, { value }) // flatten subtask annotations into a single annotations array // then return the flattened array @@ -38,6 +42,16 @@ const Drawing = types.model('Drawing', { return drawingAnnotations } })) + .actions(self => ({ + afterAttach() { + function _onMarksChange() { + const newAnnotation = self.actualTask.marks.map(mark => mark.id) + self.update(newAnnotation) + } + + addDisposer(self, autorun(_onMarksChange)) + } + })) const DrawingAnnotation = types.compose('DrawingAnnotation', Annotation, Drawing) diff --git a/packages/lib-classifier/src/plugins/tasks/experimental/transcription/models/TranscriptionAnnotation.js b/packages/lib-classifier/src/plugins/tasks/experimental/transcription/models/TranscriptionAnnotation.js index 874d04d0d66..465b215db63 100644 --- a/packages/lib-classifier/src/plugins/tasks/experimental/transcription/models/TranscriptionAnnotation.js +++ b/packages/lib-classifier/src/plugins/tasks/experimental/transcription/models/TranscriptionAnnotation.js @@ -1,4 +1,5 @@ -import { getRoot, getSnapshot, resolveIdentifier, types } from 'mobx-state-tree' +import { autorun } from 'mobx' +import { addDisposer, getRoot, getSnapshot, resolveIdentifier, types } from 'mobx-state-tree' import TranscriptionTask from './TranscriptionTask' import { TranscriptionLine } from '@plugins/drawingTools/models/marks' import Annotation from '../../../models/Annotation' @@ -8,13 +9,16 @@ const Transcription = types.model('Transcription', { value: types.array(types.safeReference(TranscriptionLine)) }) .views(self => ({ + get actualTask() { + return resolveIdentifier(TranscriptionTask, getRoot(self), self.task) + }, + // This is a copy of DrawingAnnotation's toSnapshot with the exception of // Changing the task type to TranscriptionTask toSnapshot() { const snapshot = getSnapshot(self) // resolve mark references (IDs) in the snapshot to mark snapshots - const actualTask = resolveIdentifier(TranscriptionTask, getRoot(self), self.task) - const value = actualTask.marks.map(mark => getSnapshot(mark)) + const value = self.actualTask.marks.map(mark => getSnapshot(mark)) const drawingSnapshot = Object.assign({}, snapshot, { value }) // flatten subtask annotations into a single annotations array // then return the flattened array @@ -37,6 +41,16 @@ const Transcription = types.model('Transcription', { return drawingAnnotations } })) + .actions(self => ({ + afterAttach() { + function _onMarksChange() { + const newAnnotation = self.actualTask.marks.map(mark => mark.id) + self.update(newAnnotation) + } + + addDisposer(self, autorun(_onMarksChange)) + } + })) const TranscriptionAnnotation = types.compose('TranscriptionAnnotation', Annotation, Transcription)