diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-07-04 17:24:21 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-07-04 17:24:21 +0200 |
| commit | 82c2ac11f4ef2112a0332f2f9c7cdd52444f0d2a (patch) | |
| tree | 38ce15d8cb9dd71ec756a6b3a9d7cbebe5ff084a /animism-align/frontend/views/align/components/annotations | |
| parent | e973412b5ea29685f4fa260d8eb44baae095fb81 (diff) | |
displaying annotation list, click to select, doubleclick to show form, updating annotations
Diffstat (limited to 'animism-align/frontend/views/align/components/annotations')
3 files changed, 128 insertions, 1 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 9432948..b62c36e 100644 --- a/animism-align/frontend/views/align/components/annotations/annotation.form.js +++ b/animism-align/frontend/views/align/components/annotations/annotation.form.js @@ -24,9 +24,13 @@ class AnnotationForm extends Component { this.handleSubmit = this.handleSubmit.bind(this) } 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 - console.log(e.keyCode) switch (e.keyCode) { case 38: // up e.preventDefault() diff --git a/animism-align/frontend/views/align/components/annotations/annotation.index.js b/animism-align/frontend/views/align/components/annotations/annotation.index.js new file mode 100644 index 0000000..7b562c2 --- /dev/null +++ b/animism-align/frontend/views/align/components/annotations/annotation.index.js @@ -0,0 +1,83 @@ +import React, { Component } from 'react' +import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' + +import actions from '../../../../actions' + +import { ZOOM_STEPS } from '../../constants' +import { clamp } from '../../../../util' +import { positionToTime, timeToPosition } from '../../align.util' + +import { AnnotationElementLookup } from './annotation.types' + +class AnnotationIndex extends Component { + state = { + items: [], + } + constructor(props){ + super(props) + this.handleClick = this.handleClick.bind(this) + } + componentDidUpdate(prevProps) { + if (this.props.index.loading) return + if (prevProps.timeline !== this.props.timeline || prevProps.index !== this.props.index) { + this.update() + } + } + update() { + let { timeline, index } = this.props + let { start_ts, zoom, duration } = this.props.timeline + const { order, lookup } = index + + let secondsPerPixel = ZOOM_STEPS[zoom] * 0.1 // 0.1 sec / step + let widthTimeDuration = window.innerHeight * secondsPerPixel // secs per pixel + + let timeMin = start_ts - 30.0 + let timeMax = Math.min(start_ts + widthTimeDuration, duration) + + const items = order.filter(id => { + const { start_ts: ts } = lookup[id] + return (timeMin < ts && ts < timeMax) + }).map(id => lookup[id]) + this.setState({ items }) + } + handleClick(annotation) { + actions.audio.seek(annotation.start_ts) + } + handleDoubleClick(annotation) { + actions.align.showEditAnnotationForm(annotation) + } + render() { + const { timeline } = this.props + const { start_ts } = timeline + const { items } = this.state + return ( + <div className='annotationIndex'> + {items.map(annotation => { + const { id, type, start_ts } = annotation + const AnnotationElement = AnnotationElementLookup[type] + const y = timeToPosition(start_ts, timeline) + return ( + <AnnotationElement + key={id} + y={y} + annotation={annotation} + onClick={this.handleClick} + onDoubleClick={this.handleDoubleClick} + /> + ) + })} + </div> + ) + } +} + +const mapStateToProps = state => ({ + timeline: state.align.timeline, + index: state.annotation.index, +}) + +const mapDispatchToProps = dispatch => ({ +}) + +export default connect(mapStateToProps, mapDispatchToProps)(AnnotationIndex) diff --git a/animism-align/frontend/views/align/components/annotations/annotation.types.js b/animism-align/frontend/views/align/components/annotations/annotation.types.js new file mode 100644 index 0000000..465844f --- /dev/null +++ b/animism-align/frontend/views/align/components/annotations/annotation.types.js @@ -0,0 +1,40 @@ +import React, { Component } from 'react' + +import actions from '../../../../actions' + +import { ZOOM_STEPS } from '../../constants' +import { clamp } from '../../../../util' +import { positionToTime, timeToPosition } from '../../align.util' + +export const AnnotationSentence = ({ y, annotation, onClick, onDoubleClick }) => { + const { start_ts, text } = annotation + return ( + <div + className='annotation sentence' + style={{ top: y }} + onClick={() => onClick(annotation)} + onDoubleClick={() => onDoubleClick(annotation)} + > + {text} + </div> + ) +} + +export const AnnotationHeader = ({ y, annotation, onClick, onDoubleClick }) => { + const { start_ts, text } = annotation + return ( + <div + className='annotation header' + style={{ top: y }} + onClick={() => onClick(annotation)} + onDoubleClick={() => onDoubleClick(annotation)} + > + {text} + </div> + ) +} + +export const AnnotationElementLookup = { + sentence: AnnotationSentence, + header: AnnotationHeader, +}
\ No newline at end of file |
