From 2b14723d7b4e495a465049acec6838a6bbd907a8 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 22 Jul 2020 18:28:07 +0200 Subject: display transcript with custom renderer --- .../containers/paragraphEditor.container.js | 3 +- .../app/views/paragraph/paragraph.container.js | 2 +- .../views/viewer/checklist/checklist.container.js | 28 ++++++++++ .../views/viewer/containers/checklist.container.js | 28 ---------- .../viewer/containers/transcript.container.js | 28 ---------- .../app/views/viewer/containers/viewer.nav.js | 28 ---------- .../app/views/viewer/containers/viewer.router.js | 42 --------------- .../frontend/app/views/viewer/nav/viewer.nav.js | 28 ++++++++++ .../frontend/app/views/viewer/nav/viewer.router.js | 42 +++++++++++++++ .../transcript/components/elementTypes.image.js | 47 ++++++++++++++++ .../transcript/components/elementTypes.text.js | 35 ++++++++++++ .../transcript/components/elementTypes.video.js | 21 ++++++++ .../views/viewer/transcript/components/index.js | 22 ++++++++ .../viewer/transcript/transcript.container.js | 40 ++++++++++++++ .../frontend/app/views/viewer/viewer.container.js | 10 +++- animism-align/frontend/app/views/viewer/viewer.css | 63 +++++++++++++++++++++- 16 files changed, 335 insertions(+), 132 deletions(-) create mode 100644 animism-align/frontend/app/views/viewer/checklist/checklist.container.js delete mode 100644 animism-align/frontend/app/views/viewer/containers/checklist.container.js delete mode 100644 animism-align/frontend/app/views/viewer/containers/transcript.container.js delete mode 100644 animism-align/frontend/app/views/viewer/containers/viewer.nav.js delete mode 100644 animism-align/frontend/app/views/viewer/containers/viewer.router.js create mode 100644 animism-align/frontend/app/views/viewer/nav/viewer.nav.js create mode 100644 animism-align/frontend/app/views/viewer/nav/viewer.router.js create mode 100644 animism-align/frontend/app/views/viewer/transcript/components/elementTypes.image.js create mode 100644 animism-align/frontend/app/views/viewer/transcript/components/elementTypes.text.js create mode 100644 animism-align/frontend/app/views/viewer/transcript/components/elementTypes.video.js create mode 100644 animism-align/frontend/app/views/viewer/transcript/components/index.js create mode 100644 animism-align/frontend/app/views/viewer/transcript/transcript.container.js (limited to 'animism-align') diff --git a/animism-align/frontend/app/views/paragraph/containers/paragraphEditor.container.js b/animism-align/frontend/app/views/paragraph/containers/paragraphEditor.container.js index 12ab618..c031d8a 100644 --- a/animism-align/frontend/app/views/paragraph/containers/paragraphEditor.container.js +++ b/animism-align/frontend/app/views/paragraph/containers/paragraphEditor.container.js @@ -27,7 +27,6 @@ class ParagraphEditor extends Component { } handleParagraphDoubleClick(e, paragraph) { - console.log(e.target.parentNode) let paragraphNode = e.target if (!paragraphNode.classList.contains('paragraph')) { paragraphNode = paragraphNode.parentNode @@ -48,7 +47,7 @@ class ParagraphEditor extends Component { render() { // const { media } = this.props - const { paragraphs, selectedParagraph, currentParagraph, currentAnnotation } = this.state + const { paragraphs, selectedParagraph, selectedParagraphOffset } = this.state return (
diff --git a/animism-align/frontend/app/views/paragraph/paragraph.container.js b/animism-align/frontend/app/views/paragraph/paragraph.container.js index 71af036..d0e9b86 100644 --- a/animism-align/frontend/app/views/paragraph/paragraph.container.js +++ b/animism-align/frontend/app/views/paragraph/paragraph.container.js @@ -56,7 +56,7 @@ class ParagraphContainer extends Component { } const mapStateToProps = state => ({ - loaded: !!state.annotation.lookup && !!state.paragraph.lookup && !!state.media.lookup + loaded: !!state.annotation.index.lookup && !!state.paragraph.index.lookup && !!state.media.index.lookup }) const mapDispatchToProps = dispatch => ({ diff --git a/animism-align/frontend/app/views/viewer/checklist/checklist.container.js b/animism-align/frontend/app/views/viewer/checklist/checklist.container.js new file mode 100644 index 0000000..5d35e7c --- /dev/null +++ b/animism-align/frontend/app/views/viewer/checklist/checklist.container.js @@ -0,0 +1,28 @@ +import React, { Component } from 'react' +// import { Link } from 'react-router-dom' +// import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' + +import actions from 'app/actions' +// import * as uploadActions from './upload.actions' + +class Checklist extends Component { + componentDidMount() { + } + render() { + const { } = this.props + return ( +
+
+ ) + } +} + +const mapStateToProps = state => ({ +}) + +const mapDispatchToProps = dispatch => ({ + // uploadActions: bindActionCreators({ ...uploadActions }, dispatch), +}) + +export default connect(mapStateToProps, mapDispatchToProps)(Checklist) diff --git a/animism-align/frontend/app/views/viewer/containers/checklist.container.js b/animism-align/frontend/app/views/viewer/containers/checklist.container.js deleted file mode 100644 index 5d35e7c..0000000 --- a/animism-align/frontend/app/views/viewer/containers/checklist.container.js +++ /dev/null @@ -1,28 +0,0 @@ -import React, { Component } from 'react' -// import { Link } from 'react-router-dom' -// import { bindActionCreators } from 'redux' -import { connect } from 'react-redux' - -import actions from 'app/actions' -// import * as uploadActions from './upload.actions' - -class Checklist extends Component { - componentDidMount() { - } - render() { - const { } = this.props - return ( -
-
- ) - } -} - -const mapStateToProps = state => ({ -}) - -const mapDispatchToProps = dispatch => ({ - // uploadActions: bindActionCreators({ ...uploadActions }, dispatch), -}) - -export default connect(mapStateToProps, mapDispatchToProps)(Checklist) diff --git a/animism-align/frontend/app/views/viewer/containers/transcript.container.js b/animism-align/frontend/app/views/viewer/containers/transcript.container.js deleted file mode 100644 index abe0ed1..0000000 --- a/animism-align/frontend/app/views/viewer/containers/transcript.container.js +++ /dev/null @@ -1,28 +0,0 @@ -import React, { Component } from 'react' -// import { Link } from 'react-router-dom' -// import { bindActionCreators } from 'redux' -import { connect } from 'react-redux' - -import actions from 'app/actions' -// import * as uploadActions from './upload.actions' - -class Transcript extends Component { - componentDidMount() { - } - render() { - const { } = this.props - return ( -
-
- ) - } -} - -const mapStateToProps = state => ({ -}) - -const mapDispatchToProps = dispatch => ({ - // uploadActions: bindActionCreators({ ...uploadActions }, dispatch), -}) - -export default connect(mapStateToProps, mapDispatchToProps)(Transcript) diff --git a/animism-align/frontend/app/views/viewer/containers/viewer.nav.js b/animism-align/frontend/app/views/viewer/containers/viewer.nav.js deleted file mode 100644 index e1613b4..0000000 --- a/animism-align/frontend/app/views/viewer/containers/viewer.nav.js +++ /dev/null @@ -1,28 +0,0 @@ -import React, { Component } from 'react' -// import { Link } from 'react-router-dom' -// import { bindActionCreators } from 'redux' -import { connect } from 'react-redux' - -import actions from 'app/actions' -// import * as uploadActions from './upload.actions' - -class ViewerNav extends Component { - componentDidMount() { - } - render() { - const { } = this.props - return ( -
-
- ) - } -} - -const mapStateToProps = state => ({ -}) - -const mapDispatchToProps = dispatch => ({ - // uploadActions: bindActionCreators({ ...uploadActions }, dispatch), -}) - -export default connect(mapStateToProps, mapDispatchToProps)(ViewerNav) diff --git a/animism-align/frontend/app/views/viewer/containers/viewer.router.js b/animism-align/frontend/app/views/viewer/containers/viewer.router.js deleted file mode 100644 index b432302..0000000 --- a/animism-align/frontend/app/views/viewer/containers/viewer.router.js +++ /dev/null @@ -1,42 +0,0 @@ -import React, { Component } from 'react' -import { Link } from 'react-router-dom' -import { connect } from 'react-redux' - -import actions from 'app/actions' - -class ViewerRouter extends Component { - componentDidMount() { - this.route() - } - route() { - console.log(this.props.match.params.component) - switch (this.props.match.params.component) { - case 'transcript': - actions.viewer.showSection('transcript') - break - case 'nav': - actions.viewer.showSection('nav') - break - case 'checklist': - actions.viewer.showSection('checklist') - break - case 'fullscreenImage': - break - case 'fullscreenVideo': - break - case 'fullscreenCarousel': - break - case 'end': - break - } - } - render() { - return null - } -} - -const mapStateToProps = state => ({ - viewer: state.viewer, -}) - -export default connect(mapStateToProps)(ViewerRouter) diff --git a/animism-align/frontend/app/views/viewer/nav/viewer.nav.js b/animism-align/frontend/app/views/viewer/nav/viewer.nav.js new file mode 100644 index 0000000..e1613b4 --- /dev/null +++ b/animism-align/frontend/app/views/viewer/nav/viewer.nav.js @@ -0,0 +1,28 @@ +import React, { Component } from 'react' +// import { Link } from 'react-router-dom' +// import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' + +import actions from 'app/actions' +// import * as uploadActions from './upload.actions' + +class ViewerNav extends Component { + componentDidMount() { + } + render() { + const { } = this.props + return ( +
+
+ ) + } +} + +const mapStateToProps = state => ({ +}) + +const mapDispatchToProps = dispatch => ({ + // uploadActions: bindActionCreators({ ...uploadActions }, dispatch), +}) + +export default connect(mapStateToProps, mapDispatchToProps)(ViewerNav) diff --git a/animism-align/frontend/app/views/viewer/nav/viewer.router.js b/animism-align/frontend/app/views/viewer/nav/viewer.router.js new file mode 100644 index 0000000..e352af5 --- /dev/null +++ b/animism-align/frontend/app/views/viewer/nav/viewer.router.js @@ -0,0 +1,42 @@ +import React, { Component } from 'react' +import { Link } from 'react-router-dom' +import { connect } from 'react-redux' + +import actions from 'app/actions' + +class ViewerRouter extends Component { + componentDidMount() { + this.route() + } + route() { + // console.log(this.props.match.params.component) + switch (this.props.match.params.component) { + case 'transcript': + actions.viewer.showSection('transcript') + break + case 'nav': + actions.viewer.showSection('nav') + break + case 'checklist': + actions.viewer.showSection('checklist') + break + case 'fullscreenImage': + break + case 'fullscreenVideo': + break + case 'fullscreenCarousel': + break + case 'end': + break + } + } + render() { + return null + } +} + +const mapStateToProps = state => ({ + viewer: state.viewer, +}) + +export default connect(mapStateToProps)(ViewerRouter) diff --git a/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.image.js b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.image.js new file mode 100644 index 0000000..c2477ee --- /dev/null +++ b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.image.js @@ -0,0 +1,47 @@ +import React, { Component } from 'react' + +export const MediaCitation = ({ media }) => { + if (media.citation) { + return ( + + ) + } + console.log(media) + return ( + + {media.author} + {', '} + {media.pre_title} + {media.title} + {media.post_title} + {'. '} + {media.date && ( + ' ' + media.date + '.' + )} + {media.medium && ( + ' ' + media.medium + '.' + )} + {media.source && ( + ' ' + media.source.trim() + )} + + ) +} + +export const MediaImage = ({ paragraph, media, currentParagraph, currentAnnotation, onAnnotationClick, onDoubleClick }) => { + if (!media.lookup) return
+ const className = currentParagraph ? 'media image current' : 'media image' + const annotation = paragraph.annotations[0] + const item = media.lookup[annotation.settings.media_id] + if (!item) return
Media not found: {annotation.settings.media_id}
+ return ( +
onDoubleClick(e, paragraph)} + > + {"["} + + {"]"} +
+ ) +} diff --git a/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.text.js b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.text.js new file mode 100644 index 0000000..c2ebcd7 --- /dev/null +++ b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.text.js @@ -0,0 +1,35 @@ +import React, { Component } from 'react' + +export const Paragraph = ({ paragraph, currentParagraph, currentAnnotation, onAnnotationClick, onDoubleClick }) => { + let className = paragraph.type + if (className !== 'paragraph') className += ' paragraph' + if (currentParagraph) className += ' current' + return ( +
onDoubleClick(e, paragraph)} + > + {paragraph.annotations.map(annotation => ( + onAnnotationClick(e, paragraph, annotation)} + dangerouslySetInnerHTML={{ __html: ' ' + annotation.text + ' ' }} + /> + ))} +
+ ) +} + +export const ParagraphHeader = ({ paragraph, currentParagraph, currentAnnotation, onAnnotationClick, onDoubleClick }) => { + let className = currentParagraph ? 'header current' : 'header' + const text = paragraph.annotations.map(annotation => annotation.text).join(' ') + return ( +
onDoubleClick(e, paragraph)} + > + {text} +
+ ) +} diff --git a/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.video.js b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.video.js new file mode 100644 index 0000000..fe821eb --- /dev/null +++ b/animism-align/frontend/app/views/viewer/transcript/components/elementTypes.video.js @@ -0,0 +1,21 @@ +import React, { Component } from 'react' + +import { MediaCitation } from './elementTypes.image' + +export const MediaVideo = ({ paragraph, media, currentParagraph, currentAnnotation, onAnnotationClick, onDoubleClick }) => { + if (!media.lookup) return
+ const className = currentParagraph ? 'media current' : 'media' + const annotation = paragraph.annotations[0] + const item = media.lookup[annotation.settings.media_id] + if (!item) return
Media not found: {annotation.settings.media_id}
+ return ( +
onDoubleClick(e, paragraph)} + > + {"["} + + {"]"} +
+ ) +} diff --git a/animism-align/frontend/app/views/viewer/transcript/components/index.js b/animism-align/frontend/app/views/viewer/transcript/components/index.js new file mode 100644 index 0000000..45b7d41 --- /dev/null +++ b/animism-align/frontend/app/views/viewer/transcript/components/index.js @@ -0,0 +1,22 @@ +import React from 'react' + +import { + Paragraph, ParagraphHeader +} from './elementTypes.text' + +import { + MediaVideo +} from './elementTypes.video' + +import { + MediaImage +} from './elementTypes.image' + +export const transcriptElementLookup = { + paragraph: React.memo(Paragraph), + hidden: React.memo(Paragraph), + blockquote: React.memo(Paragraph), + header: React.memo(ParagraphHeader), + video: React.memo(MediaVideo), + image: React.memo(MediaImage), +} diff --git a/animism-align/frontend/app/views/viewer/transcript/transcript.container.js b/animism-align/frontend/app/views/viewer/transcript/transcript.container.js new file mode 100644 index 0000000..039e5c8 --- /dev/null +++ b/animism-align/frontend/app/views/viewer/transcript/transcript.container.js @@ -0,0 +1,40 @@ +import React, { Component } from 'react' +// import { Link } from 'react-router-dom' +// import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' + +import actions from 'app/actions' + +import ParagraphList from 'app/views/paragraph/components/paragraph.list' +import { transcriptElementLookup } from './components' + +const noop = () => {} + +class Transcript extends Component { + componentDidMount() { + } + render() { + const { viewer } = this.props + return ( +
+
+ +
+
+ ) + } +} + +const mapStateToProps = state => ({ + viewer: state.viewer, +}) + +const mapDispatchToProps = dispatch => ({ + // uploadActions: bindActionCreators({ ...uploadActions }, dispatch), +}) + +export default connect(mapStateToProps, mapDispatchToProps)(Transcript) diff --git a/animism-align/frontend/app/views/viewer/viewer.container.js b/animism-align/frontend/app/views/viewer/viewer.container.js index ff68c4c..64fc915 100644 --- a/animism-align/frontend/app/views/viewer/viewer.container.js +++ b/animism-align/frontend/app/views/viewer/viewer.container.js @@ -8,7 +8,8 @@ import './viewer.css' import actions from 'app/actions' import { Loader } from 'app/common' -import ViewerRouter from './containers/viewer.router' +import Transcript from './transcript/transcript.container' +import ViewerRouter from './nav/viewer.router' class ViewerContainer extends Component { constructor(props) { @@ -49,6 +50,7 @@ class ViewerContainer extends Component { } return (
+
) @@ -56,7 +58,11 @@ class ViewerContainer extends Component { } const mapStateToProps = state => ({ - loaded: !!state.annotation.lookup && !!state.paragraph.lookup && !!state.media.lookup + loaded: ( + !!state.annotation.index.lookup && + !!state.paragraph.index.lookup && + !!state.media.index.lookup + ) }) const mapDispatchToProps = dispatch => ({ diff --git a/animism-align/frontend/app/views/viewer/viewer.css b/animism-align/frontend/app/views/viewer/viewer.css index 00cfa2b..fba83bc 100644 --- a/animism-align/frontend/app/views/viewer/viewer.css +++ b/animism-align/frontend/app/views/viewer/viewer.css @@ -1,3 +1,64 @@ .viewer { background: #fff; -} \ No newline at end of file + color: #000; +} + +/* transcript */ + +.transcript { + width: 100%; + height: calc(100% - 3.125rem); + overflow: scroll; + background: white; + color: black; + padding: 1rem; +} + +/* general paragraph styles */ + +.transcript .content { + font-family: 'Georgia', serif; + width: 100%; + padding-bottom: 6rem; + position: relative; +} + +.transcript .content > div { + margin-bottom: 16px; +} + +/* paragraph subtypes */ + +.transcript .header { + font-size: 32px; +} + +.transcript .paragraph, +.transcript .hidden { + font-size: 16px; + line-height: 1.5; +} + +.transcript .blockquote { + padding-left: 3rem; + line-height: 1.5; +} + +/* sentences */ + +.transcript span { + margin-right: 4px; +} +.transcript .media span { + margin-right: 0; +} + +.transcript .paragraph .current { + box-shadow: -2px -3px 0 #fff, + 2px -3px 0 #fff, + -2px 3px 0 #fff, + 2px 3px 0 #fff; + box-decoration-break: clone; + background: black; + color: white; +} -- cgit v1.2.3-70-g09d2