summaryrefslogtreecommitdiff
path: root/animism-align/frontend/app/views/viewer
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-08-28 20:24:11 +0200
committerJules Laplace <julescarbon@gmail.com>2020-08-28 20:24:11 +0200
commit15d5f168363b9592cd5f201fe2ce2a31d3d692bd (patch)
tree0f79d47a5fbaff9a3858d0aa1037aebcb6a1c66a /animism-align/frontend/app/views/viewer
parent6dea2acdf558f39c868be92c5657190d9fb6bd46 (diff)
tween-scroll the transcript
Diffstat (limited to 'animism-align/frontend/app/views/viewer')
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.media/media.vitrine.js2
-rw-r--r--animism-align/frontend/app/views/viewer/transcript/components/elementTypes.gallery.js3
-rw-r--r--animism-align/frontend/app/views/viewer/transcript/components/elementTypes.image.js3
-rw-r--r--animism-align/frontend/app/views/viewer/transcript/components/elementTypes.text.js4
-rw-r--r--animism-align/frontend/app/views/viewer/transcript/components/elementTypes.video.js3
-rw-r--r--animism-align/frontend/app/views/viewer/transcript/transcript.container.js88
6 files changed, 100 insertions, 3 deletions
diff --git a/animism-align/frontend/app/views/viewer/player/components.media/media.vitrine.js b/animism-align/frontend/app/views/viewer/player/components.media/media.vitrine.js
index 2033465..4fc3964 100644
--- a/animism-align/frontend/app/views/viewer/player/components.media/media.vitrine.js
+++ b/animism-align/frontend/app/views/viewer/player/components.media/media.vitrine.js
@@ -6,7 +6,7 @@ import actions from 'app/actions'
export const Vitrine = ({ media }) => {
const { image_order, image_lookup, thumbnail_lookup } = media.settings
- const width = (Math.floor(100 / image_order.length * 2) - 2) + 'vw'
+ const width = (Math.floor(100 / image_order.length * 2) - 2) + '%'
// console.log(width)
return (
<div className='vitrine-items'>
diff --git a/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.gallery.js b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.gallery.js
index 6d6db2d..d21cc79 100644
--- a/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.gallery.js
+++ b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.gallery.js
@@ -14,6 +14,9 @@ export const MediaGallery = ({ paragraph, media, currentParagraph, currentAnnota
return (
<div
className={className}
+ data-startts={paragraph.start_ts}
+ data-endts={paragraph.end_ts}
+ data-media={true}
onClick={e => onAnnotationClick(e, paragraph, annotation)}
>
{"["}
diff --git a/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.image.js b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.image.js
index 64de3a2..6eef6a0 100644
--- a/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.image.js
+++ b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.image.js
@@ -39,6 +39,9 @@ export const MediaImage = ({ paragraph, media, currentParagraph, currentAnnotati
return (
<div
className={className}
+ data-startts={paragraph.start_ts}
+ data-endts={paragraph.end_ts}
+ data-media={true}
onClick={e => onAnnotationClick(e, paragraph, annotation)}
>
{"["}
diff --git a/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.text.js b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.text.js
index 292eec8..5ea12da 100644
--- a/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.text.js
+++ b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.text.js
@@ -9,6 +9,8 @@ export const Paragraph = ({ paragraph, currentParagraph, currentAnnotation, onAn
return (
<div
className={className}
+ data-startts={paragraph.start_ts}
+ data-endts={paragraph.end_ts}
>
{paragraph.annotations.map(annotation => (
<span
@@ -29,6 +31,8 @@ export const ParagraphHeading = ({ paragraph, currentParagraph, currentAnnotatio
return (
<div
className={className}
+ data-startts={paragraph.start_ts}
+ data-endts={paragraph.end_ts}
onClick={e => onAnnotationClick(e, paragraph, firstAnnotation)}
>
<span>{ROMAN_NUMERALS[paragraph.sectionIndex]}{'. '}{text}</span>
diff --git a/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.video.js b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.video.js
index 423a055..1c1b3cc 100644
--- a/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.video.js
+++ b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.video.js
@@ -14,6 +14,9 @@ export const MediaVideo = ({ paragraph, media, currentParagraph, currentAnnotati
return (
<div
className={className}
+ data-startts={paragraph.start_ts}
+ data-endts={paragraph.end_ts}
+ data-media={true}
onClick={e => onAnnotationClick(e, paragraph, annotation)}
>
{"["}
diff --git a/animism-align/frontend/app/views/viewer/transcript/transcript.container.js b/animism-align/frontend/app/views/viewer/transcript/transcript.container.js
index 2dd8402..3cc23bd 100644
--- a/animism-align/frontend/app/views/viewer/transcript/transcript.container.js
+++ b/animism-align/frontend/app/views/viewer/transcript/transcript.container.js
@@ -5,24 +5,107 @@ import { connect } from 'react-redux'
import actions from 'app/actions'
+import { toArray, floatInRange } from 'app/utils'
+import oktween from 'app/utils/oktween'
import ParagraphList from 'app/views/paragraph/components/paragraph.list'
import { transcriptElementLookup } from './components'
class Transcript extends Component {
+ state = {
+ built: false,
+ paragraphs: [],
+ windowHeight: 0.0,
+ scrolling: false,
+ }
+
constructor(props){
super(props)
this.handleClose = this.handleClose.bind(this)
this.handleAnnotationClick = this.handleAnnotationClick.bind(this)
this.handleParagraphDoubleClick = this.handleParagraphDoubleClick.bind(this)
+ this.containerRef = React.createRef()
}
componentDidMount() {
actions.transcript.buildAllParagraphs()
+ this.setState({
+ built: true,
+ windowHeight: window.innerHeight * 0.6 - 48,
+ })
+ }
+
+ componentDidUpdate(prevProps, prevState) {
+ if (this.state.built !== prevState.built) {
+ setTimeout(() => {
+ this.cacheScrollPositions()
+ }, 1000)
+ }
+ if (!this.state.scrolling) {
+ this.updateScrollPosition(this.props.play_ts)
+ }
+ }
+
+ cacheScrollPositions() {
+ let paragraphs = toArray(this.containerRef.current.querySelectorAll('.content > div')).map(el => {
+ const isHeading = el.classList.contains('section_heading')
+ const isMedia = el.dataset.media === 'true'
+ const scrollTop = isHeading ? el.offsetTop : el.offsetTop - 16 // 1.5rem
+ const start_ts = parseFloat(el.dataset.startts)
+ let end_ts = parseFloat(el.dataset.endts)
+ if (isHeading) console.log(scrollTop, start_ts, end_ts)
+ if (!start_ts || !end_ts) return null
+ if (end_ts < start_ts) {
+ end_ts = start_ts + 0.5
+ }
+ return { start_ts, end_ts, scrollTop }
+ }).filter(el => !!el)
+ this.setState({ paragraphs })
+ }
+
+ updateScrollPosition(play_ts, forceScroll) {
+ const { paragraphs, windowHeight, currentParagraph } = this.state
+ const scrollTop = this.containerRef.current.scrollTop
+ if (!forceScroll && currentParagraph && floatInRange(currentParagraph.start_ts, play_ts, currentParagraph.end_ts)) return
+ let nextParagraph;
+ const insideParagraph = paragraphs.some(paragraph => {
+ if (floatInRange(paragraph.start_ts, play_ts, paragraph.end_ts)) {
+ nextParagraph = paragraph
+ return true
+ }
+ return false
+ })
+ if (insideParagraph && nextParagraph) {
+ console.log(nextParagraph.scrollTop)
+ if (!floatInRange(scrollTop, nextParagraph.scrollTop, scrollTop + windowHeight) || forceScroll) {
+ this.setState({ currentParagraph: nextParagraph, scrolling: true })
+ this.scrollToParagraph(scrollTop, nextParagraph.scrollTop)
+ } else {
+ this.setState({ currentParagraph: nextParagraph })
+ }
+ }
+ }
+
+ scrollToParagraph(scrollFrom, scrollTo) {
+ if (this.state.scrolling) return
+ console.log('scrolling!', scrollFrom, scrollTo)
+ oktween.add({
+ from: { scrollTop: scrollFrom },
+ to: { scrollTop: scrollTo },
+ duration: 1000,
+ easing: oktween.easing.quad_in_out,
+ update: obj => {
+ this.containerRef.current.scrollTo(0, obj.scrollTop)
+ },
+ finished: tween => {
+ this.containerRef.current.scrollTo(0, tween.obj.scrollTop)
+ this.setState({ scrolling: false })
+ }
+ })
}
handleAnnotationClick(e, paragraph, annotation) {
- // console.log(annotation)
actions.viewer.seekToTimestamp(paragraph.start_ts)
+ this.updateScrollPosition(paragraph.start_ts + 0.1, annotation.type === 'section_heading')
}
handleParagraphDoubleClick(e, paragraph) {
@@ -37,7 +120,7 @@ class Transcript extends Component {
const { viewer, paragraphs } = this.props
return (
<div className="transcript">
- <div className='content'>
+ <div className='content' ref={this.containerRef}>
<ParagraphList
paragraphs={paragraphs}
paragraphElementLookup={transcriptElementLookup}
@@ -59,6 +142,7 @@ class Transcript extends Component {
const mapStateToProps = state => ({
viewer: state.viewer,
+ play_ts: state.audio.play_ts,
paragraphs: state.paragraph.paragraphs,
})