Skip to content
Snippets Groups Projects
Verified Commit d28b5feb authored by Loïs Poujade's avatar Loïs Poujade
Browse files

Lint + minor fixes

- to webanno format: "id" property need to be image address
- reorder keys for linter
- show image in edition form if existing
- add minimal test
parent 3b4d3851
No related branches found
No related tags found
1 merge request!5Create image annotation creation dialog
Pipeline #1266 failed
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"env": { "env": {
"jest/globals": true "jest/globals": true
}, },
"extends": ["airbnb"], "extends": ["airbnb", "react-app"],
"globals": { "globals": {
"page": true, "page": true,
"document": true "document": true
......
...@@ -130,6 +130,28 @@ describe('WebAnnotation', () => { ...@@ -130,6 +130,28 @@ describe('WebAnnotation', () => {
value: 'tags', value: 'tags',
}); });
}); });
it('with image and text', () => {
subject = createSubject({ body: { value: 'hello' }, image: { url: 'http://example.photo/pic.jpg' }, tags: null });
expect(subject.createBody()).toEqual([
{
type: 'TextualBody',
value: 'hello',
},
{
format: 'image/jpg',
id: 'http://example.photo/pic.jpg',
type: 'Image',
},
]);
});
it('with image only', () => {
subject = createSubject({ body: null, image: { url: 'http://example.photo/pic.jpg' }, tags: null });
expect(subject.createBody()).toEqual({
format: 'image/jpg',
id: 'http://example.photo/pic.jpg',
type: 'Image',
});
});
}); });
describe('toJson', () => { describe('toJson', () => {
it('generates a WebAnnotation', () => { it('generates a WebAnnotation', () => {
......
This diff is collapsed.
...@@ -19,6 +19,14 @@ import StrokeColorIcon from '@material-ui/icons/BorderColor'; ...@@ -19,6 +19,14 @@ import StrokeColorIcon from '@material-ui/icons/BorderColor';
import LineWeightIcon from '@material-ui/icons/LineWeight'; import LineWeightIcon from '@material-ui/icons/LineWeight';
import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown'; import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';
import FormatShapesIcon from '@material-ui/icons/FormatShapes'; import FormatShapesIcon from '@material-ui/icons/FormatShapes';
import InsertPhotoIcon from '@material-ui/icons/InsertPhoto';
import Dialog from '@material-ui/core/Dialog';
import DialogTitle from '@material-ui/core/DialogTitle';
import DialogContent from '@material-ui/core/DialogContent';
import DialogActions from '@material-ui/core/DialogActions';
import TextField from '@material-ui/core/TextField';
import Checkbox from '@material-ui/core/Checkbox';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import { SketchPicker } from 'react-color'; import { SketchPicker } from 'react-color';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { withStyles } from '@material-ui/core/styles'; import { withStyles } from '@material-ui/core/styles';
...@@ -80,7 +88,6 @@ class AnnotationCreation extends Component { ...@@ -80,7 +88,6 @@ class AnnotationCreation extends Component {
const annoState = {}; const annoState = {};
annoState.image = false; annoState.image = false;
console.log('edition/creation annotation: ', props.annotation);
if (props.annotation) { if (props.annotation) {
// //
...@@ -93,15 +100,15 @@ class AnnotationCreation extends Component { ...@@ -93,15 +100,15 @@ class AnnotationCreation extends Component {
} else if (body.type === 'TextualBody') { } else if (body.type === 'TextualBody') {
annoState.textBody = body.value; annoState.textBody = body.value;
} else if (body.type === 'Image') { } else if (body.type === 'Image') {
annoState.textBody = body.value; // annoState.textBody = body.value; // why text body here ???
annoState.image = body.image; annoState.image = body;
} }
}); });
} else if (props.annotation.body.type === 'TextualBody') { } else if (props.annotation.body.type === 'TextualBody') {
annoState.textBody = props.annotation.body.value; annoState.textBody = props.annotation.body.value;
} else if (props.annotation.body.type === 'Image') { } else if (props.annotation.body.type === 'Image') {
annoState.textBody = props.annotation.body.value; // annoState.textBody = props.annotation.body.value; // why text body here ???
annoState.image = props.annotation.body.image; annoState.image = props.annotation.body;
} }
// //
// drawing position // drawing position
...@@ -129,6 +136,7 @@ class AnnotationCreation extends Component { ...@@ -129,6 +136,7 @@ class AnnotationCreation extends Component {
const toolState = { const toolState = {
activeTool: 'cursor', activeTool: 'cursor',
closedMode: 'closed', closedMode: 'closed',
colorPopoverOpen: false,
currentColorType: false, currentColorType: false,
fillColor: null, fillColor: null,
strokeColor: '#00BFFF', strokeColor: '#00BFFF',
...@@ -143,14 +151,10 @@ class AnnotationCreation extends Component { ...@@ -143,14 +151,10 @@ class AnnotationCreation extends Component {
this.state = { this.state = {
...toolState, ...toolState,
...timeState, ...timeState,
textBody: '', activeTool: 'cursor',
colorPopoverOpen: false, closedMode: 'closed',
lineWeightPopoverOpen: false, currentColorType: false,
openAddImgDialog: false, fillColor: null,
popoverAnchorEl: null,
popoverLineWeightAnchorEl: null,
svg: null,
textEditorStateBustingKey: 0,
imgConstrain: false, imgConstrain: false,
imgHeight: { imgHeight: {
lastSubmittedValue: '', lastSubmittedValue: '',
...@@ -169,6 +173,13 @@ class AnnotationCreation extends Component { ...@@ -169,6 +173,13 @@ class AnnotationCreation extends Component {
validity: 0, validity: 0,
value: '', value: '',
}, },
lineWeightPopoverOpen: false,
openAddImgDialog: false,
popoverAnchorEl: null,
popoverLineWeightAnchorEl: null,
svg: null,
textBody: '',
textEditorStateBustingKey: 0,
xywh: null, xywh: null,
...annoState, ...annoState,
}; };
...@@ -246,6 +257,7 @@ class AnnotationCreation extends Component { ...@@ -246,6 +257,7 @@ class AnnotationCreation extends Component {
} }
this.setState({ this.setState({
image: { id: imgUrl.value },
imgHeight: { imgHeight: {
...imgHeight, ...imgHeight,
lastSubmittedValue: heightValidity === 1 ? imgHeight.value : imgHeight.lastSubmittedValue, lastSubmittedValue: heightValidity === 1 ? imgHeight.value : imgHeight.lastSubmittedValue,
...@@ -285,6 +297,18 @@ class AnnotationCreation extends Component { ...@@ -285,6 +297,18 @@ class AnnotationCreation extends Component {
}); });
} }
/** set annotation start time to current time */
setTstartNow() {
// eslint-disable-next-line react/destructuring-assignment
this.setState({ tstart: Math.floor(this.props.currentTime) });
}
/** set annotation end time to current time */
setTendNow() {
// eslint-disable-next-line react/destructuring-assignment
this.setState({ tend: Math.floor(this.props.currentTime) });
}
/** */ /** */
async getImgDimensions(url) { async getImgDimensions(url) {
const { imgHeight, imgWidth, imgUrl } = this.state; const { imgHeight, imgWidth, imgUrl } = this.state;
...@@ -354,6 +378,34 @@ class AnnotationCreation extends Component { ...@@ -354,6 +378,34 @@ class AnnotationCreation extends Component {
}); });
} }
/** seekTo/goto annotation start time */
seekToTstart() {
const { paused, setCurrentTime, setSeekTo } = this.props;
const { tstart } = this.state;
if (!paused) {
this.setState(setSeekTo(tstart));
} else {
this.setState(setCurrentTime(tstart));
}
}
/** seekTo/goto annotation end time */
seekToTend() {
const { paused, setCurrentTime, setSeekTo } = this.props;
const { tend } = this.state;
if (!paused) {
this.setState(setSeekTo(tend));
} else {
this.setState(setCurrentTime(tend));
}
}
/** update annotation start time */
updateTstart(value) { this.setState({ tstart: value }); }
/** update annotation end time */
updateTend(value) { this.setState({ tend: value }); }
/** */ /** */
isConstrained(event) { // adjust other dimension in proportion to inputted dimension isConstrained(event) { // adjust other dimension in proportion to inputted dimension
const { imgConstrain, imgWidth, imgHeight } = this.state; const { imgConstrain, imgWidth, imgHeight } = this.state;
...@@ -385,47 +437,6 @@ class AnnotationCreation extends Component { ...@@ -385,47 +437,6 @@ class AnnotationCreation extends Component {
} }
} }
/** set annotation start time to current time */
setTstartNow() {
// eslint-disable-next-line react/destructuring-assignment
this.setState({ tstart: Math.floor(this.props.currentTime) });
}
/** set annotation end time to current time */
setTendNow() {
// eslint-disable-next-line react/destructuring-assignment
this.setState({ tend: Math.floor(this.props.currentTime) });
}
/** update annotation start time */
updateTstart(value) { this.setState({ tstart: value }); }
/** update annotation end time */
updateTend(value) { this.setState({ tend: value }); }
/** seekTo/goto annotation start time */
seekToTstart() {
const { paused, setCurrentTime, setSeekTo } = this.props;
const { tstart } = this.state;
if (!paused) {
this.setState(setSeekTo(tstart));
} else {
this.setState(setCurrentTime(tstart));
}
}
/** seekTo/goto annotation end time */
seekToTend() {
const { paused, setCurrentTime, setSeekTo } = this.props;
const { tend } = this.state;
if (!paused) {
this.setState(setSeekTo(tend));
} else {
this.setState(setCurrentTime(tend));
}
}
/** */ /** */
openChooseColor(e) { openChooseColor(e) {
this.setState({ this.setState({
...@@ -470,9 +481,10 @@ class AnnotationCreation extends Component { ...@@ -470,9 +481,10 @@ class AnnotationCreation extends Component {
textBody, image, imgWidth, imgHeight, imgUrl, tags, xywh, svg, textBody, image, imgWidth, imgHeight, imgUrl, tags, xywh, svg,
imgConstrain, tstart, tend, textEditorStateBustingKey, imgConstrain, tstart, tend, textEditorStateBustingKey,
} = this.state; } = this.state;
const annoBody = { value: textBody };
const t = (tstart && tend) ? `${tstart},${tend}` : null; const t = (tstart && tend) ? `${tstart},${tend}` : null;
const annoBody = { value: (!textBody.length && t) ? `${secondsToHMS(tstart)} -> ${secondsToHMS(tend)}` : textBody };
let imgBody;
if (imgWidth.validity === 1 && imgHeight.validity === 1 && imgUrl.validity === 1) { if (imgWidth.validity === 1 && imgHeight.validity === 1 && imgUrl.validity === 1) {
imgBody = { imgBody = {
constrain: imgConstrain, constrain: imgConstrain,
...@@ -488,7 +500,7 @@ class AnnotationCreation extends Component { ...@@ -488,7 +500,7 @@ class AnnotationCreation extends Component {
const storageAdapter = config.annotation.adapter(canvas.id); const storageAdapter = config.annotation.adapter(canvas.id);
const anno = new WebAnnotation({ const anno = new WebAnnotation({
body: (!annoBody.length && t) ? `${secondsToHMS(tstart)} -> ${secondsToHMS(tend)}` : annoBody, body: annoBody,
canvasId: canvas.id, canvasId: canvas.id,
fragsel: { t, xywh }, fragsel: { t, xywh },
id: (annotation && annotation.id) || `${uuid()}`, id: (annotation && annotation.id) || `${uuid()}`,
...@@ -510,9 +522,10 @@ class AnnotationCreation extends Component { ...@@ -510,9 +522,10 @@ class AnnotationCreation extends Component {
}); });
this.setState({ this.setState({
textBody: '', image: false,
svg: null, svg: null,
tend: null, tend: null,
textBody: '',
textEditorStateBustingKey: textEditorStateBustingKey + 1, textEditorStateBustingKey: textEditorStateBustingKey + 1,
tstart: null, tstart: null,
xywh: null, xywh: null,
...@@ -554,7 +567,8 @@ class AnnotationCreation extends Component { ...@@ -554,7 +567,8 @@ class AnnotationCreation extends Component {
const { const {
activeTool, colorPopoverOpen, currentColorType, fillColor, openAddImgDialog, popoverAnchorEl, activeTool, colorPopoverOpen, currentColorType, fillColor, openAddImgDialog, popoverAnchorEl,
strokeColor, popoverLineWeightAnchorEl, lineWeightPopoverOpen, strokeWidth, closedMode, strokeColor, popoverLineWeightAnchorEl, lineWeightPopoverOpen, strokeWidth, closedMode,
textBody, imgUrl, imgWidth, imgHeight, imgConstrain, svg, tstart, tend, textEditorStateBustingKey, textBody, imgUrl, imgWidth, imgHeight, imgConstrain, svg, tstart, tend,
textEditorStateBustingKey, image,
} = this.state; } = this.state;
const mediaIsVideo = typeof VideosReferences.get(windowId) !== 'undefined'; const mediaIsVideo = typeof VideosReferences.get(windowId) !== 'undefined';
...@@ -705,7 +719,7 @@ class AnnotationCreation extends Component { ...@@ -705,7 +719,7 @@ class AnnotationCreation extends Component {
<Grid item xs={12}> <Grid item xs={12}>
<Typography variant="overline"> <Typography variant="overline">
<ToggleButton value="true" title="Go to start time" size="small" onClick={this.seekToTend} className={classes.timecontrolsbutton}> <ToggleButton value="true" title="Go to end time" size="small" onClick={this.seekToTend} className={classes.timecontrolsbutton}>
<LastPage /> <LastPage />
</ToggleButton> </ToggleButton>
End End
...@@ -727,7 +741,8 @@ class AnnotationCreation extends Component { ...@@ -727,7 +741,8 @@ class AnnotationCreation extends Component {
</Grid> </Grid>
<Grid item xs={12} style={{ marginBottom: 10 }}> <Grid item xs={12} style={{ marginBottom: 10 }}>
<ToggleButton value="image-icon" aria-label="insert an image" onClick={() => this.handleImgDialogChange(true)}> <ToggleButton value="image-icon" aria-label="insert an image" onClick={() => this.handleImgDialogChange(true)}>
<InsertPhotoIcon /> { image === false && <InsertPhotoIcon /> }
{ image !== false && <img src={image.id} width="100" height="auto" alt="loading failed" /> }
</ToggleButton> </ToggleButton>
</Grid> </Grid>
<Dialog open={openAddImgDialog} fullWidth onClose={() => this.handleImgDialogChange(false)} aria-labelledby="form-dialog-title"> <Dialog open={openAddImgDialog} fullWidth onClose={() => this.handleImgDialogChange(false)} aria-labelledby="form-dialog-title">
......
...@@ -19,7 +19,7 @@ export default class WebAnnotation { ...@@ -19,7 +19,7 @@ export default class WebAnnotation {
return { return {
body: this.createBody(), body: this.createBody(),
id: this.id, id: this.id,
motivation: 'supplementing', motivation: 'commenting',
target: this.target(), target: this.target(),
type: 'Annotation', type: 'Annotation',
}; };
...@@ -37,12 +37,11 @@ export default class WebAnnotation { ...@@ -37,12 +37,11 @@ export default class WebAnnotation {
bodies.push(textBody); bodies.push(textBody);
} }
// TODO correct WebAnnotation format
if (this.image) { if (this.image) {
const imgBody = { const imgBody = { type: 'Image' };
format: 'image/jpg', Object.assign(imgBody, this.image);
id: this.image.url, imgBody.id = imgBody.url;
type: 'Image',
};
bodies.push(imgBody); bodies.push(imgBody);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment