summaryrefslogtreecommitdiff
path: root/animism-align
diff options
context:
space:
mode:
Diffstat (limited to 'animism-align')
-rw-r--r--animism-align/frontend/app/constants.js4
-rw-r--r--animism-align/frontend/app/utils/annotation.utils.js6
-rw-r--r--animism-align/frontend/app/views/align/align.reducer.js2
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.utility.js2
-rw-r--r--animism-align/frontend/app/views/audio/audio.actions.js2
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.image.js16
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.utility.js18
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.fullscreen/index.js19
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.inline/index.js6
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.inline/inline.image.js (renamed from animism-align/frontend/app/views/viewer/player/components.inline/elementTypes.image.js)0
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.inline/inline.text.js (renamed from animism-align/frontend/app/views/viewer/player/components.inline/elementTypes.text.js)0
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.inline/inline.video.js (renamed from animism-align/frontend/app/views/viewer/player/components.inline/elementTypes.video.js)0
-rw-r--r--animism-align/frontend/app/views/viewer/player/player.container.js8
-rw-r--r--animism-align/frontend/app/views/viewer/player/player.fullscreen.css37
-rw-r--r--animism-align/frontend/app/views/viewer/player/player.fullscreen.js65
-rw-r--r--animism-align/frontend/app/views/viewer/viewer.actions.js19
-rw-r--r--animism-align/package-lock.json35
-rw-r--r--animism-align/package.json1
18 files changed, 218 insertions, 22 deletions
diff --git a/animism-align/frontend/app/constants.js b/animism-align/frontend/app/constants.js
index db710a5..2ed5563 100644
--- a/animism-align/frontend/app/constants.js
+++ b/animism-align/frontend/app/constants.js
@@ -72,3 +72,7 @@ export const CURTAIN_COLOR_SELECT_OPTIONS = CURTAIN_COLORS.map(color => ({
name: color.label,
}))
+export const CURTAIN_COLOR_LOOKUP = CURTAIN_COLORS.reduce((a,b) => {
+ a[b.label] = b
+ return a
+}, {})
diff --git a/animism-align/frontend/app/utils/annotation.utils.js b/animism-align/frontend/app/utils/annotation.utils.js
index 4dd7478..6b47f36 100644
--- a/animism-align/frontend/app/utils/annotation.utils.js
+++ b/animism-align/frontend/app/utils/annotation.utils.js
@@ -1,9 +1,9 @@
import { timestampToSeconds } from 'app/utils'
export const annotationFadeTimings = annotation => {
- const fadeInDuration = timestampToSeconds(annotation.settings.fade_in_duration || '0')
- const fadeOutDuration = timestampToSeconds(annotation.settings.fade_out_duration || '0')
- const duration = timestampToSeconds(annotation.settings.duration || '0')
+ const fadeInDuration = timestampToSeconds(annotation.settings.fade_in_duration || '0') || 0.1
+ const fadeOutDuration = timestampToSeconds(annotation.settings.fade_out_duration || '0') || 0.1
+ const duration = timestampToSeconds(annotation.settings.duration || '0') || 0.1
const start_ts = annotation.start_ts
const end_ts = start_ts + duration
diff --git a/animism-align/frontend/app/views/align/align.reducer.js b/animism-align/frontend/app/views/align/align.reducer.js
index 1f79180..50498c5 100644
--- a/animism-align/frontend/app/views/align/align.reducer.js
+++ b/animism-align/frontend/app/views/align/align.reducer.js
@@ -20,7 +20,7 @@ export default function alignReducer(state = initialState, action) {
// console.log(action.type, action)
switch (action.type) {
case types.peaks.loaded:
- console.log('peaks duration:', action.data.length / 10)
+ // console.log('peaks duration:', action.data.length / 10)
return state
case types.align.set_display_setting:
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.utility.js b/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.utility.js
index a3c35d4..8b59e18 100644
--- a/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.utility.js
+++ b/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.utility.js
@@ -33,7 +33,7 @@ export const checkAnnotationMediaNotReady = (annotation, media) => {
return (!media) || (!(annotation.settings.media_id in media))
}
-export const AnnotationMediaLoading = ({ y, className, onClick, onDoubleClick }) => {
+export const AnnotationMediaLoading = ({ y, media, className, onClick, onDoubleClick }) => {
if (!media) {
return (
<div
diff --git a/animism-align/frontend/app/views/audio/audio.actions.js b/animism-align/frontend/app/views/audio/audio.actions.js
index 0ee41c6..9d9727d 100644
--- a/animism-align/frontend/app/views/audio/audio.actions.js
+++ b/animism-align/frontend/app/views/audio/audio.actions.js
@@ -6,7 +6,7 @@ import { session } from 'app/session'
const audioPlayer = document.createElement('audio')
audioPlayer.src = '/static/data_store/peaks/animismA080720.mp3'
audioPlayer.addEventListener('loadedmetadata', () => {
- console.log('audio duration:', audioPlayer.duration)
+ // console.log('audio duration:', audioPlayer.duration)
dispatch({ type: types.align.set_display_setting, key: 'duration', value: audioPlayer.duration })
})
audioPlayer.addEventListener('play', () => {
diff --git a/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.image.js b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.image.js
new file mode 100644
index 0000000..c0e4b0e
--- /dev/null
+++ b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.image.js
@@ -0,0 +1,16 @@
+import React from 'react'
+
+export const Image = ({ element, media, transitionDuration }) => {
+ const item = media.lookup[element.settings.media_id]
+ const style = {
+ transitionDuration,
+ backgroundImage: 'url(' + item.settings.display.url + ')',
+ }
+ return (
+ <div
+ className='fullscreen-element image'
+ style={style}
+ >
+ </div>
+ )
+}
diff --git a/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.utility.js b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.utility.js
new file mode 100644
index 0000000..c86236d
--- /dev/null
+++ b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.utility.js
@@ -0,0 +1,18 @@
+import React from 'react'
+
+export const Curtain = ({ element, transitionDuration }) => {
+ // console.log(element, isEntering)
+ const { color } = element
+ const style = {
+ backgroundColor: color.backgroundColor,
+ color: color.textColor,
+ transitionDuration,
+ }
+ return (
+ <div
+ className='fullscreen-element curtain'
+ style={style}
+ >
+ </div>
+ )
+}
diff --git a/animism-align/frontend/app/views/viewer/player/components.fullscreen/index.js b/animism-align/frontend/app/views/viewer/player/components.fullscreen/index.js
new file mode 100644
index 0000000..3befbde
--- /dev/null
+++ b/animism-align/frontend/app/views/viewer/player/components.fullscreen/index.js
@@ -0,0 +1,19 @@
+import React from 'react'
+
+// import {
+// MediaVideo
+// } from './fullscreen.video'
+
+import {
+ Image
+} from './fullscreen.image'
+
+import {
+ Curtain
+} from './fullscreen.utility'
+
+export const fullscreenComponents = {
+ curtain: React.memo(Curtain),
+ // video: React.memo(MediaVideo),
+ image: React.memo(Image),
+}
diff --git a/animism-align/frontend/app/views/viewer/player/components.inline/index.js b/animism-align/frontend/app/views/viewer/player/components.inline/index.js
index ee65641..89d1d42 100644
--- a/animism-align/frontend/app/views/viewer/player/components.inline/index.js
+++ b/animism-align/frontend/app/views/viewer/player/components.inline/index.js
@@ -2,15 +2,15 @@ import React from 'react'
import {
Paragraph, ParagraphHeading
-} from './elementTypes.text'
+} from './inline.text'
import {
MediaVideo
-} from './elementTypes.video'
+} from './inline.video'
import {
MediaImage
-} from './elementTypes.image'
+} from './inline.image'
export const transcriptElementLookup = {
paragraph: React.memo(Paragraph),
diff --git a/animism-align/frontend/app/views/viewer/player/components.inline/elementTypes.image.js b/animism-align/frontend/app/views/viewer/player/components.inline/inline.image.js
index f005fc0..f005fc0 100644
--- a/animism-align/frontend/app/views/viewer/player/components.inline/elementTypes.image.js
+++ b/animism-align/frontend/app/views/viewer/player/components.inline/inline.image.js
diff --git a/animism-align/frontend/app/views/viewer/player/components.inline/elementTypes.text.js b/animism-align/frontend/app/views/viewer/player/components.inline/inline.text.js
index 8825479..8825479 100644
--- a/animism-align/frontend/app/views/viewer/player/components.inline/elementTypes.text.js
+++ b/animism-align/frontend/app/views/viewer/player/components.inline/inline.text.js
diff --git a/animism-align/frontend/app/views/viewer/player/components.inline/elementTypes.video.js b/animism-align/frontend/app/views/viewer/player/components.inline/inline.video.js
index fe821eb..fe821eb 100644
--- a/animism-align/frontend/app/views/viewer/player/components.inline/elementTypes.video.js
+++ b/animism-align/frontend/app/views/viewer/player/components.inline/inline.video.js
diff --git a/animism-align/frontend/app/views/viewer/player/player.container.js b/animism-align/frontend/app/views/viewer/player/player.container.js
index 1ddb5c7..9655955 100644
--- a/animism-align/frontend/app/views/viewer/player/player.container.js
+++ b/animism-align/frontend/app/views/viewer/player/player.container.js
@@ -1,8 +1,8 @@
import React, { Component } from 'react'
import { connect } from 'react-redux'
-import { floatInRange } from 'app/utils'
import actions from 'app/actions'
+import { floatInRange } from 'app/utils'
import PlayerTranscript from './player.transcript'
import PlayerFullscreen from './player.fullscreen'
@@ -38,17 +38,16 @@ class PlayerContainer extends Component {
actions.viewer.setCurrentSection(sections[0])
}
}
-
render() {
// const { } = this.props
- const { currentSection, fullscreenTimeline } = this.props
+ const { currentSection } = this.props
if (!currentSection) { return <div /> }
// console.log(currentSection)
return (
<div className='viewer-container'>
<PlayerTranscript section={currentSection} />
- <PlayerFullscreen timeline={fullscreenTimeline} />
+ <PlayerFullscreen />
</div>
)
}
@@ -57,7 +56,6 @@ class PlayerContainer extends Component {
const mapStateToProps = state => ({
audio: state.audio,
sections: state.viewer.sections,
- fullscreenTimeline: state.viewer.fullscreenTimeline,
currentSection: state.viewer.currentSection,
})
diff --git a/animism-align/frontend/app/views/viewer/player/player.fullscreen.css b/animism-align/frontend/app/views/viewer/player/player.fullscreen.css
index 8041c84..fb4d8af 100644
--- a/animism-align/frontend/app/views/viewer/player/player.fullscreen.css
+++ b/animism-align/frontend/app/views/viewer/player/player.fullscreen.css
@@ -11,4 +11,39 @@
.viewer-fullscreen.active {
pointer-events: auto;
user-select: auto;
-} \ No newline at end of file
+}
+
+/* transitions */
+
+.viewer-fullscreen .fade-enter {
+ opacity: 0;
+}
+.viewer-fullscreen .fade-enter.fade-enter-active {
+ opacity: 1;
+ transition-property: opacity;
+}
+.viewer-fullscreen .fade-exit {
+ opacity: 1;
+}
+.viewer-fullscreen .fade-exit-active {
+ opacity: 0;
+ transition-property: opacity;
+}
+
+/* elements */
+
+.viewer-fullscreen .fullscreen-element {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+}
+
+.viewer-fullscreen .curtain {
+}
+
+.viewer-fullscreen .image {
+ background-size: cover;
+ background-position: center center;
+}
diff --git a/animism-align/frontend/app/views/viewer/player/player.fullscreen.js b/animism-align/frontend/app/views/viewer/player/player.fullscreen.js
index 89052ed..47c6cd2 100644
--- a/animism-align/frontend/app/views/viewer/player/player.fullscreen.js
+++ b/animism-align/frontend/app/views/viewer/player/player.fullscreen.js
@@ -1,22 +1,83 @@
import React, { Component } from 'react'
import { connect } from 'react-redux'
+import { TransitionGroup, CSSTransition } from 'react-transition-group'
import actions from 'app/actions'
+import { floatInRange, floatLT } from 'app/utils'
+
+import { fullscreenComponents } from './components.fullscreen'
class PlayerFullscreen extends Component {
+ state = {
+ elements: [],
+ }
+
componentDidMount() {
+ this.setCurrentElements()
+ }
+
+ componentDidUpdate(prevProps) {
+ if (this.props.audio.play_ts === prevProps.audio.play_ts) return
+ this.setCurrentElements()
}
-
+
+ setCurrentElements() {
+ const { audio, timeline } = this.props
+ const { play_ts } = audio
+ const elements = timeline.filter(element => (
+ floatInRange(element.start_ts, play_ts, element.fade_out_start_ts + 0.1)
+ ))
+ this.setState({ elements })
+ }
+
render() {
- const { } = this.props
+ const { audio, media } = this.props
+ const { play_ts } = audio
+ const { elements } = this.state
+ // console.log(elements, play_ts)
return (
<div className="viewer-fullscreen">
+ <TransitionGroup>
+ {elements.map(element => {
+ if (!(element.type in fullscreenComponents)) {
+ return null
+ }
+ const isEntering = floatInRange(element.start_ts, play_ts, element.fade_in_end_ts)
+ const FullscreenComponent = fullscreenComponents[element.type]
+ const transitionDuration = (isEntering ? (1000 * element.fadeInDuration) : (1000 * element.fadeOutDuration)) + 'ms'
+ return (
+ <CSSTransition
+ key={element.index}
+ classNames="fade"
+ timeout={{
+ enter: element.fadeInDuration * 1000,
+ exit: element.fadeOutDuration * 1000,
+ }}
+ component={FirstChild}
+ >
+ <FullscreenComponent
+ element={element}
+ media={media}
+ transitionDuration={transitionDuration}
+ />
+ </CSSTransition>
+ )
+ })}
+ </TransitionGroup>
</div>
)
}
}
+const FirstChild = (props) => {
+ const childrenArray = React.Children.toArray(props.children);
+ return childrenArray[0] || null;
+}
+
const mapStateToProps = state => ({
+ audio: state.audio,
+ media: state.media.index,
+ timeline: state.viewer.fullscreenTimeline,
})
export default connect(mapStateToProps)(PlayerFullscreen)
diff --git a/animism-align/frontend/app/views/viewer/viewer.actions.js b/animism-align/frontend/app/views/viewer/viewer.actions.js
index 836c677..a456646 100644
--- a/animism-align/frontend/app/views/viewer/viewer.actions.js
+++ b/animism-align/frontend/app/views/viewer/viewer.actions.js
@@ -3,6 +3,7 @@ import { store, history, dispatch } from 'app/store'
import {
MEDIA_ANNOTATION_TYPES, MEDIA_LABEL_TYPES,
TEXT_ANNOTATION_TYPES, UTILITY_ANNOTATION_TYPES,
+ CURTAIN_COLOR_LOOKUP,
} from 'app/constants'
import { buildParagraphs } from 'app/utils/transcript.utils'
import { annotationFadeTimings } from 'app/utils/annotation.utils'
@@ -26,6 +27,7 @@ export const loadSections = () => dispatch => {
// keep tally of all media, so that we can display them with correct IDs in the checklist
let mediaIndex = 0
+ let eventIndex = 0
// dedupe the labels that we see in each section
let currentMediaLabels = {}
@@ -96,7 +98,7 @@ export const loadSections = () => dispatch => {
// build timeline of fullscreen events
if (UTILITY_ANNOTATION_TYPES.has(annotation.type) || annotation.settings.fullscreen) {
- const event = makeFullscreenEvent(annotation)
+ const event = makeFullscreenEvent(eventIndex++, annotation)
fullscreenTimeline.push(event)
}
@@ -121,15 +123,22 @@ export const loadSections = () => dispatch => {
}
}
- console.log(sections)
- console.log(fullscreenTimeline)
+ // console.log(sections)
+ // console.log(fullscreenTimeline)
dispatch({ type: types.viewer.load_sections, sections, fullscreenTimeline })
}
-const makeFullscreenEvent = annotation => {
+const makeFullscreenEvent = (index, annotation) => {
const timing = annotationFadeTimings(annotation)
const event = {
- annotation, timing
+ ...timing,
+ annotation,
+ index,
+ settings: annotation.settings,
+ type: annotation.type,
+ }
+ if (event.type === 'curtain') {
+ event.color = CURTAIN_COLOR_LOOKUP[annotation.settings.color] || CURTAIN_COLOR_LOOKUP.white
}
return event
}
diff --git a/animism-align/package-lock.json b/animism-align/package-lock.json
index 0865065..4124245 100644
--- a/animism-align/package-lock.json
+++ b/animism-align/package-lock.json
@@ -5482,6 +5482,30 @@
"esutils": "^2.0.2"
}
},
+ "dom-helpers": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz",
+ "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==",
+ "requires": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^2.6.7"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.10.5",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.5.tgz",
+ "integrity": "sha512-otddXKhdNn7d0ptoFRHtMLa8LqDxLYwTjB4nYgM1yy5N6gU/MUf8zqyyLltCH3yAVitBzmwK4us+DD0l/MauAg==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.13.7",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
+ "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
+ }
+ }
+ },
"dom-serializer": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
@@ -9242,6 +9266,17 @@
"tiny-invariant": "^1.0.6"
}
},
+ "react-transition-group": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz",
+ "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==",
+ "requires": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ }
+ },
"read-pkg": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
diff --git a/animism-align/package.json b/animism-align/package.json
index 44c9d87..efbbe06 100644
--- a/animism-align/package.json
+++ b/animism-align/package.json
@@ -58,6 +58,7 @@
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"react-sortablejs": "^2.0.11",
+ "react-transition-group": "^4.4.1",
"redux": "^4.0.5",
"redux-debounce": "^1.0.1",
"redux-debounced": "^0.5.0",