|
|
@ -32,8 +32,38 @@ class Poll extends ImmutablePureComponent { |
|
|
|
|
|
|
|
|
|
|
|
state = { |
|
|
|
state = { |
|
|
|
selected: {}, |
|
|
|
selected: {}, |
|
|
|
|
|
|
|
expired: null, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static getDerivedStateFromProps (props, state) { |
|
|
|
|
|
|
|
const { poll, intl } = props; |
|
|
|
|
|
|
|
const expired = poll.get('expired') || (new Date(poll.get('expires_at'))).getTime() < intl.now(); |
|
|
|
|
|
|
|
return (expired === state.expired) ? null : { expired }; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
componentDidMount () { |
|
|
|
|
|
|
|
this._setupTimer(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
componentDidUpdate () { |
|
|
|
|
|
|
|
this._setupTimer(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
componentWillUnmount () { |
|
|
|
|
|
|
|
clearTimeout(this._timer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_setupTimer () { |
|
|
|
|
|
|
|
const { poll, intl } = this.props; |
|
|
|
|
|
|
|
clearTimeout(this._timer); |
|
|
|
|
|
|
|
if (!this.state.expired) { |
|
|
|
|
|
|
|
const delay = (new Date(poll.get('expires_at'))).getTime() - intl.now(); |
|
|
|
|
|
|
|
this._timer = setTimeout(() => { |
|
|
|
|
|
|
|
this.setState({ expired: true }); |
|
|
|
|
|
|
|
}, delay); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
handleOptionChange = e => { |
|
|
|
handleOptionChange = e => { |
|
|
|
const { target: { value } } = e; |
|
|
|
const { target: { value } } = e; |
|
|
|
|
|
|
|
|
|
|
@ -68,12 +98,11 @@ class Poll extends ImmutablePureComponent { |
|
|
|
this.props.dispatch(fetchPoll(this.props.poll.get('id'))); |
|
|
|
this.props.dispatch(fetchPoll(this.props.poll.get('id'))); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
renderOption (option, optionIndex) { |
|
|
|
renderOption (option, optionIndex, showResults) { |
|
|
|
const { poll, disabled } = this.props; |
|
|
|
const { poll, disabled } = this.props; |
|
|
|
const percent = poll.get('votes_count') === 0 ? 0 : (option.get('votes_count') / poll.get('votes_count')) * 100; |
|
|
|
const percent = poll.get('votes_count') === 0 ? 0 : (option.get('votes_count') / poll.get('votes_count')) * 100; |
|
|
|
const leading = poll.get('options').filterNot(other => other.get('title') === option.get('title')).every(other => option.get('votes_count') > other.get('votes_count')); |
|
|
|
const leading = poll.get('options').filterNot(other => other.get('title') === option.get('title')).every(other => option.get('votes_count') > other.get('votes_count')); |
|
|
|
const active = !!this.state.selected[`${optionIndex}`]; |
|
|
|
const active = !!this.state.selected[`${optionIndex}`]; |
|
|
|
const showResults = poll.get('voted') || poll.get('expired'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let titleEmojified = option.get('title_emojified'); |
|
|
|
let titleEmojified = option.get('title_emojified'); |
|
|
|
if (!titleEmojified) { |
|
|
|
if (!titleEmojified) { |
|
|
@ -112,19 +141,20 @@ class Poll extends ImmutablePureComponent { |
|
|
|
|
|
|
|
|
|
|
|
render () { |
|
|
|
render () { |
|
|
|
const { poll, intl } = this.props; |
|
|
|
const { poll, intl } = this.props; |
|
|
|
|
|
|
|
const { expired } = this.state; |
|
|
|
|
|
|
|
|
|
|
|
if (!poll) { |
|
|
|
if (!poll) { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const timeRemaining = poll.get('expired') ? intl.formatMessage(messages.closed) : <RelativeTimestamp timestamp={poll.get('expires_at')} futureDate />; |
|
|
|
const timeRemaining = expired ? intl.formatMessage(messages.closed) : <RelativeTimestamp timestamp={poll.get('expires_at')} futureDate />; |
|
|
|
const showResults = poll.get('voted') || poll.get('expired'); |
|
|
|
const showResults = poll.get('voted') || expired; |
|
|
|
const disabled = this.props.disabled || Object.entries(this.state.selected).every(item => !item); |
|
|
|
const disabled = this.props.disabled || Object.entries(this.state.selected).every(item => !item); |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<div className='poll'> |
|
|
|
<div className='poll'> |
|
|
|
<ul> |
|
|
|
<ul> |
|
|
|
{poll.get('options').map((option, i) => this.renderOption(option, i))} |
|
|
|
{poll.get('options').map((option, i) => this.renderOption(option, i, showResults))} |
|
|
|
</ul> |
|
|
|
</ul> |
|
|
|
|
|
|
|
|
|
|
|
<div className='poll__footer'> |
|
|
|
<div className='poll__footer'> |
|
|
|