react-lite-audio
Version:
Audio Player of jianliao.com
151 lines (141 loc) • 4.18 kB
JavaScript
(function() {
var React, T, audio, bus, cx, div, span;
React = require('react');
cx = require('classnames');
bus = require('./bus');
div = React.createFactory('div');
span = React.createFactory('span');
audio = React.createFactory('audio');
T = React.PropTypes;
module.exports = React.createClass({
displayName: 'quote-audio-slim',
propTypes: {
isUnread: T.bool,
duration: T.number,
source: T.string.isRequired
},
getDefaultProps: function() {
return {
isUnread: false
};
},
getInitialState: function() {
return {
pause: true,
played: false,
currentTime: 0,
duration: this.props.duration || 0
};
},
componentDidMount: function() {
this._audioEl = this.refs.audio;
this._audioEl.addEventListener('durationchange', this.setDuration);
this._audioEl.addEventListener('timeupdate', this.updateProgress);
this._audioEl.addEventListener('ended', this.endProgress);
return bus.on('play', this.onBusPlay);
},
componentWillUnmount: function() {
this._audioEl.removeEventListener('durationchange', this.setDuration);
this._audioEl.removeEventListener('timeupdate', this.updateProgress);
this._audioEl.removeEventListener('ended', this.endProgress);
return bus.off('play', this.onBusPlay);
},
setDuration: function() {
var defaultDuration, duration;
defaultDuration = this.props.duration || 0;
duration = Math.round(this._audioEl.duration);
if (window.isFinite(duration) && defaultDuration < duration) {
return this.setState({
duration: duration
});
}
},
formatDuration: function(duration) {
var durationFormat, minutes, seconds;
if (duration <= 0) {
return '00:00';
}
minutes = Math.floor(duration / 60);
seconds = Math.floor(duration % 60);
minutes = minutes >= 10 ? minutes : '0' + minutes;
seconds = seconds >= 10 ? seconds : '0' + seconds;
durationFormat = minutes + ':' + seconds;
return durationFormat;
},
updateProgress: function() {
var currentTime;
currentTime = this._audioEl.currentTime;
this.setState({
currentTime: currentTime
});
if (currentTime >= this.state.duration) {
return this.endPlay();
}
},
endProgress: function() {
return this.endPlay();
},
endPlay: function() {
this.setState({
pause: true
});
this._audioEl.pause();
return this._audioEl.currentTime = 0;
},
playClick: function() {
if (this._audioEl.paused) {
bus.trigger('play');
this._audioEl.play();
return this.setState({
pause: false,
played: true
});
} else {
this._audioEl.pause();
return this.setState({
pause: true,
played: true
});
}
},
onBusPlay: function(event) {
if (!this.state.paused) {
this._audioEl.pause();
return this.setState({
pause: true,
played: true
});
}
},
render: function() {
var className, duration, durationFormat, playedTime, src;
src = this.props.source;
duration = this.state.duration;
durationFormat = this.formatDuration(duration);
playedTime = this.formatDuration(Math.round(this.state.currentTime));
className = cx('icon', {
'icon-play': this.state.pause,
'icon-pause': !this.state.pause
});
return div({
className: 'lite-audio slim'
}, div({
className: 'audio-player',
onClick: this.playClick
}, div({
className: 'content'
}, span({
className: className
}), this.state.currentTime !== 0 ? span({
className: 'time'
}, playedTime + "/") : void 0, span({
className: 'time'
}, durationFormat), (!this.state.played) && this.props.isUnread ? div({
className: 'unread-dot'
}) : void 0)), audio({
ref: 'audio',
src: src
}));
}
});
}).call(this);