From d2cb17038b8537a609be06be2ed7013dbe27117e Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 8 Mar 2021 22:11:55 +0100 Subject: beginning the BIG refactor. moving editor stuff into per-episode hierarchy --- .../components/annotations/annotation.form.css | 67 ++++++++ .../components/annotations/annotation.form.js | 190 +++++++++++++++++++++ .../components/annotations/annotation.index.css | 125 ++++++++++++++ .../components/annotations/annotation.index.js | 125 ++++++++++++++ .../annotationForms/annotationForm.gallery.js | 132 ++++++++++++++ .../annotationForms/annotationForm.image.js | 120 +++++++++++++ .../annotationForms/annotationForm.text.js | 153 +++++++++++++++++ .../annotationForms/annotationForm.utility.js | 172 +++++++++++++++++++ .../annotationForms/annotationForm.video.js | 160 +++++++++++++++++ .../annotations/annotationForms/index.js | 46 +++++ .../annotationTypes/annotationTypes.gallery.js | 75 ++++++++ .../annotationTypes/annotationTypes.image.js | 54 ++++++ .../annotationTypes/annotationTypes.text.js | 121 +++++++++++++ .../annotationTypes/annotationTypes.utility.js | 107 ++++++++++++ .../annotationTypes/annotationTypes.video.js | 51 ++++++ .../annotations/annotationTypes/index.js | 57 +++++++ .../components/player/playButton.component.js | 22 +++ .../align/components/sidebar/script.component.js | 23 +++ .../sidebar/tableOfContents.component.js | 30 ++++ .../align/components/timeline/cursor.component.js | 26 +++ .../components/timeline/cursorRegion.component.js | 28 +++ .../components/timeline/playCursor.component.js | 36 ++++ .../align/components/timeline/ticks.component.js | 88 ++++++++++ .../components/timeline/waveform.component.js | 105 ++++++++++++ 24 files changed, 2113 insertions(+) create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotation.form.css create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotation.form.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotation.index.css create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotation.index.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotationForms/annotationForm.gallery.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotationForms/annotationForm.image.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotationForms/annotationForm.text.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotationForms/annotationForm.utility.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotationForms/annotationForm.video.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotationForms/index.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotationTypes/annotationTypes.gallery.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotationTypes/annotationTypes.image.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotationTypes/annotationTypes.text.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotationTypes/annotationTypes.utility.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotationTypes/annotationTypes.video.js create mode 100644 animism-align/frontend/app/views/editor/align/components/annotations/annotationTypes/index.js create mode 100644 animism-align/frontend/app/views/editor/align/components/player/playButton.component.js create mode 100644 animism-align/frontend/app/views/editor/align/components/sidebar/script.component.js create mode 100644 animism-align/frontend/app/views/editor/align/components/sidebar/tableOfContents.component.js create mode 100644 animism-align/frontend/app/views/editor/align/components/timeline/cursor.component.js create mode 100644 animism-align/frontend/app/views/editor/align/components/timeline/cursorRegion.component.js create mode 100644 animism-align/frontend/app/views/editor/align/components/timeline/playCursor.component.js create mode 100644 animism-align/frontend/app/views/editor/align/components/timeline/ticks.component.js create mode 100644 animism-align/frontend/app/views/editor/align/components/timeline/waveform.component.js (limited to 'animism-align/frontend/app/views/editor/align/components') diff --git a/animism-align/frontend/app/views/editor/align/components/annotations/annotation.form.css b/animism-align/frontend/app/views/editor/align/components/annotations/annotation.form.css new file mode 100644 index 0000000..fa663c7 --- /dev/null +++ b/animism-align/frontend/app/views/editor/align/components/annotations/annotation.form.css @@ -0,0 +1,67 @@ +/* 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 div.textarea { + margin-bottom: 0.5rem; +} +.annotationForm img { + max-width: 100%; + max-height: 6rem; +} + +.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; +} +.annotationForm .checkbox { + margin-top: 0.5rem; + margin-bottom: 0.5rem; +} \ No newline at end of file diff --git a/animism-align/frontend/app/views/editor/align/components/annotations/annotation.form.js b/animism-align/frontend/app/views/editor/align/components/annotations/annotation.form.js new file mode 100644 index 0000000..7b1918a --- /dev/null +++ b/animism-align/frontend/app/views/editor/align/components/annotations/annotation.form.js @@ -0,0 +1,190 @@ +import React, { Component } from 'react' +// import { Link } from 'react-router-dom' +import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' + +import actions from 'app/actions' + +import { ANNOTATION_SELECT_OPTIONS, MEDIA_ANNOTATION_TYPES } from 'app/constants' +import { timestamp } from 'app/utils' +import { timeToPosition } from 'app/utils/align.utils' +import { Select } from 'app/common' + +import { annotationFormLookup } from './annotationForms' + +const annotationTextTypes = new Set([ + 'sentence', 'section_heading', 'heading_text', 'pullquote_credit', 'footnote', 'text_plate', +]) + +class AnnotationForm extends Component { + constructor(props){ + 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) + this.handleDestroy = this.handleDestroy.bind(this) + this.textareaRef = React.createRef() + } + componentDidMount() { + if (this.textareaRef && this.textareaRef.current) { + this.textareaRef.current.focus() + } + } + handleKeyDown(e) { + if (e.keyCode === 27) { // escape + actions.align.hideAnnotationForm() + return + } + // console.log(e.keyCode) + if (!e.metaKey && !e.ctrlKey) return + let { start_ts } = this.props.annotation + switch (e.keyCode) { + case 38: // up + e.preventDefault() + start_ts -= 0.1 + actions.align.updateAnnotationForm('start_ts', Math.max(0, start_ts)) + actions.audio.seek(start_ts) + actions.align.setCursor(start_ts) + break + case 40: // down + e.preventDefault() + start_ts += 0.1 + actions.align.updateAnnotationForm('start_ts', Math.max(0, start_ts)) + actions.audio.seek(start_ts) + actions.align.setCursor(start_ts) + break + case 83: // ctrl-S + e.preventDefault() + this.handleSubmit() + default: + break + } + } + handleChange(e) { + const { name, value } = e.target + this.handleSelect(name, value) + } + 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) + } + handleSubmit() { + const { annotation } = this.props + if (annotation.type === 'paragraph_end') { + annotation.text = '' + } + if (annotation.type in MEDIA_ANNOTATION_TYPES) { + if (!annotation.settings.media_id) return + annotation.text = '' + } + if (annotation.id === 'new') { + delete annotation.id + actions.annotation.create(annotation) + .then(response => { + console.log(response) + actions.align.hideAnnotationForm() + }) + } else { + actions.annotation.update(annotation) + .then(response => { + console.log(response) + actions.align.hideAnnotationForm() + }) + } + } + handleDestroy() { + const { annotation } = this.props + if (annotation.id === 'new') { + actions.align.hideAnnotationForm() + } else { + actions.annotation.destroy(annotation) + .then(response => { + console.log(response) + actions.align.hideAnnotationForm() + }) + } + } + render() { + const { timeline, annotation } = this.props + return ( +
+ {this.renderButtons()} + {annotationTextTypes.has(annotation.type) && this.renderTextarea()} + {(annotation.type in annotationFormLookup) && this.renderElementForm()} +
+ ) + } + renderButtons() { + const { annotation } = this.props + return ( +
+
+