diff options
Diffstat (limited to 'animism-align/frontend/app/views/viewer/sections')
| -rw-r--r-- | animism-align/frontend/app/views/viewer/sections/sections.css | 48 | ||||
| -rw-r--r-- | animism-align/frontend/app/views/viewer/sections/viewer.sections.js | 42 |
2 files changed, 83 insertions, 7 deletions
diff --git a/animism-align/frontend/app/views/viewer/sections/sections.css b/animism-align/frontend/app/views/viewer/sections/sections.css index 1ddb9d2..a60a063 100644 --- a/animism-align/frontend/app/views/viewer/sections/sections.css +++ b/animism-align/frontend/app/views/viewer/sections/sections.css @@ -58,6 +58,14 @@ margin: 1rem 0 1rem 1rem; font-size: 16px; cursor: pointer; + opacity: 0.6; + transition: opacity 0.2s; +} +.viewer-sections .viewer-section:hover { + opacity: 1.0; +} +.viewer-sections .viewer-section.current-section { + opacity: 1.0; } .viewer-sections .viewer-section:last-child { margin-right: 1rem; @@ -66,7 +74,7 @@ height: calc(20rem - 4px); width: 12rem; } -.viewer-sections .section-thumbnail { +.viewer-section .section-thumbnail { display: block; border-radius: 1rem; width: 12rem; @@ -74,8 +82,44 @@ margin-bottom: 0.5rem; background-size: cover; background-position: center center; + position: relative; + overflow: hidden; } -.viewer-sections .section-media { +.viewer-section .section-duration { + position: absolute; + bottom: 0.5rem; + left: 0.5rem; + font-size: 0.75rem; +} +.section-duration-white { color: white; } +.section-duration-black { color: black; } +.section-duration-white svg path { fill: white; } +.section-duration-black svg path { fill: black; } +.viewer-section .section-media { margin-top: 0.75rem; font-size: 12px; } +.viewer-section .section-has-audio { + position: absolute; + bottom: -0.25rem; + right: 0.25rem; +} +.viewer-section .section-has-audio svg { + width: 2.5rem; + height: 2.5rem; +} +.viewer-section .section-progress-bar { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 3px; + background: #333; +} +.viewer-section .section-progress { + position: absolute; + top: 0; + left: 0; + height: 3px; + background: #fff; +}
\ No newline at end of file diff --git a/animism-align/frontend/app/views/viewer/sections/viewer.sections.js b/animism-align/frontend/app/views/viewer/sections/viewer.sections.js index 4bb61ec..05eef9c 100644 --- a/animism-align/frontend/app/views/viewer/sections/viewer.sections.js +++ b/animism-align/frontend/app/views/viewer/sections/viewer.sections.js @@ -4,27 +4,52 @@ import { connect } from 'react-redux' import actions from 'app/actions' import ViewerSectionsNav from './viewer.sections.nav' -import { ROMAN_NUMERALS } from 'app/constants' +import { ROMAN_NUMERALS, CURTAIN_COLOR_LOOKUP } from 'app/constants' +import { clamp, timestamp, floatInRange, floatLT } from 'app/utils' import { thumbnailURL } from 'app/utils/annotation.utils' +import { SpeakerIcon } from '../nav/viewer.icons' class ViewerSections extends Component { + shouldComponentUpdate(nextProps) { + if (nextProps.nav !== this.props.nav) return true + return nextProps.nav + } render() { - const { sections } = this.props + const { play_ts, sections, currentSection } = this.props return ( <div className="viewer-sections"> <div className="viewer-sections-scroll"> {sections.map(section => { // console.log(section) + const media = section.media.length ? section.media[0].media : null + const { no_audio, section_nav_color } = section + const progress = Math.round(sectionProgress(section, play_ts) * 100) return ( <div - className="viewer-section" + className={(!currentSection || section.index === currentSection.index) ? "viewer-section current-section" : "viewer-section"} key={section.index} onClick={() => actions.viewer.seekToSection(section)} > <div> <div className="section-thumbnail" style={{ - backgroundImage: section.media.length && 'url(' + thumbnailURL(section.media[0].media) + ')', - }}/> + backgroundImage: media && 'url(' + thumbnailURL(media) + ')', + }}> + {!no_audio && + <div className={"section-duration-" + section_nav_color}> + <div className="section-duration"> + {timestamp(section.duration)} + </div> + <div className="section-has-audio"> + {SpeakerIcon} + </div> + <div className="section-progress-bar"> + <div className="section-progress" + style={{ width: progress + '%' }} + /> + </div> + </div> + } + </div> <div className="section-title"> {ROMAN_NUMERALS[section.index]}<br /> {section.title} @@ -43,8 +68,15 @@ class ViewerSections extends Component { } } +const sectionProgress = (section, play_ts) => { + return (clamp(play_ts, section.start_ts, section.end_ts) - section.start_ts) / section.duration +} + const mapStateToProps = state => ({ + nav: state.viewer.nav, + play_ts: state.audio.play_ts, sections: state.viewer.sections, + currentSection: state.viewer.currentSection, }) export default connect(mapStateToProps)(ViewerSections) |
