Skip to content

Commit

Permalink
Fix expiring polls not being displayed as such in the WebUI (mastodon…
Browse files Browse the repository at this point in the history
…#11835)

* Fix expiring polls not being displayed as such in the WebUI

* Reset expiration state and timer when a poll changes

* Refactor timer logic in `_setupTimer`, only set expiration if props have changed

* Refactor and do not use deprecated React lifecycles
  • Loading branch information
ClearlyClaire authored and hiyuki2578 committed Oct 2, 2019
1 parent c740187 commit e7b1f39
Showing 1 changed file with 35 additions and 5 deletions.
40 changes: 35 additions & 5 deletions app/javascript/mastodon/components/poll.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,38 @@ class Poll extends ImmutablePureComponent {

state = {
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 => {
const { target: { value } } = e;

Expand Down Expand Up @@ -68,12 +98,11 @@ class Poll extends ImmutablePureComponent {
this.props.dispatch(fetchPoll(this.props.poll.get('id')));
};

renderOption (option, optionIndex) {
renderOption (option, optionIndex, showResults) {
const { poll, disabled } = this.props;
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 active = !!this.state.selected[`${optionIndex}`];
const showResults = poll.get('voted') || poll.get('expired');

let titleEmojified = option.get('title_emojified');
if (!titleEmojified) {
Expand Down Expand Up @@ -112,19 +141,20 @@ class Poll extends ImmutablePureComponent {

render () {
const { poll, intl } = this.props;
const { expired } = this.state;

if (!poll) {
return null;
}

const timeRemaining = poll.get('expired') ? intl.formatMessage(messages.closed) : <RelativeTimestamp timestamp={poll.get('expires_at')} futureDate />;
const showResults = poll.get('voted') || poll.get('expired');
const timeRemaining = expired ? intl.formatMessage(messages.closed) : <RelativeTimestamp timestamp={poll.get('expires_at')} futureDate />;
const showResults = poll.get('voted') || expired;
const disabled = this.props.disabled || Object.entries(this.state.selected).every(item => !item);

return (
<div className='poll'>
<ul>
{poll.get('options').map((option, i) => this.renderOption(option, i))}
{poll.get('options').map((option, i) => this.renderOption(option, i, showResults))}
</ul>

<div className='poll__footer'>
Expand Down

0 comments on commit e7b1f39

Please sign in to comment.