summaryrefslogtreecommitdiff
path: root/animism-align/frontend
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-07-05 17:02:39 +0200
committerJules Laplace <julescarbon@gmail.com>2020-07-05 17:02:39 +0200
commit3e5bc2f5581890f2d7d9f679ab5171c0637ff460 (patch)
treefc88ac2387974ba0bd8377957732fdf697cef961 /animism-align/frontend
parentbc1515b965e02641cab2a984410a3cb5cfae891c (diff)
notion of selected annotation
Diffstat (limited to 'animism-align/frontend')
-rw-r--r--animism-align/frontend/app.js1
-rw-r--r--animism-align/frontend/views/align/align.actions.js23
-rw-r--r--animism-align/frontend/views/align/align.css33
-rw-r--r--animism-align/frontend/views/align/align.reducer.js1
-rw-r--r--animism-align/frontend/views/align/components/annotations/annotation.index.js15
-rw-r--r--animism-align/frontend/views/align/components/annotations/annotation.types.js23
-rw-r--r--animism-align/frontend/views/align/components/timeline/waveform.component.js4
-rw-r--r--animism-align/frontend/views/align/containers/timeline.container.js2
8 files changed, 82 insertions, 20 deletions
diff --git a/animism-align/frontend/app.js b/animism-align/frontend/app.js
index 1c40c09..9270cc8 100644
--- a/animism-align/frontend/app.js
+++ b/animism-align/frontend/app.js
@@ -20,6 +20,7 @@ export default class App extends Component {
actions.site.loadText()
actions.site.loadPeaks()
actions.annotation.index()
+ actions.paragraph.index()
}
render() {
return (
diff --git a/animism-align/frontend/views/align/align.actions.js b/animism-align/frontend/views/align/align.actions.js
index b10f257..b819584 100644
--- a/animism-align/frontend/views/align/align.actions.js
+++ b/animism-align/frontend/views/align/align.actions.js
@@ -17,6 +17,14 @@ export const setZoom = zoom => dispatch => {
}
}
+export const setSelectedAnnotation = annotation_id => dispatch => {
+ dispatch({ type: types.align.set_display_setting, key: 'selected_annotation_id', value: annotation_id })
+}
+
+export const clearSelectedAnnotation = annotation_id => dispatch => {
+ dispatch({ type: types.align.set_display_setting, key: 'selected_annotation_id', value: -1 })
+}
+
export const throttledSetZoom = throttle(zoom => dispatch => {
setZoom(zoom)(dispatch)
}, 250, { leading: true })
@@ -59,9 +67,22 @@ export const updateAnnotationSettings = (key, value) => dispatch => {
dispatch({ type: types.align.update_temporary_annotation_settings, key, value })
}
+const getFirstPunctuationMarkIndex = text => {
+ return Math.min(
+ text.indexOf('. '),
+ text.indexOf('? '),
+ text.indexOf('! '),
+ text.indexOf('." '),
+ text.indexOf('?" '),
+ text.indexOf('!" '),
+ text.indexOf('.” '),
+ text.indexOf('?” '),
+ text.indexOf('!” '),
+ ) + 1
+}
const cutFirstSentence = text => {
const textToCrop = text.trim().replace("\n", " ").split("\n")[0]
- let cropIndex = textToCrop.indexOf('. ') + 1
+ let cropIndex = getFirstPunctuationMarkIndex(textToCrop)
if (!cropIndex) cropIndex = textToCrop.length
const croppedText = textToCrop.substr(0, cropIndex).trim()
const updatedText = text.trim().replace(croppedText, '').trim()
diff --git a/animism-align/frontend/views/align/align.css b/animism-align/frontend/views/align/align.css
index 799693c..c2de8a1 100644
--- a/animism-align/frontend/views/align/align.css
+++ b/animism-align/frontend/views/align/align.css
@@ -109,6 +109,7 @@ canvas {
position: absolute;
left: 0.25rem;
background: #448;
+ z-index: 10;
}
.annotationForm .row {
justify-content: space-between;
@@ -119,16 +120,42 @@ canvas {
.annotationIndex .annotation {
position: absolute;
left: 5px;
- max-width: 450px;
+ max-width: 400px;
padding: 0.25rem 0.375rem;
- box-shadow: 0px 0px 4px rgba(0,0,0,0.7);
+ box-shadow: 0px 0px 3px rgba(0,0,0,1.0);
+ border: 1px solid transparent;
border-radius: 2px;
font-size: 12px;
cursor: pointer;
}
-.annotation.sentence {
+.annotation.selected {
+ border-color: #bbf;
+ box-shadow: 0px 0px 4px rgba(0,0,0,1.0), 0px 0px 2px rgba(0,0,0,1.0);
+ z-index: 1;
+ background-image: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.4));
+}
+.annotation.sentence.even {
background-color: #83b;
}
+.annotation.sentence.odd {
+ background-color: #638;
+}
.annotation.header {
background-color: #838;
}
+.annotationIndex.condensed .annotation.sentence {
+ z-index: 0;
+ white-space: pre;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.annotationIndex.collapsed .annotation.header {
+ z-index: 1;
+}
+
+.annotationIndex.collapsed .annotation.sentence {
+ height: 1px; overflow: hidden; padding: 0; z-index: 0;
+}
+.annotationIndex.collapsed .annotation.header {
+ z-index: 1;
+}
diff --git a/animism-align/frontend/views/align/align.reducer.js b/animism-align/frontend/views/align/align.reducer.js
index f080c24..0bd6c56 100644
--- a/animism-align/frontend/views/align/align.reducer.js
+++ b/animism-align/frontend/views/align/align.reducer.js
@@ -7,6 +7,7 @@ const initialState = {
start_ts: 0,
zoom: 1,
duration: 0,
+ selected_annotation_id: -1,
},
annotation: {},
options: {
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 09cb255..9117a80 100644
--- a/animism-align/frontend/views/align/components/annotations/annotation.index.js
+++ b/animism-align/frontend/views/align/components/annotations/annotation.index.js
@@ -41,18 +41,24 @@ class AnnotationIndex extends Component {
}).map(id => lookup[id]).reverse()
this.setState({ items })
}
- handleClick(annotation) {
+ handleClick(e, annotation) {
actions.audio.seek(annotation.start_ts)
+ actions.align.setSelectedAnnotation(annotation.id)
}
- handleDoubleClick(annotation) {
+ handleDoubleClick(e, annotation) {
actions.align.showEditAnnotationForm(annotation)
}
render() {
const { timeline } = this.props
- const { start_ts } = timeline
+ const { start_ts, zoom, selected_annotation_id } = timeline
const { items } = this.state
+ const className = (zoom < 2)
+ ? 'annotationIndex'
+ : (zoom < 3)
+ ? 'annotationIndex condensed'
+ : 'annotationIndex collapsed'
return (
- <div className='annotationIndex'>
+ <div className={className}>
{items.map(annotation => {
const { id, type, start_ts } = annotation
const AnnotationElement = AnnotationElementLookup[type]
@@ -61,6 +67,7 @@ class AnnotationIndex extends Component {
<AnnotationElement
key={id}
y={y}
+ selected={annotation.id === selected_annotation_id}
annotation={annotation}
onClick={this.handleClick}
onDoubleClick={this.handleDoubleClick}
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 465844f..7639821 100644
--- a/animism-align/frontend/views/align/components/annotations/annotation.types.js
+++ b/animism-align/frontend/views/align/components/annotations/annotation.types.js
@@ -6,28 +6,33 @@ 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
+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'
+ if (selected) className += ' selected'
return (
<div
- className='annotation sentence'
+ className={className}
style={{ top: y }}
- onClick={() => onClick(annotation)}
- onDoubleClick={() => onDoubleClick(annotation)}
+ onClick={e => onClick(e, annotation)}
+ onDoubleClick={e => onDoubleClick(e, annotation)}
>
{text}
</div>
)
}
-export const AnnotationHeader = ({ y, annotation, onClick, onDoubleClick }) => {
+export const AnnotationHeader = ({ y, annotation, selected, onClick, onDoubleClick }) => {
const { start_ts, text } = annotation
+ const className = selected ? 'annotation header selected' : 'annotation header'
return (
<div
- className='annotation header'
+ className={className}
style={{ top: y }}
- onClick={() => onClick(annotation)}
- onDoubleClick={() => onDoubleClick(annotation)}
+ onClick={e => onClick(e, annotation)}
+ onDoubleClick={e => onDoubleClick(e, annotation)}
>
{text}
</div>
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 0a118cf..785b020 100644
--- a/animism-align/frontend/views/align/components/timeline/waveform.component.js
+++ b/animism-align/frontend/views/align/components/timeline/waveform.component.js
@@ -48,8 +48,8 @@ class Waveform extends Component {
let widthTimeDuration = h * secondsPerPixel // secs per pixel
- let timeMin = start_ts
- let timeMax = Math.min(start_ts + widthTimeDuration, duration)
+ let timeMin = Math.round(start_ts / secondsPerPixel) * secondsPerPixel
+ let timeMax = Math.min(timeMin + widthTimeDuration, duration)
let timeWidth = timeMax - timeMin
let stepMin = Math.floor(timeMin * 10)
diff --git a/animism-align/frontend/views/align/containers/timeline.container.js b/animism-align/frontend/views/align/containers/timeline.container.js
index ceb9012..591af03 100644
--- a/animism-align/frontend/views/align/containers/timeline.container.js
+++ b/animism-align/frontend/views/align/containers/timeline.container.js
@@ -84,7 +84,7 @@ class Timeline extends Component {
let { deltaY } = e
let secondsPerPixel = ZOOM_STEPS[zoom] * 0.1 // 0.1 sec / step
let widthTimeDuration = window.innerHeight * secondsPerPixel // secs per pixel
- start_ts += (deltaY / 2) * ZOOM_STEPS[zoom]
+ start_ts += Math.round((deltaY / 8) * ZOOM_STEPS[zoom])
start_ts = clamp(start_ts, 0, Math.max(0, duration - widthTimeDuration / 2))
if (e.shiftKey) {
if (Math.abs(deltaY) < 2) return