Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 14 additions & 19 deletions src/components/views/messages/MPollBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,10 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
constructor(props: IBodyProps) {
super(props);

const pollRelations = this.fetchPollRelations();
let selected = null;

const userVotes = collectUserVotes(allVotes(pollRelations), null);
const userId = MatrixClientPeg.get().getUserId();
const currentVote = userVotes.get(userId);
if (currentVote) {
selected = currentVote.answers[0];
}

this.state = { selected, pollRelations };
this.state = {
selected: null,
pollRelations: this.fetchPollRelations(),
};

this.addListeners(this.state.pollRelations);
this.props.mxEvent.on("Event.relationsCreated", this.onPollRelationsCreated);
Expand Down Expand Up @@ -145,12 +138,11 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
}

/**
* @returns answer-id -> number-of-votes
* @returns userId -> UserVote
*/
private collectVotes(): Map<string, number> {
return countVotes(
collectUserVotes(allVotes(this.state.pollRelations), this.state.selected),
this.props.mxEvent.getContent(),
private collectUserVotes(): Map<string, UserVote> {
return collectUserVotes(
allVotes(this.state.pollRelations), this.state.selected,
);
}

Expand All @@ -171,15 +163,18 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
}

const pollId = this.props.mxEvent.getId();
const votes = this.collectVotes();
const userVotes = this.collectUserVotes();
const votes = countVotes(userVotes, this.props.mxEvent.getContent());
const totalVotes = this.totalVotes(votes);
const userId = MatrixClientPeg.get().getUserId();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use a MatrixClientContext here instead of MatrixClientPeg?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like 17b726c ? I've never used this before so please check I did it right :-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! This way will make any future transitions to a multi-account world much easier, thanks!

const myVote = userVotes.get(userId)?.answers[0];

return <div className="mx_MPollBody">
<h2>{ pollInfo.question[TEXT_NODE_TYPE] }</h2>
<div className="mx_MPollBody_allOptions">
{
pollInfo.answers.map((answer: IPollAnswer) => {
const checked = this.state.selected === answer.id;
const checked = myVote === answer.id;
const classNames = `mx_MPollBody_option${
checked ? " mx_MPollBody_option_checked": ""
}`;
Expand All @@ -194,7 +189,7 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
<StyledRadioButton
name={`poll_answer_select-${pollId}`}
value={answer.id}
checked={this.state.selected === answer.id}
checked={checked}
onChange={this.onOptionSelected}
>
<div className="mx_MPollBody_optionDescription">
Expand Down
27 changes: 27 additions & 0 deletions test/components/views/messages/MPollBody-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import { IPollAnswer, IPollContent } from "../../../../src/polls/consts";
import { UserVote, allVotes } from "../../../../src/components/views/messages/MPollBody";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";

const CHECKED = "mx_MPollBody_option_checked";

const _MPollBody = sdk.getComponent("views.messages.MPollBody");
const MPollBody = TestUtils.wrapInMatrixClientContext(_MPollBody);

Expand Down Expand Up @@ -142,6 +144,25 @@ describe("MPollBody", () => {
expect(votesCount(body, "wings")).toBe("1 vote");

expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 2 votes");

// And my vote is highlighted
expect(voteButton(body, "wings").hasClass(CHECKED)).toBe(true);
expect(voteButton(body, "italian").hasClass(CHECKED)).toBe(false);
});

it("highlights my vote even if I did it on another device", () => {
// Given I voted italian
const votes = [
responseEvent("@me:example.com", "italian"),
responseEvent("@nf:example.com", "wings"),
];
const body = newMPollBody(votes);

// But I didn't click anything locally

// Then my vote is highlighted, and others are not
expect(voteButton(body, "italian").hasClass(CHECKED)).toBe(true);
expect(voteButton(body, "wings").hasClass(CHECKED)).toBe(false);
});

it("ignores extra answers", () => {
Expand Down Expand Up @@ -380,6 +401,12 @@ function clickRadio(wrapper: ReactWrapper, value: string) {
wrapper.find(`StyledRadioButton[value="${value}"]`).simulate("click");
}

function voteButton(wrapper: ReactWrapper, value: string): ReactWrapper {
return wrapper.find(
`div.mx_MPollBody_option`,
).findWhere(w => w.key() === value);
}

function votesCount(wrapper: ReactWrapper, value: string): string {
return wrapper.find(
`StyledRadioButton[value="${value}"] .mx_MPollBody_optionVoteCount`,
Expand Down