Merge branch 'more-poll-fixes' into 'develop'

More poll normalization fixes

See merge request soapbox-pub/soapbox-fe!1090
This commit is contained in:
Alex Gleason 2022-03-10 22:37:18 +00:00
commit 4c2d9a8856
5 changed files with 45 additions and 19 deletions

View file

@ -12,7 +12,6 @@ import { vote, fetchPoll } from 'soapbox/actions/polls';
import Icon from 'soapbox/components/icon';
import emojify from 'soapbox/features/emoji/emoji';
import Motion from 'soapbox/features/ui/util/optional_motion';
import SoapboxPropTypes from 'soapbox/utils/soapbox_prop_types';
import RelativeTimestamp from './relative_timestamp';
@ -35,7 +34,6 @@ class Poll extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
dispatch: PropTypes.func,
disabled: PropTypes.bool,
me: SoapboxPropTypes.me,
status: PropTypes.string,
};
@ -105,7 +103,7 @@ class Poll extends ImmutablePureComponent {
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 voted = option.get('voted') || (poll.get('own_votes') && poll.get('own_votes').includes(optionIndex));
const voted = poll.own_votes?.includes(optionIndex);
let titleEmojified = option.get('title_emojified');
if (!titleEmojified) {
@ -156,7 +154,7 @@ class Poll extends ImmutablePureComponent {
}
render() {
const { me, poll, intl } = this.props;
const { poll, intl } = this.props;
if (!poll) {
return null;
@ -165,7 +163,7 @@ class Poll extends ImmutablePureComponent {
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 disabled = this.props.disabled || Object.entries(this.state.selected).every(item => !item);
const voted = me && poll.get('own_votes').size > 0;
const voted = poll.voted;
return (
<div className={classNames('poll', { voted })}>

View file

@ -4,7 +4,6 @@ import Poll from 'soapbox/components/poll';
const mapStateToProps = (state, { pollId }) => ({
poll: state.getIn(['polls', pollId]),
me: state.get('me'),
});

View file

@ -147,7 +147,7 @@ describe('normalizeStatus', () => {
multiple: false,
voters_count: 0,
votes_count: 0,
own_votes: [],
own_votes: null,
voted: false,
};
@ -163,6 +163,6 @@ describe('normalizeStatus', () => {
// Adds logged-in fields
expect(result.poll.voted).toBe(false);
expect(result.poll.own_votes).toEqual(fromJS([]));
expect(result.poll.own_votes).toBe(null);
});
});

View file

@ -57,11 +57,12 @@ const PollRecord = ImmutableRecord({
emojis: ImmutableList(),
expired: false,
expires_at: new Date(),
id: '',
multiple: false,
options: ImmutableList(),
voters_count: 0,
votes_count: 0,
own_votes: ImmutableList(),
own_votes: null,
voted: false,
});
@ -106,14 +107,42 @@ const normalizeMentions = (status: ImmutableMap<string, any>) => {
});
};
// Normalize poll
const normalizePoll = (status: ImmutableMap<string, any>) => {
if (status.hasIn(['poll', 'options'])) {
return status.update('poll', ImmutableMap(), poll => {
return PollRecord(poll).update('options', (options: ImmutableList<ImmutableMap<string, any>>) => {
// Normalize poll options
const normalizePollOptions = (poll: ImmutableMap<string, any>) => {
return poll.update('options', (options: ImmutableList<ImmutableMap<string, any>>) => {
return options.map(PollOptionRecord);
});
};
// Normalize own_votes to `null` if empty (like Mastodon)
const normalizePollOwnVotes = (poll: ImmutableMap<string, any>) => {
return poll.update('own_votes', ownVotes => {
return ownVotes?.size > 0 ? ownVotes : null;
});
};
// Whether the user voted in the poll
const normalizePollVoted = (poll: ImmutableMap<string, any>) => {
return poll.update('voted', voted => {
return typeof voted === 'boolean' ? voted : poll.get('own_votes')?.size > 0;
});
};
// Normalize the actual poll
const normalizePoll = (poll: ImmutableMap<string, any>) => {
return PollRecord(
poll.withMutations((poll: ImmutableMap<string, any>) => {
normalizePollOptions(poll);
normalizePollOwnVotes(poll);
normalizePollVoted(poll);
}),
);
};
// Normalize the poll in the status, if applicable
const normalizeStatusPoll = (status: ImmutableMap<string, any>) => {
if (status.hasIn(['poll', 'options'])) {
return status.update('poll', ImmutableMap(), normalizePoll);
} else {
return status.set('poll', null);
}
@ -161,12 +190,12 @@ const fixQuote = (status: ImmutableMap<string, any>) => {
});
};
export const normalizeStatus = (status: ImmutableMap<any, string>): IStatus => {
export const normalizeStatus = (status: ImmutableMap<string, any>): IStatus => {
return StatusRecord(
status.withMutations(status => {
normalizeAttachments(status);
normalizeMentions(status);
normalizePoll(status);
normalizeStatusPoll(status);
fixMentionsOrder(status);
addSelfMention(status);
fixQuote(status);

View file

@ -24,7 +24,7 @@ describe('polls reducer', () => {
multiple: false,
voters_count: 0,
votes_count: 0,
own_votes: [],
own_votes: null,
voted: false,
},
};