Skip to content

Instantly share code, notes, and snippets.

@Stenerson
Last active November 9, 2018 22:45
Show Gist options
  • Save Stenerson/3dd48e7c83ebf7fc69f3f56aaeb5e32a to your computer and use it in GitHub Desktop.
Save Stenerson/3dd48e7c83ebf7fc69f3f56aaeb5e32a to your computer and use it in GitHub Desktop.
A basic button that will control a ReactHowler instance
<HowlerButton
className="btn btn-inverse"
src={`assets/audio/${fileName}`}
/>
// For use with FontAwesome 4.x
import React from 'react';
import PropTypes from 'prop-types';
const FontAwesomeIcon = props => {
const { icon, className, ...rest } = props;
return (<i className={`fa fa-${icon} ${props.className}`} {...rest} />);
};
FontAwesomeIcon.propTypes = {
icon: PropTypes.string.isRequired,
className: PropTypes.string,
};
FontAwesomeIcon.defaultProps = {
className: '',
};
export default FontAwesomeIcon;
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import ReactHowler from 'react-howler';
import classnames from 'classnames';
import FontAwesomeIcon from './FontAwesomeIcon';
const propTypes = {
/**
* Audio file URL
*/
src: PropTypes.string.isRequired,
/**
* Button class
*/
className: PropTypes.string,
/**
* Show icon before text?
*/
showIcon: PropTypes.bool,
/**
* Icon shown when audio is not playing
*/
playIcon: PropTypes.string,
/**
* Icon shown when audio is playing
*/
pauseIcon: PropTypes.string,
/**
* Icon shown when audio is loading
*/
loadingIcon: PropTypes.string,
/**
* Show text?
*/
showText: PropTypes.bool,
/**
* Text shown when audio is not playing
*/
playText: PropTypes.string,
/**
* Text shown when audio is playing
*/
pauseText: PropTypes.string,
/**
* Text shown when audio is loading
*/
loadingText: PropTypes.string,
};
const defaultProps = {
showText: true,
showIcon: true,
playIcon: 'volume-up',
pauseIcon: 'pause',
loadingIcon: 'spinner fa-pulse',
playText: 'Play',
pauseText: 'Pause',
loadingText: 'Loading',
};
class HowlerButton extends PureComponent {
constructor(props) {
super(props);
this.state = { isPlaying: false, loaded: false };
this.handleTogglePlay = this.handleTogglePlay.bind(this);
}
handleTogglePlay() {
this.setState({ isPlaying: !this.state.isPlaying });
}
render() {
const buttonText = classnames({
[this.props.playText]: !this.state.isPlaying && this.state.loaded,
[this.props.pauseText]: this.state.isPlaying && this.state.loaded,
[this.props.loadingText]: !this.state.loaded,
});
return (
<span>
<ReactHowler
src={this.props.src}
playing={this.state.isPlaying}
onEnd={this.handleTogglePlay}
onLoad={() => this.setState({ loaded: true })}
/>
<button className={this.props.className} onClick={this.handleTogglePlay}>
{this.props.showIcon &&
<FontAwesomeIcon
icon={classnames({
[this.props.playIcon]: !this.state.isPlaying && this.state.loaded,
[this.props.pauseIcon]: this.state.isPlaying && this.state.loaded,
[this.props.loadingIcon]: !this.state.loaded,
})}
style={{ marginRight: '.25em', marginLeft: '.25em' }}
/>}
{this.props.showText && buttonText}
</button>
</span>
);
}
}
HowlerButton.propTypes = propTypes;
HowlerButton.defaultProps = defaultProps;
export default HowlerButton;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment