summaryrefslogtreecommitdiff
path: root/animism-align/frontend/app/views
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-11-02 16:38:13 +0100
committerJules Laplace <julescarbon@gmail.com>2020-11-02 16:38:13 +0100
commit4e2121e9160b627415a31f628fa3f00711138375 (patch)
treea0d328b4e0bd3fd92c9326a52c2e22bab130bf2a /animism-align/frontend/app/views
parentfaee66ed90bca15fa803deb733cbe9ccce9c19d8 (diff)
images can include images from galleries. command to duplicate annotations
Diffstat (limited to 'animism-align/frontend/app/views')
-rw-r--r--animism-align/frontend/app/views/align/align.actions.js19
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotation.form.css4
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotation.index.css12
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.gallery.js38
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.image.js27
-rw-r--r--animism-align/frontend/app/views/align/components/annotations/annotationForms/annotationForm.utility.js10
-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/annotationTypes/annotationTypes.image.js7
-rw-r--r--animism-align/frontend/app/views/align/containers/timeline.container.js5
-rw-r--r--animism-align/frontend/app/views/paragraph/components/paragraphTypes/paragraphTypes.image.js8
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.image.js9
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.inline/inline.image.js10
12 files changed, 90 insertions, 69 deletions
diff --git a/animism-align/frontend/app/views/align/align.actions.js b/animism-align/frontend/app/views/align/align.actions.js
index 0766460..1583e4e 100644
--- a/animism-align/frontend/app/views/align/align.actions.js
+++ b/animism-align/frontend/app/views/align/align.actions.js
@@ -8,6 +8,7 @@ import debounce from 'lodash.debounce'
import { ZOOM_STEPS } from 'app/constants'
import { timestampToSeconds, post } from 'app/utils'
import { cutFirstSentence } from 'app/utils/align.utils'
+import { annotationFadeTimings } from 'app/utils/annotation.utils'
export const setScrollPosition = start_ts => dispatch => (
dispatch({ type: types.align.set_display_setting, key: 'start_ts', value: start_ts })
@@ -49,6 +50,24 @@ export const debouncedUpdateAnnotation = debounce(annotation => {
actions.annotation.update(annotation)
}, 2000, { leading: false, trailing: true })
+export const cloneSelectedAnnotation = annotation => dispatch => {
+ const newAnnotation = { ...annotation }
+ delete newAnnotation.id
+ if (annotation.settings.fullscreen) {
+ const {
+ fadeInDuration, fadeOutDuration, duration,
+ start_ts, end_ts, fade_in_end_ts, fade_out_start_ts,
+ } = annotationFadeTimings(annotation)
+ newAnnotation.start_ts += duration - fadeOutDuration - fadeInDuration
+ } else {
+ newAnnotation.start_ts += 1
+ }
+ actions.annotation.create(newAnnotation)
+ .then(res => {
+ console.log('cloned annotation', res.res)
+ setSelectedParagraph(res.res)
+ })
+}
export const setSelectedParagraph = paragraph_id => dispatch => {
dispatch({ type: types.align.set_display_setting, key: 'selected_paragraph_id', value: paragraph_id })
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotation.form.css b/animism-align/frontend/app/views/align/components/annotations/annotation.form.css
index cea5830..fa663c7 100644
--- a/animism-align/frontend/app/views/align/components/annotations/annotation.form.css
+++ b/animism-align/frontend/app/views/align/components/annotations/annotation.form.css
@@ -33,6 +33,10 @@
.annotationForm div.textarea {
margin-bottom: 0.5rem;
}
+.annotationForm img {
+ max-width: 100%;
+ max-height: 6rem;
+}
.annotationForm .options label span:first-child {
display: inline-block;
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotation.index.css b/animism-align/frontend/app/views/align/components/annotations/annotation.index.css
index af44212..5f5fda7 100644
--- a/animism-align/frontend/app/views/align/components/annotations/annotation.index.css
+++ b/animism-align/frontend/app/views/align/components/annotations/annotation.index.css
@@ -6,7 +6,7 @@
.annotationIndex .annotation {
position: absolute;
left: 5px;
- max-width: 400px;
+ max-width: 300px;
padding: 0.25rem 0.375rem;
box-shadow: 0px 0px 3px rgba(0,0,0,1.0);
border: 1px solid transparent;
@@ -23,7 +23,7 @@
background-image: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.4));
}
.annotationIndex .annotation.media {
- min-width: 300px;
+ width: 300px;
left: calc(405px + 0.5rem);
}
.annotation.sentence.even {
@@ -41,14 +41,15 @@
.annotation.paragraph_end {
background-color: #003;
border-top: 1px solid #888;
- width: 100%;
+ width: 300px;
padding: 1px;
}
.annotationIndex .annotation.utility {
- left: calc(405px + 0.5rem);
+ left: calc(505px + 0.5rem);
+ width: 200px;
}
.annotationIndex .annotation.footnote {
- left: calc(405px + 0.5rem);
+ left: calc(605px + 0.5rem);
width: 200px;
}
.annotationIndex .annotation.text_plate {
@@ -58,6 +59,7 @@
background-image: linear-gradient(rgba(255,255,255,1.0), rgba(255,255,255,1.0));
width: 8rem;
padding: 0;
+ overflow: hidden;
}
.annotation.curtain span {
position: absolute;
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
index c43d8d5..55bdd86 100644
--- 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
@@ -3,17 +3,11 @@ import React, { Component } from 'react'
import { CURTAIN_COLOR_SELECT_OPTIONS } from 'app/constants'
import { TextInput, Select, Checkbox, LabelDescription } from 'app/common'
import { AnnotationFormFullscreen } from './annotationForm.utility'
+import { makeMediaItems, makeGalleryItems } from 'app/utils/annotation.utils'
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
- }
- })
+ const image_list_items = makeMediaItems(media, ['gallery'])
return (
<div className='options'>
<Select
@@ -77,30 +71,8 @@ export const AnnotationFormGallery = ({ annotation, media, handleSettingsSelect,
export const AnnotationFormGalleryAdvance = ({ 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
- }
- })
- let item, gallery_items, frame_id, thumbnail
- if (annotation.settings.media_id && lookup[annotation.settings.media_id]) {
- item = lookup[annotation.settings.media_id]
- gallery_items = item.settings.image_order.map((id, index) => {
- const caption = item.settings.caption_lookup && item.settings.caption_lookup[id]
- console.log(caption)
- return {
- name: index,
- label: (index + 1) + ") " + (caption ? (caption.title || "") : "")
- }
- })
- if (annotation.settings.frame_index) {
- frame_id = item.settings.image_order[annotation.settings.frame_index]
- thumbnail = item.settings.thumbnail_lookup[frame_id]
- }
- }
+ const image_list_items = makeMediaItems(media, ['gallery'])
+ const { gallery_items, thumbnail } = makeGalleryItems(annotation, media)
return (
<div className='options'>
<Select
@@ -112,7 +84,7 @@ export const AnnotationFormGalleryAdvance = ({ annotation, media, handleSettings
onChange={handleSettingsSelect}
/>
- {item && (
+ {gallery_items && (
<Select
name='frame_index'
selected={annotation.settings.frame_index}
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 28f7e79..d3e981a 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
@@ -3,17 +3,12 @@ import React, { Component } from 'react'
import { CURTAIN_COLOR_SELECT_OPTIONS } from 'app/constants'
import { Select, Checkbox, TextInput } from 'app/common'
import { AnnotationFormFullscreen } from './annotationForm.utility'
+import { makeMediaItems, makeGalleryItems } from 'app/utils/annotation.utils'
export const AnnotationFormImage = ({ annotation, media, handleSettingsSelect, handleSettingsChange }) => {
if (!media.lookup) return <div />
- const { lookup, order } = media
- const image_list_items = order.filter(id => lookup[id].type === 'image').map(id => {
- const image = lookup[id]
- return {
- name: image.id,
- label: image.author + ' - ' + image.title
- }
- })
+ const image_list_items = makeMediaItems(media, ['image', 'gallery'])
+ const { gallery_items, thumbnail } = makeGalleryItems(annotation, media)
return (
<div className='options'>
<Select
@@ -24,7 +19,21 @@ export const AnnotationFormImage = ({ annotation, media, handleSettingsSelect, h
defaultOption='Choose an image'
onChange={handleSettingsSelect}
/>
-
+
+ {gallery_items && (
+ <Select
+ name='frame_index'
+ selected={annotation.settings.frame_index}
+ options={gallery_items}
+ defaultOption='Choose an image'
+ onChange={handleSettingsSelect}
+ />
+ )}
+
+ {thumbnail && (
+ <img src={thumbnail.url} />
+ )}
+
<Checkbox
label="Fullscreen"
name="fullscreen"
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 ff1de04..d83005e 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
@@ -4,17 +4,11 @@ import { timestamp } from 'app/utils'
import { TextInput, LabelDescription, Select, Checkbox } from 'app/common'
import { CURTAIN_COLOR_SELECT_OPTIONS } from 'app/constants'
import { annotationFadeTimings } from 'app/utils/annotation.utils'
+import { makeMediaItems } from 'app/utils/annotation.utils'
export const AnnotationFormIntro = ({ annotation, media, handleSettingsChange, handleSettingsSelect }) => {
if (!media.lookup) return <div />
- const { lookup, order } = media
- const image_list_items = order.filter(id => lookup[id].type === 'file').map(id => {
- const image = lookup[id]
- return {
- name: image.id,
- label: image.title
- }
- })
+ const image_list_items = makeMediaItems(media, 'file')
return (
<div className='options'>
<Select
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 f4cf4c5..f634faa 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
@@ -3,17 +3,11 @@ import React, { Component } from 'react'
import { CURTAIN_COLOR_SELECT_OPTIONS, IMAGE_BACKGROUND_SIZE_OPTIONS } from 'app/constants'
import { Select, Checkbox, TextInput, LabelDescription } from 'app/common'
import { AnnotationFormFullscreen } from './annotationForm.utility'
+import { makeMediaItems } from 'app/utils/annotation.utils'
export const AnnotationFormVideo = ({ annotation, media, handleSettingsSelect, handleSettingsChange }) => {
if (!media.lookup) return <div />
- const { lookup, order } = media
- const video_list_items = order.filter(id => lookup[id].type === 'video').map(id => {
- const video = lookup[id]
- return {
- name: video.id,
- label: video.author + ' - ' + video.title
- }
- })
+ const video_list_items = makeMediaItems(media, ['video'])
return (
<div className='options'>
<Select
diff --git a/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.image.js b/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.image.js
index 8574067..9dcd976 100644
--- a/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.image.js
+++ b/animism-align/frontend/app/views/align/components/annotations/annotationTypes/annotationTypes.image.js
@@ -37,9 +37,10 @@ export const AnnotationImage = ({ y, annotation, media, timeline, selected, onCl
>
<div className='meta center'>
<div>
- <i>{mediaItem.title}</i><br />
- {mediaItem.author}<br />
- {mediaItem.date}
+ <i>{mediaItem.title}</i>{' - '}{mediaItem.author}
+ {mediaItem.type === 'gallery' && (
+ ' [Frame ' + (1 + annotation.settings.frame_index) + ']'
+ )}
</div>
</div>
</div>
diff --git a/animism-align/frontend/app/views/align/containers/timeline.container.js b/animism-align/frontend/app/views/align/containers/timeline.container.js
index 0cf49f8..57bac5d 100644
--- a/animism-align/frontend/app/views/align/containers/timeline.container.js
+++ b/animism-align/frontend/app/views/align/containers/timeline.container.js
@@ -51,7 +51,7 @@ class Timeline extends Component {
if (document.activeElement !== document.body) {
return
}
- // console.log(e.keyCode)
+ console.log(e.keyCode)
if (e.metaKey && this.props.selectedAnnotation.id) {
const { selectedAnnotation } = this.props
switch (e.keyCode) {
@@ -69,6 +69,9 @@ class Timeline extends Component {
actions.audio.seek(selectedAnnotation.start_ts)
actions.align.setCursor(selectedAnnotation.start_ts)
break
+ case 68: // D
+ e.preventDefault()
+ actions.align.cloneSelectedAnnotation(selectedAnnotation)
}
return
}
diff --git a/animism-align/frontend/app/views/paragraph/components/paragraphTypes/paragraphTypes.image.js b/animism-align/frontend/app/views/paragraph/components/paragraphTypes/paragraphTypes.image.js
index 36c72e9..8aaedc9 100644
--- a/animism-align/frontend/app/views/paragraph/components/paragraphTypes/paragraphTypes.image.js
+++ b/animism-align/frontend/app/views/paragraph/components/paragraphTypes/paragraphTypes.image.js
@@ -6,6 +6,14 @@ export const MediaImage = ({ paragraph, media, currentParagraph, currentAnnotati
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>
+
+ let url;
+ if (item.type === 'gallery' && item.settings.display_lookup[annotation.settings.frame_index]) {
+ url = item.settings.display_lookup[annotation.settings.frame_index].url
+ } else {
+ url = item.settings.display.url
+ }
+
return (
<div
className={className}
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 85badb0..ead2591 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
@@ -10,13 +10,20 @@ export const FullscreenImage = ({ element, media, transitionDuration }) => {
color: color.textColor,
transitionDuration,
}
+ let url;
+ if (item.type === 'gallery' && item.settings.display_lookup[element.annotation.settings.frame_index]) {
+ url = item.settings.display_lookup[element.annotation.settings.frame_index].url
+ } else {
+ url = item.settings.display.url
+ }
+
return (
<div
className='fullscreen-element image'
style={style}
>
<div style={{
- backgroundImage: 'url(' + item.settings.display.url + ')',
+ backgroundImage: 'url(' + url + ')',
}} />
</div>
)
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 10a4653..1f81aae 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
@@ -8,6 +8,14 @@ export const MediaImage = ({ paragraph, media, currentParagraph, currentAnnotati
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>
+
+ let url;
+ if (item.type === 'gallery' && item.settings.display_lookup[annotation.settings.frame_index]) {
+ url = item.settings.display_lookup[annotation.settings.frame_index].url
+ } else {
+ url = item.settings.display.url
+ }
+
if (annotation.settings.fullscreen) {
return (
<div className="media image fullscreen" onClick={e => onAnnotationClick(e, paragraph, annotation)}>
@@ -21,7 +29,7 @@ export const MediaImage = ({ paragraph, media, currentParagraph, currentAnnotati
return (
<div className="media image" onClick={e => onAnnotationClick(e, paragraph, annotation)}>
<div className="image-container">
- <img src={item.settings.display.url} />
+ <img src={url} />
<div className="speaker-icon">{SpeakerIcon}</div>
</div>
<MediaCitation media={item} />