diff --git a/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/MultiFrameViewer/MultiFrameViewerContainer.js b/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/MultiFrameViewer/MultiFrameViewerContainer.js index 0e3d41552c..597611f28d 100644 --- a/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/MultiFrameViewer/MultiFrameViewerContainer.js +++ b/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/MultiFrameViewer/MultiFrameViewerContainer.js @@ -13,7 +13,6 @@ import locationValidator from '../../helpers/locationValidator' import SingleImageViewer from '../SingleImageViewer/SingleImageViewer' import SVGPanZoom from '../SVGComponents/SVGPanZoom' - function storeMapper(store) { const { enableRotation, @@ -25,7 +24,17 @@ function storeMapper(store) { setOnZoom } = store.subjectViewer + const { activeStepTasks } = store.workflowSteps + + const [activeInteractionTask] = activeStepTasks.filter( + (task) => task.type === 'drawing' || task.type === 'transcription' + ) + const { + activeTool + } = activeInteractionTask || {} + return { + activeTool, enableRotation, frame, move, @@ -48,7 +57,7 @@ class MultiFrameViewerContainer extends React.Component { this.setOnDrag = this.setOnDrag.bind(this) this.subjectImage = React.createRef() - + this.state = { img: {} } @@ -86,7 +95,15 @@ class MultiFrameViewerContainer extends React.Component { } onFrameChange(frame) { - const { setFrame } = this.props + const { + activeTool, + setFrame + } = this.props + + if (activeTool?.marks?.size > 0) { + activeTool.validate() + } + setFrame(frame) } @@ -139,7 +156,7 @@ class MultiFrameViewerContainer extends React.Component { subject } = this.props const { img } = this.state - + // If image hasn't been fully retrieved, use a placeholder const src = img?.src || 'https://static.zooniverse.org/www.zooniverse.org/assets/fe-project-subject-placeholder-800x600.png' // Use this instead of https://www.zooniverse.org/assets/fe-project-subject-placeholder-800x600.png to save on network calls const naturalWidth = img?.naturalWidth || 800 @@ -204,6 +221,9 @@ class MultiFrameViewerContainer extends React.Component { } MultiFrameViewerContainer.propTypes = { + activeTool: PropTypes.shape({ + validate: PropTypes.func + }), enableInteractionLayer: PropTypes.bool, enableRotation: PropTypes.func, frame: PropTypes.number, @@ -219,6 +239,9 @@ MultiFrameViewerContainer.propTypes = { } MultiFrameViewerContainer.defaultProps = { + activeTool: { + validate: () => {} + }, enableInteractionLayer: true, enableRotation: () => null, frame: 0, diff --git a/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/MultiFrameViewer/MultiFrameViewerContainer.spec.js b/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/MultiFrameViewer/MultiFrameViewerContainer.spec.js index 5b55177ac7..4c29119e24 100644 --- a/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/MultiFrameViewer/MultiFrameViewerContainer.spec.js +++ b/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/MultiFrameViewer/MultiFrameViewerContainer.spec.js @@ -5,6 +5,7 @@ import React from 'react' import { DraggableImage, MultiFrameViewerContainer } from './MultiFrameViewerContainer' import FrameCarousel from './FrameCarousel' import SingleImageViewer from '../SingleImageViewer/SingleImageViewer' +import TranscriptionLineTool from '../../../../../../plugins/drawingTools/experimental/models/tools/TranscriptionLineTool/TranscriptionLineTool' import asyncStates from '@zooniverse/async-states' describe('Component > MultiFrameViewerContainer', function () { @@ -140,7 +141,31 @@ describe('Component > MultiFrameViewerContainer', function () { expect(image).to.have.lengthOf(1) expect(image.prop('xlinkHref')).to.equal('https://some.domain/image.jpg') }) - }) + }) + + describe('with invalid marks', function () { + // mock an active transcription task tool: + const activeTool = TranscriptionLineTool.create({ + color: '#ff0000', + type: 'transcriptionLine' + }) + + // add a valid first mark: + const pointerEvent = { x: 10, y: 10 } + const validMark = activeTool.createMark({ x: 0, y: 0 }) + activeTool.handlePointerDown(pointerEvent, validMark) + + // add an invalid second mark (start, but don't finish a line): + activeTool.createMark({ x: 15, y: 15 }) + + it('should delete invalid marks on frame change', function () { + wrapper.setProps({ activeTool }) + expect(activeTool.marks.size).to.equal(2) + + wrapper.instance().onFrameChange(2) + expect(activeTool.marks.size).to.equal(1) + }) + }) }) describe('with an invalid subject', function () {