From 136eeeda21cefe3544b3d7ffd4210f9788774301 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 10 Mar 2021 15:40:32 +0100 Subject: sorting mdia. attach annotations and paragraphs to episods --- .../app/views/editor/align/align.actions.js | 28 +++++++++++++++------- .../components/annotations/annotation.index.js | 2 ++ .../views/editor/media/components/media.form.js | 4 ++-- .../editor/media/components/media.indexOptions.js | 8 +++---- .../views/editor/media/containers/media.index.js | 12 +++++----- .../app/views/editor/media/media.reducer.js | 2 +- .../views/editor/overview/overview.container.js | 4 ++-- .../frontend/app/views/nav/header.component.js | 22 +++++++++++------ animism-align/frontend/app/views/nav/nav.css | 3 +++ 9 files changed, 54 insertions(+), 31 deletions(-) (limited to 'animism-align') diff --git a/animism-align/frontend/app/views/editor/align/align.actions.js b/animism-align/frontend/app/views/editor/align/align.actions.js index 1583e4e..65e3d46 100644 --- a/animism-align/frontend/app/views/editor/align/align.actions.js +++ b/animism-align/frontend/app/views/editor/align/align.actions.js @@ -10,10 +10,11 @@ import { timestampToSeconds, post } from 'app/utils' import { cutFirstSentence } from 'app/utils/align.utils' import { annotationFadeTimings } from 'app/utils/annotation.utils' +/* scrolling the view */ + export const setScrollPosition = start_ts => dispatch => ( dispatch({ type: types.align.set_display_setting, key: 'start_ts', value: start_ts }) ) - export const setZoom = zoom => dispatch => { if (0 <= zoom && zoom < ZOOM_STEPS.length) { dispatch({ type: types.align.set_display_setting, key: 'zoom', value: zoom }) @@ -23,6 +24,8 @@ export const throttledSetZoom = throttle(zoom => dispatch => { setZoom(zoom)(dispatch) }, 250, { leading: true }) +/* cursor */ + export const setCursor = cursor_ts => dispatch => ( dispatch({ type: types.align.set_display_setting, key: 'cursor_ts', value: cursor_ts }) ) @@ -33,6 +36,8 @@ export const clearCursorRegion = () => dispatch => ( dispatch({ type: types.align.set_display_setting, key: 'cursor_region', value: null }) ) +/* selecting annotations in the list */ + export const setSelectedAnnotation = annotation => dispatch => { debouncedUpdateAnnotation.flush() dispatch({ type: types.align.set_selected_annotation, data: annotation }) @@ -69,6 +74,8 @@ export const cloneSelectedAnnotation = annotation => dispatch => { }) } +/* paragraph management */ + export const setSelectedParagraph = paragraph_id => dispatch => { dispatch({ type: types.align.set_display_setting, key: 'selected_paragraph_id', value: paragraph_id }) } @@ -76,18 +83,20 @@ export const clearSelectedParagraph = () => dispatch => { dispatch({ type: types.align.set_display_setting, key: 'selected_paragraph_id', value: -1 }) } +/* annotation form - show / hide / update */ + export const showNewAnnotationForm = (start_ts, text) => dispatch => { - let croppedText; - if (store.getState().align.annotation.start_ts) { - croppedText = store.getState().align.annotation.text - } else { - croppedText = cutFirstSentence(text) - } + const state = store.getState() + let croppedText = state.align.annotation.start_ts + ? state.align.annotation.text + : cutFirstSentence(text) + // console.log(croppedText) dispatch({ type: types.align.set_temporary_annotation, data: { id: 'new', + episode_id: state.site.episode.id, start_ts, end_ts: 0.0, text: croppedText, @@ -102,14 +111,12 @@ export const showEditAnnotationForm = (annotation) => dispatch => { data: annotation, }) } - export const updateAnnotationForm = (key, value) => dispatch => { dispatch({ type: types.align.update_temporary_annotation, key, value }) } export const updateAnnotationSettings = (key, value) => dispatch => { dispatch({ type: types.align.update_temporary_annotation_settings, key, value }) } - export const hideAnnotationForm = () => dispatch => { dispatch({ type: types.align.set_temporary_annotation, @@ -117,8 +124,10 @@ export const hideAnnotationForm = () => dispatch => { }) } +/* insert / removing time */ export const spliceTime = start_ts => dispatch => { + const state = store.getState() let duration = timestampToSeconds(prompt("How many seconds to add or remove? Enter a positive / negative number")) if (!duration) { return @@ -126,6 +135,7 @@ export const spliceTime = start_ts => dispatch => { console.log(start_ts, duration) const data = { start_ts, duration, + episode_id: state.site.episode.id, } post(dispatch, types.api, 'splice', '/api/v1/annotation/splice', data) .then(res => { diff --git a/animism-align/frontend/app/views/editor/align/components/annotations/annotation.index.js b/animism-align/frontend/app/views/editor/align/components/annotations/annotation.index.js index 7c76fca..e2c7a51 100644 --- a/animism-align/frontend/app/views/editor/align/components/annotations/annotation.index.js +++ b/animism-align/frontend/app/views/editor/align/components/annotations/annotation.index.js @@ -58,6 +58,7 @@ class AnnotationIndex extends PureComponent { } else { actions.paragraph.create({ type: 'paragraph', + episode_id: this.props.episode_id, start_ts: annotation.start_ts, }).then(data => { actions.align.setSelectedParagraph(data.res.id) @@ -119,6 +120,7 @@ const mapStateToProps = state => ({ selectedAnnotation: state.align.selectedAnnotation, index: state.annotation.index, media: state.media.index.lookup, + episode_id: state.site.episode.id, }) export default connect(mapStateToProps)(AnnotationIndex) diff --git a/animism-align/frontend/app/views/editor/media/components/media.form.js b/animism-align/frontend/app/views/editor/media/components/media.form.js index 2d21838..2c89fcd 100644 --- a/animism-align/frontend/app/views/editor/media/components/media.form.js +++ b/animism-align/frontend/app/views/editor/media/components/media.form.js @@ -124,8 +124,8 @@ export default class MediaForm extends Component { } const { isNew, onSubmit } = this.props const { data } = this.state - const requiredKeys = "author title date".split(" ") - const validKeys = "type tag url title author pre_title post_title translated_title date source medium start_ts settings".split(" ") + const requiredKeys = "episode_id author title date".split(" ") + const validKeys = "episode_id type tag url title author pre_title post_title translated_title date source medium start_ts settings".split(" ") const validData = validKeys.reduce((a,b) => { a[b] = data[b]; return a }, {}) const errorFields = requiredKeys.filter(key => !validData[key]) if (errorFields.length) { diff --git a/animism-align/frontend/app/views/editor/media/components/media.indexOptions.js b/animism-align/frontend/app/views/editor/media/components/media.indexOptions.js index beb9517..a3b763b 100644 --- a/animism-align/frontend/app/views/editor/media/components/media.indexOptions.js +++ b/animism-align/frontend/app/views/editor/media/components/media.indexOptions.js @@ -14,8 +14,8 @@ const thumbnailOptions = [ ] const sortOptions = [ - { name: 'id-asc', label: 'Most recent' }, - { name: 'id-desc', label: 'Oldest first' }, + { name: 'id-desc', label: 'Most recent' }, + { name: 'id-asc', label: 'Oldest first' }, // { name: 'username-asc', label: 'Username (A-Z)' }, // { name: 'username-desc', label: 'Username (Z-A)' }, { name: 'author-asc', label: 'Author (A-Z)' }, @@ -40,7 +40,7 @@ class IndexOptions extends Component { name={'sort'} options={sortOptions} selected={options.sort} - onChange={actions.upload.updateOption} + onChange={actions.media.updateOption} /> ) @@ -48,7 +48,7 @@ class IndexOptions extends Component { } const mapStateToProps = state => ({ - options: state.upload.options, + options: state.media.options, }) export default connect(mapStateToProps)(IndexOptions) diff --git a/animism-align/frontend/app/views/editor/media/containers/media.index.js b/animism-align/frontend/app/views/editor/media/containers/media.index.js index da467fb..0fe47ef 100644 --- a/animism-align/frontend/app/views/editor/media/containers/media.index.js +++ b/animism-align/frontend/app/views/editor/media/containers/media.index.js @@ -25,12 +25,12 @@ class MediaIndex extends Component { } fetch(load_more) { - const { options, index } = this.props.media - const { order: index_order } = index - const [ sort, order ] = options.sort.split(' ') + const { options } = this.props.media + const [ sort, order ] = options.sort.split('-') actions.media.index({ - sort, order, limit: 5000, // offset: load_more ? index_order.length : 0, - }, load_more) + episode_id: this.props.episode_id, + sort, order, + }) } render() { @@ -82,7 +82,6 @@ class MediaIndex extends Component { {order.filter(id => lookup[id].type === 'file').map(id => )} - {order.length >= 50 && } ) } @@ -149,6 +148,7 @@ const FileItem = ({ data }) => { const mapStateToProps = state => ({ media: state.media, + episode_id: state.site.episode.id, }) export default connect(mapStateToProps)(MediaIndex) diff --git a/animism-align/frontend/app/views/editor/media/media.reducer.js b/animism-align/frontend/app/views/editor/media/media.reducer.js index f13f9de..a4fe645 100644 --- a/animism-align/frontend/app/views/editor/media/media.reducer.js +++ b/animism-align/frontend/app/views/editor/media/media.reducer.js @@ -5,7 +5,7 @@ import { crudState, crudReducer } from 'app/api/crud.reducer' const initialState = crudState('media', { options: { - sort: 'author asc', + sort: 'id-desc', thumbnailSize: getDefault('upload.thumbnailSize', 'small'), } }) diff --git a/animism-align/frontend/app/views/editor/overview/overview.container.js b/animism-align/frontend/app/views/editor/overview/overview.container.js index d64bd9f..71ca6c2 100644 --- a/animism-align/frontend/app/views/editor/overview/overview.container.js +++ b/animism-align/frontend/app/views/editor/overview/overview.container.js @@ -32,7 +32,7 @@ class OverviewContainer extends Component { const { annotation } = this.props const stats = annotation.order.reduce((stats, annotation_id) => { const { paragraph_id, type } = annotation.lookup[annotation_id] - if (paragraph_id) { + if (paragraph_id && type === 'sentence') { stats.paragraphs[paragraph_id] = true } if (!stats.types[type]) { @@ -72,7 +72,7 @@ class OverviewContainer extends Component { media: media.order.length + ' media', sections: courtesyS(viewer.sections.length, 'section'), paragraphs: courtesyS(Object.keys(stats.paragraphs).length, 'paragraph'), - duration: timestampHMS(align.duration), + duration: align.duration ? timestampHMS(align.duration) : "No audio file attached", }} />
- Home -
-
+ + {props.project && props.project.title} + {props.episode && ": Episode " + props.episode.episode_number} + Overview Timeline Transcript Media Viewer
+
+ + Hi {props.currentUser.username} + + Projects +
) } @@ -34,14 +41,14 @@ function Header(props) {
- {props.router.location.pathname !== '/' && ( - Home - )}
Hi {props.currentUser.username} + {props.router.location.pathname !== '/' && ( + Projects + )} {props.currentUser.is_admin && Users} Logout @@ -53,7 +60,8 @@ function Header(props) { const mapStateToProps = (state) => ({ currentUser: state.auth.user, - site: state.site, + project: state.site.project, + episode: state.site.episode, router: state.router, playing: state.audio.playing, }) diff --git a/animism-align/frontend/app/views/nav/nav.css b/animism-align/frontend/app/views/nav/nav.css index 0c9a992..765c00f 100644 --- a/animism-align/frontend/app/views/nav/nav.css +++ b/animism-align/frontend/app/views/nav/nav.css @@ -41,6 +41,9 @@ header > div > button:hover { border-color: #fff; color: #fff; } +header > div:first-child a { + padding: 0.5rem; +} header > div:last-child a { padding: 0.5rem; } -- cgit v1.2.3-70-g09d2