diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-07-08 23:37:40 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-07-08 23:37:40 +0200 |
| commit | 18472645a7879baf00332a7ee5be8c4338bb8d21 (patch) | |
| tree | fc3f57803f605e4942aac010a0f7c528d0d0386c /animism-align/frontend/views/align/components | |
| parent | f7cf600fe1abc92ddccdbadf30315d6f9785994f (diff) | |
adding annotations of type video
Diffstat (limited to 'animism-align/frontend/views/align/components')
3 files changed, 93 insertions, 15 deletions
diff --git a/animism-align/frontend/views/align/components/annotations/annotation.form.js b/animism-align/frontend/views/align/components/annotations/annotation.form.js index 226bb45..0a71233 100644 --- a/animism-align/frontend/views/align/components/annotations/annotation.form.js +++ b/animism-align/frontend/views/align/components/annotations/annotation.form.js @@ -12,7 +12,7 @@ import { timeToPosition } from '../../align.util' import { Select } from '../../../../common' const ANNOTATION_TYPES = [ - 'sentence', 'header', 'paragraph_end' + 'sentence', 'header', 'paragraph_end', 'video', ].map(name => ({ name, label: name })) class AnnotationForm extends Component { @@ -20,6 +20,7 @@ class AnnotationForm extends Component { super(props) this.handleChange = this.handleChange.bind(this) this.handleSelect = this.handleSelect.bind(this) + this.handleSettingsSelect = this.handleSettingsSelect.bind(this) this.handleKeyDown = this.handleKeyDown.bind(this) this.handleSubmit = this.handleSubmit.bind(this) this.textareaRef = React.createRef() @@ -66,6 +67,10 @@ class AnnotationForm extends Component { handleSelect(name, value) { actions.align.updateAnnotationForm(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') { @@ -96,21 +101,28 @@ class AnnotationForm extends Component { top: timeToPosition(annotation.start_ts, timeline), }} > + {this.renderButtons()} {annotation.type === 'sentence' && this.renderTextarea()} {annotation.type === 'header' && this.renderTextarea()} - <div className='row buttons'> - <div> - <Select - name='type' - selected={annotation.type} - options={ANNOTATION_TYPES} - defaultOption='text' - onChange={this.handleSelect} - /> - <div className='ts'>{timestamp(annotation.start_ts, 1, true)}</div> - </div> - <button onClick={this.handleSubmit}>Save</button> + {annotation.type === 'video' && this.renderVideo()} + </div> + ) + } + renderButtons() { + const { annotation } = this.props + return ( + <div className='row buttons'> + <div> + <Select + name='type' + selected={annotation.type} + options={ANNOTATION_TYPES} + defaultOption='text' + onChange={this.handleSelect} + /> + <div className='ts'>{timestamp(annotation.start_ts, 1, true)}</div> </div> + <button onClick={this.handleSubmit}>Save</button> </div> ) } @@ -128,11 +140,36 @@ class AnnotationForm extends Component { </div> ) } + renderVideo() { + const { annotation, media } = this.props + if (!media.lookup) return <div /> + const { lookup, order } = media + const video_list_items = order.filter(id => lookup[id].type === 'video').map(id => { + const video = lookup[id] + return { + name: video.id, + label: video.author + ' - ' + video.title + } + }) + return ( + <div> + <Select + name='media_id' + className="media_id" + selected={annotation.settings.media_id} + options={video_list_items} + defaultOption='Choose a video' + onChange={this.handleSettingsSelect} + /> + </div> + ) + } } const mapStateToProps = state => ({ annotation: state.align.annotation, timeline: state.align.timeline, + media: state.media.index, }) const mapDispatchToProps = dispatch => ({ diff --git a/animism-align/frontend/views/align/components/annotations/annotation.index.js b/animism-align/frontend/views/align/components/annotations/annotation.index.js index eccd8b7..3a78dd4 100644 --- a/animism-align/frontend/views/align/components/annotations/annotation.index.js +++ b/animism-align/frontend/views/align/components/annotations/annotation.index.js @@ -75,7 +75,7 @@ class AnnotationIndex extends Component { actions.align.showEditAnnotationForm(annotation) } render() { - const { timeline, annotationInForm } = this.props + const { timeline, media, annotationInForm } = this.props const { start_ts, zoom, selected_annotation_id } = timeline const { items } = this.state const className = (zoom < 2) @@ -98,6 +98,7 @@ class AnnotationIndex extends Component { y={y} selected={annotation.id === selected_annotation_id} annotation={annotation} + media={media} onClick={this.handleClick} onDoubleClick={this.handleDoubleClick} /> @@ -112,6 +113,7 @@ const mapStateToProps = state => ({ timeline: state.align.timeline, annotationInForm: state.align.annotation, index: state.annotation.index, + media: state.media.index, }) const mapDispatchToProps = dispatch => ({ diff --git a/animism-align/frontend/views/align/components/annotations/annotation.types.js b/animism-align/frontend/views/align/components/annotations/annotation.types.js index 06be4a8..b927a12 100644 --- a/animism-align/frontend/views/align/components/annotations/annotation.types.js +++ b/animism-align/frontend/views/align/components/annotations/annotation.types.js @@ -4,7 +4,7 @@ import actions from '../../../../actions' import { ZOOM_STEPS } from '../../constants' import { clamp } from '../../../../util' -import { positionToTime, timeToPosition } from '../../align.util' +import { positionToTime, timeToPosition, thumbnailURL } from '../../align.util' export const AnnotationSentence = ({ y, annotation, selected, onClick, onDoubleClick }) => { const { start_ts, text, paragraph_id } = annotation @@ -55,8 +55,47 @@ export const AnnotationParagraphEnd = ({ y, annotation, selected, onClick, onDou ) } +export const AnnotationVideo = ({ y, annotation, media, selected, onClick, onDoubleClick }) => { + const { start_ts, text } = annotation + const className = selected ? 'annotation media video selected' : 'annotation media video' + if (!(annotation.settings.media_id in media)) { + return ( + <div + className={className} + style={{ top: y }} + onClick={e => onClick(e, annotation)} + onDoubleClick={e => onDoubleClick(e, annotation)} + >MEDIA NOT FOUND</div> + ) + } + const data = media[annotation.settings.media_id] + return ( + <div + className={className} + style={{ top: y }} + onClick={e => onClick(e, annotation)} + onDoubleClick={e => onDoubleClick(e, annotation)} + > + <div className='img'> + <Link to={"/media/" + data.id + "/edit/"}> + <img src={thumbnailURL(data)} alt={data.title} /> + </Link> + </div> + <div className='meta center'> + <div> + <i>{data.title}</i><br /> + {data.author}<br /> + {data.date} + </div> + </div> + </div> + ) +} + + export const AnnotationElementLookup = { sentence: React.memo(AnnotationSentence), header: React.memo(AnnotationHeader), paragraph_end: React.memo(AnnotationParagraphEnd), + video: React.memo(AnnotationVideo), } |
