summaryrefslogtreecommitdiff
path: root/animism-align
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-09-08 16:05:54 +0200
committerJules Laplace <julescarbon@gmail.com>2020-09-08 16:05:54 +0200
commit0a6a7fb9b49a2180a68f6c96815ebd9b7f6b5ab7 (patch)
tree09d112663ca6e6b8255b58fec64522b2b6888c8d /animism-align
parent064e8652dc4fae7167e3cd34a6fbe6b36e6239d1 (diff)
section 2 carousel
Diffstat (limited to 'animism-align')
-rw-r--r--animism-align/frontend/app/utils/viewer.utils.js14
-rw-r--r--animism-align/frontend/app/views/viewer/nav/viewer.router.js11
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.gallery.js22
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.fullscreen/index.js7
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.media/media.carousel.js80
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.media/media.citation.js15
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.media/media.css113
-rw-r--r--animism-align/frontend/app/views/viewer/player/player.fullscreen.css15
-rw-r--r--animism-align/frontend/app/views/viewer/viewer.actions.js9
9 files changed, 232 insertions, 54 deletions
diff --git a/animism-align/frontend/app/utils/viewer.utils.js b/animism-align/frontend/app/utils/viewer.utils.js
new file mode 100644
index 0000000..b61f998
--- /dev/null
+++ b/animism-align/frontend/app/utils/viewer.utils.js
@@ -0,0 +1,14 @@
+import { store } from 'app/store'
+
+export const getSection = index => {
+ const { sections } = store.getState().viewer
+ return sections[index]
+}
+
+export const getNextSection = section => {
+ const { sections } = store.getState().viewer
+ if (section.index === sections.length - 1) {
+ return null
+ }
+ return sections[section.index + 1]
+}
diff --git a/animism-align/frontend/app/views/viewer/nav/viewer.router.js b/animism-align/frontend/app/views/viewer/nav/viewer.router.js
index 837bd5e..7f18b94 100644
--- a/animism-align/frontend/app/views/viewer/nav/viewer.router.js
+++ b/animism-align/frontend/app/views/viewer/nav/viewer.router.js
@@ -3,6 +3,7 @@ import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import { timestampToSeconds } from 'app/utils'
+import { getSection } from 'app/utils/viewer.utils'
import actions from 'app/actions'
class ViewerRouter extends Component {
@@ -21,11 +22,17 @@ class ViewerRouter extends Component {
case 'checklist':
actions.viewer.showComponent('checklist')
break
+ case 'carousel':
+ actions.viewer.seekToSection(getSection(1))
+ break
case 'vitrine':
- actions.audio.seek(timestampToSeconds('7:36'))
+ actions.viewer.seekToSection(getSection(2))
break
case 'gallery':
- actions.audio.seek(timestampToSeconds('27:36'))
+ actions.viewer.seekToSection(getSection(3))
+ break
+ case 'video':
+ actions.viewer.seekToSection(getSection(4))
break
case 'end':
break
diff --git a/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.gallery.js b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.gallery.js
index 0549f09..9cd2787 100644
--- a/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.gallery.js
+++ b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.gallery.js
@@ -1,6 +1,7 @@
import React from 'react'
-import { MediaCitation, Vitrine } from '../components.media'
+import { CURTAIN_COLOR_LOOKUP } from 'app/constants'
+import { MediaCitation, Vitrine, Gallery, Carousel, Grid } from '../components.media'
export const FullscreenVitrine = ({ element, media, transitionDuration }) => {
const { color } = element
@@ -38,3 +39,22 @@ export const FullscreenGallery = ({ element, media, transitionDuration }) => {
</div>
)
}
+
+export const FullscreenCarousel = ({ element, media, transitionDuration }) => {
+ const { color } = element
+ const item = media.lookup[element.settings.media_id]
+ const style = {
+ backgroundColor: color.backgroundColor,
+ color: color.textColor,
+ transitionDuration,
+ }
+ return (
+ <div
+ className='fullscreen-element carousel'
+ style={style}
+ >
+ {element.settings.title && <div className='heading'>{element.settings.title}</div>}
+ <Carousel media={item} withCitation />
+ </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
index 538632f..25fbc83 100644
--- a/animism-align/frontend/app/views/viewer/player/components.fullscreen/index.js
+++ b/animism-align/frontend/app/views/viewer/player/components.fullscreen/index.js
@@ -9,7 +9,9 @@ import {
} from './fullscreen.video'
import {
- FullscreenVitrine
+ FullscreenVitrine,
+ FullscreenGallery,
+ FullscreenCarousel
} from './fullscreen.gallery'
import {
@@ -20,6 +22,7 @@ export const fullscreenComponents = {
curtain: React.memo(FullscreenCurtain),
video: React.memo(FullscreenVideo),
image: React.memo(FullscreenImage),
- // gallery: React.memo(FullscreenGallery),
+ gallery: React.memo(FullscreenGallery),
+ carousel: React.memo(FullscreenCarousel),
vitrine: React.memo(FullscreenVitrine),
}
diff --git a/animism-align/frontend/app/views/viewer/player/components.media/media.carousel.js b/animism-align/frontend/app/views/viewer/player/components.media/media.carousel.js
index 914a8d9..edaa209 100644
--- a/animism-align/frontend/app/views/viewer/player/components.media/media.carousel.js
+++ b/animism-align/frontend/app/views/viewer/player/components.media/media.carousel.js
@@ -2,20 +2,32 @@ import React, { Component } from 'react'
import { useKeenSlider } from "keen-slider/react"
import "keen-slider/keen-slider.min.css"
+import { MediaCitation } from './media.citation'
+import { Arrow } from 'app/views/viewer/nav/viewer.icons'
+
export const Carousel = ({ media }) => {
- const { image_order, image_lookup, display_lookup, thumbnail_lookup } = media.settings
+ const { image_order, image_lookup, display_lookup, thumbnail_lookup, caption_lookup } = media.settings
- const [sliderRef] = useKeenSlider({
+ const [currentSlide, setCurrentSlide] = React.useState(0)
+ const [currentCaption, setCurrentCaption] = React.useState(caption_lookup[image_order[0]])
+ const [sliderRef, slider] = useKeenSlider({
slidesPerView: 2,
mode: "free-snap",
spacing: 15,
centered: true,
- loop: false
- });
+ loop: false,
+ slideChanged: slider => {
+ const currentSlideIndex = slider.details().relativeSlide
+ const currentImageId = image_order[currentSlideIndex]
+ const currentCaption = caption_lookup[currentImageId]
+ setCurrentSlide(currentSlideIndex)
+ setCurrentCaption(currentCaption)
+ }
+ })
// console.log(display_lookup)
// console.log(width)
- return (
- <div ref={sliderRef} className='keen-slider carousel-items'>
+ return [
+ <div key={'carousel_' + media.id} ref={sliderRef} className='keen-slider carousel-items'>
{image_order.map(id => {
const image = display_lookup[id]
// console.log(image)
@@ -23,7 +35,63 @@ export const Carousel = ({ media }) => {
<CarouselItem key={id} image={image} />
)
})}
+ </div>,
+ <MediaCitation key={'caption_' + media.id} media={currentCaption} />,
+ <CarouselNav
+ key={'arrows_' + media.id}
+ currentSlide={currentSlide}
+ slides={image_order}
+ onPrev={() => {
+ slider.prev()
+ }}
+ onNext={() => {
+ slider.next()
+ }}
+ onPick={index => {
+ slider.moveToSlideRelative(index)
+ }}
+ />
+ ]
+}
+
+const CarouselNav = ({ currentSlide, slides, onPrev, onNext, onPick }) => {
+ return (
+ <div className="carousel-nav">
+ <div
+ className={currentSlide ? "arrow-prev" : "arrow-prev arrow-disabled"}
+ onClick={e => {
+ e.stopPropagation()
+ onPrev()
+ }}
+ >
+ <Arrow type="left" />
+ </div>
+ <div
+ className={currentSlide < slides.length - 1 ? "arrow-next" : "arrow-next arrow-disabled"}
+ onClick={e => {
+ e.stopPropagation()
+ onNext()
+ }}
+ >
+ <Arrow type="right" />
+ </div>
+ <div className="dots">
+ {[...slides.keys()].map(idx => {
+ return (
+ <div
+ key={idx}
+ onClick={() => {
+ onPick(idx)
+ }}
+ className={"dot-item" + (currentSlide === idx ? " active" : "")}
+ >
+ <div className="dot-circle" />
+ </div>
+ )
+ })}
+ </div>
</div>
+
)
}
diff --git a/animism-align/frontend/app/views/viewer/player/components.media/media.citation.js b/animism-align/frontend/app/views/viewer/player/components.media/media.citation.js
index 14c8c53..ea20a3b 100644
--- a/animism-align/frontend/app/views/viewer/player/components.media/media.citation.js
+++ b/animism-align/frontend/app/views/viewer/player/components.media/media.citation.js
@@ -1,9 +1,20 @@
import React, { Component } from 'react'
export const MediaCitation = ({ media }) => {
- if (media.settings.bibliography) {
+ if (!media) {
return (
- <div className='citation' dangerouslySetInnerHTML={{ __html: media.settings.bibliography }} />
+ <div className='citation' />
+ )
+ }
+ const settings = media.settings || media
+ if (settings.bibliography) {
+ return (
+ <div className='citation' dangerouslySetInnerHTML={{ __html: settings.bibliography }} />
+ )
+ }
+ if (settings.short_caption) {
+ return (
+ <div className='citation' dangerouslySetInnerHTML={{ __html: settings.short_caption }} />
)
}
return (
diff --git a/animism-align/frontend/app/views/viewer/player/components.media/media.css b/animism-align/frontend/app/views/viewer/player/components.media/media.css
index 62eb9af..f552eba 100644
--- a/animism-align/frontend/app/views/viewer/player/components.media/media.css
+++ b/animism-align/frontend/app/views/viewer/player/components.media/media.css
@@ -1,3 +1,90 @@
+/* heading and caption */
+
+.viewer-fullscreen .heading {
+ font-family: "Freight Text", serif;
+ font-size: 3rem;
+ line-height: 1.28;
+ width: 80%;
+ margin: 4rem auto 0 auto;
+ padding-bottom: 1rem;
+ text-align: center;
+}
+.viewer-fullscreen .citation {
+ width: 45rem;
+ margin: 0 auto 3rem auto;
+ padding: 1rem 0;
+ font-family: "Neue Haas Unica";
+ color: #888;
+}
+
+.viewer-fullscreen .fullscreen-element.gallery,
+.viewer-fullscreen .fullscreen-element.carousel,
+.viewer-fullscreen .fullscreen-element.vitrine {
+ flex-direction: column;
+ justify-content: space-between;
+ align-items: center;
+}
+.viewer-fullscreen .fullscreen-element.gallery .citation,
+.viewer-fullscreen .fullscreen-element.carousel .citation,
+.viewer-fullscreen .fullscreen-element.vitrine .citation {
+ margin-top: 3rem;
+}
+
+/* arrows and dots */
+
+.carousel-nav .arrow-prev {
+ position: absolute;
+ left: 1rem;
+ top: 50%;
+ margin-top: -3.5rem;
+ transform: translateY(-50%);
+ cursor: pointer;
+}
+.carousel-nav .arrow-next {
+ position: absolute;
+ right: 1rem;
+ top: 50%;
+ margin-top: -3.5rem;
+ transform: translateY(-50%);
+ cursor: pointer;
+}
+.carousel-nav .arrow {
+ width: 4rem;
+}
+.carousel-nav .arrow-disabled {
+ cursor: default;
+ opacity: 0.2;
+}
+.carousel-nav .dots {
+ position: absolute;
+ bottom: 5.5rem;
+ left: 0;
+ width: 100%;
+ display: flex;
+ padding: 10px 0;
+ justify-content: center;
+}
+.dots .dot-item {
+ cursor: pointer;
+ opacity: 0.2;
+ margin: 0;
+ padding: 15px 7px;
+ background: transparent;
+ cursor: pointer;
+}
+.dots .dot-circle {
+ border-radius: 50%;
+ background: #000;
+ width: 10px;
+ height: 10px;
+}
+.dots .dot-item:focus {
+ outline: none;
+}
+.dots .dot-item.active {
+ opacity: 1.0;
+}
+
/* carousel */
.carousel-container {
@@ -6,12 +93,18 @@
padding: 1rem;
}
.carousel-item {
- height: calc(100vh - 9rem);
- width: 50vw;
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
}
+.player-transcript .carousel-item {
+ width: 50vw;
+ height: calc(100vh - 9rem);
+}
+.viewer-fullscreen .carousel-item {
+ width: 50vw;
+ height: calc(100vh - 8rem);
+}
/* gallery */
@@ -91,22 +184,6 @@
/* vitrine */
-.vitrine .heading {
- font-family: "Freight Text", serif;
- font-size: 3rem;
- line-height: 1.28;
- width: 80%;
- margin: 0 auto;
- padding-bottom: 2rem;
- text-align: center;
-}
-.vitrine .citation {
- width: 45rem;
- margin: 0 auto;
- padding: 1rem 0;
- font-family: "Neue Haas Unica";
- color: #888;
-}
.vitrine-items {
display: flex;
flex-flow: row wrap;
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 e6a3504..8d38fa0 100644
--- a/animism-align/frontend/app/views/viewer/player/player.fullscreen.css
+++ b/animism-align/frontend/app/views/viewer/player/player.fullscreen.css
@@ -53,18 +53,3 @@
background-repeat: no-repeat;
background-position: center center;
}
-
-/* vitrine */
-
-.viewer-fullscreen .fullscreen-element.vitrine {
- flex-direction: column;
- justify-content: space-between;
- align-items: center;
-}
-.viewer-fullscreen .fullscreen-element.vitrine .heading {
- margin-top: 4rem;
- padding-bottom: 1rem;
-}
-.viewer-fullscreen .fullscreen-element.vitrine .citation {
- margin-bottom: 3rem;
-}
diff --git a/animism-align/frontend/app/views/viewer/viewer.actions.js b/animism-align/frontend/app/views/viewer/viewer.actions.js
index c1b11be..3b6fbdd 100644
--- a/animism-align/frontend/app/views/viewer/viewer.actions.js
+++ b/animism-align/frontend/app/views/viewer/viewer.actions.js
@@ -11,6 +11,7 @@ import {
import { floatInRange } from 'app/utils'
import { buildParagraphs } from 'app/utils/transcript.utils'
import { annotationFadeTimings } from 'app/utils/annotation.utils'
+import { getNextSection } from 'app/utils/viewer.utils'
const newSection = (annotation, index, mediaIndex) => ({
start_ts: annotation.start_ts,
@@ -176,14 +177,6 @@ export const toggleComponent = key => dispatch => {
dispatch({ type: types.viewer.toggle_component, key, value: !store.getState().viewer[key] })
}
-const getNextSection = section => {
- const { sections } = store.getState().viewer
- if (section.index === sections.length - 1) {
- return null
- }
- return sections[section.index + 1]
-}
-
export const reachedEndOfSection = () => dispatch => {
actions.audio.pause()
dispatch({ type: types.viewer.reached_end_of_section })