diff --git a/app/soapbox/components/poll.tsx b/app/soapbox/components/poll.tsx index 0eae7c93e..4b0628d2d 100644 --- a/app/soapbox/components/poll.tsx +++ b/app/soapbox/components/poll.tsx @@ -3,6 +3,7 @@ import React from 'react'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { defineMessages, injectIntl, useIntl, FormattedMessage, IntlShape } from 'react-intl'; import { spring } from 'react-motion'; +import { useDispatch } from 'react-redux'; import { openModal } from 'soapbox/actions/modals'; import { vote, fetchPoll } from 'soapbox/actions/polls'; @@ -20,12 +21,7 @@ const messages = defineMessages({ votes: { id: 'poll.votes', defaultMessage: '{votes, plural, one {# vote} other {# votes}}' }, }); -interface IPollPercentageBar { - percent: number, - leading: boolean, -} - -const PollPercentageBar: React.FC = ({ percent, leading }): JSX.Element => { +const PollPercentageBar: React.FC<{percent: number, leading: boolean}> = ({ percent, leading }): JSX.Element => { return ( {({ width }) =>( @@ -44,7 +40,7 @@ interface IPollOptionText extends IPollOption { percent: number, } -const PollOptionText: React.FC = ({ poll, option, index, active, disabled, percent, showResults, onToggle }) => { +const PollOptionText: React.FC = ({ poll, option, index, active, percent, showResults, onToggle }) => { const intl = useIntl(); const voted = poll.own_votes?.includes(index); @@ -68,7 +64,6 @@ const PollOptionText: React.FC = ({ poll, option, index, active value={index} checked={active} onChange={handleOptionChange} - disabled={disabled} /> {!showResults && ( @@ -100,7 +95,6 @@ interface IPollOption { option: PollOptionEntity, index: number, showResults?: boolean, - disabled?: boolean, active: boolean, onToggle: (value: number) => void, } @@ -127,19 +121,68 @@ interface IPoll { poll?: PollEntity, intl: IntlShape, dispatch?: Function, - disabled?: boolean, me?: string | null | false | undefined, status?: string, } interface IPollState { - selected: Record, + selected: Selected, +} + +const RefreshButton: React.FC<{poll: PollEntity}> = ({ poll }): JSX.Element => { + const dispatch = useDispatch(); + const handleRefresh = () => dispatch(fetchPoll(poll.id)); + + return ( + + + + ); +}; + +const VoteButton: React.FC<{poll: PollEntity, selected: Selected}> = ({ poll, selected }): JSX.Element => { + const dispatch = useDispatch(); + const handleVote = dispatch(vote(poll.id, Object.keys(selected))); + + return ( + + ); +}; + +interface IPollFooter { + poll: PollEntity, + showResults: boolean, + selected: Selected, } +const PollFooter: React.FC = ({ poll, showResults, selected }): JSX.Element => { + const intl = useIntl(); + const timeRemaining = poll.expired ? intl.formatMessage(messages.closed) : ; + + return ( +
+ {!showResults && } + + {showResults && ( + <> · + )} + + {poll.expires_at && · {timeRemaining}} + +
+ ); +}; + +type Selected = Record; + class Poll extends ImmutablePureComponent { state = { - selected: {} as Record, + selected: {} as Selected, }; toggleOption = (value: number) => { @@ -155,7 +198,7 @@ class Poll extends ImmutablePureComponent { } this.setState({ selected: tmp }); } else { - const tmp: Record = {}; + const tmp: Selected = {}; tmp[value] = true; this.setState({ selected: tmp }); } @@ -165,8 +208,8 @@ class Poll extends ImmutablePureComponent { } handleVote = () => { - const { disabled, dispatch, poll } = this.props; - if (disabled || !dispatch || !poll) return; + const { dispatch, poll } = this.props; + if (!dispatch || !poll) return; dispatch(vote(poll.id, Object.keys(this.state.selected))); }; @@ -179,22 +222,12 @@ class Poll extends ImmutablePureComponent { })); } - handleRefresh = () => { - const { disabled, dispatch, poll } = this.props; - if (disabled || !poll || !dispatch) return; - dispatch(fetchPoll(poll.id)); - }; - render() { - const { poll, intl } = this.props; + const { poll } = this.props; + if (!poll) return null; - if (!poll) { - return null; - } - - const timeRemaining = poll.expired ? intl.formatMessage(messages.closed) : ; - const showResults = poll.voted || poll.expired; - const disabled = this.props.disabled || Object.entries(this.state.selected).every(item => !item); + const { selected } = this.state; + const showResults = poll.voted || poll.expired; return (
@@ -206,25 +239,17 @@ class Poll extends ImmutablePureComponent { option={option} index={i} showResults={showResults} - disabled={disabled} active={!!this.state.selected[i]} onToggle={this.toggleOption} /> ))} -
- {!showResults && } - - {showResults && !this.props.disabled && ( - · - )} - - {poll.expires_at && · {timeRemaining}} - -
+
); }