diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-07-22 14:05:15 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-07-22 14:05:15 +0200 |
| commit | ef78bc6a084f92b4794e987b5832240d85b6479e (patch) | |
| tree | b314b630800db6aa60f28ef0b115625e6ca176db /animism-align/frontend/app/views/paragraph/components/paragraph.list.js | |
| parent | 85d4cb9addf9ca887d3440b2786665d67d9917c4 (diff) | |
refactor app using babel module-resolver
Diffstat (limited to 'animism-align/frontend/app/views/paragraph/components/paragraph.list.js')
| -rw-r--r-- | animism-align/frontend/app/views/paragraph/components/paragraph.list.js | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/animism-align/frontend/app/views/paragraph/components/paragraph.list.js b/animism-align/frontend/app/views/paragraph/components/paragraph.list.js new file mode 100644 index 0000000..1b8a0ac --- /dev/null +++ b/animism-align/frontend/app/views/paragraph/components/paragraph.list.js @@ -0,0 +1,165 @@ +import React, { Component } from 'react' +import { Route } from 'react-router-dom' +import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' + +import { floatLT, floatLTE } from 'app/utils' +import actions from 'app/actions' +import ParagraphForm from '../components/paragraph.form' + +const MEDIA_TYPES = new Set([ + 'image', 'gallery', 'vitrine', + 'video', +]) + +class ParagraphList extends Component { + state = { + paragraphs: [], + currentParagraph: -1, + currentAnnotation: -1, + } + + componentDidMount() { + this.build() + } + + componentDidUpdate(prevProps) { + if (this.props.paragraph !== prevProps.paragraph) { + this.build() + } + if (this.props.audio.play_ts === prevProps.audio.play_ts) return + this.setCurrentParagraph() + } + + setCurrentParagraph() { + const { play_ts } = this.props.audio + const insideParagraph = this.state.paragraphs.some(paragraph => { + if (floatLTE(paragraph.start_ts, play_ts) && floatLT(play_ts, paragraph.end_ts)) { + this.setCurrentAnnotation(paragraph, play_ts) + return true + } + return false + }) + if (!insideParagraph) { + this.setState({ + currentParagraph: -1, + currentAnnotation: -1, + }) + } + } + + setCurrentAnnotation(paragraph, play_ts) { + const { id: currentParagraph, annotations } = paragraph + let currentAnnotation + let annotation + let i = 0 + let len = annotations.length + for (let i = 0; i < len - 1; i++) { + if (floatLT(play_ts, annotations[i+1].start_ts)) { + currentAnnotation = annotations[i].id + break + } + } + if (!currentAnnotation) { + currentAnnotation = annotations[len-1].id + } + this.setState({ currentParagraph, currentAnnotation }) + } + + build() { + const { order: annotationOrder, lookup: annotationLookup } = this.props.annotation + const { lookup: paragraphLookup } = this.props.paragraph + let currentParagraph = {} + const paragraphs = [] + // loop over the annotations in time order + annotationOrder.forEach((annotation_id, i) => { + const annotation = annotationLookup[annotation_id] + const paragraph = paragraphLookup[annotation.paragraph_id] + // if this annotation is media, insert it after the current paragraph + if (MEDIA_TYPES.has(annotation.type)) { + paragraphs.push({ + id: ('index_' + i), + type: annotation.type, + start_ts: annotation.start_ts, + end_ts: 0, + annotations: [annotation], + }) + return + } + // if this annotation is from a different paragraph, make a new paragraph + if (annotation.paragraph_id !== currentParagraph.id) { + const paragraph_type = getParagraphType(annotation, paragraph) + currentParagraph = { + id: annotation.paragraph_id || ('index_' + i), + type: paragraph_type, + start_ts: annotation.start_ts, + end_ts: 0, + annotations: [], + } + paragraphs.push(currentParagraph) + } + // if this annotation is a paragraph_end, set the end timestamp + if (annotation.type === 'paragraph_end') { + currentParagraph.end_ts = annotation.start_ts + } + // otherwise, just append this annotation to the paragraph + else { + currentParagraph.annotations.push(annotation) + } + }) + for (let i = 0; i < (paragraphs.length - 1); i++) { + if (!paragraphs[i].end_ts) { + paragraphs[i].end_ts = paragraphs[i+1].start_ts - 0.1 + } + } + this.setState({ paragraphs }) + } + + render() { + const { + media, paragraphElementLookup, selectedParagraph, + onAnnotationClick, onParagraphDoubleClick + } = this.props + const { paragraphs, currentParagraph, currentAnnotation } = this.state + return paragraphs.map(paragraph => { + if (selectedParagraph && selectedParagraph.id === paragraph.id) { + paragraph = selectedParagraph + } + if (paragraph.type in paragraphElementLookup) { + const ParagraphElement = paragraphElementLookup[paragraph.type] + return ( + <ParagraphElement + key={paragraph.id} + paragraph={paragraph} + media={media} + currentParagraph={paragraph.id === currentParagraph} + currentAnnotation={paragraph.id === currentParagraph && currentAnnotation} + onAnnotationClick={onAnnotationClick} + onDoubleClick={onParagraphDoubleClick} + /> + ) + } else { + return <div key={paragraph.id}>{'(waiting to implement' + paragraph.type + ')'}</div> + } + }) + } +} + +const getParagraphType = (annotation, paragraph) => { + if (!paragraph) { + return annotation.type + } + return paragraph.type +} + +const mapStateToProps = state => ({ + paragraph: state.paragraph.index, + annotation: state.annotation.index, + audio: state.audio, + media: state.media.index, +}) + +const mapDispatchToProps = dispatch => ({ +}) + +export default connect(mapStateToProps, mapDispatchToProps)(ParagraphList) |
