diff options
Diffstat (limited to 'frontend/site/projects/museum/views/subtitles.overlay.js')
| -rw-r--r-- | frontend/site/projects/museum/views/subtitles.overlay.js | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/frontend/site/projects/museum/views/subtitles.overlay.js b/frontend/site/projects/museum/views/subtitles.overlay.js new file mode 100644 index 0000000..b3bea35 --- /dev/null +++ b/frontend/site/projects/museum/views/subtitles.overlay.js @@ -0,0 +1,129 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' + +import { SUBTITLES_OVERLAY } from '../subtitles.js' + +import './overlay.css' + +const TITLE_SHOW_DELAY = 3000 +const TITLE_HIDE_DELAY = 10000 +const SUBTITLE_DELAY = 2500 +const LAST_SUBTITLE_DELAY = 5000 + +class SubtitlesOverlay extends Component { + state = { + content: null, + } + + constructor(props) { + super(props) + this.titleRef = React.createRef() + this.subtitleRef = React.createRef() + this.toggle = this.toggle.bind(this) + this.showTitle = this.showTitle.bind(this) + this.nextSubtitle = this.nextSubtitle.bind(this) + } + + componentDidMount() { + this.load() + } + + componentDidUpdate(prevProps) { + // console.log(this.props.location.pathname, prevProps.location.pathname) + if (this.props.location.pathname !== prevProps.location.pathname) { + this.load() + } + if ( + this.props.popups !== prevProps.popups + && this.state.content + && this.state.content.popup + && this.props.popups[this.state.content.popup] + ) { + this.startSubtitles() + } + } + + load() { + const { page_name } = this.props.match.params + clearTimeout(this.titleTimeout) + clearTimeout(this.subtitleTimeout) + this.props.audio.player.stop("text-overlay") + if (SUBTITLES[page_name]) { + this.setState({ + content: SUBTITLES[page_name], + open: false, + }) + setTimeout(this.showTitle, 0) + } else { + this.setState({ + content: null, + open: false, + }) + } + } + + showTitle() { + if (!this.titleRef.current) return + this.titleRef.current.style.opacity = 0 + this.titleTimeout = setTimeout(() => { + this.titleRef.current.style.opacity = 1 + this.titleTimeout = setTimeout(() => { + this.titleRef.current.style.opacity = 0 + }, TITLE_HIDE_DELAY) + }, TITLE_SHOW_DELAY) + } + + startSubtitles() { + if (this.state.content.audio_url) { + this.props.audio.player.stop("text-overlay") + this.props.audio.player.playURL({ + id: "text-overlay", + url: this.state.content.audio_url, + }) + } + clearTimeout(this.subtitleTimeout) + this.index = -1 + this.nextSubtitle() + } + + nextSubtitle() { + if (!this.subtitleRef.current) return + this.index += 1 + const subtitle = this.state.content.subtitles[this.index] || "" + this.subtitleRef.current.innerHTML = subtitle + if (this.index === (this.state.content.subtitles.length - 1)) { + this.subtitleTimeout = setTimeout(this.nextSubtitle, LAST_SUBTITLE_DELAY) + } + else if (subtitle.length) { + this.subtitleTimeout = setTimeout(this.nextSubtitle, SUBTITLE_DELAY) + } + } + + render() { + const { content } = this.state + const { popups, interactive } = this.props + if (!interactive || !content) return null + if (content.popup && !popups[content.popup]) return null + return ( + <div> + <div + ref={this.titleRef} + className="chapter-title" + dangerouslySetInnerHTML={{ __html: content.title }} + /> + <div + ref={this.subtitleRef} + className="subtitles" + /> + </div> + ) + } +} + +const mapStateToProps = state => ({ + audio: state.audio, + popups: state.site.popups, + interactive: state.site.interactive, +}) + +export default connect(mapStateToProps)(SubtitlesOverlay) |
