summaryrefslogtreecommitdiff
path: root/animism-align
diff options
context:
space:
mode:
Diffstat (limited to 'animism-align')
-rw-r--r--animism-align/frontend/app/common/app.css6
-rw-r--r--animism-align/frontend/app/constants.js3
-rw-r--r--animism-align/frontend/app/utils/annotation.utils.js2
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotation.form.js3
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.gallery.js69
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.image.js13
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.utility.js27
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.video.js10
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotationForms/index.js7
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.gallery.js50
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotationTypes/index.js7
-rw-r--r--animism-align/frontend/app/views/paragraph/components/paragraph.list.js4
-rw-r--r--animism-align/frontend/app/views/viewer/nav/nav.css9
-rw-r--r--animism-align/frontend/app/views/viewer/nav/viewer.icons.js10
-rw-r--r--animism-align/frontend/app/views/viewer/nav/viewer.router.js7
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.gallery.js41
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.fullscreen/index.js6
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.inline/inline.image.js27
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.inline/inline.video.js7
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.utility/index.js14
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.utility/media.citation.js29
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.utility/media.vitrine.js30
-rw-r--r--animism-align/frontend/app/views/viewer/player/player.fullscreen.css65
-rw-r--r--animism-align/frontend/app/views/viewer/transcript/components/elementTypes.gallery.js22
-rw-r--r--animism-align/frontend/app/views/viewer/transcript/components/index.js7
25 files changed, 423 insertions, 52 deletions
diff --git a/animism-align/frontend/app/common/app.css b/animism-align/frontend/app/common/app.css
index e9efdc3..cca40fd 100644
--- a/animism-align/frontend/app/common/app.css
+++ b/animism-align/frontend/app/common/app.css
@@ -80,7 +80,7 @@ li {
/* headings */
h1 {
- color: #eee;
+ /*color: #eee;*/
margin-bottom: 1.25rem;
font-size: 1.5rem;
font-weight: normal;
@@ -90,12 +90,12 @@ div:first-child > h1:first-child,
margin-top: 0;
}
h2 {
- color: #eee;
+ /*color: #eee;*/
font-size: 1.25rem;
font-weight: normal;
}
h3 {
- color: #eee;
+ /*color: #eee;*/
margin-top: 0;
margin-bottom: 1.25rem;
font-size: 1.0rem;
diff --git a/animism-align/frontend/app/constants.js b/animism-align/frontend/app/constants.js
index 1acdf5b..69f2b44 100644
--- a/animism-align/frontend/app/constants.js
+++ b/animism-align/frontend/app/constants.js
@@ -43,7 +43,7 @@ export const TEXT_ANNOTATION_TYPES = new Set([
])
export const MEDIA_ANNOTATION_TYPES = new Set([
- 'image', 'carousel', 'grid',
+ 'image', 'carousel', 'grid', 'gallery',
'video',
'vitrine',
])
@@ -66,6 +66,7 @@ export const FULLSCREEN_UTILITY_ANNOTATION_TYPES = new Set([
export const CURTAIN_COLORS = [
{ label: 'white', backgroundColor: '#ffffff', textColor: '#000000' },
+ { label: 'light gray', backgroundColor: '#eeeeee', textColor: '#000000' },
{ label: 'dark blue', backgroundColor: '#1a1f33', textColor: '#ffffff' },
{ label: 'dark gray', backgroundColor: '#222222', textColor: '#ffffff' },
{ label: 'black', backgroundColor: '#000000', textColor: '#ffffff' },
diff --git a/animism-align/frontend/app/utils/annotation.utils.js b/animism-align/frontend/app/utils/annotation.utils.js
index 6dab36d..1af08a2 100644
--- a/animism-align/frontend/app/utils/annotation.utils.js
+++ b/animism-align/frontend/app/utils/annotation.utils.js
@@ -17,7 +17,7 @@ export const annotationFadeTimings = annotation => {
}
export const thumbnailURL = media => {
- console.log(media)
+ // console.log(media)
switch (media.type) {
case 'video': return media.settings.video.thumbnail_url
case 'image': return media.settings.thumbnail.url
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotation.form.js b/animism-align/frontend/app/views/align/components/annotations/annotation.form.js
index 80a960f..caf64be 100644
--- a/animism-align/frontend/app/views/align/components/annotations/annotation.form.js
+++ b/animism-align/frontend/app/views/align/components/annotations/annotation.form.js
@@ -15,7 +15,8 @@ import { annotationFormLookup } from './annotationForms'
const ANNOTATION_TYPES = [
'sentence', 'section_heading', 'heading_text', 'paragraph_end',
'video',
- 'image', 'image_carousel',
+ 'image',
+ 'gallery', 'grid', 'vitrine',
'curtain', 'intro',
].map(name => ({ name, label: capitalize(name.replace('_', ' ')) }))
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.gallery.js b/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.gallery.js
new file mode 100644
index 0000000..e85c6f3
--- /dev/null
+++ b/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.gallery.js
@@ -0,0 +1,69 @@
+import React, { Component } from 'react'
+
+import { CURTAIN_COLOR_SELECT_OPTIONS } from 'app/constants'
+import { TextInput, Select, Checkbox } from 'app/common'
+import { AnnotationFormFullscreen } from './annotationForm.utility'
+
+export const AnnotationFormGallery = ({ annotation, media, handleSettingsSelect, handleSettingsChange }) => {
+ if (!media.lookup) return <div />
+ const { lookup, order } = media
+ const image_list_items = order.filter(id => lookup[id].type === 'gallery').map(id => {
+ const image = lookup[id]
+ return {
+ name: image.id,
+ label: image.author + ' - ' + image.title
+ }
+ })
+ return (
+ <div className='options'>
+ <Select
+ name='media_id'
+ className="media_id"
+ selected={annotation.settings.media_id}
+ options={image_list_items}
+ defaultOption='Choose an image'
+ onChange={handleSettingsSelect}
+ />
+
+ <TextInput
+ title="Title"
+ name="title"
+ placeholder="Enter title or leave blank"
+ data={annotation.settings}
+ onChange={handleSettingsChange}
+ autoComplete="off"
+ />
+
+ <Checkbox
+ label="Fullscreen"
+ name="fullscreen"
+ checked={annotation.settings.fullscreen}
+ onChange={handleSettingsSelect}
+ />
+
+ <Checkbox
+ label="Inline"
+ name="inline"
+ checked={annotation.settings.inline}
+ onChange={handleSettingsSelect}
+ />
+
+ <Select
+ title='Color'
+ name='color'
+ selected={annotation.settings.color}
+ options={CURTAIN_COLOR_SELECT_OPTIONS}
+ defaultOption='Pick a color'
+ onChange={handleSettingsSelect}
+ />
+
+ {(annotation.settings.fullscreen && !annotation.settings.inline) && (
+ <AnnotationFormFullscreen
+ annotation={annotation}
+ handleSettingsChange={handleSettingsChange}
+ handleSettingsSelect={handleSettingsSelect}
+ />
+ )}
+ </div>
+ )
+}
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.image.js b/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.image.js
index 9ca5295..285dbcc 100644
--- a/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.image.js
+++ b/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.image.js
@@ -1,5 +1,6 @@
import React, { Component } from 'react'
+import { CURTAIN_COLOR_SELECT_OPTIONS } from 'app/constants'
import { Select, Checkbox } from 'app/common'
import { AnnotationFormFullscreen } from './annotationForm.utility'
@@ -23,18 +24,30 @@ export const AnnotationFormImage = ({ annotation, media, handleSettingsSelect, h
defaultOption='Choose an image'
onChange={handleSettingsSelect}
/>
+
<Checkbox
label="Fullscreen"
name="fullscreen"
checked={annotation.settings.fullscreen}
onChange={handleSettingsSelect}
/>
+
<Checkbox
label="Inline"
name="inline"
checked={annotation.settings.inline}
onChange={handleSettingsSelect}
/>
+
+ <Select
+ title='Color'
+ name='color'
+ selected={annotation.settings.color}
+ options={CURTAIN_COLOR_SELECT_OPTIONS}
+ defaultOption='Pick a color'
+ onChange={handleSettingsSelect}
+ />
+
{(annotation.settings.fullscreen && !annotation.settings.inline) && (
<AnnotationFormFullscreen
annotation={annotation}
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.utility.js b/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.utility.js
index 750c3a7..4220eff 100644
--- a/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.utility.js
+++ b/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.utility.js
@@ -44,6 +44,15 @@ export const AnnotationFormIntro = ({ annotation, media, handleSettingsChange, h
autoComplete="off"
/>
+ <Select
+ title='Color'
+ name='color'
+ selected={annotation.settings.color}
+ options={CURTAIN_COLOR_SELECT_OPTIONS}
+ defaultOption='Pick a color'
+ onChange={handleSettingsSelect}
+ />
+
<AnnotationFormFullscreen
annotation={annotation}
handleSettingsChange={handleSettingsChange}
@@ -65,6 +74,15 @@ export const AnnotationFormCurtain = ({ annotation, handleSettingsChange, handle
autoComplete="off"
/>
+ <Select
+ title='Color'
+ name='color'
+ selected={annotation.settings.color}
+ options={CURTAIN_COLOR_SELECT_OPTIONS}
+ defaultOption='Pick a color'
+ onChange={handleSettingsSelect}
+ />
+
<AnnotationFormFullscreen
alwaysAccessible
annotation={annotation}
@@ -82,15 +100,6 @@ export const AnnotationFormFullscreen = ({ annotation, handleSettingsChange, han
} = annotationFadeTimings(annotation)
return (
<div>
- <Select
- title='Color'
- name='color'
- selected={annotation.settings.color}
- options={CURTAIN_COLOR_SELECT_OPTIONS}
- defaultOption='Pick a color'
- onChange={handleSettingsSelect}
- />
-
<TextInput
title="Total duration"
name="duration"
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.video.js b/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.video.js
index 6f58d60..9d15b44 100644
--- a/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.video.js
+++ b/animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.video.js
@@ -1,5 +1,6 @@
import React, { Component } from 'react'
+import { CURTAIN_COLOR_SELECT_OPTIONS } from 'app/constants'
import { Select, Checkbox } from 'app/common'
import { AnnotationFormFullscreen } from './annotationForm.utility'
@@ -41,6 +42,15 @@ export const AnnotationFormVideo = ({ annotation, media, handleSettingsSelect, h
checked={annotation.settings.inline}
onChange={handleSettingsSelect}
/>
+ <Select
+ title='Color'
+ name='color'
+ selected={annotation.settings.color}
+ options={CURTAIN_COLOR_SELECT_OPTIONS}
+ defaultOption='Pick a color'
+ onChange={handleSettingsSelect}
+ />
+
{(annotation.settings.fullscreen && !annotation.settings.inline) && (
<AnnotationFormFullscreen
annotation={annotation}
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationForms/index.js b/animism-align/frontend/app/views/align/components/annotations/annotationForms/index.js
index dd601bc..f8b3698 100644
--- a/animism-align/frontend/app/views/align/components/annotations/annotationForms/index.js
+++ b/animism-align/frontend/app/views/align/components/annotations/annotationForms/index.js
@@ -11,6 +11,10 @@ import {
} from './annotationForm.image'
import {
+ AnnotationFormGallery,
+} from './annotationForm.gallery'
+
+import {
AnnotationFormCurtain,
AnnotationFormIntro,
} from './annotationForm.utility'
@@ -21,4 +25,7 @@ export const annotationFormLookup = {
video: AnnotationFormVideo,
intro: AnnotationFormIntro,
curtain: AnnotationFormCurtain,
+ gallery: AnnotationFormGallery,
+ grid: AnnotationFormGallery,
+ vitrine: AnnotationFormGallery,
}
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.gallery.js b/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.gallery.js
new file mode 100644
index 0000000..e25f78e
--- /dev/null
+++ b/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.gallery.js
@@ -0,0 +1,50 @@
+import React, { Component } from 'react'
+
+import { durationToHeight } from 'app/utils/align.utils'
+import { capitalize } from 'app/utils'
+import { annotationFadeTimings, thumbnailURL } from 'app/utils/annotation.utils'
+
+import { checkAnnotationMediaNotReady, AnnotationMediaLoading } from './annotationTypes.utility'
+
+export const AnnotationGallery = ({ y, annotation, media, timeline, selected, onClick, onDoubleClick }) => {
+ const { text } = annotation
+ const className = selected ? 'annotation media gallery selected' : 'annotation media gallery'
+ if (checkAnnotationMediaNotReady(annotation, media)) {
+ return <AnnotationMediaLoading y={y} className={className} onClick={onClick} onDoubleClick={onDoubleClick} />
+ }
+ const mediaItem = media[annotation.settings.media_id]
+
+ const {
+ fadeInDuration, fadeOutDuration, duration,
+ start_ts, end_ts, fade_in_end_ts, fade_out_start_ts,
+ } = annotationFadeTimings(annotation)
+ const durationHeight = annotation.settings.fullscreen ? durationToHeight(duration, timeline) : 'auto'
+ const fadeInHeight = durationToHeight(fadeInDuration, timeline)
+ const fadeOutHeight = durationToHeight(fadeOutDuration, timeline)
+
+ const style = {
+ top: y,
+ }
+ if (annotation.settings.fullscreen && !annotation.settings.inline) {
+ style.height = durationHeight
+ }
+
+ return (
+ <div
+ className={className}
+ style={style}
+ onClick={e => onClick(e, annotation)}
+ onDoubleClick={e => onDoubleClick(e, annotation)}
+ >
+ <div className='meta center'>
+ <div>
+ {capitalize(annotation.type)}<br/>
+ <i>{mediaItem.title}</i><br />
+ {mediaItem.author}<br />
+ {mediaItem.date}
+ </div>
+ </div>
+ </div>
+ )
+}
+
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationTypes/index.js b/animism-align/frontend/app/views/align/components/annotations/annotationTypes/index.js
index 5b13496..512ce6d 100644
--- a/animism-align/frontend/app/views/align/components/annotations/annotationTypes/index.js
+++ b/animism-align/frontend/app/views/align/components/annotations/annotationTypes/index.js
@@ -16,6 +16,10 @@ import {
} from './annotationTypes.image'
import {
+ AnnotationGallery,
+} from './annotationTypes.gallery'
+
+import {
AnnotationCurtain,
AnnotationIntro,
} from './annotationTypes.utility'
@@ -27,6 +31,9 @@ export const AnnotationElementLookup = {
paragraph_end: React.memo(AnnotationParagraphEnd),
video: React.memo(AnnotationVideo),
image: React.memo(AnnotationImage),
+ gallery: React.memo(AnnotationGallery),
+ grid: React.memo(AnnotationGallery),
+ vitrine: React.memo(AnnotationGallery),
intro: React.memo(AnnotationIntro),
curtain: React.memo(AnnotationCurtain),
}
diff --git a/animism-align/frontend/app/views/paragraph/components/paragraph.list.js b/animism-align/frontend/app/views/paragraph/components/paragraph.list.js
index 473a0e9..2cc54a0 100644
--- a/animism-align/frontend/app/views/paragraph/components/paragraph.list.js
+++ b/animism-align/frontend/app/views/paragraph/components/paragraph.list.js
@@ -3,7 +3,7 @@ import { Route } from 'react-router-dom'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
-import { floatLT, floatInRange } from 'app/utils'
+import { floatLT, floatInRange, capitalize } from 'app/utils'
import ParagraphForm from '../components/paragraph.form'
class ParagraphList extends Component {
@@ -77,7 +77,7 @@ class ParagraphList extends Component {
/>
)
} else {
- return <div key={paragraph.id}>{'(waiting to implement' + paragraph.type + ')'}</div>
+ return <div key={paragraph.id}>{'(' + capitalize(paragraph.type) + ')'}</div>
}
})
}
diff --git a/animism-align/frontend/app/views/viewer/nav/nav.css b/animism-align/frontend/app/views/viewer/nav/nav.css
index 2c17621..922bd01 100644
--- a/animism-align/frontend/app/views/viewer/nav/nav.css
+++ b/animism-align/frontend/app/views/viewer/nav/nav.css
@@ -222,3 +222,12 @@
display: none;
}
}
+
+/* Zoom Plus */
+
+.zoomPlus {
+ width: 40px; height: 40px;
+}
+.zoomPlus path {
+ stroke: white;
+} \ No newline at end of file
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 183c3e0..002e00e 100644
--- a/animism-align/frontend/app/views/viewer/nav/viewer.icons.js
+++ b/animism-align/frontend/app/views/viewer/nav/viewer.icons.js
@@ -82,3 +82,13 @@ export const PlayerTime = ({ play_ts, duration }) => (
</span>
</span>
)
+
+// zoom button
+
+export const ZoomPlus = (
+ <svg className='zoomPlus' version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">
+ <path d="M20,35.5c-8.55,0-15.5-6.95-15.5-15.5c0-8.55,6.95-15.5,15.5-15.5S35.5,11.45,35.5,20C35.5,28.55,28.55,35.5,20,35.5z
+ M20,5.5C12,5.5,5.5,12,5.5,20c0,8,6.5,14.5,14.5,14.5S34.5,28,34.5,20C34.5,12,28,5.5,20,5.5z M27.5,19.5h-7v-7h-1v7h-7v1h7v7h1v-7
+ h7V19.5z"/>
+ </svg>
+)
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 75aaed7..ad30333 100644
--- a/animism-align/frontend/app/views/viewer/nav/viewer.router.js
+++ b/animism-align/frontend/app/views/viewer/nav/viewer.router.js
@@ -20,11 +20,8 @@ class ViewerRouter extends Component {
case 'checklist':
actions.viewer.showComponent('checklist')
break
- case 'fullscreenImage':
- break
- case 'fullscreenVideo':
- break
- case 'fullscreenCarousel':
+ case 'seek':
+ actions.audio.seek(456)
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
new file mode 100644
index 0000000..31a4176
--- /dev/null
+++ b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.gallery.js
@@ -0,0 +1,41 @@
+import React from 'react'
+
+import { MediaCitation, Vitrine } from '../components.utility'
+
+export const FullscreenVitrine = ({ element, media, transitionDuration }) => {
+ const { color } = element
+ const item = media.lookup[element.settings.media_id]
+ const style = {
+ backgroundColor: color.backgroundColor,
+ color: color.textColor,
+ transitionDuration,
+ }
+ console.log(item)
+ return (
+ <div
+ className='fullscreen-element vitrine'
+ style={style}
+ >
+ {element.settings.title && <div className='heading'>{element.settings.title}</div>}
+ <Vitrine media={item} />
+ <MediaCitation media={item} />
+ </div>
+ )
+}
+
+export const FullscreenGallery = ({ 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 gallery'
+ 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
index f533123..538632f 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,6 +9,10 @@ import {
} from './fullscreen.video'
import {
+ FullscreenVitrine
+} from './fullscreen.gallery'
+
+import {
FullscreenCurtain
} from './fullscreen.utility'
@@ -16,4 +20,6 @@ export const fullscreenComponents = {
curtain: React.memo(FullscreenCurtain),
video: React.memo(FullscreenVideo),
image: React.memo(FullscreenImage),
+ // gallery: React.memo(FullscreenGallery),
+ vitrine: React.memo(FullscreenVitrine),
}
diff --git a/animism-align/frontend/app/views/viewer/player/components.inline/inline.image.js b/animism-align/frontend/app/views/viewer/player/components.inline/inline.image.js
index 0312a8f..0e2d205 100644
--- a/animism-align/frontend/app/views/viewer/player/components.inline/inline.image.js
+++ b/animism-align/frontend/app/views/viewer/player/components.inline/inline.image.js
@@ -1,31 +1,6 @@
import React, { Component } from 'react'
-export const MediaCitation = ({ media }) => {
- if (media.citation) {
- return (
- <div className='citation' dangerouslySetInnerHTML={{ _html: media.citation }} />
- )
- }
- return (
- <div className='citation'>
- {media.author}
- {', '}
- {media.pre_title}
- <i>{media.title}</i>
- {media.post_title}
- {'. '}
- {media.date && (
- ' ' + media.date + '.'
- )}
- {media.medium && (
- ' ' + media.medium + '.'
- )}
- {media.source && (
- ' ' + media.source.trim()
- )}
- </div>
- )
-}
+import { MediaCitation } from '../components.utility'
export const MediaImage = ({ paragraph, media, currentParagraph, currentAnnotation, onAnnotationClick, onDoubleClick }) => {
if (!media.lookup) return <div />
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 2b3449c..fc24f9e 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,9 +1,8 @@
import React, { Component } from 'react'
import VimeoPlayer from '@u-wave/react-vimeo'
-import {
- CURTAIN_COLOR_LOOKUP,
-} from 'app/constants'
-import { MediaCitation } from './inline.image'
+
+import { CURTAIN_COLOR_LOOKUP } from 'app/constants'
+import { MediaCitation } from '../components.utility'
export const MediaVideo = ({ paragraph, media, currentParagraph, currentAnnotation, onAnnotationClick, onDoubleClick }) => {
if (!media.lookup) return <div />
diff --git a/animism-align/frontend/app/views/viewer/player/components.utility/index.js b/animism-align/frontend/app/views/viewer/player/components.utility/index.js
new file mode 100644
index 0000000..be38cac
--- /dev/null
+++ b/animism-align/frontend/app/views/viewer/player/components.utility/index.js
@@ -0,0 +1,14 @@
+import React from 'react'
+
+import {
+ MediaCitation
+} from './media.citation'
+
+import {
+ Vitrine
+} from './media.vitrine'
+
+export {
+ MediaCitation,
+ Vitrine,
+} \ No newline at end of file
diff --git a/animism-align/frontend/app/views/viewer/player/components.utility/media.citation.js b/animism-align/frontend/app/views/viewer/player/components.utility/media.citation.js
new file mode 100644
index 0000000..7b3212d
--- /dev/null
+++ b/animism-align/frontend/app/views/viewer/player/components.utility/media.citation.js
@@ -0,0 +1,29 @@
+import React, { Component } from 'react'
+
+export const MediaCitation = ({ media }) => {
+ if (media.settings.bibliography) {
+ return (
+ <div className='citation' dangerouslySetInnerHTML={{ __html: media.settings.bibliography }} />
+ )
+ }
+ return (
+ <div className='citation'>
+ {media.author}
+ {', '}
+ {media.pre_title}
+ <i>{media.title}</i>
+ {media.post_title}
+ {'. '}
+ {media.date && (
+ ' ' + media.date + '.'
+ )}
+ {media.medium && (
+ ' ' + media.medium + '.'
+ )}
+ {media.source && (
+ ' ' + media.source.trim()
+ )}
+ </div>
+ )
+}
+
diff --git a/animism-align/frontend/app/views/viewer/player/components.utility/media.vitrine.js b/animism-align/frontend/app/views/viewer/player/components.utility/media.vitrine.js
new file mode 100644
index 0000000..abe0241
--- /dev/null
+++ b/animism-align/frontend/app/views/viewer/player/components.utility/media.vitrine.js
@@ -0,0 +1,30 @@
+import React, { Component } from 'react'
+
+import { ZoomPlus } from '../../nav/viewer.icons.js'
+
+export const Vitrine = ({ media }) => {
+ const { image_order, image_lookup, thumbnail_lookup } = media.settings
+ const width = (Math.floor(100 / image_order.length * 2) - 2) + 'vw'
+ console.log(width)
+ return (
+ <div className='vitrine-items'>
+ {image_order.map(id => {
+ const thumbnail = thumbnail_lookup[id]
+ return (
+ <VitrineItem key={id} image={thumbnail} width={width} />
+ )
+ })}
+ </div>
+ )
+}
+
+const VitrineItem = ({ image, width }) => {
+ return (
+ <div className='vitrine-item' style={{ width }}>
+ <div className='vitrine-image'>
+ <img src={image.url} />
+ </div>
+ {ZoomPlus}
+ </div>
+ )
+}
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 8d38fa0..29f68c2 100644
--- a/animism-align/frontend/app/views/viewer/player/player.fullscreen.css
+++ b/animism-align/frontend/app/views/viewer/player/player.fullscreen.css
@@ -53,3 +53,68 @@
background-repeat: no-repeat;
background-position: center center;
}
+
+/* vitrine */
+
+.viewer-fullscreen .fullscreen-element.vitrine {
+ flex-direction: column;
+ justify-content: space-between;
+ align-items: center;
+}
+.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;
+}
+
+.viewer-fullscreen .fullscreen-element.vitrine .heading {
+ margin-top: 4rem;
+}
+.viewer-fullscreen .fullscreen-element.vitrine .citation {
+ margin-bottom: 3rem;
+}
+
+.vitrine-items {
+ display: flex;
+ flex-flow: row wrap;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 1rem;
+}
+.vitrine-items .vitrine-item {
+ display: flex;
+ flex-flow: column nowrap;
+ align-items: center;
+ justify-content: space-between;
+ height: calc(45vh - 7rem);
+}
+.vitrine-items .vitrine-item .vitrine-image {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 80%;
+ cursor: pointer;
+}
+.vitrine-items .vitrine-item .vitrine-image img {
+ max-width: 100%;
+ max-height: 100%;
+ pointer-events: none;
+}
+.vitrine-items .vitrine-item .zoomPlus {
+ cursor: pointer;
+}
+.vitrine-items .vitrine-item:hover .zoomPlus path {
+ stroke: #000;
+}
diff --git a/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.gallery.js b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.gallery.js
new file mode 100644
index 0000000..0eb8b19
--- /dev/null
+++ b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.gallery.js
@@ -0,0 +1,22 @@
+import React, { Component } from 'react'
+
+import { MediaCitation } from './elementTypes.image'
+
+export const MediaGallery = ({ paragraph, media, currentParagraph, currentAnnotation, onAnnotationClick, onDoubleClick }) => {
+ if (!media.lookup) return <div />
+ const className = currentParagraph ? 'media current' : 'media'
+ const annotation = paragraph.annotations[0]
+ const item = media.lookup[annotation.settings.media_id]
+ if (!item) return <div>Media not found: {annotation.settings.media_id}</div>
+ return (
+ <div
+ className={className}
+ onClick={e => onAnnotationClick(e, paragraph, annotation)}
+ onDoubleClick={e => onDoubleClick(e, paragraph)}
+ >
+ {"["}
+ <MediaCitation media={item} />
+ {"]"}
+ </div>
+ )
+}
diff --git a/animism-align/frontend/app/views/viewer/transcript/components/index.js b/animism-align/frontend/app/views/viewer/transcript/components/index.js
index a2433ae..5cf7196 100644
--- a/animism-align/frontend/app/views/viewer/transcript/components/index.js
+++ b/animism-align/frontend/app/views/viewer/transcript/components/index.js
@@ -12,6 +12,10 @@ import {
MediaImage
} from './elementTypes.image'
+import {
+ MediaGallery
+} from './elementTypes.gallery'
+
export const transcriptElementLookup = {
paragraph: React.memo(Paragraph),
intro_paragraph: React.memo(Paragraph),
@@ -22,4 +26,7 @@ export const transcriptElementLookup = {
header: React.memo(ParagraphHeading),
video: React.memo(MediaVideo),
image: React.memo(MediaImage),
+ gallery: React.memo(MediaGallery),
+ grid: React.memo(MediaGallery),
+ vitrine: React.memo(MediaGallery),
}