import { h, Component } from 'preact' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' import * as liveActions from '../live/live.actions' const SLIDER_THROTTLE_TIME = 100 class Slider extends Component { constructor(props){ super(props) this.timeout = 0 this.state = { value: props.live ? props.opt[props.name] : props.value } this.handleInput = this.handleInput.bind(this) this.handleRange = this.handleRange.bind(this) } componentWillReceiveProps(nextProps) { let next_value = nextProps.value || nextProps.opt[nextProps.name] if (next_value !== this.state.value) { if (this.props.type === 'int') { next_value = parseInt(next_value) } this.setState({ value: next_value }); } } handleInput(e){ let { name, opt } = this.props let old_value = opt[name] let new_value = e.target.value if (new_value === '') { new_value = this.props.defaultValue || (this.props.max - this.props.min) / 2 } else if (this.props.type === 'int') { new_value = parseInt(new_value) } else if (this.props.type === 'odd') { new_value = parseInt(Math.floor(new_value / 2) * 2 + 1) } if (old_value !== new_value) { this.setState({ value: new_value }) this.props.live && this.props.actions.set_param(this.props.name, new_value) this.props.onChange && this.props.onChange(new_value) } clearTimeout(this.timeout) } handleRange(e){ clearTimeout(this.timeout) let new_value = e.target.value if (this.props.type === 'int') { new_value = parseInt(new_value) } if (this.props.type === 'odd') { new_value = parseInt(Math.floor(new_value / 2) * 2 + 1) } if (this.props.type === 'list') { new_value = this.props.options[new_value] || this.props.options[0] } this.setState({ value: new_value }) this.timeout = setTimeout(() => { this.props.live && this.props.actions.set_param(this.props.name, new_value) this.props.onChange && this.props.onChange(new_value) }, SLIDER_THROTTLE_TIME) } render(){ let { name, title } = this.props let value = this.state.value if (typeof value === 'undefined') { value = this.props.min } let text_value = value let step; let min = this.props.min || 0 let max = this.props.max || 0 if (this.props.type === 'int') { step = 1 } else if (this.props.type === 'list') { min = 0 max = this.props.options.length-1 step = 1 value = this.props.options.indexOf(value) } else { step = (this.props.max - this.props.min) / 100 text_value = parseFloat(value).toFixed(2) } return (
) } } const mapStateToProps = state => ({ opt: state.live.opt, }) const mapDispatchToProps = (dispatch, ownProps) => ({ actions: bindActionCreators(liveActions, dispatch) }) export default connect(mapStateToProps, mapDispatchToProps)(Slider)