diff options
Diffstat (limited to 'animism-align/frontend/views/align')
12 files changed, 93 insertions, 43 deletions
diff --git a/animism-align/frontend/views/align/align.css b/animism-align/frontend/views/align/align.css index d430e1f..12d5b1d 100644 --- a/animism-align/frontend/views/align/align.css +++ b/animism-align/frontend/views/align/align.css @@ -1,6 +1,9 @@ * { } +.body.loading > div { + padding: 1rem; +} .body { width: 100%; height: 100%; @@ -74,8 +77,8 @@ canvas { /* Audio player */ .playButton { - position: absolute; - top: 0; left: 0; + /*position: absolute;*/ + /*top: 0; left: 0;*/ width: 3rem; height: 3rem; padding: 1rem; background: #000; @@ -104,6 +107,9 @@ canvas { position: relative; width: 450px; } + +/* Annotation form */ + .annotationForm { width: 401px; padding: 0.5rem; @@ -118,7 +124,18 @@ canvas { } .annotationForm .row { justify-content: space-between; + align-items: center; } +.annotationForm .row > div { + display: flex; + align-items: center; +} +.annotationForm .ts { + color: #fff; +} + +/* Annotation index */ + .annotationIndex { width: 405px; } @@ -132,6 +149,8 @@ canvas { border-radius: 2px; font-size: 12px; cursor: pointer; + user-select: none; + background-color: #768; } .annotation.selected { border-color: #bbf; @@ -143,7 +162,7 @@ canvas { background-color: #83b; } .annotation.sentence.odd { - background-color: #638; + background-color: #537; } .annotation.header { background-color: #838; diff --git a/animism-align/frontend/views/align/align.reducer.js b/animism-align/frontend/views/align/align.reducer.js index 679f63b..dc471a6 100644 --- a/animism-align/frontend/views/align/align.reducer.js +++ b/animism-align/frontend/views/align/align.reducer.js @@ -21,6 +21,7 @@ export default function alignReducer(state = initialState, action) { case types.peaks.loaded: console.log('peaks duration:', action.data.length / 10) return state + case types.align.set_display_setting: return { ...state, diff --git a/animism-align/frontend/views/align/align.util.js b/animism-align/frontend/views/align/align.util.js index ce72aef..d7b4c39 100644 --- a/animism-align/frontend/views/align/align.util.js +++ b/animism-align/frontend/views/align/align.util.js @@ -1,9 +1,13 @@ import { ZOOM_STEPS } from './constants' import { clamp } from '../../util' +import actions from '../../actions' + +import { HEADER_MARGIN, INNER_HEIGHT } from './constants' export const positionToTime = (y, { start_ts, zoom, duration }) => { + y -= HEADER_MARGIN const secondsPerPixel = ZOOM_STEPS[zoom] * 0.1 - const widthTimeDuration = window.innerHeight * secondsPerPixel + const widthTimeDuration = INNER_HEIGHT * secondsPerPixel const timeMin = start_ts const timeMax = Math.min(start_ts + widthTimeDuration, duration) const timeWidth = timeMax - timeMin @@ -11,20 +15,19 @@ export const positionToTime = (y, { start_ts, zoom, duration }) => { } export const timeToPosition = (ts, { start_ts, zoom, duration }) => { - const height = window.innerHeight const secondsPerPixel = ZOOM_STEPS[zoom] * 0.1 - const widthTimeDuration = height * secondsPerPixel + const widthTimeDuration = INNER_HEIGHT * secondsPerPixel const timeMin = start_ts const timeMax = Math.min(start_ts + widthTimeDuration, duration) const timeWidth = timeMax - timeMin - const timeHalfHeight = height * secondsPerPixel / 2 + const timeHalfHeight = INNER_HEIGHT * secondsPerPixel / 2 if (ts < timeMin - timeHalfHeight) { return -9999 } if (ts > timeMax) { return -9999 } - return (ts - timeMin) / timeWidth * height + return (ts - timeMin) / timeWidth * INNER_HEIGHT } export const getFirstPunctuationMarkIndex = text => { 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 6972f93..e18d6df 100644 --- a/animism-align/frontend/views/align/components/annotations/annotation.form.js +++ b/animism-align/frontend/views/align/components/annotations/annotation.form.js @@ -7,7 +7,7 @@ import actions from '../../../../actions' // import * as alignActions from '../align.actions' import { ZOOM_STEPS } from '../../constants' -import { clamp } from '../../../../util' +import { clamp, timestamp } from '../../../../util' import { timeToPosition } from '../../align.util' import { Select } from '../../../../common' @@ -95,14 +95,17 @@ class AnnotationForm extends Component { > {annotation.type === 'sentence' && this.renderTextarea()} {annotation.type === 'header' && this.renderTextarea()} - <div className='row'> - <Select - name='type' - selected={annotation.type} - options={ANNOTATION_TYPES} - defaultOption='text' - onChange={this.handleSelect} - /> + <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> </div> 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 8121d1d..d5c1eed 100644 --- a/animism-align/frontend/views/align/components/annotations/annotation.index.js +++ b/animism-align/frontend/views/align/components/annotations/annotation.index.js @@ -4,7 +4,7 @@ import { connect } from 'react-redux' import actions from '../../../../actions' -import { ZOOM_STEPS } from '../../constants' +import { ZOOM_STEPS, INNER_HEIGHT } from '../../constants' import { clamp } from '../../../../util' import { positionToTime, timeToPosition } from '../../align.util' @@ -30,7 +30,7 @@ class AnnotationIndex extends Component { const { order, lookup } = index let secondsPerPixel = ZOOM_STEPS[zoom] * 0.1 // 0.1 sec / step - let widthTimeDuration = window.innerHeight * secondsPerPixel // secs per pixel + let widthTimeDuration = INNER_HEIGHT * secondsPerPixel // secs per pixel let timeMin = start_ts - 30.0 let timeMax = Math.min(start_ts + widthTimeDuration, duration) @@ -43,9 +43,37 @@ class AnnotationIndex extends Component { } handleClick(e, annotation) { e.stopPropagation() + if (e.shiftKey) { + e.preventDefault() + this.handleParagraphSelection(annotation) + } actions.audio.seek(annotation.start_ts) actions.align.setSelectedAnnotation(annotation.id) } + handleParagraphSelection(annotation) { + const { selected_paragraph_id } = this.props.timeline + console.log("___________________") + console.log(annotation) + console.log(selected_paragraph_id) + if (!selected_paragraph_id || selected_paragraph_id === -1) { + if (annotation.paragraph_id) { + actions.align.setSelectedParagraph(annotation.paragraph_id) + } else { + actions.paragraph.create({ + type: 'paragraph', + start_ts: annotation.start_ts, + }) .then(data => { + console.log(data.res) + actions.align.setSelectedParagraph(data.res.id) + annotation.paragraph_id = data.res.id + actions.annotation.update(annotation) + }) + } + } else if (selected_paragraph_id !== annotation.paragraph_id) { + annotation.paragraph_id = selected_paragraph_id + actions.annotation.update(annotation) + } + } handleDoubleClick(e, annotation) { e.stopPropagation() actions.align.showEditAnnotationForm(annotation) 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 7639821..f95589d 100644 --- a/animism-align/frontend/views/align/components/annotations/annotation.types.js +++ b/animism-align/frontend/views/align/components/annotations/annotation.types.js @@ -8,9 +8,11 @@ import { positionToTime, timeToPosition } from '../../align.util' export const AnnotationSentence = ({ y, annotation, selected, onClick, onDoubleClick }) => { const { start_ts, text, paragraph_id } = annotation - let className = (paragraph_id % 2) - ? 'annotation sentence odd' - : 'annotation sentence even' + let className = !paragraph_id + ? 'annotation sentence' + : (paragraph_id % 2) + ? 'annotation sentence odd' + : 'annotation sentence even' if (selected) className += ' selected' return ( <div diff --git a/animism-align/frontend/views/align/components/timeline/playButton.component.js b/animism-align/frontend/views/align/components/player/playButton.component.js index 486eaee..486eaee 100644 --- a/animism-align/frontend/views/align/components/timeline/playButton.component.js +++ b/animism-align/frontend/views/align/components/player/playButton.component.js diff --git a/animism-align/frontend/views/align/components/timeline/playCursor.component.js b/animism-align/frontend/views/align/components/timeline/playCursor.component.js index 71e6a3a..e03d212 100644 --- a/animism-align/frontend/views/align/components/timeline/playCursor.component.js +++ b/animism-align/frontend/views/align/components/timeline/playCursor.component.js @@ -24,13 +24,6 @@ const PlayCursor = ({ timeline, audio }) => { ) } -/* - <div className='tickLabel'> - {timestamp(cursor_ts, 1)} - </div> - -*/ - const mapStateToProps = state => ({ timeline: state.align.timeline, audio: state.audio, diff --git a/animism-align/frontend/views/align/components/timeline/ticks.component.js b/animism-align/frontend/views/align/components/timeline/ticks.component.js index 72f9bd0..747fb7a 100644 --- a/animism-align/frontend/views/align/components/timeline/ticks.component.js +++ b/animism-align/frontend/views/align/components/timeline/ticks.component.js @@ -1,16 +1,15 @@ import React, { Component } from 'react' -import { ZOOM_STEPS, ZOOM_LABEL_STEPS, ZOOM_TICK_STEPS } from '../../constants' +import { ZOOM_STEPS, ZOOM_LABEL_STEPS, ZOOM_TICK_STEPS, INNER_HEIGHT } from '../../constants' import { timestamp } from '../../../../util' export default class Ticks extends Component { render() { let { start_ts, zoom, duration } = this.props.timeline - const width = window.innerHeight let secondsPerPixel = ZOOM_STEPS[zoom] * 0.1 // 0.1 sec / step - let widthTimeDuration = width * secondsPerPixel // secs per pixel + let widthTimeDuration = INNER_HEIGHT * secondsPerPixel // secs per pixel let timeMin = start_ts let timeMax = Math.min(start_ts + widthTimeDuration, duration) @@ -26,11 +25,11 @@ export default class Ticks extends Component { let startOffset = pixelsPerLabel - (pixelMin % pixelsPerLabel) let startTiming = (pixelMin + startOffset) * secondsPerPixel - let labelCount = Math.ceil(width / pixelsPerLabel) + 1 + let labelCount = Math.ceil(INNER_HEIGHT / pixelsPerLabel) + 1 let offset, timing, tickLabels = [], ticks = [] for (var i = -1; i < labelCount; i++) { offset = i * pixelsPerLabel + startOffset - if (offset > width) continue + if (offset > INNER_HEIGHT) continue timing = i * secondsPerLabel + startTiming if (timing > duration) { break @@ -63,7 +62,7 @@ export default class Ticks extends Component { /> ) } - let tickCount = Math.ceil(width / pixelsPerTick) + 6 + let tickCount = Math.ceil(INNER_HEIGHT / pixelsPerTick) + 6 for (var i = 0; i < tickCount; i += 1) { offset = i * pixelsPerTick + startOffset - pixelsPerLabel if (offset > durationOffset) { diff --git a/animism-align/frontend/views/align/components/timeline/waveform.component.js b/animism-align/frontend/views/align/components/timeline/waveform.component.js index 785b020..16ceaf6 100644 --- a/animism-align/frontend/views/align/components/timeline/waveform.component.js +++ b/animism-align/frontend/views/align/components/timeline/waveform.component.js @@ -6,7 +6,7 @@ import { connect } from 'react-redux' import actions from '../../../../actions' // import * as uploadActions from './upload.actions' -import { WAVEFORM_SIZE, ZOOM_STEPS, ZOOM_LABEL_STEPS, ZOOM_TICK_STEPS } from '../../constants' +import { WAVEFORM_SIZE, ZOOM_STEPS, ZOOM_LABEL_STEPS, ZOOM_TICK_STEPS, INNER_HEIGHT } from '../../constants' class Waveform extends Component { constructor(props){ @@ -23,12 +23,12 @@ class Waveform extends Component { resize() { const canvas = this.canvasRef.current canvas.width = WAVEFORM_SIZE - canvas.height = window.innerHeight + canvas.height = INNER_HEIGHT } draw() { const canvas = this.canvasRef.current const ctx = canvas.getContext('2d') - const h = window.innerHeight + const h = INNER_HEIGHT this.clearCanvas(ctx, h) this.drawCurve(ctx, h) } diff --git a/animism-align/frontend/views/align/constants.js b/animism-align/frontend/views/align/constants.js index c797784..cf504d3 100644 --- a/animism-align/frontend/views/align/constants.js +++ b/animism-align/frontend/views/align/constants.js @@ -29,3 +29,6 @@ export const ZOOM_TICK_STEPS = [ 60, 600, ] + +export const HEADER_MARGIN = 50 +export const INNER_HEIGHT = window.innerHeight - HEADER_MARGIN diff --git a/animism-align/frontend/views/align/containers/timeline.container.js b/animism-align/frontend/views/align/containers/timeline.container.js index 760da82..ba6b7e0 100644 --- a/animism-align/frontend/views/align/containers/timeline.container.js +++ b/animism-align/frontend/views/align/containers/timeline.container.js @@ -10,10 +10,10 @@ import Annotations from '../containers/annotations.container' import Waveform from '../components/timeline/waveform.component' import Ticks from '../components/timeline/ticks.component' import Cursor from '../components/timeline/cursor.component' -import PlayButton from '../components/timeline/playButton.component' +import PlayButton from '../components/player/playButton.component' import PlayCursor from '../components/timeline/playCursor.component' -import { WAVEFORM_SIZE, ZOOM_STEPS } from '../constants' +import { WAVEFORM_SIZE, ZOOM_STEPS, INNER_HEIGHT } from '../constants' import { clamp } from '../../../util' import { positionToTime } from '../align.util' @@ -84,7 +84,7 @@ class Timeline extends Component { let { start_ts, zoom, duration } = this.props.timeline let { deltaY } = e let secondsPerPixel = ZOOM_STEPS[zoom] * 0.1 // 0.1 sec / step - let widthTimeDuration = window.innerHeight * secondsPerPixel // secs per pixel + let widthTimeDuration = INNER_HEIGHT * secondsPerPixel // secs per pixel start_ts += Math.round((deltaY / 8) * ZOOM_STEPS[zoom]) start_ts = clamp(start_ts, 0, Math.max(0, duration - widthTimeDuration / 2)) if (e.shiftKey) { @@ -105,8 +105,8 @@ class Timeline extends Component { actions.align.setCursor(cursor_ts) } handleContainerClick(e) { - console.log('container click') actions.align.clearSelectedAnnotation() + actions.align.clearSelectedParagraph() } handleTimelineClick(e) { const play_ts = positionToTime(e.pageY, this.props.timeline) @@ -131,7 +131,6 @@ class Timeline extends Component { </div> <Annotations timeline={this.props.timeline} /> <PlayCursor /> - <PlayButton /> </div> ) } |
