summaryrefslogtreecommitdiff
path: root/animism-align/frontend
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-11-18 15:37:42 +0100
committerJules Laplace <julescarbon@gmail.com>2020-11-18 15:37:42 +0100
commitd351d8dd915c5075983eaa5cac6f0d5a1b99a877 (patch)
tree57a89011f201711a902870f7b9a23426d1d40413 /animism-align/frontend
parent50411efc89fabb77c02b472446221e6bcd9ff621 (diff)
staggered, cancellable preloading of all section image assets, as soon as the section loads
Diffstat (limited to 'animism-align/frontend')
-rw-r--r--animism-align/frontend/app/utils/annotation.utils.js26
-rw-r--r--animism-align/frontend/app/utils/image.utils.js28
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.image.js20
-rw-r--r--animism-align/frontend/app/views/viewer/player/player.container.js13
4 files changed, 66 insertions, 21 deletions
diff --git a/animism-align/frontend/app/utils/annotation.utils.js b/animism-align/frontend/app/utils/annotation.utils.js
index a055d91..90ac498 100644
--- a/animism-align/frontend/app/utils/annotation.utils.js
+++ b/animism-align/frontend/app/utils/annotation.utils.js
@@ -72,6 +72,30 @@ export const displayThumbnailURL = media => {
}
}
+export const displayElementImageURL = (element, mediaItem) => {
+ // console.log(element, mediaItem)
+ if (!element || !mediaItem) return null
+ if (mediaItem.type === 'gallery') {
+ const index = parseInt(element.settings.frame_index)
+ const frame_id = mediaItem.settings.image_order[index]
+ const frame = mediaItem.settings.display_lookup[frame_id]
+ if (!frame) {
+ console.error("Slide not found:", element.settings.frame_index)
+ return null
+ }
+ return frame.url
+ }
+ return mediaItem.settings.display.url
+}
+
+// list all full-size images URLs for the vitrine
+export const galleryFullsizeImageURLS = media => {
+ const { image_order, image_lookup, display_lookup } = media.settings
+ return image_order.map(id => (
+ display_lookup[id] || image_lookup[id]
+ )).map(img => img.url)
+}
+
export const posterURL = media => {
if (!media.settings.video) return null
if (media.settings.poster) return media.settings.poster.url
@@ -111,7 +135,7 @@ export const makeGalleryItems = (annotation, media) => {
if (item.type !== 'gallery') return {}
const gallery_items = item.settings.image_order.map((id, index) => {
const caption = item.settings.caption_lookup && item.settings.caption_lookup[id]
- console.log(caption)
+ // console.log(caption)
return {
name: index,
label: (index + 1) + ") " + (caption ? (caption.title || "") : "")
diff --git a/animism-align/frontend/app/utils/image.utils.js b/animism-align/frontend/app/utils/image.utils.js
index d7b7508..358c91d 100644
--- a/animism-align/frontend/app/utils/image.utils.js
+++ b/animism-align/frontend/app/utils/image.utils.js
@@ -1,4 +1,24 @@
-const preloadedImages = {}
+import { displayElementImageURL, galleryFullsizeImageURLS } from 'app/utils/annotation.utils'
+
+export const preloadSectionImages = (section, mediaLookup) => {
+ // console.log(section)
+ let urls = []
+ section.fullscreenTimeline.forEach(element => {
+ // console.log(element)
+ const mediaItem = mediaLookup[element.settings.media_id]
+ if (!mediaItem) return
+ // console.log(mediaItem)
+ switch (mediaItem.type) {
+ case 'image':
+ urls.push(displayElementImageURL(element, mediaItem))
+ break
+ case 'gallery':
+ urls = urls.concat(galleryFullsizeImageURLS(mediaItem))
+ break
+ }
+ })
+ return preloadImages(urls)
+}
export const preloadImages = urls => batchPromise(urls, 4, preloadImage)
@@ -41,12 +61,14 @@ export const batchPromise = (list, count, fn) => {
}
}
+const preloadedImageCache = {}
export const preloadImage = (url, anonymous=false) => (
new Promise((resolve, reject) => {
- if (preloadedImages[url] || typeof url === 'object' && url instanceof Image) {
+ if (!url || preloadedImageCache[url] || typeof url === 'object' && url instanceof Image) {
return resolve(url)
}
- preloadedImages[url] = true
+ // console.log('preload', url)
+ preloadedImageCache[url] = true
const image = new Image()
let loaded = false
image.onload = () => {
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
index 60ba7c9..a05789b 100644
--- 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
@@ -1,29 +1,21 @@
import React from 'react'
import { CURTAIN_COLOR_LOOKUP } from 'app/constants'
+import { displayElementImageURL } from 'app/utils/annotation.utils'
+
export const FullscreenImage = ({ element, media, transitionDuration }) => {
const color = element.color || CURTAIN_COLOR_LOOKUP.white
- const item = media.lookup[element.settings.media_id]
+ const mediaItem = media.lookup[element.settings.media_id]
const style = {
backgroundColor: color.backgroundColor,
color: color.textColor,
transitionDuration,
}
- let url;
- // console.log(element, item)
- if (item.type === 'gallery') {
- const index = parseInt(element.settings.frame_index)
- const frame_id = item.settings.image_order[index]
- const frame = item.settings.display_lookup[frame_id]
- if (!frame) {
- console.error("Slide not found:", element.settings.frame_index)
- return <div />
- }
- url = frame.url
- } else {
- url = item.settings.display.url
+ let url = displayElementImageURL(element, mediaItem)
+ if (!url) {
+ return <div />
}
return (
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 87a325b..8602284 100644
--- a/animism-align/frontend/app/views/viewer/player/player.container.js
+++ b/animism-align/frontend/app/views/viewer/player/player.container.js
@@ -2,7 +2,8 @@ import React, { Component } from 'react'
import { connect } from 'react-redux'
import actions from 'app/actions'
-import { floatEQ, floatInRange, clamp } from 'app/utils'
+import { floatInRange, clamp } from 'app/utils'
+import { preloadSectionImages } from 'app/utils/image.utils'
import PlayerTranscript from './player.transcript'
import PlayerFullscreen from './player.fullscreen'
@@ -70,8 +71,13 @@ class PlayerContainer extends Component {
}
componentDidUpdate(prevProps) {
- if (this.props.audio.play_ts === prevProps.audio.play_ts) return
- this.handleTimeUpdate()
+ if (this.props.audio.play_ts !== prevProps.audio.play_ts) {
+ this.handleTimeUpdate()
+ }
+ if (this.props.currentSection !== prevProps.currentSection) {
+ this.preloader && this.preloader.cancel()
+ this.preloader = preloadSectionImages(this.props.currentSection, this.props.mediaLookup)
+ }
}
handleTimeUpdate() {
@@ -114,6 +120,7 @@ class PlayerContainer extends Component {
const mapStateToProps = state => ({
viewer: state.viewer,
audio: state.audio,
+ mediaLookup: state.media.index.lookup,
sections: state.viewer.sections,
currentSection: state.viewer.currentSection,
autoAdvance: state.viewer.autoAdvance,