diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-11-18 15:37:42 +0100 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-11-18 15:37:42 +0100 |
| commit | d351d8dd915c5075983eaa5cac6f0d5a1b99a877 (patch) | |
| tree | 57a89011f201711a902870f7b9a23426d1d40413 /animism-align/frontend | |
| parent | 50411efc89fabb77c02b472446221e6bcd9ff621 (diff) | |
staggered, cancellable preloading of all section image assets, as soon as the section loads
Diffstat (limited to 'animism-align/frontend')
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, |
