summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--animism-align/frontend/app/constants.js5
-rw-r--r--animism-align/frontend/app/types.js2
-rw-r--r--animism-align/frontend/app/views/align/components/player/playButton.component.js12
-rw-r--r--animism-align/frontend/app/views/audio/audio.actions.js8
-rw-r--r--animism-align/frontend/app/views/audio/audio.reducer.js6
-rw-r--r--animism-align/frontend/app/views/viewer/nav/viewer.icons.js97
-rw-r--r--animism-align/frontend/app/views/viewer/nav/viewer.nav.js20
-rw-r--r--animism-align/frontend/app/views/viewer/transcript/transcript.container.js5
-rw-r--r--animism-align/frontend/app/views/viewer/transcript/transcript.css15
-rw-r--r--animism-align/frontend/app/views/viewer/viewer.container.js6
-rw-r--r--animism-align/frontend/app/views/viewer/viewer.nav.css93
-rw-r--r--animism-align/static/img/close-black.pngbin1511 -> 0 bytes
-rw-r--r--animism-align/static/img/close.pngbin3738 -> 0 bytes
13 files changed, 251 insertions, 18 deletions
diff --git a/animism-align/frontend/app/constants.js b/animism-align/frontend/app/constants.js
index cf504d3..9643b5f 100644
--- a/animism-align/frontend/app/constants.js
+++ b/animism-align/frontend/app/constants.js
@@ -32,3 +32,8 @@ export const ZOOM_TICK_STEPS = [
export const HEADER_MARGIN = 50
export const INNER_HEIGHT = window.innerHeight - HEADER_MARGIN
+
+export const ROMAN_NUMERALS = [
+ 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X',
+ 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX',
+] \ No newline at end of file
diff --git a/animism-align/frontend/app/types.js b/animism-align/frontend/app/types.js
index 7e4b9f1..296b3fd 100644
--- a/animism-align/frontend/app/types.js
+++ b/animism-align/frontend/app/types.js
@@ -19,7 +19,7 @@ export const align = crud_type('align', [
])
export const audio = with_type('audio', [
- 'play', 'pause', 'update_time',
+ 'play', 'pause', 'update_time', 'toggle_muted',
])
export const viewer = with_type('viewer', [
diff --git a/animism-align/frontend/app/views/align/components/player/playButton.component.js b/animism-align/frontend/app/views/align/components/player/playButton.component.js
index c6a8487..03603ce 100644
--- a/animism-align/frontend/app/views/align/components/player/playButton.component.js
+++ b/animism-align/frontend/app/views/align/components/player/playButton.component.js
@@ -1,13 +1,7 @@
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 alignActions from '../align.actions'
-
-import { ZOOM_STEPS } from 'app/constants'
-import { clamp } from 'app/utils'
const PlayButton = ({ audio }) => {
return (
@@ -24,8 +18,4 @@ const mapStateToProps = state => ({
audio: state.audio,
})
-const mapDispatchToProps = dispatch => ({
- // alignActions: bindActionCreators({ ...alignActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(PlayButton)
+export default connect(mapStateToProps)(PlayButton)
diff --git a/animism-align/frontend/app/views/audio/audio.actions.js b/animism-align/frontend/app/views/audio/audio.actions.js
index bd256a4..c12f7ee 100644
--- a/animism-align/frontend/app/views/audio/audio.actions.js
+++ b/animism-align/frontend/app/views/audio/audio.actions.js
@@ -38,3 +38,11 @@ export const toggle = () => dispatch => {
play()(dispatch)
}
}
+export const toggleMuted = () => dispatch => {
+ if (store.getState().audio.muted) {
+ audioPlayer.muted = false
+ } else {
+ audioPlayer.muted = true
+ }
+ dispatch({ type: types.audio.toggle_muted })
+}
diff --git a/animism-align/frontend/app/views/audio/audio.reducer.js b/animism-align/frontend/app/views/audio/audio.reducer.js
index 6149ca6..09ce6ce 100644
--- a/animism-align/frontend/app/views/audio/audio.reducer.js
+++ b/animism-align/frontend/app/views/audio/audio.reducer.js
@@ -4,6 +4,7 @@ import { session, getDefault, getDefaultInt } from 'app/session'
const initialState = {
playing: false,
play_ts: 0,
+ muted: false,
}
export default function alignReducer(state = initialState, action) {
@@ -24,6 +25,11 @@ export default function alignReducer(state = initialState, action) {
...state,
play_ts: action.play_ts,
}
+ case types.audio.toggle_muted:
+ return {
+ ...state,
+ muted: !state.muted,
+ }
default:
return state
}
diff --git a/animism-align/frontend/app/views/viewer/nav/viewer.icons.js b/animism-align/frontend/app/views/viewer/nav/viewer.icons.js
new file mode 100644
index 0000000..c65c2e6
--- /dev/null
+++ b/animism-align/frontend/app/views/viewer/nav/viewer.icons.js
@@ -0,0 +1,97 @@
+import React from 'react'
+import { connect } from 'react-redux'
+
+import actions from 'app/actions'
+import { timestamp } from 'app/utils'
+
+// arrows
+
+const arrows = {
+ down: (
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">
+ <polygon points="10.06,16.14 9.51,16.98 20,23.86 30.49,16.98 29.94,16.14 20,22.66" />
+ </svg>
+ ),
+ up: (
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">
+ <polygon points="10.06,23.86 9.51,23.02 20,16.14 30.49,23.02 29.94,23.86 20,17.34" />
+ </svg>
+ ),
+ right: (
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="10 0 20 40">
+ <polygon points="16.98,30.49 16.14,29.94 22.66,20 16.14,10.06 16.98,9.51 23.86,20" />
+ </svg>
+ ),
+ left: (
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="10 0 20 40">
+ <polygon points="23.02,30.49 16.14,20 23.02,9.51 23.86,10.06 17.34,20 23.86,29.94" />
+ </svg>
+ ),
+}
+
+export const Arrow = React.memo(({ type }) => (
+ <div className={'arrow ' + type}>
+ {arrows[type]}
+ </div>
+))
+
+
+// volume toggle
+
+const VolumeIcon = React.memo(({ muted }) => (
+ <div className={muted ? 'volume muted' : 'volume'} onClick={() => actions.audio.toggleMuted()}>
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">
+ <path d="M5,25h4.17l0,2.5H5V25z M15.33,27.5h4.17V20h-4.17V27.5z M20.5,27.5h4.17v-10H20.5V27.5z M25.67,27.5h4.17V15h-4.17V27.5z
+ M30.83,27.5H35v-15h-4.17V27.5z M10.17,27.5h4.17v-5h-4.17V27.5z"/>
+ </svg>
+ </div>
+))
+
+export const VolumeControl = connect(state => ({
+ muted: state.audio.muted,
+}))(VolumeIcon)
+
+
+// play / pause button
+
+const PlayIcon = (
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">
+ <polygon points="12.5,11 12.5,29 27.5,20 " />
+ </svg>
+)
+const PauseIcon = (
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">
+ <path d="M14.34,12.5h4.16v15h-4.16V12.5z M21.5,27.5h4.17v-15H21.5V27.5z" />
+ </svg>
+)
+
+const PlayButtonIcon = ({ playing }) => {
+ return (
+ <div
+ className='playToggle'
+ onClick={() => playing ? actions.audio.pause() : actions.audio.play()}
+ >
+ {playing ? PauseIcon : PlayIcon}
+ </div>
+ )
+}
+
+export const PlayButton = connect(state => ({
+ playing: state.audio.playing,
+}))(PlayButtonIcon)
+
+
+// player current time
+
+const PlayerTimeSpan = ({ play_ts, duration }) => (
+ <span className='playerTime'>
+ {timestamp(play_ts)}
+ {' / '}
+ {timestamp(duration)}
+ </span>
+)
+
+export const PlayerTime = connect(state => ({
+ play_ts: state.audio.play_ts,
+ duration: state.align.timeline.duration,
+}))(PlayerTimeSpan)
diff --git a/animism-align/frontend/app/views/viewer/nav/viewer.nav.js b/animism-align/frontend/app/views/viewer/nav/viewer.nav.js
index 7b5a4c7..4200b03 100644
--- a/animism-align/frontend/app/views/viewer/nav/viewer.nav.js
+++ b/animism-align/frontend/app/views/viewer/nav/viewer.nav.js
@@ -3,6 +3,8 @@ import React, { Component } from 'react'
import { connect } from 'react-redux'
import actions from 'app/actions'
+import { ROMAN_NUMERALS } from 'app/constants'
+import { Arrow, VolumeControl, PlayButton, PlayerTime } from './viewer.icons'
class ViewerNav extends Component {
componentDidMount() {
@@ -12,7 +14,23 @@ class ViewerNav extends Component {
const { } = this.props
return (
<div className="viewer-nav">
- Viewer nav
+ <div className='nav-row main-nav'>
+ <div>
+ <Arrow type={'up'} />
+ {ROMAN_NUMERALS[0]}
+ {'. '}
+ {'Introduction'}
+ </div>
+ <div>
+ <PlayButton />
+ <PlayerTime />
+ <VolumeControl />
+ </div>
+ <div>
+ Next
+ <Arrow type={'right'} />
+ </div>
+ </div>
</div>
)
}
diff --git a/animism-align/frontend/app/views/viewer/transcript/transcript.container.js b/animism-align/frontend/app/views/viewer/transcript/transcript.container.js
index e6d7d09..d3d3e9f 100644
--- a/animism-align/frontend/app/views/viewer/transcript/transcript.container.js
+++ b/animism-align/frontend/app/views/viewer/transcript/transcript.container.js
@@ -27,7 +27,7 @@ class Transcript extends Component {
render() {
const { viewer } = this.props
return (
- <div className={viewer.transcript ? "transcript visible" : "transcript"}>
+ <div className="transcript">
<div className='content'>
<ParagraphList
paragraphElementLookup={transcriptElementLookup}
@@ -39,6 +39,9 @@ class Transcript extends Component {
className='close'
onClick={this.handleClose}
/>
+ <a className='footer' href='#'>
+ Download PDF
+ </a>
</div>
)
}
diff --git a/animism-align/frontend/app/views/viewer/transcript/transcript.css b/animism-align/frontend/app/views/viewer/transcript/transcript.css
index 38af9f5..a42615d 100644
--- a/animism-align/frontend/app/views/viewer/transcript/transcript.css
+++ b/animism-align/frontend/app/views/viewer/transcript/transcript.css
@@ -18,11 +18,22 @@
pointer-events: none;
user-select: none;
}
-.transcript.visible {
+.transcript-open .transcript {
pointer-events: auto;
user-select: auto;
transform: translateZ(0) translateX(0);
}
+.transcript .footer {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ background: black;
+ color: white;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
/* general paragraph styles */
@@ -34,7 +45,7 @@
padding: 1.5rem 2rem 6rem 1.5rem;
position: relative;
}
-.transcript.visible .content {
+.transcript-open .transcript .content {
overflow-y: scroll;
}
diff --git a/animism-align/frontend/app/views/viewer/viewer.container.js b/animism-align/frontend/app/views/viewer/viewer.container.js
index 080925f..b5d9721 100644
--- a/animism-align/frontend/app/views/viewer/viewer.container.js
+++ b/animism-align/frontend/app/views/viewer/viewer.container.js
@@ -55,13 +55,15 @@ class ViewerContainer extends Component {
if (!loaded) {
return <div className='viewer loading'><Loader /></div>
}
+ let className = 'viewer-container'
+ if (viewer.transcript) className += 'transcript-open'
return (
<div>
<div className='viewer'>
- <div className={viewer.transcript ? 'viewer-container transcript-open' : 'viewer-container'}>
+ <div className={className}>
<Player />
- <ViewerNav />
</div>
+ <ViewerNav />
<Transcript />
<Checklist />
<Route exact path='/viewer/:component/' component={ViewerRouter} />
diff --git a/animism-align/frontend/app/views/viewer/viewer.nav.css b/animism-align/frontend/app/views/viewer/viewer.nav.css
index 809f2af..3797619 100644
--- a/animism-align/frontend/app/views/viewer/viewer.nav.css
+++ b/animism-align/frontend/app/views/viewer/viewer.nav.css
@@ -3,4 +3,97 @@
bottom: 0;
left: 0;
width: 100%;
+ font-size: 18px;
+}
+
+/* The main nav row */
+
+.viewer-nav > .nav-row {
+ width: 100%;
+ padding: 0.25rem 0 0.25rem 0;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+.viewer-nav > .nav-row > div {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 32%;
+}
+.viewer-nav > .nav-row > div:nth-child(1) {
+ justify-content: flex-start;
+ align-items: center;
+}
+.viewer-nav > .nav-row > div:nth-child(2) {
+ justify-content: center;
+ align-items: center;
+}
+.viewer-nav > .nav-row > div:nth-child(3) {
+ justify-content: flex-end;
+ align-items: center;
+}
+
+/* Arrows */
+
+.viewer-nav .arrow {
+ width: 2.5rem;
+ height: 2.5rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+.viewer-nav .arrow.left,
+.viewer-nav .arrow.right {
+ width: 1.25rem;
+}
+.viewer-nav .arrow svg {
+ width: 100%;
+ height: 100%;
+}
+
+/* Volume button */
+
+.volume {
+ cursor: pointer;
+ width: 2.5rem;
+ height: 2.5rem;
+}
+.volume path {
+ fill: #000;
+}
+.volume.muted path {
+ fill: #fff;
+ stroke: #000;
+ stroke-width: 0.5;
+}
+.nav-open .volume path {
+ fill: #fff;
+}
+.nav-open .volume.muted path {
+ fill: #000;
+ stroke: #fff;
+}
+
+/* Play button */
+
+.playToggle {
+ cursor: pointer;
+ width: 2.5rem;
+ height: 2.5rem;
+}
+.playToggle path,
+.playToggle polygon {
+ fill: #000;
+}
+.nav-open .playToggle path,
+.nav-open .playToggle polygon {
+ fill: #fff;
+}
+
+/* Player time */
+
+.playerTime {
+ margin-left: 0.5rem;
+ margin-right: 0.75rem;
}
diff --git a/animism-align/static/img/close-black.png b/animism-align/static/img/close-black.png
deleted file mode 100644
index 191442a..0000000
--- a/animism-align/static/img/close-black.png
+++ /dev/null
Binary files differ
diff --git a/animism-align/static/img/close.png b/animism-align/static/img/close.png
deleted file mode 100644
index 529d730..0000000
--- a/animism-align/static/img/close.png
+++ /dev/null
Binary files differ