summaryrefslogtreecommitdiff
path: root/animism-align/frontend/views
diff options
context:
space:
mode:
Diffstat (limited to 'animism-align/frontend/views')
-rw-r--r--animism-align/frontend/views/align/align.css7
-rw-r--r--animism-align/frontend/views/align/align.util.js4
-rw-r--r--animism-align/frontend/views/align/components/annotations/annotation.form.js63
-rw-r--r--animism-align/frontend/views/align/components/annotations/annotation.index.js4
-rw-r--r--animism-align/frontend/views/align/components/annotations/annotation.types.js41
-rw-r--r--animism-align/frontend/views/audio/audio.actions.js2
-rw-r--r--animism-align/frontend/views/media/components/media.formImage.js2
-rw-r--r--animism-align/frontend/views/media/components/media.formImageSelection.js2
-rw-r--r--animism-align/frontend/views/media/components/media.indexOptions.js4
-rw-r--r--animism-align/frontend/views/media/containers/media.index.js7
-rw-r--r--animism-align/frontend/views/media/media.actions.js1
-rw-r--r--animism-align/frontend/views/media/media.reducer.js2
12 files changed, 115 insertions, 24 deletions
diff --git a/animism-align/frontend/views/align/align.css b/animism-align/frontend/views/align/align.css
index ec39cd8..38a2bc7 100644
--- a/animism-align/frontend/views/align/align.css
+++ b/animism-align/frontend/views/align/align.css
@@ -130,9 +130,16 @@ canvas {
display: flex;
align-items: center;
}
+.annotationForm .buttons {
+ margin-bottom: 0.5rem;
+}
.annotationForm .ts {
color: #fff;
}
+.annotationForm .select.media_id {
+ width: 100%;
+ margin-right: 0;
+}
/* Annotation index */
diff --git a/animism-align/frontend/views/align/align.util.js b/animism-align/frontend/views/align/align.util.js
index 91af64c..c99ff3b 100644
--- a/animism-align/frontend/views/align/align.util.js
+++ b/animism-align/frontend/views/align/align.util.js
@@ -58,3 +58,7 @@ export const cutFirstSentence = text => {
actions.site.updateText(updatedText)
return croppedText
}
+
+export const thumbnailURL = data => {
+ if (data.type === 'video') return data.settings.video.thumbnail_url
+}
diff --git a/animism-align/frontend/views/align/components/annotations/annotation.form.js b/animism-align/frontend/views/align/components/annotations/annotation.form.js
index 226bb45..0a71233 100644
--- a/animism-align/frontend/views/align/components/annotations/annotation.form.js
+++ b/animism-align/frontend/views/align/components/annotations/annotation.form.js
@@ -12,7 +12,7 @@ import { timeToPosition } from '../../align.util'
import { Select } from '../../../../common'
const ANNOTATION_TYPES = [
- 'sentence', 'header', 'paragraph_end'
+ 'sentence', 'header', 'paragraph_end', 'video',
].map(name => ({ name, label: name }))
class AnnotationForm extends Component {
@@ -20,6 +20,7 @@ class AnnotationForm extends Component {
super(props)
this.handleChange = this.handleChange.bind(this)
this.handleSelect = this.handleSelect.bind(this)
+ this.handleSettingsSelect = this.handleSettingsSelect.bind(this)
this.handleKeyDown = this.handleKeyDown.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.textareaRef = React.createRef()
@@ -66,6 +67,10 @@ class AnnotationForm extends Component {
handleSelect(name, value) {
actions.align.updateAnnotationForm(name, value)
}
+ handleSettingsSelect(name, value) {
+ if (name.indexOf('_id') !== -1) value = parseInt(value) || 0
+ actions.align.updateAnnotationSettings(name, value)
+ }
handleSubmit() {
const { annotation } = this.props
if (annotation.type === 'paragraph_end') {
@@ -96,21 +101,28 @@ class AnnotationForm extends Component {
top: timeToPosition(annotation.start_ts, timeline),
}}
>
+ {this.renderButtons()}
{annotation.type === 'sentence' && this.renderTextarea()}
{annotation.type === 'header' && this.renderTextarea()}
- <div className='row buttons'>
- <div>
- <Select
- name='type'
- selected={annotation.type}
- options={ANNOTATION_TYPES}
- defaultOption='text'
- onChange={this.handleSelect}
- />
- <div className='ts'>{timestamp(annotation.start_ts, 1, true)}</div>
- </div>
- <button onClick={this.handleSubmit}>Save</button>
+ {annotation.type === 'video' && this.renderVideo()}
+ </div>
+ )
+ }
+ renderButtons() {
+ const { annotation } = this.props
+ return (
+ <div className='row buttons'>
+ <div>
+ <Select
+ name='type'
+ selected={annotation.type}
+ options={ANNOTATION_TYPES}
+ defaultOption='text'
+ onChange={this.handleSelect}
+ />
+ <div className='ts'>{timestamp(annotation.start_ts, 1, true)}</div>
</div>
+ <button onClick={this.handleSubmit}>Save</button>
</div>
)
}
@@ -128,11 +140,36 @@ class AnnotationForm extends Component {
</div>
)
}
+ renderVideo() {
+ const { annotation, media } = this.props
+ 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
+ }
+ })
+ return (
+ <div>
+ <Select
+ name='media_id'
+ className="media_id"
+ selected={annotation.settings.media_id}
+ options={video_list_items}
+ defaultOption='Choose a video'
+ onChange={this.handleSettingsSelect}
+ />
+ </div>
+ )
+ }
}
const mapStateToProps = state => ({
annotation: state.align.annotation,
timeline: state.align.timeline,
+ media: state.media.index,
})
const mapDispatchToProps = dispatch => ({
diff --git a/animism-align/frontend/views/align/components/annotations/annotation.index.js b/animism-align/frontend/views/align/components/annotations/annotation.index.js
index eccd8b7..3a78dd4 100644
--- a/animism-align/frontend/views/align/components/annotations/annotation.index.js
+++ b/animism-align/frontend/views/align/components/annotations/annotation.index.js
@@ -75,7 +75,7 @@ class AnnotationIndex extends Component {
actions.align.showEditAnnotationForm(annotation)
}
render() {
- const { timeline, annotationInForm } = this.props
+ const { timeline, media, annotationInForm } = this.props
const { start_ts, zoom, selected_annotation_id } = timeline
const { items } = this.state
const className = (zoom < 2)
@@ -98,6 +98,7 @@ class AnnotationIndex extends Component {
y={y}
selected={annotation.id === selected_annotation_id}
annotation={annotation}
+ media={media}
onClick={this.handleClick}
onDoubleClick={this.handleDoubleClick}
/>
@@ -112,6 +113,7 @@ const mapStateToProps = state => ({
timeline: state.align.timeline,
annotationInForm: state.align.annotation,
index: state.annotation.index,
+ media: state.media.index,
})
const mapDispatchToProps = dispatch => ({
diff --git a/animism-align/frontend/views/align/components/annotations/annotation.types.js b/animism-align/frontend/views/align/components/annotations/annotation.types.js
index 06be4a8..b927a12 100644
--- a/animism-align/frontend/views/align/components/annotations/annotation.types.js
+++ b/animism-align/frontend/views/align/components/annotations/annotation.types.js
@@ -4,7 +4,7 @@ import actions from '../../../../actions'
import { ZOOM_STEPS } from '../../constants'
import { clamp } from '../../../../util'
-import { positionToTime, timeToPosition } from '../../align.util'
+import { positionToTime, timeToPosition, thumbnailURL } from '../../align.util'
export const AnnotationSentence = ({ y, annotation, selected, onClick, onDoubleClick }) => {
const { start_ts, text, paragraph_id } = annotation
@@ -55,8 +55,47 @@ export const AnnotationParagraphEnd = ({ y, annotation, selected, onClick, onDou
)
}
+export const AnnotationVideo = ({ y, annotation, media, selected, onClick, onDoubleClick }) => {
+ const { start_ts, text } = annotation
+ const className = selected ? 'annotation media video selected' : 'annotation media video'
+ if (!(annotation.settings.media_id in media)) {
+ return (
+ <div
+ className={className}
+ style={{ top: y }}
+ onClick={e => onClick(e, annotation)}
+ onDoubleClick={e => onDoubleClick(e, annotation)}
+ >MEDIA NOT FOUND</div>
+ )
+ }
+ const data = media[annotation.settings.media_id]
+ return (
+ <div
+ className={className}
+ style={{ top: y }}
+ onClick={e => onClick(e, annotation)}
+ onDoubleClick={e => onDoubleClick(e, annotation)}
+ >
+ <div className='img'>
+ <Link to={"/media/" + data.id + "/edit/"}>
+ <img src={thumbnailURL(data)} alt={data.title} />
+ </Link>
+ </div>
+ <div className='meta center'>
+ <div>
+ <i>{data.title}</i><br />
+ {data.author}<br />
+ {data.date}
+ </div>
+ </div>
+ </div>
+ )
+}
+
+
export const AnnotationElementLookup = {
sentence: React.memo(AnnotationSentence),
header: React.memo(AnnotationHeader),
paragraph_end: React.memo(AnnotationParagraphEnd),
+ video: React.memo(AnnotationVideo),
}
diff --git a/animism-align/frontend/views/audio/audio.actions.js b/animism-align/frontend/views/audio/audio.actions.js
index 4b1bcdc..64c8215 100644
--- a/animism-align/frontend/views/audio/audio.actions.js
+++ b/animism-align/frontend/views/audio/audio.actions.js
@@ -4,7 +4,7 @@ import actions from '../../actions'
import { session } from '../../session'
const audioPlayer = document.createElement('audio')
-audioPlayer.src = '/static/data_store/peaks/animismA200620.mp3'
+audioPlayer.src = '/static/data_store/peaks/animismA080720.mp3'
audioPlayer.addEventListener('loadedmetadata', () => {
console.log('audio duration:', audioPlayer.duration)
dispatch({ type: types.align.set_display_setting, key: 'duration', value: audioPlayer.duration })
diff --git a/animism-align/frontend/views/media/components/media.formImage.js b/animism-align/frontend/views/media/components/media.formImage.js
index c757d03..d86a6d8 100644
--- a/animism-align/frontend/views/media/components/media.formImage.js
+++ b/animism-align/frontend/views/media/components/media.formImage.js
@@ -6,7 +6,7 @@ import { capitalize } from '../../../util'
import { TextInput, LabelDescription, FileInputField, Select, TextArea, Checkbox, SubmitButton, Loader } from '../../../common'
-import { ImageSelection } from './media.formImageSelection'
+import ImageSelection from './media.formImageSelection'
export default class MediaImageForm extends Component {
state = {
diff --git a/animism-align/frontend/views/media/components/media.formImageSelection.js b/animism-align/frontend/views/media/components/media.formImageSelection.js
index 142525b..5572793 100644
--- a/animism-align/frontend/views/media/components/media.formImageSelection.js
+++ b/animism-align/frontend/views/media/components/media.formImageSelection.js
@@ -21,7 +21,7 @@ const defaultState = {
}
}
-class ImageSelection extends Component {
+export default class ImageSelection extends Component {
state = {
...defaultState
}
diff --git a/animism-align/frontend/views/media/components/media.indexOptions.js b/animism-align/frontend/views/media/components/media.indexOptions.js
index 774bf22..5dbc415 100644
--- a/animism-align/frontend/views/media/components/media.indexOptions.js
+++ b/animism-align/frontend/views/media/components/media.indexOptions.js
@@ -20,6 +20,10 @@ const sortOptions = [
{ name: 'id-desc', label: 'Oldest first' },
{ name: 'username-asc', label: 'Username (A-Z)' },
{ name: 'username-desc', label: 'Username (Z-A)' },
+ { name: 'author-asc', label: 'Author (A-Z)' },
+ { name: 'author-desc', label: 'Author (Z-A)' },
+ { name: 'title-asc', label: 'Title (A-Z)' },
+ { name: 'title-desc', label: 'Title (Z-A)' },
// { name: '-asc', label: '' },
// { name: '-desc', label: '' },
// { name: '-asc', label: '' },
diff --git a/animism-align/frontend/views/media/containers/media.index.js b/animism-align/frontend/views/media/containers/media.index.js
index 7797fd7..19ef4c5 100644
--- a/animism-align/frontend/views/media/containers/media.index.js
+++ b/animism-align/frontend/views/media/containers/media.index.js
@@ -7,6 +7,8 @@ import { formatDateTime } from '../../../util'
import { MenuButton, SmallMenuButton, Loader } from '../../../common'
import actions from '../../../actions'
+import { thumbnailURL } from '../../align/align.util'
+
import MediaIndexOptions from '../components/media.indexOptions'
import MediaMenu from '../components/media.menu'
@@ -14,7 +16,7 @@ import MediaMenu from '../components/media.menu'
class MediaIndex extends Component {
componentDidMount() {
- this.fetch(false)
+ // this.fetch(false)
}
componentDidUpdate(prevProps) {
@@ -79,9 +81,6 @@ class MediaIndex extends Component {
}
}
-const thumbnailURL = data => {
- if (data.type === 'video') return data.settings.video.thumbnail_url
-}
const MediaItem = ({ data }) => {
// console.log(data)
return (
diff --git a/animism-align/frontend/views/media/media.actions.js b/animism-align/frontend/views/media/media.actions.js
index e33746e..1f1ab01 100644
--- a/animism-align/frontend/views/media/media.actions.js
+++ b/animism-align/frontend/views/media/media.actions.js
@@ -6,5 +6,4 @@ export const getVimeoMetadata = url => {
.then(data => {
return data
})
- // const id = url.match(/\d+/i)[0];
}
diff --git a/animism-align/frontend/views/media/media.reducer.js b/animism-align/frontend/views/media/media.reducer.js
index bc885e8..6a04b9a 100644
--- a/animism-align/frontend/views/media/media.reducer.js
+++ b/animism-align/frontend/views/media/media.reducer.js
@@ -5,7 +5,7 @@ import { crudState, crudReducer } from '../../api/crud.reducer'
const initialState = crudState('media', {
options: {
- sort: getDefault('media.sort', 'id-desc'),
+ sort: 'author-asc',
thumbnailSize: getDefault('upload.thumbnailSize', 'small'),
}
})