summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--animism-align/frontend/app/types.js1
-rw-r--r--animism-align/frontend/app/views/viewer/modals/modals.video.css43
-rw-r--r--animism-align/frontend/app/views/viewer/modals/modals.video.js177
-rw-r--r--animism-align/frontend/app/views/viewer/nav/eflux.chrome.js37
-rw-r--r--animism-align/frontend/app/views/viewer/nav/eflux.css1
-rw-r--r--animism-align/frontend/app/views/viewer/nav/nav.parent.js4
-rw-r--r--animism-align/frontend/app/views/viewer/nav/viewer.icons.js10
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js1
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.inline/inline.video.js10
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js13
-rw-r--r--animism-align/frontend/app/views/viewer/player/player.container.js2
-rw-r--r--animism-align/frontend/app/views/viewer/viewer.actions.js12
-rw-r--r--animism-align/frontend/app/views/viewer/viewer.container.js4
-rw-r--r--animism-align/frontend/app/views/viewer/viewer.reducer.js43
14 files changed, 230 insertions, 128 deletions
diff --git a/animism-align/frontend/app/types.js b/animism-align/frontend/app/types.js
index bbc76b2..e1015d2 100644
--- a/animism-align/frontend/app/types.js
+++ b/animism-align/frontend/app/types.js
@@ -31,6 +31,7 @@ export const viewer = with_type('viewer', [
'set_current_section', 'reached_end_of_section',
'set_nav_style', 'set_media_title', 'set_value',
'open_vitrine_modal', 'close_vitrine_modal', 'set_vitrine_index',
+ 'open_video_modal', 'close_video_modal', 'reset_video_modal',
'open_growl', 'close_growl',
'open_footnote',
])
diff --git a/animism-align/frontend/app/views/viewer/modals/modals.video.css b/animism-align/frontend/app/views/viewer/modals/modals.video.css
new file mode 100644
index 0000000..090391b
--- /dev/null
+++ b/animism-align/frontend/app/views/viewer/modals/modals.video.css
@@ -0,0 +1,43 @@
+.video-modal {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ transition: opacity 0.5s;
+ opacity: 0.0;
+ pointer-events: none;
+}
+.video-modal.open {
+ opacity: 1.0;
+ pointer-events: auto;
+}
+.video-modal .video {
+ width: 100%;
+ height: 100%;
+}
+.video-modal .video .videoPlayer {
+ pointer-events: none;
+ width: 100%;
+ height: calc(100vh) !important;
+ padding: 3rem 0 3rem 0;
+ transition: opacity 0.5s;
+}
+.video-modal .video .videoPlayer div {
+ width: 100%;
+ height: 100% !important;
+ padding: 0 !important;
+}
+.nav-open .video-modal .video-scrubber {
+ transform: translateZ(0) translateY(3rem);
+ opacity: 0;
+ pointer-events: none;
+}
+
+.video-modal-open .nav-player {
+ opacity: 0;
+ pointer-events: none;
+} \ No newline at end of file
diff --git a/animism-align/frontend/app/views/viewer/modals/modals.video.js b/animism-align/frontend/app/views/viewer/modals/modals.video.js
index e94b4c4..b67fc4b 100644
--- a/animism-align/frontend/app/views/viewer/modals/modals.video.js
+++ b/animism-align/frontend/app/views/viewer/modals/modals.video.js
@@ -4,7 +4,7 @@ import VimeoPlayer from 'app/utils/vendor/vimeo'
import actions from 'app/actions'
import { timestampToSeconds } from 'app/utils'
-import { VideoScrubber, VideoSubtitles } from '../components.media'
+import { VideoScrubber, VideoSubtitles } from '../player/components.media'
class ModalVideo extends Component {
state = {
@@ -28,6 +28,8 @@ class ModalVideo extends Component {
volume: 1.0,
volumeFadeTime: 1000,
lastCue: -1,
+ // play state
+ playing: false,
}
constructor(props) {
super(props)
@@ -35,70 +37,24 @@ class ModalVideo extends Component {
this.handlePause = this.handlePause.bind(this)
this.handleTimeUpdate = this.handleTimeUpdate.bind(this)
this.handleScrub = this.handleScrub.bind(this)
+ this.handleToggle = this.handleToggle.bind(this)
this.handleEnd = this.handleEnd.bind(this)
}
- componentDidMount() {
- const video_start_ts = timestampToSeconds(this.props.element.settings.video_start_ts) || 0.0
- // TODO: here you can add the current play time modulo ...
- this.setState({
- seek: video_start_ts,
- video_start_ts,
- })
- }
componentDidUpdate(prevProps) {
- // if the play_ts jumped more than a second, seek
- const { play_ts, element, currentSection, fadeOutDuration } = this.props
- if (Math.abs(play_ts - prevProps.play_ts) > 1.0) {
- // handle seek
- const { duration, video_start_ts } = this.state
- const seek = ((play_ts - element.start_ts) % duration) + video_start_ts
- this.setState({ seek })
- }
- // console.log(play_ts, currentSection.cues.length, fadeOutDuration, element.settings.unmuted, this.state.fadeOut)
- // volume changes - only if unmuted and not already leaving.
- if (element.settings.unmuted && !this.state.fadeOut) {
- // if we just started leaving the element, fade out the audio
- if (fadeOutDuration) {
- // console.log("fade out audio", this.props.fadeOutDuration)
- setTimeout(() => this.setState({ fadeOut: true }), 0)
- }
- // otherwise, check if we gotta set the volume based on the position
- else if (currentSection.cues.length) {
- this.checkCuePosition(play_ts, currentSection.cues)
- }
- }
- }
- checkCuePosition(play_ts, cues) {
- // const { volume element.settings.unmuted ? volume : 0.0
- const { unmuted } = this.props.element.settings
- let volume = unmuted ? 1.0 : 0.0
- let { volumeFadeTime, lastCue } = this.state
- // console.log(cues)
- cues.some((cue, i) => {
- if (cue.start_ts < play_ts) {
- lastCue = i
- if (cue.settings.volume) {
- volume = parseFloat(cue.settings.volume)
- volumeFadeTime = timestampToSeconds(cue.settings.duration) * 1000
- // console.log(volume, volumeFadeTime)
- return false
- }
- }
- return true
- })
- // console.log('last cue', lastCue, volume, volumeFadeTime)
- if (lastCue !== this.state.lastCue) {
- this.setState({ volume, volumeFadeTime, lastCue })
+ if (prevProps.open && !this.props.open) {
+ setTimeout(() => {
+ actions.viewer.resetVideoModal()
+ }, 500)
}
}
handlePlay() {
- this.setState({ ready: true })
+ this.setState({ ready: true, playing: true })
}
handlePause() {
-
+ this.setState({ playing: false })
}
handleEnd() {
-
+ this.setState({ playing: false })
}
handleTimeUpdate(timing) {
if (!this.state.scrubbing || ('scrubbing' in timing)) {
@@ -107,80 +63,87 @@ class ModalVideo extends Component {
}
handleScrub(timing) {
// console.log(timing)
- this.setState(timing)
+ this.setState({
+ ...timing,
+ seek: timing.seconds,
+ })
+ }
+ handleToggle() {
+ console.log('handle toggle to', !this.state.playing)
+ this.setState({ playing: !this.state.playing })
}
-
render() {
- const { element, media, transitionDuration, play_ts, playing, cc, playerVolume } = this.props
- const { duration, seconds, ready, volume, volumeFadeTime, fadeOut, lastCue } = this.state
- const { color } = element
- const item = media.lookup[element.settings.media_id]
+ const { open, media: mediaItem, color, cc, playerVolume } = this.props
+ const { duration, seconds, ready, volume, volumeFadeTime, playing, fadeOut, lastCue } = this.state
+ if (!color || !mediaItem) {
+ return <div />
+ }
const style = {
backgroundColor: color.backgroundColor,
color: color.textColor,
- transitionDuration,
}
const playerStyle = {
opacity: ready ? 1.0 : 0.0
}
- //
// console.log(volume, playerVolume)
return (
<div
- className='fullscreen-element video'
+ className={open ? 'video-modal open' : 'video-modal'}
style={style}
>
- <div
- className='videoPlayer'
- style={playerStyle}
- >
- <VimeoPlayer
- video={item.url}
- paused={!playing}
- autoplay={true}
- autopause={false}
- muted={!element.settings.unmuted}
- loop={!!element.settings.loop}
- seek={this.state.seek}
- responsive={true}
- controls={false}
- byline={false}
- volume={element.settings.unmuted ? playerVolume : 0.0}
- targetVolume={element.settings.unmuted ? volume * playerVolume : 0.0}
- volumeFadeTime={volumeFadeTime}
- fadeOut={fadeOut && this.props.fadeOutDuration}
- onPlay={this.handlePlay}
- onPause={this.handlePause}
- onTimeUpdate={this.handleTimeUpdate}
- onEnd={this.handleEnd}
- lastCue={lastCue}
+ <div className='fullscreen-element video' onClick={this.handleToggle}>
+ <div
+ className='videoPlayer'
+ style={playerStyle}
+ >
+ <VimeoPlayer
+ video={mediaItem.url}
+ paused={!open || (ready && !playing)}
+ autoplay={true}
+ autopause={false}
+ muted={false}
+ loop={false}
+ seek={this.state.seek}
+ responsive={true}
+ controls={false}
+ byline={false}
+ volume={playerVolume}
+ targetVolume={playerVolume}
+ volumeFadeTime={volumeFadeTime}
+ fadeOut={0}
+ onPlay={this.handlePlay}
+ onPause={this.handlePause}
+ onTimeUpdate={this.handleTimeUpdate}
+ onEnd={this.handleEnd}
+ lastCue={lastCue}
+ />
+ </div>
+ <VideoScrubber
+ play_ts={seconds}
+ start_ts={0}
+ video_start_ts={0}
+ playing={playing}
+ duration={duration}
+ timing={this.state}
+ mediaItem={mediaItem}
+ cc={cc}
+ onScrub={this.handleScrub}
+ onToggle={this.handleToggle}
+ scrubMasterAudio={false}
+ />
+ <VideoSubtitles
+ cc={cc}
+ play_ts={seconds}
+ mediaItem={mediaItem}
/>
</div>
- <VideoScrubber
- play_ts={play_ts}
- start_ts={element.start_ts}
- video_start_ts={this.state.video_start_ts}
- playing={playing}
- duration={element.duration}
- timing={this.state}
- mediaItem={item}
- cc={cc}
- onScrub={this.handleScrub}
- />
- <VideoSubtitles
- cc={cc}
- play_ts={seconds}
- mediaItem={item}
- />
</div>
)
}
}
const mapStateToProps = state => ({
- viewer: state.viewer,
- play_ts: state.audio.play_ts,
- playing: state.audio.playing,
+ ...state.viewer.videoModal,
playerVolume: state.audio.volume,
cc: state.audio.cc,
})
diff --git a/animism-align/frontend/app/views/viewer/nav/eflux.chrome.js b/animism-align/frontend/app/views/viewer/nav/eflux.chrome.js
index d365c9c..00851be 100644
--- a/animism-align/frontend/app/views/viewer/nav/eflux.chrome.js
+++ b/animism-align/frontend/app/views/viewer/nav/eflux.chrome.js
@@ -24,12 +24,33 @@ class EfluxChrome extends Component {
started: false,
playMessage: PLAY_MESSAGES.not_started,
}
+ constructor(props) {
+ super(props)
+ this.handleToggle = this.handleToggle.bind(this)
+ this.handleClose = this.handleClose.bind(this)
+ }
handleMouseEnter(category) {
this.setState({ [category]: true })
}
handleMouseLeave(category) {
this.setState({ [category]: false })
}
+ handleToggle() {
+ if (this.props.playing) {
+ actions.audio.pause()
+ } else {
+ actions.viewer.playFromClick()
+ }
+ }
+ handleClose() {
+ if (this.props.videoModalOpen) {
+ actions.viewer.closeVideoModal()
+ } else {
+ actions.viewer.toggleFullscreenVisible(false)
+ actions.audio.pause()
+ }
+ this.handleMouseLeave('close')
+ }
componentDidUpdate(prevProps) {
if (this.props.playing !== prevProps.playing) {
if (!this.state.started) {
@@ -61,7 +82,8 @@ class EfluxChrome extends Component {
playing, transcriptOpen,
isFullscreen, fullscreenVisible, isFullscreenSingleton,
growlOpen, growlMessage,
- atEndOfSection, currentSection
+ atEndOfSection, currentSection,
+ videoModalOpen
} = this.props
let className = "eflux-header"
if (navStyle) className += ' ' + navStyle
@@ -69,7 +91,7 @@ class EfluxChrome extends Component {
if (transcriptOpen) className += ' transcript-open'
if (isFullscreen) className += ' is-fullscreen'
// console.log(isFullscreen, fullscreenVisible, isFullscreenSingleton)
- const fullscreenWantsCloseButton = isFullscreen && fullscreenVisible && !isFullscreenSingleton
+ const fullscreenWantsCloseButton = (isFullscreen && fullscreenVisible && !isFullscreenSingleton) || videoModalOpen
return (
<div className={className}>
<div className="eflux-gradient" />
@@ -92,7 +114,7 @@ class EfluxChrome extends Component {
onMouseEnter={() => this.handleMouseEnter('play')}
onMouseLeave={() => this.handleMouseLeave('play')}
>
- <PlayButton playing={playing} />
+ <PlayButton playing={playing} onClick={this.handleToggle} />
</span>
<div
className="transcript-icon"
@@ -108,7 +130,7 @@ class EfluxChrome extends Component {
? "growl-tooltip tooltip-close hover"
: "growl-tooltip tooltip-close"
}>
- {'Close fullscreen player'}
+ {videoModalOpen ? 'Close video' : 'Close fullscreen player'}
</div>
<div className={
this.state.eflux
@@ -142,11 +164,7 @@ class EfluxChrome extends Component {
className="fullscreen-close"
onMouseEnter={() => this.handleMouseEnter('close')}
onMouseLeave={() => this.handleMouseLeave('close')}
- onClick={() => {
- actions.viewer.toggleFullscreenVisible(false)
- actions.audio.pause()
- this.handleMouseLeave('close')
- }}
+ onClick={this.handleClose}
>
{EfluxClose}
</div>
@@ -166,6 +184,7 @@ const mapStateToProps = state => ({
isFullscreen: state.viewer.isFullscreen,
fullscreenVisible: state.viewer.fullscreenVisible,
isFullscreenSingleton: state.viewer.isFullscreenSingleton,
+ videoModalOpen: state.viewer.videoModal.open,
})
export default connect(mapStateToProps)(EfluxChrome)
diff --git a/animism-align/frontend/app/views/viewer/nav/eflux.css b/animism-align/frontend/app/views/viewer/nav/eflux.css
index 3c464ae..2670518 100644
--- a/animism-align/frontend/app/views/viewer/nav/eflux.css
+++ b/animism-align/frontend/app/views/viewer/nav/eflux.css
@@ -128,6 +128,7 @@
padding: 0.75rem;
text-align: center;
pointer-events: none;
+ user-select: none;
}
.growl-tooltip.tooltip-eflux {
left: 1.8rem;
diff --git a/animism-align/frontend/app/views/viewer/nav/nav.parent.js b/animism-align/frontend/app/views/viewer/nav/nav.parent.js
index 33f2d58..0f829dd 100644
--- a/animism-align/frontend/app/views/viewer/nav/nav.parent.js
+++ b/animism-align/frontend/app/views/viewer/nav/nav.parent.js
@@ -74,7 +74,7 @@ class NavParent extends Component {
e && e.stopPropagation()
if (isMobile) {
actions.viewer.toggleComponent('nav')
- } else {
+ } else if (!this.props.videoModal.open) {
// console.log('>> CLICK NAV')
// actions.viewer.toggleComponent('nav')
const percent = (e.pageX / this.navbarRef.current.offsetWidth)
@@ -115,7 +115,7 @@ class NavParent extends Component {
let containerClassName = "viewer-nav " + viewer.navStyle
let navClassName = 'nav-row main-nav'
if (this.state.hoveringNav || !started) containerClassName += ' hovering-nav'
- if ((this.state.hoveringNext || (viewer.atEndOfSection && !playing)) && !viewer.nav && viewer.nextSection) containerClassName += ' hovering-next'
+ if ((this.state.hoveringNext || (viewer.atEndOfSection && !playing && !viewer.videoModal.open)) && !viewer.nav && viewer.nextSection) containerClassName += ' hovering-next'
return (
<div ref={this.navbarRef} className={containerClassName} onMouseMove={this.handleMouseMove} onMouseLeave={this.handleMouseLeave}>
<div className={navClassName} onClick={this.handleNavBarClick}>
diff --git a/animism-align/frontend/app/views/viewer/nav/viewer.icons.js b/animism-align/frontend/app/views/viewer/nav/viewer.icons.js
index 31910b7..95be8b6 100644
--- a/animism-align/frontend/app/views/viewer/nav/viewer.icons.js
+++ b/animism-align/frontend/app/views/viewer/nav/viewer.icons.js
@@ -67,13 +67,19 @@ export const PauseIcon = (
</svg>
)
-export const PlayButton = ({ playing }) => {
+export const PlayButton = ({ playing, onClick }) => {
return (
<div
className={playing ? 'playToggle playing' : 'playToggle paused'}
onClick={e => {
e && e.stopPropagation()
- playing ? actions.audio.pause() : actions.viewer.playFromClick()
+ if (onClick) {
+ onClick(playing)
+ } else if (playing) {
+ actions.audio.pause()
+ } else {
+ actions.viewer.playFromClick()
+ }
}}
>
{playing ? PauseIcon : PlayIcon}
diff --git a/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js
index adbc443..cd40746 100644
--- a/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js
+++ b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js
@@ -166,6 +166,7 @@ class FullscreenVideo extends Component {
mediaItem={item}
cc={cc}
onScrub={this.handleScrub}
+ scrubMasterAudio={true}
/>
<VideoSubtitles
cc={cc}
diff --git a/animism-align/frontend/app/views/viewer/player/components.inline/inline.video.js b/animism-align/frontend/app/views/viewer/player/components.inline/inline.video.js
index ea73d03..00f2de4 100644
--- a/animism-align/frontend/app/views/viewer/player/components.inline/inline.video.js
+++ b/animism-align/frontend/app/views/viewer/player/components.inline/inline.video.js
@@ -1,6 +1,7 @@
import React, { Component } from 'react'
import VimeoPlayer from 'app/utils/vendor/vimeo'
+import actions from 'app/actions'
import { CURTAIN_COLOR_LOOKUP } from 'app/constants'
import { SpeakerIcon } from '../../nav/viewer.icons'
import { MediaCitation } from '../components.media'
@@ -61,7 +62,14 @@ export class MediaVideo extends Component {
<div
className='videoPoster'
style={style}
- onClick={e => onAnnotationClick(e, paragraph, annotation)}
+ onClick={e => {
+ if (annotation.settings.can_play_full_video) {
+ e && e.stopPropagation()
+ actions.viewer.openVideoModal(item, color)
+ } else {
+ onAnnotationClick(e, paragraph, annotation)
+ }
+ }}
>
<div className='posterImage'>
<img src={posterURL(item)} />
diff --git a/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js b/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js
index e43c7ec..10677dc 100644
--- a/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js
+++ b/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js
@@ -47,15 +47,17 @@ class VideoScrubber extends Component {
this.defer = false
}
scrub(x, scrubbing) {
- const { timing, start_ts, video_start_ts, onScrub, duration } = this.props
+ const { timing, start_ts, video_start_ts, onScrub, onToggle, duration, scrubMasterAudio } = this.props
const bounds = this.scrubberRef.current.getBoundingClientRect()
// get percent offset from the scrubber
const percent = clamp((x - bounds.left) / bounds.width, 0, 1)
// this offset in seconds based on the length of the fullscreen element
const seconds = percent * duration
// we can use this to seek the audio
- actions.audio.seek(start_ts + seconds)
- actions.audio.play()
+ if (scrubMasterAudio) {
+ actions.audio.seek(start_ts + seconds)
+ actions.audio.play()
+ }
// apply the video start offset.
// in case the video loops, modulo the length of the original video
const video_seek = ((seconds + video_start_ts) % timing.duration)
@@ -104,7 +106,7 @@ class VideoScrubber extends Component {
clearTimeout(this.hideTimeout)
}
render() {
- const { playing, start_ts, play_ts, volume, timing, video_start_ts, duration, cc, mediaItem } = this.props
+ const { playing, start_ts, play_ts, volume, timing, video_start_ts, duration, cc, mediaItem, onToggle } = this.props
const { hovering, showing } = this.state
// remove video start offset from timing
// console.log(start_ts, play_ts)
@@ -119,7 +121,7 @@ class VideoScrubber extends Component {
return (
<div className={className}>
<div className='start-controls'>
- <PlayButton playing={playing} />
+ <PlayButton playing={playing} onClick={onToggle} />
</div>
<div
className='scrub-bar-container'
@@ -153,7 +155,6 @@ class VideoScrubber extends Component {
}
const mapStateToProps = state => ({
- playing: state.audio.playing,
volume: state.audio.volume,
cc: state.audio.cc,
})
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 77de555..39a08dc 100644
--- a/animism-align/frontend/app/views/viewer/player/player.container.js
+++ b/animism-align/frontend/app/views/viewer/player/player.container.js
@@ -7,6 +7,7 @@ import { preloadSectionImages } from 'app/utils/image.utils'
import PlayerTranscript from './player.transcript'
import PlayerFullscreen from './player.fullscreen'
+import VideoModal from '../modals/modals.video'
class PlayerContainer extends Component {
constructor(props) {
@@ -110,6 +111,7 @@ class PlayerContainer extends Component {
<div className='viewer-container'>
<PlayerTranscript />
<PlayerFullscreen />
+ <VideoModal />
</div>
)
}
diff --git a/animism-align/frontend/app/views/viewer/viewer.actions.js b/animism-align/frontend/app/views/viewer/viewer.actions.js
index c8b43b6..39aa9f8 100644
--- a/animism-align/frontend/app/views/viewer/viewer.actions.js
+++ b/animism-align/frontend/app/views/viewer/viewer.actions.js
@@ -455,6 +455,18 @@ export const vitrineGo = direction => dispatch => {
}
}
+/* video modal */
+
+export const openVideoModal = (media, color) => dispatch => {
+ dispatch({ type: types.viewer.open_video_modal, media, color })
+}
+export const closeVideoModal = () => dispatch => {
+ dispatch({ type: types.viewer.close_video_modal })
+}
+export const resetVideoModal = () => dispatch => {
+ dispatch({ type: types.viewer.reset_video_modal })
+}
+
/* growl */
export const openGrowl = message => dispatch => {
diff --git a/animism-align/frontend/app/views/viewer/viewer.container.js b/animism-align/frontend/app/views/viewer/viewer.container.js
index 5bc95f0..3d18745 100644
--- a/animism-align/frontend/app/views/viewer/viewer.container.js
+++ b/animism-align/frontend/app/views/viewer/viewer.container.js
@@ -15,6 +15,7 @@ import './checklist/checklist.css'
import './checklist/credits.css'
import './modals/modals.vitrine.css'
import './modals/modals.handheld.css'
+import './modals/modals.video.css'
import './forms/forms.css'
import './player/player.container.css'
import './player/player.fullscreen.css'
@@ -52,6 +53,9 @@ class ViewerContainer extends Component {
if (viewer.atEndOfSection) {
className += ' section-end'
}
+ if (viewer.videoModal.open) {
+ className += ' video-modal-open'
+ }
if (viewer.checklist || viewer.credits) {
className += ' checklist-open'
} else {
diff --git a/animism-align/frontend/app/views/viewer/viewer.reducer.js b/animism-align/frontend/app/views/viewer/viewer.reducer.js
index 0fcbfa2..be4e7bb 100644
--- a/animism-align/frontend/app/views/viewer/viewer.reducer.js
+++ b/animism-align/frontend/app/views/viewer/viewer.reducer.js
@@ -45,11 +45,19 @@ const initialState = {
growlMessage: GROWL.OPENING_MESSAGE,
growlTranscriptOpen: false,
- /* vitrine */
+ /* vitrine modal */
vitrineModal: {
open: false,
media: null,
index: null,
+ color: null,
+ },
+
+ /* video modal */
+ videoModal: {
+ open: false,
+ media: null,
+ color: null,
},
options: {},
@@ -112,6 +120,10 @@ export default function viewerReducer(state = initialState, action) {
navStyle: action.currentSection.color,
fullscreenVisible: true,
atEndOfSection: false,
+ videoModal: {
+ ...state.videoModal,
+ open: false,
+ }
}
case types.viewer.reached_end_of_section:
@@ -167,6 +179,35 @@ export default function viewerReducer(state = initialState, action) {
}
}
+ case types.viewer.open_video_modal:
+ return {
+ ...state,
+ videoModal: {
+ open: true,
+ media: action.media,
+ color: action.color,
+ }
+ }
+
+ case types.viewer.close_video_modal:
+ return {
+ ...state,
+ videoModal: {
+ ...state.videoModal,
+ open: false,
+ }
+ }
+
+ case types.viewer.reset_video_modal:
+ return {
+ ...state,
+ videoModal: {
+ open: false,
+ media: null,
+ color: null,
+ }
+ }
+
case types.viewer.open_footnote:
return {
...state,