diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-07-06 19:28:29 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-07-06 19:28:29 +0200 |
| commit | 07294becb5823b387e6b0ae8caae190a8b08551d (patch) | |
| tree | 6ba377768f56aac219425973c7a1e57af230e7ec | |
| parent | 6f5ff3cdfac3fc154281fdda7c1ec9ff7ebbd1fa (diff) | |
highlight the current paragraph
5 files changed, 128 insertions, 21 deletions
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 f95589d..a2eae62 100644 --- a/animism-align/frontend/views/align/components/annotations/annotation.types.js +++ b/animism-align/frontend/views/align/components/annotations/annotation.types.js @@ -41,7 +41,23 @@ export const AnnotationHeader = ({ y, annotation, selected, onClick, onDoubleCli ) } +export const AnnotationParagraphEnd = ({ y, annotation, selected, onClick, onDoubleClick }) => { + const { start_ts, text } = annotation + const className = selected ? 'annotation paragraph_end selected' : 'annotation paragraph_end' + return ( + <div + className={className} + style={{ top: y }} + onClick={e => onClick(e, annotation)} + onDoubleClick={e => onDoubleClick(e, annotation)} + > + {text} + </div> + ) +} + export const AnnotationElementLookup = { - sentence: AnnotationSentence, - header: AnnotationHeader, -}
\ No newline at end of file + sentence: React.memo(AnnotationSentence), + header: React.memo(AnnotationHeader), + paragraph_end: React.memo(AnnotationParagraphEnd), +} diff --git a/animism-align/frontend/views/paragraph/components/paragraph.types.js b/animism-align/frontend/views/paragraph/components/paragraph.types.js index c200a19..daab5db 100644 --- a/animism-align/frontend/views/paragraph/components/paragraph.types.js +++ b/animism-align/frontend/views/paragraph/components/paragraph.types.js @@ -3,7 +3,8 @@ import React, { Component } from 'react' import actions from '../../../actions' export const Paragraph = ({ paragraph, selectedParagraph, selectedAnnotation, onAnnotationClick, onDoubleClick }) => { - const className = paragraph.type + let className = paragraph.type + if (className !== 'paragraph') className += ' paragraph' if (selectedParagraph) className += ' selected' return ( <div @@ -16,7 +17,7 @@ export const Paragraph = ({ paragraph, selectedParagraph, selectedAnnotation, on className={annotation.id === selectedAnnotation ? 'selected' : ''} onClick={e => onAnnotationClick(e, paragraph, annotation)} > - {annotation.text} + {' '}{annotation.text}{' '} </span> ))} </div> @@ -24,7 +25,7 @@ export const Paragraph = ({ paragraph, selectedParagraph, selectedAnnotation, on } export const ParagraphHeader = ({ paragraph, selectedParagraph, selectedAnnotation, onAnnotationClick, onDoubleClick }) => { - const className = selectedParagraph ? 'header selected' : 'header' + let className = selectedParagraph ? 'header selected' : 'header' const text = paragraph.annotations.map(annotation => annotation.text).join(' ') console.log(text) return ( @@ -38,7 +39,7 @@ export const ParagraphHeader = ({ paragraph, selectedParagraph, selectedAnnotati } export const ParagraphElementLookup = { - paragraph: Paragraph, - blockquote: Paragraph, - header: ParagraphHeader, + paragraph: React.memo(Paragraph), + blockquote: React.memo(Paragraph), + header: React.memo(ParagraphHeader), } diff --git a/animism-align/frontend/views/paragraph/containers/paragraphList.container.js b/animism-align/frontend/views/paragraph/containers/paragraphList.container.js index 059baff..8b61df5 100644 --- a/animism-align/frontend/views/paragraph/containers/paragraphList.container.js +++ b/animism-align/frontend/views/paragraph/containers/paragraphList.container.js @@ -6,9 +6,14 @@ import { connect } from 'react-redux' import actions from '../../../actions' import { ParagraphElementLookup } from '../components/paragraph.types' +const floatLT = (a,b) => ((a*10|0) < (b*10|0)) +const floatLTE = (a,b) => (a*10|0 === b*10|0 || floatLT(a,b)) + class ParagraphList extends Component { state = { paragraphs: [], + currentParagraph: -1, + currentAnnotation: -1, } constructor(props) { super(props) @@ -18,6 +23,37 @@ class ParagraphList extends Component { componentDidMount() { this.build() } + componentDidUpdate(prevProps) { + if (this.props.audio.play_ts === prevProps.audio.play_ts) return + this.setCurrentParagraph() + } + setCurrentParagraph() { + const { play_ts } = this.props.audio + 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 + }) + } + 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 @@ -31,22 +67,33 @@ class ParagraphList extends Component { currentParagraph = { id: annotation.paragraph_id || ('index_' + i), type: paragraph_type, + start_ts: annotation.start_ts, + end_ts: 0, annotations: [], } paragraphs.push(currentParagraph) } - currentParagraph.annotations.push(annotation) + if (annotation.type === 'paragraph_end') { + currentParagraph.end_ts = annotation.start_ts + } 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 }) } onAnnotationClick(e, paragraph, annotation){ - // + actions.audio.seek(annotation.start_ts) } onParagraphDoubleClick(e, paragraph) { // } render() { - const { paragraphs } = this.state + const { paragraphs, currentParagraph, currentAnnotation } = this.state return ( <div className='paragraphs'> <div className='content'> @@ -57,8 +104,8 @@ class ParagraphList extends Component { <ParagraphElement key={paragraph.id} paragraph={paragraph} - selectedParagraph={false} - selectedAnnotation={-1} + selectedParagraph={paragraph.id === currentParagraph} + selectedAnnotation={paragraph.id === currentParagraph && currentAnnotation} onAnnotationClick={this.onAnnotationClick} onDoubleClick={this.onParagraphDoubleClick} /> diff --git a/animism-align/frontend/views/paragraph/paragraph.container.js b/animism-align/frontend/views/paragraph/paragraph.container.js index ecd5417..13753a4 100644 --- a/animism-align/frontend/views/paragraph/paragraph.container.js +++ b/animism-align/frontend/views/paragraph/paragraph.container.js @@ -11,6 +11,36 @@ import { Loader } from '../../common' import ParagraphList from './containers/paragraphList.container' class ParagraphContainer extends Component { + componentDidMount() { + this.bind() + } + componentWillUnmount() { + this.unbind() + } + bind() { + document.addEventListener('keydown', this.handleKeydown) + } + unbind() { + document.removeEventListener('keydown', this.handleKeydown) + } + handleKeydown(e) { + if (document.activeElement !== document.body) { + return + } + // console.log(e.keyCode) + switch (e.keyCode) { + case 32: // spacebar + e.preventDefault() + actions.audio.toggle() + break + case 38: // up + actions.audio.jump(- ZOOM_STEPS[this.props.timeline.zoom] * 0.1) + break + case 40: // down + actions.audio.jump(ZOOM_STEPS[this.props.timeline.zoom] * 0.1) + break + } + } render() { if (!this.props.annotation.lookup || !this.props.paragraph.lookup) { return <div className='body loading'><Loader /></div> diff --git a/animism-align/frontend/views/paragraph/paragraph.css b/animism-align/frontend/views/paragraph/paragraph.css index e96fd4f..1915cd6 100644 --- a/animism-align/frontend/views/paragraph/paragraph.css +++ b/animism-align/frontend/views/paragraph/paragraph.css @@ -21,16 +21,29 @@ .paragraphs .paragraph { font-size: 16px; - line-height: 1.5; -} -.paragraphs .paragraph span:after { - content: ' '; + line-height: 24px; } .paragraphs .blockquote { - line-height: 1.5; padding-left: 3rem; } -.paragraphs .blockquote span:after { - content: ' '; + +.paragraphs span { + /*padding: 1px;*/ + margin-right: 4px; +} + +.paragraphs .paragraph.selected { + background: rgba(255,255,255,0.1); +} + + +.paragraphs .paragraph .selected { + box-shadow: -2px -3px 0 #fff, + 2px -3px 0 #fff, + -2px 3px 0 #fff, + 2px 3px 0 #fff; + box-decoration-break: clone; + background: #fff; + color: #000; }
\ No newline at end of file |
