From 2aad507650fa3263ef81be759ab0531b43e5b7cc Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 27 Jul 2020 15:44:29 +0200 Subject: annotation form for curtain events. refactor utilities --- .../components/annotations/annotation.form.css | 55 +++++++++++++++ .../components/annotations/annotation.form.js | 37 ++++++---- .../components/annotations/annotation.index.css | 76 ++++++++++++++++++++ .../components/annotations/annotation.index.js | 6 +- .../annotationForms/annotationForm.utility.js | 80 ++++++++++++++++++++++ .../annotations/annotationForms/index.js | 11 ++- .../annotationTypes/annotationTypes.image.js | 4 +- .../annotationTypes/annotationTypes.util.js | 28 -------- .../annotationTypes/annotationTypes.utility.js | 42 ++++++++++++ .../annotationTypes/annotationTypes.video.js | 4 +- .../annotations/annotationTypes/index.js | 5 ++ 11 files changed, 295 insertions(+), 53 deletions(-) create mode 100644 animism-align/frontend/app/views/align/components/annotations/annotation.form.css create mode 100644 animism-align/frontend/app/views/align/components/annotations/annotation.index.css create mode 100644 animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.utility.js delete mode 100644 animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.util.js create mode 100644 animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.utility.js (limited to 'animism-align/frontend/app/views/align/components/annotations') diff --git a/animism-align/frontend/app/views/align/components/annotations/annotation.form.css b/animism-align/frontend/app/views/align/components/annotations/annotation.form.css new file mode 100644 index 0000000..fdb4abe --- /dev/null +++ b/animism-align/frontend/app/views/align/components/annotations/annotation.form.css @@ -0,0 +1,55 @@ +/* Annotation form */ + +.annotationForm { + width: 401px; + padding: 0.5rem; + position: absolute; + left: 0.25rem; + background: #448; + box-shadow: 0 0 2px #000, 0 0 4px #000; + z-index: 10; +} +.annotationForm textarea { + width: 100%; +} +.annotationForm .row { + justify-content: space-between; + align-items: center; +} +.annotationForm .row > div { + display: flex; + align-items: center; +} +.annotationForm .buttons { + margin-bottom: 0.5rem; +} +.annotationForm .ts { + color: #fff; +} +.annotationForm .select.media_id { + width: 100%; + margin-right: 0; +} +.annotationForm .options label span:first-child { + display: inline-block; + width: 6rem; +} +.annotationForm .options .description { + font-size: 0.75rem; + margin-top: 0.25rem; + margin-bottom: 0.5rem; +} +.annotationForm .color input[type="text"].number { + width: 8rem; +} +.annotationForm .color input[type="text"] { + width: 8rem; +} +.annotationForm .color input[type="color"] { + background: transparent; + border: 0; + height: 1.7rem; + padding: 0; + margin: 0 0.5rem 0 0; + width: 1.4rem; +} diff --git a/animism-align/frontend/app/views/align/components/annotations/annotation.form.js b/animism-align/frontend/app/views/align/components/annotations/annotation.form.js index f4620bc..7882884 100644 --- a/animism-align/frontend/app/views/align/components/annotations/annotation.form.js +++ b/animism-align/frontend/app/views/align/components/annotations/annotation.form.js @@ -7,18 +7,16 @@ import actions from 'app/actions' import { ZOOM_STEPS } from 'app/constants' import { clamp, timestamp, capitalize } from 'app/utils' -import { timeToPosition } from 'app/views/align/align.util' +import { timeToPosition } from 'app/utils/align.utils' import { Select } from 'app/common' -import { - AnnotationFormVideo, - AnnotationFormImage, -} from './annotationForms' +import { annotationFormLookup } from './annotationForms' const ANNOTATION_TYPES = [ 'sentence', 'header', 'paragraph_end', 'video', 'image', 'image_carousel', + 'curtain', ].map(name => ({ name, label: capitalize(name.replace('_', ' ')) })) class AnnotationForm extends Component { @@ -26,6 +24,7 @@ class AnnotationForm extends Component { super(props) this.handleChange = this.handleChange.bind(this) this.handleSelect = this.handleSelect.bind(this) + this.handleSettingsChange = this.handleSettingsChange.bind(this) this.handleSettingsSelect = this.handleSettingsSelect.bind(this) this.handleKeyDown = this.handleKeyDown.bind(this) this.handleSubmit = this.handleSubmit.bind(this) @@ -74,6 +73,10 @@ class AnnotationForm extends Component { handleSelect(name, value) { actions.align.updateAnnotationForm(name, value) } + handleSettingsChange(e) { + const { name, value } = e.target + this.handleSettingsSelect(name, value) + } handleSettingsSelect(name, value) { if (name.indexOf('_id') !== -1) value = parseInt(value) || 0 actions.align.updateAnnotationSettings(name, value) @@ -111,7 +114,7 @@ class AnnotationForm extends Component { } } render() { - const { timeline, annotation, media } = this.props + const { timeline, annotation } = this.props return (
- } - {annotation.type === 'image' && - - } - {annotation.type === 'image_carousel' && - - } + {(annotation.type in annotationFormLookup) && this.renderElementForm()}
) } @@ -169,6 +164,18 @@ class AnnotationForm extends Component { ) } + renderElementForm() { + const { annotation, media } = this.props + const AnnotationFormElement = annotationFormLookup[annotation.type] + return ( + + ) + } } const mapStateToProps = state => ({ diff --git a/animism-align/frontend/app/views/align/components/annotations/annotation.index.css b/animism-align/frontend/app/views/align/components/annotations/annotation.index.css new file mode 100644 index 0000000..d39e5de --- /dev/null +++ b/animism-align/frontend/app/views/align/components/annotations/annotation.index.css @@ -0,0 +1,76 @@ +/* Annotation index */ + +.annotationIndex { + width: 800px; +} +.annotationIndex .annotation { + position: absolute; + left: 5px; + max-width: 400px; + padding: 0.25rem 0.375rem; + box-shadow: 0px 0px 3px rgba(0,0,0,1.0); + border: 1px solid transparent; + border-radius: 2px; + font-size: 12px; + cursor: pointer; + user-select: none; + background-color: #768; +} +.annotation.selected { + border-color: #bbf; + box-shadow: 0px 0px 4px rgba(0,0,0,1.0), 0px 0px 2px rgba(0,0,0,1.0); + z-index: 1; + background-image: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.4)); +} +.annotationIndex .annotation.media { + left: calc(405px + 0.5rem); +} +.annotation.sentence.even { + background-color: #83b; +} +.annotation.sentence.odd { + background-color: #537; +} +.annotation.header { + background-color: #838; +} +.annotation.paragraph_end { + background-color: #003; + border-top: 1px solid #888; + width: 100%; + padding: 1px; +} +.annotationIndex .annotation.utility { + left: calc(405px + 0.5rem); +} + + +/* Condensed layout (first lines) */ + +.annotationIndex.condensed .annotation.sentence { + z-index: 0; + white-space: pre; + overflow: hidden; + text-overflow: ellipsis; +} +.annotationIndex.condensed .annotation.header { + z-index: 1; +} +.annotationIndex.condensed .annotation.paragraph_end { + border-top-color: #888; +} + +/* Collapsed layout (borders) */ + +.annotationIndex.collapsed .annotation.sentence { + height: 2px; overflow: hidden; padding: 0; z-index: 0; +} +.annotationIndex.collapsed .annotation.sentence.selected { + z-index: 1; +} +.annotationIndex.collapsed .annotation.header { + z-index: 2; +} +.annotationIndex.collapsed .annotation.paragraph_end { + border-top-color: #333; +} diff --git a/animism-align/frontend/app/views/align/components/annotations/annotation.index.js b/animism-align/frontend/app/views/align/components/annotations/annotation.index.js index aa31268..da1038f 100644 --- a/animism-align/frontend/app/views/align/components/annotations/annotation.index.js +++ b/animism-align/frontend/app/views/align/components/annotations/annotation.index.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react' +import React, { PureComponent } from 'react' import { bindActionCreators } from 'redux' import { connect } from 'react-redux' @@ -6,11 +6,11 @@ import actions from 'app/actions' import { ZOOM_STEPS, INNER_HEIGHT } from 'app/constants' import { clamp } from 'app/utils' -import { positionToTime, timeToPosition } from 'app/views/align/align.util' +import { positionToTime, timeToPosition } from 'app/utils/align.utils' import { AnnotationElementLookup } from './annotationTypes' -class AnnotationIndex extends Component { +class AnnotationIndex extends PureComponent { state = { items: [], } diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.utility.js b/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.utility.js new file mode 100644 index 0000000..2b6f868 --- /dev/null +++ b/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.utility.js @@ -0,0 +1,80 @@ +import React, { Component } from 'react' + +import { timestamp } from 'app/utils' +import { TextInput, LabelDescription, Select } from 'app/common' +import { CURTAIN_COLOR_SELECT_OPTIONS } from 'app/constants' +import { curtainTimings } from 'app/utils/annotation.utils' + +export const AnnotationFormCurtain = ({ annotation, handleSettingsChange, handleSettingsSelect }) => { + const { + fadeInDurationInSeconds, fadeOutDurationInSeconds, durationInSeconds, + start_ts, end_ts, fade_in_end_ts, fade_out_start_ts, + } = curtainTimings(annotations) + + return ( +
+ + + {durationInSeconds} + {' seconds, ends at '} + {timestamp(end_ts)} + + + + + {fadeInDurationInSeconds} + {' seconds, ends at '} + {timestamp(fade_in_end_ts)} + + + + + {fadeOutDurationInSeconds} + {' seconds, starts at '} + {timestamp(fade_out_start_ts)} + + +