UNPKG

twreporter-react

Version:

React-Redux site for The Reporter Foundation in Taiwan

451 lines (393 loc) 17.7 kB
/* eslint no-unused-vars:0 */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.Audio = undefined; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _Image = require('./Image'); var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _CircleProgressButton = require('./CircleProgressButton'); var _CircleProgressButton2 = _interopRequireDefault(_CircleProgressButton); var _reactAddonsCssTransitionGroup = require('react-addons-css-transition-group'); var _reactAddonsCssTransitionGroup2 = _interopRequireDefault(_reactAddonsCssTransitionGroup); var _reactHowler = require('react-howler'); var _reactHowler2 = _interopRequireDefault(_reactHowler); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _rcSlider = require('rc-slider'); var _rcSlider2 = _interopRequireDefault(_rcSlider); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _Common = { "inner-block": "Common__inner-block___2cOrF", "disable-inner-block": "Common__disable-inner-block___1MLd0", "text-color": "Common__text-color___1TD3U", "desc-text-color": "Common__desc-text-color___2fV3l", "desc-text-block": "Common__desc-text-block___1Z4b-", "text-link": "Common__text-link___1jaLy", "topic-box": "Common__topic-box___2Q-kN" }; var _Common2 = _interopRequireDefault(_Common); var _audioPlay = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjQ4cHgiIGhlaWdodD0iNDhweCIgdmlld0JveD0iMCAwIDQ4IDQ4IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IHNrZXRjaHRvb2wgMzkuMSAoMzE3MjApIC0gaHR0cDovL3d3dy5ib2hlbWlhbmNvZGluZy5jb20vc2tldGNoIC0tPgogICAgPHRpdGxlPjgxMjgwRDM3LURGRTEtNDAzMi1CNTg1LTE3RDA2MjMxNzVEODwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggc2tldGNodG9vbC48L2Rlc2M+CiAgICA8ZGVmcz48L2RlZnM+CiAgICA8ZyBpZD0iQ29tcG9uZW50cyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IkF1ZGlvIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNTA0LjAwMDAwMCwgLTY0NS4wMDAwMDApIiBmaWxsPSIjQzcxQjBBIj4KICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0ODAuMDAwMDAwLCA2MTcuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNDgsNzYgQzYxLjI1NDgzNCw3NiA3Miw2NS4yNTQ4MzQgNzIsNTIgQzcyLDM4Ljc0NTE2NiA2MS4yNTQ4MzQsMjggNDgsMjggQzM0Ljc0NTE2NiwyOCAyNCwzOC43NDUxNjYgMjQsNTIgQzI0LDY1LjI1NDgzNCAzNC43NDUxNjYsNzYgNDgsNzYgWiBNNDMuNzI3MDQ4Nyw2MS4wMTEzMTA1IEM0Mi43NzMyMjYsNjEuNTYxNDIzMyA0Miw2MS4xMjE2MDExIDQyLDYwLjAxNTI0MzEgTDQyLDQzLjk4NjA1NDkgQzQyLDQyLjg4NTgyOTMgNDIuNzY3OTA5Nyw0Mi40MzY4MDg1IDQzLjcyNzA0ODcsNDIuOTg5OTg3NSBMNTcuNjIzMjkyMiw1MS4wMDQ1ODE2IEM1OC41NzcxMTQ5LDUxLjU1NDY5NDUgNTguNTgyNDMxMiw1Mi40NDM1Mzc0IDU3LjYyMzI5MjIsNTIuOTk2NzE2NCBMNDMuNzI3MDQ4Nyw2MS4wMTEzMTA1IFoiIGlkPSJpY29uLWF1ZGlvLXBsYXkiPjwvcGF0aD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+"; var _audioPlay2 = _interopRequireDefault(_audioPlay); var _audioPause = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjQ4cHgiIGhlaWdodD0iNDhweCIgdmlld0JveD0iMCAwIDQ4IDQ4IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCAzOS4xICgzMTcyMCkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+aWNvbi1hdWRpby1wYXVzZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPjwvZGVmcz4KICAgIDxnIGlkPSJDb21wb25lbnRzIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iQXVkaW8iIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMDQuMDAwMDAwLCAtNzI0LjAwMDAwMCkiIGZpbGw9IiNDNzFCMEEiPgogICAgICAgICAgICA8ZyBpZD0iR3JvdXAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDgwLjAwMDAwMCwgNjkyLjAwMDAwMCkiPgogICAgICAgICAgICAgICAgPHBhdGggZD0iTTQ4LDgwIEM2MS4yNTQ4MzQsODAgNzIsNjkuMjU0ODM0IDcyLDU2IEM3Miw0Mi43NDUxNjYgNjEuMjU0ODM0LDMyIDQ4LDMyIEMzNC43NDUxNjYsMzIgMjQsNDIuNzQ1MTY2IDI0LDU2IEMyNCw2OS4yNTQ4MzQgMzQuNzQ1MTY2LDgwIDQ4LDgwIFogTTQzLDQ5IEw0Niw0OSBMNDYsNjMgTDQzLDYzIEw0Myw0OSBaIE01MCw0OSBMNTMsNDkgTDUzLDYzIEw1MCw2MyBMNTAsNDkgWiIgaWQ9Imljb24tYXVkaW8tcGF1c2UiPjwvcGF0aD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+"; var _audioPause2 = _interopRequireDefault(_audioPause); var _raf = require('raf'); var _raf2 = _interopRequireDefault(_raf); var _Audio = { "audio-container": "Audio__audio-container___272mU", "mobile": "Audio__mobile___3_Ppq", "audio-coverphoto": "Audio__audio-coverphoto___2tsS6", "enter": "Audio__enter___35iQs", "enterActive": "Audio__enterActive___G44gg", "leave": "Audio__leave___IC3cB", "leaveActive": "Audio__leaveActive____G-04", "appear": "Audio__appear___hvk1L", "appearActive": "Audio__appearActive___3Xktl", "audio-slider": "Audio__audio-slider___GLra_", "audio-time-display": "Audio__audio-time-display___2l6SY", "audio-img-filter": "Audio__audio-img-filter___2Q-T8", "audio-duration-block": "Audio__audio-duration-block___1WnVB", "audio-info-container": "Audio__audio-info-container___2O6Oh", "html": "Audio__html___17sp2", "without-cp": "Audio__without-cp___3meJ6", "progress-bt": "Audio__progress-bt___3l7Rq" }; var _Audio2 = _interopRequireDefault(_Audio); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // eslint-disable-line // requestAnimationFrame polyfill if (process.env.BROWSER) {} function getMinSecStr(time) { time = Math.round(time); var minutes = Math.floor(time / 60); var seconds = time - minutes * 60; seconds = seconds < 10 ? 0 + seconds.toString() : seconds.toString(); return minutes + ':' + seconds; } var AudioSlider = function AudioSlider(_ref) { var duration = _ref.duration; var onSeekChange = _ref.onSeekChange; var seek = _ref.seek; return _react2.default.createElement( 'div', { key: 'audio-slider', className: _Audio2.default['audio-slider'] }, _react2.default.createElement( 'div', { className: _Audio2.default['audio-time-display'] }, getMinSecStr(seek) ), _react2.default.createElement(_rcSlider2.default, { tipFormatter: null, onChange: onSeekChange, value: seek, max: duration }), _react2.default.createElement( 'div', { className: _Audio2.default['audio-time-display'] }, getMinSecStr(duration) ) ); }; var AudioController = function AudioController(props) { var duration = props.duration; var isOncePlayed = props.isOncePlayed; var isPlaying = props.isPlaying; var isFocused = props.isFocused; var onSeekChange = props.onSeekChange; var onToggle = props.onToggle; var seek = props.seek; return _react2.default.createElement( _reactAddonsCssTransitionGroup2.default, { transitionName: _Audio2.default, transitionAppear: true, transitionAppearTimeout: 1000, transitionEnterTimeout: 1000, transitionLeaveTimeout: 1000 }, !isOncePlayed ? _react2.default.createElement( 'div', { key: 'notPlayedYet' }, _react2.default.createElement(_CircleProgressButton2.default, { duration: duration, isOncePlayed: isOncePlayed, isPlaying: isPlaying, onToggle: onToggle, seek: seek }), _react2.default.createElement( 'div', { className: _Audio2.default['audio-duration-block'] }, getMinSecStr(duration) ) ) : null, isOncePlayed && !isPlaying || isPlaying && isFocused ? _react2.default.createElement( 'div', { key: 'oncePlayed' }, _react2.default.createElement(_CircleProgressButton2.default, { duration: duration, isOncePlayed: isOncePlayed, isPlaying: isPlaying, onToggle: onToggle, seek: seek }), _react2.default.createElement(AudioSlider, { duration: duration, onSeekChange: onSeekChange, seek: seek }) ) : null ); }; var Audio = function (_React$Component) { _inherits(Audio, _React$Component); function Audio(props) { _classCallCheck(this, Audio); var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Audio).call(this, props)); _this.state = { duration: 100, loaded: false, isOncePlayed: false, isPlaying: false, isFocused: false, seek: 0 }; _this.handleMouseClick = _this._handleMouseClick.bind(_this); _this.handleOnLoad = _this._handleOnLoad.bind(_this); _this.handleOnEnd = _this._handleOnEnd.bind(_this); _this.handleOnMouseOut = _this._handleOnMouseOut.bind(_this); _this.handleOnMouseOver = _this._handleOnMouseOver.bind(_this); _this.handleOnPlay = _this._handleOnPlay.bind(_this); _this.handleToggle = _this._handleToggle.bind(_this); _this.renderSeekPos = _this._renderSeekPos.bind(_this); _this.handleSeekChange = _this._handleSeekChange.bind(_this); return _this; } _createClass(Audio, [{ key: 'componentWillUnmount', value: function componentWillUnmount() { this.clearRAF(); } }, { key: '_handleMouseClick', value: function _handleMouseClick(e) { e.stopPropagation(); this.setState({ isFocused: !this.state.isFocused }); } }, { key: '_handleToggle', value: function _handleToggle(e) { e.stopPropagation(); this.setState({ isOncePlayed: true, isPlaying: !this.state.isPlaying, isFocused: false }); } }, { key: '_handleOnLoad', value: function _handleOnLoad() { this.setState({ loaded: true, duration: this.player.duration() }); } }, { key: '_handleOnPlay', value: function _handleOnPlay() { this.setState({ isPlaying: true }); this.renderSeekPos(); } }, { key: '_handleOnEnd', value: function _handleOnEnd() { this.setState({ isPlaying: false }); this.clearRAF(); } }, { key: '_handleOnMouseOver', value: function _handleOnMouseOver(e) { e.stopPropagation(); this.setState({ isFocused: true }); } }, { key: '_handleOnMouseOut', value: function _handleOnMouseOut(e) { e.stopPropagation(); this.setState({ isFocused: false }); } }, { key: '_handleSelect', value: function _handleSelect(e) { e.stopPropagation(); this.props.onSelect(e); } }, { key: '_renderSeekPos', value: function _renderSeekPos() { this.setState({ seek: this.player.seek() }); if (this.state.isPlaying) { this._raf = (0, _raf2.default)(this.renderSeekPos); } } }, { key: '_handleSeekChange', value: function _handleSeekChange(seek) { var _this2 = this; this.setState({ seek: seek }, function () { _this2.player.seek(seek); }); } }, { key: 'clearRAF', value: function clearRAF() { _raf2.default.cancel(this._raf); } }, { key: 'render', value: function render() { var _this3 = this; var _props = this.props; var content = _props.content; var device = _props.device; var _state = this.state; var duration = _state.duration; var isFocused = _state.isFocused; var isOncePlayed = _state.isOncePlayed; var isPlaying = _state.isPlaying; var seek = _state.seek; var _$get = _lodash2.default.get(content, 0, {}); var url = _$get.url; var coverPhoto = _$get.coverPhoto; var title = _$get.title; var description = _$get.description; var player = _react2.default.createElement(_reactHowler2.default, { src: url, playing: isPlaying, onLoad: this.handleOnLoad, onPlay: this.handleOnPlay, onEnd: this.handleOnEnd, ref: function ref(_ref2) { return _this3.player = _ref2; } }); // render Audio without cover photo if (!coverPhoto) { var btRadius = 24; return _react2.default.createElement( 'div', { className: (0, _classnames2.default)(_Audio2.default['audio-container'], _defineProperty({}, _Audio2.default['mobile'], device === 'mobile' ? true : false)) }, _react2.default.createElement(_rcSlider2.default, { tipFormatter: null, onChange: this.handleSeekChange, value: seek, max: duration }), _react2.default.createElement( 'div', { className: (0, _classnames2.default)(_Audio2.default['audio-info-container'], _Audio2.default['without-cp']) }, _react2.default.createElement( 'div', { className: _Audio2.default['progress-bt'], style: { width: btRadius * 2, height: btRadius * 2 } }, isPlaying ? _react2.default.createElement('img', { onClick: this.handleToggle, src: _audioPause2.default }) : _react2.default.createElement('img', { onClick: this.handleToggle, src: _audioPlay2.default }) ), _react2.default.createElement( 'div', { style: { display: 'inline-block' } }, _react2.default.createElement( 'h4', { className: _Common2.default['text-color'] }, title ), _react2.default.createElement( 'span', { className: _Common2.default['desc-text-block'] }, getMinSecStr(seek), ' / ' ), _react2.default.createElement( 'span', { className: _Common2.default['desc-text-block'] }, getMinSecStr(duration) ) ), _react2.default.createElement('div', { className: _Audio2.default['html'], dangerouslySetInnerHTML: { __html: description }, style: { marginTop: '16px' } }) ), player ); } // render Audio with cover photo return _react2.default.createElement( 'div', { className: (0, _classnames2.default)(_Audio2.default['audio-container'], _defineProperty({}, _Audio2.default['mobile'], device === 'mobile' ? true : false)) }, _react2.default.createElement( 'div', { className: _Audio2.default['audio-coverphoto'], onClick: this.handleMouseClick, onMouseEnter: this.handleOnMouseOver, onMouseLeave: this.handleOnMouseOut }, _react2.default.createElement( 'div', { className: _Audio2.default['audio-img-filter'], style: isOncePlayed ? { opacity: 1 } : {} }, _react2.default.createElement(_Image.Image, { content: [coverPhoto], isToShowDescription: false }) ), _react2.default.createElement(AudioController, { duration: duration, isFocused: isFocused, isOncePlayed: isOncePlayed, isPlaying: isPlaying, onToggle: this.handleToggle, onSeekChange: this.handleSeekChange, seek: seek }) ), _react2.default.createElement( 'div', { className: _Audio2.default['audio-info-container'] }, _react2.default.createElement( 'h4', { className: (0, _classnames2.default)('text-center', _Common2.default['text-color']) }, title ), _react2.default.createElement('div', { dangerouslySetInnerHTML: { __html: description } }) ), player ); } }]); return Audio; }(_react2.default.Component); Audio.propTypes = { content: _react2.default.PropTypes.array.isRequired, customStyles: _react2.default.PropTypes.array, device: _react2.default.PropTypes.string }; Audio.defaultProps = { content: [], customStyles: [], device: '' }; exports.Audio = Audio;