Move all polls processing to events-sdk & prep for stable polls (#7517)
* Move all polls processing to events-sdk This makes polls support the full range of extensible events (both parsing and generation). * Appease the linter * Fix & update tests * Update events-sdk for polls bugfix * Update events-sdk for typechecking * Add missing type cast * Update per review
This commit is contained in:
parent
12e967a97c
commit
65987e6b72
17 changed files with 727 additions and 299 deletions
|
@ -89,7 +89,7 @@
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"maplibre-gl": "^1.15.2",
|
"maplibre-gl": "^1.15.2",
|
||||||
"matrix-analytics-events": "https://github.com/matrix-org/matrix-analytics-events.git#1eab4356548c97722a183912fda1ceabbe8cc7c1",
|
"matrix-analytics-events": "https://github.com/matrix-org/matrix-analytics-events.git#1eab4356548c97722a183912fda1ceabbe8cc7c1",
|
||||||
"matrix-events-sdk": "^0.0.1-beta.2",
|
"matrix-events-sdk": "^0.0.1-beta.6",
|
||||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||||
"matrix-widget-api": "^0.1.0-beta.18",
|
"matrix-widget-api": "^0.1.0-beta.18",
|
||||||
"minimist": "^1.2.5",
|
"minimist": "^1.2.5",
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { removeDirectionOverrideChars } from 'matrix-js-sdk/src/utils';
|
import { removeDirectionOverrideChars } from 'matrix-js-sdk/src/utils';
|
||||||
import { GuestAccess, HistoryVisibility, JoinRule } from "matrix-js-sdk/src/@types/partials";
|
import { GuestAccess, HistoryVisibility, JoinRule } from "matrix-js-sdk/src/@types/partials";
|
||||||
import { EventType, MsgType } from "matrix-js-sdk/src/@types/event";
|
import { EventType, MsgType } from "matrix-js-sdk/src/@types/event";
|
||||||
import { EmoteEvent, NoticeEvent, MessageEvent } from "matrix-events-sdk";
|
import { M_EMOTE, M_NOTICE, M_MESSAGE, MessageEvent } from "matrix-events-sdk";
|
||||||
|
|
||||||
import { _t } from './languageHandler';
|
import { _t } from './languageHandler';
|
||||||
import * as Roles from './Roles';
|
import * as Roles from './Roles';
|
||||||
|
@ -342,11 +342,11 @@ function textForMessageEvent(ev: MatrixEvent): () => string | null {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SettingsStore.isEnabled("feature_extensible_events")) {
|
if (SettingsStore.isEnabled("feature_extensible_events")) {
|
||||||
const extev = ev.unstableExtensibleEvent;
|
const extev = ev.unstableExtensibleEvent as MessageEvent;
|
||||||
if (extev) {
|
if (extev) {
|
||||||
if (extev instanceof EmoteEvent) {
|
if (extev.isEquivalentTo(M_EMOTE)) {
|
||||||
return `* ${senderDisplayName} ${extev.text}`;
|
return `* ${senderDisplayName} ${extev.text}`;
|
||||||
} else if (extev instanceof NoticeEvent || extev instanceof MessageEvent) {
|
} else if (extev.isEquivalentTo(M_NOTICE) || extev.isEquivalentTo(M_MESSAGE)) {
|
||||||
return `${senderDisplayName}: ${extev.text}`;
|
return `${senderDisplayName}: ${extev.text}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@ import React, { ReactElement } from 'react';
|
||||||
import { EventStatus, MatrixEvent } from 'matrix-js-sdk/src/models/event';
|
import { EventStatus, MatrixEvent } from 'matrix-js-sdk/src/models/event';
|
||||||
import { EventType, RelationType } from "matrix-js-sdk/src/@types/event";
|
import { EventType, RelationType } from "matrix-js-sdk/src/@types/event";
|
||||||
import { Relations } from 'matrix-js-sdk/src/models/relations';
|
import { Relations } from 'matrix-js-sdk/src/models/relations';
|
||||||
import { POLL_START_EVENT_TYPE } from "matrix-js-sdk/src/@types/polls";
|
|
||||||
import { LOCATION_EVENT_TYPE } from 'matrix-js-sdk/src/@types/location';
|
import { LOCATION_EVENT_TYPE } from 'matrix-js-sdk/src/@types/location';
|
||||||
|
import { M_POLL_START } from "matrix-events-sdk";
|
||||||
|
|
||||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||||
import dis from '../../../dispatcher/dispatcher';
|
import dis from '../../../dispatcher/dispatcher';
|
||||||
|
@ -140,7 +140,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||||
|
|
||||||
private canEndPoll(mxEvent: MatrixEvent): boolean {
|
private canEndPoll(mxEvent: MatrixEvent): boolean {
|
||||||
return (
|
return (
|
||||||
POLL_START_EVENT_TYPE.matches(mxEvent.getType()) &&
|
M_POLL_START.matches(mxEvent.getType()) &&
|
||||||
this.state.canRedact &&
|
this.state.canRedact &&
|
||||||
!isPollEnded(mxEvent, MatrixClientPeg.get(), this.props.getRelationsForEvent)
|
!isPollEnded(mxEvent, MatrixClientPeg.get(), this.props.getRelationsForEvent)
|
||||||
);
|
);
|
||||||
|
|
|
@ -18,8 +18,7 @@ import React from "react";
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
import { Relations } from "matrix-js-sdk/src/models/relations";
|
import { Relations } from "matrix-js-sdk/src/models/relations";
|
||||||
import { IPollEndContent, POLL_END_EVENT_TYPE } from "matrix-js-sdk/src/@types/polls";
|
import { PollEndEvent } from "matrix-events-sdk";
|
||||||
import { TEXT_NODE_TYPE } from "matrix-js-sdk/src/@types/extensible_events";
|
|
||||||
|
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
import { IDialogProps } from "./IDialogProps";
|
import { IDialogProps } from "./IDialogProps";
|
||||||
|
@ -57,17 +56,10 @@ export default class EndPollDialog extends React.Component<IProps> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (endPoll) {
|
if (endPoll) {
|
||||||
const endContent: IPollEndContent = {
|
const endEvent = PollEndEvent.from(this.props.event.getId(), message).serialize();
|
||||||
[POLL_END_EVENT_TYPE.name]: {},
|
|
||||||
"m.relates_to": {
|
|
||||||
"event_id": this.props.event.getId(),
|
|
||||||
"rel_type": "m.reference",
|
|
||||||
},
|
|
||||||
[TEXT_NODE_TYPE.name]: message,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.props.matrixClient.sendEvent(
|
this.props.matrixClient.sendEvent(
|
||||||
this.props.event.getRoomId(), POLL_END_EVENT_TYPE.name, endContent,
|
this.props.event.getRoomId(), endEvent.type, endEvent.content,
|
||||||
).catch((e: any) => {
|
).catch((e: any) => {
|
||||||
console.error("Failed to submit poll response event:", e);
|
console.error("Failed to submit poll response event:", e);
|
||||||
Modal.createTrackedDialog(
|
Modal.createTrackedDialog(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
Copyright 2021 - 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -16,8 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import React, { ChangeEvent, createRef } from "react";
|
import React, { ChangeEvent, createRef } from "react";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { makePollContent } from "matrix-js-sdk/src/content-helpers";
|
import { M_POLL_KIND_DISCLOSED, PollStartEvent } from "matrix-events-sdk";
|
||||||
import { POLL_KIND_DISCLOSED, POLL_START_EVENT_TYPE } from "matrix-js-sdk/src/@types/polls";
|
|
||||||
|
|
||||||
import ScrollableBaseModal, { IScrollableBaseState } from "../dialogs/ScrollableBaseModal";
|
import ScrollableBaseModal, { IScrollableBaseState } from "../dialogs/ScrollableBaseModal";
|
||||||
import { IDialogProps } from "../dialogs/IDialogProps";
|
import { IDialogProps } from "../dialogs/IDialogProps";
|
||||||
|
@ -99,13 +98,12 @@ export default class PollCreateDialog extends ScrollableBaseModal<IProps, IState
|
||||||
|
|
||||||
protected submit(): void {
|
protected submit(): void {
|
||||||
this.setState({ busy: true, canSubmit: false });
|
this.setState({ busy: true, canSubmit: false });
|
||||||
this.matrixClient.sendEvent(
|
const pollEvent = PollStartEvent.from(
|
||||||
this.props.room.roomId,
|
this.state.question.trim(),
|
||||||
POLL_START_EVENT_TYPE.name,
|
this.state.options.map(a => a.trim()).filter(a => !!a),
|
||||||
makePollContent(
|
M_POLL_KIND_DISCLOSED,
|
||||||
this.state.question, this.state.options, POLL_KIND_DISCLOSED.name,
|
).serialize();
|
||||||
),
|
this.matrixClient.sendEvent(this.props.room.roomId, pollEvent.type, pollEvent.content).then(
|
||||||
).then(
|
|
||||||
() => this.props.onFinished(true),
|
() => this.props.onFinished(true),
|
||||||
).catch(e => {
|
).catch(e => {
|
||||||
console.error("Failed to post poll:", e);
|
console.error("Failed to post poll:", e);
|
||||||
|
|
|
@ -19,15 +19,16 @@ import classNames from 'classnames';
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
import { Relations } from 'matrix-js-sdk/src/models/relations';
|
import { Relations } from 'matrix-js-sdk/src/models/relations';
|
||||||
import { MatrixClient } from 'matrix-js-sdk/src/matrix';
|
import { MatrixClient } from 'matrix-js-sdk/src/matrix';
|
||||||
import { TEXT_NODE_TYPE } from "matrix-js-sdk/src/@types/extensible_events";
|
|
||||||
import {
|
import {
|
||||||
IPollAnswer,
|
M_POLL_END,
|
||||||
IPollContent,
|
M_POLL_RESPONSE,
|
||||||
IPollResponseContent,
|
M_POLL_START,
|
||||||
POLL_END_EVENT_TYPE,
|
NamespacedValue,
|
||||||
POLL_RESPONSE_EVENT_TYPE,
|
PollAnswerSubevent,
|
||||||
POLL_START_EVENT_TYPE,
|
PollResponseEvent,
|
||||||
} from "matrix-js-sdk/src/@types/polls";
|
PollStartEvent,
|
||||||
|
} from "matrix-events-sdk";
|
||||||
|
import { RelatedRelations } from "matrix-js-sdk/src/models/related-relations";
|
||||||
|
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
|
@ -40,8 +41,8 @@ import ErrorDialog from '../dialogs/ErrorDialog';
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
selected?: string; // Which option was clicked by the local user
|
selected?: string; // Which option was clicked by the local user
|
||||||
voteRelations: Relations; // Voting (response) events
|
voteRelations: RelatedRelations; // Voting (response) events
|
||||||
endRelations: Relations; // Poll end events
|
endRelations: RelatedRelations; // Poll end events
|
||||||
}
|
}
|
||||||
|
|
||||||
export function findTopAnswer(
|
export function findTopAnswer(
|
||||||
|
@ -57,28 +58,41 @@ export function findTopAnswer(
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const pollContents: IPollContent = pollEvent.getContent();
|
const poll = pollEvent.unstableExtensibleEvent as PollStartEvent;
|
||||||
|
if (!poll?.isEquivalentTo(M_POLL_START)) {
|
||||||
|
console.warn("Failed to parse poll to determine top answer - assuming no best answer");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
const findAnswerText = (answerId: string) => {
|
const findAnswerText = (answerId: string) => {
|
||||||
for (const answer of pollContents[POLL_START_EVENT_TYPE.name].answers) {
|
return poll.answers.find(a => a.id === answerId)?.text ?? "";
|
||||||
if (answer.id == answerId) {
|
|
||||||
return answer[TEXT_NODE_TYPE.name];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const voteRelations: Relations = getRelationsForEvent(
|
const voteRelations = new RelatedRelations([
|
||||||
pollEvent.getId(),
|
getRelationsForEvent(
|
||||||
"m.reference",
|
pollEvent.getId(),
|
||||||
POLL_RESPONSE_EVENT_TYPE.name,
|
"m.reference",
|
||||||
);
|
M_POLL_RESPONSE.name,
|
||||||
|
),
|
||||||
|
getRelationsForEvent(
|
||||||
|
pollEvent.getId(),
|
||||||
|
"m.reference",
|
||||||
|
M_POLL_RESPONSE.altName,
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
const endRelations: Relations = getRelationsForEvent(
|
const endRelations = new RelatedRelations([
|
||||||
pollEvent.getId(),
|
getRelationsForEvent(
|
||||||
"m.reference",
|
pollEvent.getId(),
|
||||||
POLL_END_EVENT_TYPE.name,
|
"m.reference",
|
||||||
);
|
M_POLL_END.name,
|
||||||
|
),
|
||||||
|
getRelationsForEvent(
|
||||||
|
pollEvent.getId(),
|
||||||
|
"m.reference",
|
||||||
|
M_POLL_END.altName,
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
const userVotes: Map<string, UserVote> = collectUserVotes(
|
const userVotes: Map<string, UserVote> = collectUserVotes(
|
||||||
allVotes(pollEvent, matrixClient, voteRelations, endRelations),
|
allVotes(pollEvent, matrixClient, voteRelations, endRelations),
|
||||||
|
@ -86,7 +100,7 @@ export function findTopAnswer(
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
const votes: Map<string, number> = countVotes(userVotes, pollEvent.getContent());
|
const votes: Map<string, number> = countVotes(userVotes, poll);
|
||||||
const highestScore: number = Math.max(...votes.values());
|
const highestScore: number = Math.max(...votes.values());
|
||||||
|
|
||||||
const bestAnswerIds: string[] = [];
|
const bestAnswerIds: string[] = [];
|
||||||
|
@ -122,11 +136,18 @@ export function isPollEnded(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const endRelations = getRelationsForEvent(
|
const endRelations = new RelatedRelations([
|
||||||
pollEvent.getId(),
|
getRelationsForEvent(
|
||||||
"m.reference",
|
pollEvent.getId(),
|
||||||
POLL_END_EVENT_TYPE.name,
|
"m.reference",
|
||||||
);
|
M_POLL_END.name,
|
||||||
|
),
|
||||||
|
getRelationsForEvent(
|
||||||
|
pollEvent.getId(),
|
||||||
|
"m.reference",
|
||||||
|
M_POLL_END.altName,
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
if (!endRelations) {
|
if (!endRelations) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -163,7 +184,7 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
||||||
this.removeListeners(this.state.voteRelations, this.state.endRelations);
|
this.removeListeners(this.state.voteRelations, this.state.endRelations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private addListeners(voteRelations?: Relations, endRelations?: Relations) {
|
private addListeners(voteRelations?: RelatedRelations, endRelations?: RelatedRelations) {
|
||||||
if (voteRelations) {
|
if (voteRelations) {
|
||||||
voteRelations.on("Relations.add", this.onRelationsChange);
|
voteRelations.on("Relations.add", this.onRelationsChange);
|
||||||
voteRelations.on("Relations.remove", this.onRelationsChange);
|
voteRelations.on("Relations.remove", this.onRelationsChange);
|
||||||
|
@ -176,7 +197,7 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private removeListeners(voteRelations?: Relations, endRelations?: Relations) {
|
private removeListeners(voteRelations?: RelatedRelations, endRelations?: RelatedRelations) {
|
||||||
if (voteRelations) {
|
if (voteRelations) {
|
||||||
voteRelations.off("Relations.add", this.onRelationsChange);
|
voteRelations.off("Relations.add", this.onRelationsChange);
|
||||||
voteRelations.off("Relations.remove", this.onRelationsChange);
|
voteRelations.off("Relations.remove", this.onRelationsChange);
|
||||||
|
@ -194,13 +215,13 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (POLL_RESPONSE_EVENT_TYPE.matches(eventType)) {
|
if (M_POLL_RESPONSE.matches(eventType)) {
|
||||||
this.voteRelationsReceived = true;
|
this.voteRelationsReceived = true;
|
||||||
const newVoteRelations = this.fetchVoteRelations();
|
const newVoteRelations = this.fetchVoteRelations();
|
||||||
this.addListeners(newVoteRelations);
|
this.addListeners(newVoteRelations);
|
||||||
this.removeListeners(this.state.voteRelations);
|
this.removeListeners(this.state.voteRelations);
|
||||||
this.setState({ voteRelations: newVoteRelations });
|
this.setState({ voteRelations: newVoteRelations });
|
||||||
} else if (POLL_END_EVENT_TYPE.matches(eventType)) {
|
} else if (M_POLL_END.matches(eventType)) {
|
||||||
this.endRelationsReceived = true;
|
this.endRelationsReceived = true;
|
||||||
const newEndRelations = this.fetchEndRelations();
|
const newEndRelations = this.fetchEndRelations();
|
||||||
this.addListeners(newEndRelations);
|
this.addListeners(newEndRelations);
|
||||||
|
@ -233,20 +254,12 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const responseContent: IPollResponseContent = {
|
const response = PollResponseEvent.from([answerId], this.props.mxEvent.getId()).serialize();
|
||||||
[POLL_RESPONSE_EVENT_TYPE.name]: {
|
|
||||||
"answers": [answerId],
|
|
||||||
},
|
|
||||||
"m.relates_to": {
|
|
||||||
"event_id": this.props.mxEvent.getId(),
|
|
||||||
"rel_type": "m.reference",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
this.context.sendEvent(
|
this.context.sendEvent(
|
||||||
this.props.mxEvent.getRoomId(),
|
this.props.mxEvent.getRoomId(),
|
||||||
POLL_RESPONSE_EVENT_TYPE.name,
|
response.type,
|
||||||
responseContent,
|
response.content,
|
||||||
).catch((e: any) => {
|
).catch((e: any) => {
|
||||||
console.error("Failed to submit poll response event:", e);
|
console.error("Failed to submit poll response event:", e);
|
||||||
|
|
||||||
|
@ -269,21 +282,28 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
||||||
this.selectOption(e.currentTarget.value);
|
this.selectOption(e.currentTarget.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
private fetchVoteRelations(): Relations | null {
|
private fetchVoteRelations(): RelatedRelations | null {
|
||||||
return this.fetchRelations(POLL_RESPONSE_EVENT_TYPE.name);
|
return this.fetchRelations(M_POLL_RESPONSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private fetchEndRelations(): Relations | null {
|
private fetchEndRelations(): RelatedRelations | null {
|
||||||
return this.fetchRelations(POLL_END_EVENT_TYPE.name);
|
return this.fetchRelations(M_POLL_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
private fetchRelations(eventType: string): Relations | null {
|
private fetchRelations(eventType: NamespacedValue<string, string>): RelatedRelations | null {
|
||||||
if (this.props.getRelationsForEvent) {
|
if (this.props.getRelationsForEvent) {
|
||||||
return this.props.getRelationsForEvent(
|
return new RelatedRelations([
|
||||||
this.props.mxEvent.getId(),
|
this.props.getRelationsForEvent(
|
||||||
"m.reference",
|
this.props.mxEvent.getId(),
|
||||||
eventType,
|
"m.reference",
|
||||||
);
|
eventType.name,
|
||||||
|
),
|
||||||
|
this.props.getRelationsForEvent(
|
||||||
|
this.props.mxEvent.getId(),
|
||||||
|
"m.reference",
|
||||||
|
eventType.altName,
|
||||||
|
),
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -349,17 +369,13 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const pollStart: IPollContent = this.props.mxEvent.getContent();
|
const poll = this.props.mxEvent.unstableExtensibleEvent as PollStartEvent;
|
||||||
const pollInfo = pollStart[POLL_START_EVENT_TYPE.name];
|
if (!poll?.isEquivalentTo(M_POLL_START)) return null; // invalid
|
||||||
|
|
||||||
if (pollInfo.answers.length < 1 || pollInfo.answers.length > 20) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ended = this.isEnded();
|
const ended = this.isEnded();
|
||||||
const pollId = this.props.mxEvent.getId();
|
const pollId = this.props.mxEvent.getId();
|
||||||
const userVotes = this.collectUserVotes();
|
const userVotes = this.collectUserVotes();
|
||||||
const votes = countVotes(userVotes, this.props.mxEvent.getContent());
|
const votes = countVotes(userVotes, poll);
|
||||||
const totalVotes = this.totalVotes(votes);
|
const totalVotes = this.totalVotes(votes);
|
||||||
const winCount = Math.max(...votes.values());
|
const winCount = Math.max(...votes.values());
|
||||||
const userId = this.context.getUserId();
|
const userId = this.context.getUserId();
|
||||||
|
@ -385,10 +401,10 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div className="mx_MPollBody">
|
return <div className="mx_MPollBody">
|
||||||
<h2>{ pollInfo.question[TEXT_NODE_TYPE.name] }</h2>
|
<h2>{ poll.question.text }</h2>
|
||||||
<div className="mx_MPollBody_allOptions">
|
<div className="mx_MPollBody_allOptions">
|
||||||
{
|
{
|
||||||
pollInfo.answers.map((answer: IPollAnswer) => {
|
poll.answers.map((answer: PollAnswerSubevent) => {
|
||||||
let answerVotes = 0;
|
let answerVotes = 0;
|
||||||
let votesText = "";
|
let votesText = "";
|
||||||
|
|
||||||
|
@ -448,7 +464,7 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IEndedPollOptionProps {
|
interface IEndedPollOptionProps {
|
||||||
answer: IPollAnswer;
|
answer: PollAnswerSubevent;
|
||||||
checked: boolean;
|
checked: boolean;
|
||||||
votesText: string;
|
votesText: string;
|
||||||
}
|
}
|
||||||
|
@ -461,7 +477,7 @@ function EndedPollOption(props: IEndedPollOptionProps) {
|
||||||
return <div className={cls} data-value={props.answer.id}>
|
return <div className={cls} data-value={props.answer.id}>
|
||||||
<div className="mx_MPollBody_optionDescription">
|
<div className="mx_MPollBody_optionDescription">
|
||||||
<div className="mx_MPollBody_optionText">
|
<div className="mx_MPollBody_optionText">
|
||||||
{ props.answer[TEXT_NODE_TYPE.name] }
|
{ props.answer.text }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_MPollBody_optionVoteCount">
|
<div className="mx_MPollBody_optionVoteCount">
|
||||||
{ props.votesText }
|
{ props.votesText }
|
||||||
|
@ -472,7 +488,7 @@ function EndedPollOption(props: IEndedPollOptionProps) {
|
||||||
|
|
||||||
interface ILivePollOptionProps {
|
interface ILivePollOptionProps {
|
||||||
pollId: string;
|
pollId: string;
|
||||||
answer: IPollAnswer;
|
answer: PollAnswerSubevent;
|
||||||
checked: boolean;
|
checked: boolean;
|
||||||
votesText: string;
|
votesText: string;
|
||||||
onOptionSelected: (e: React.FormEvent<HTMLInputElement>) => void;
|
onOptionSelected: (e: React.FormEvent<HTMLInputElement>) => void;
|
||||||
|
@ -487,7 +503,7 @@ function LivePollOption(props: ILivePollOptionProps) {
|
||||||
>
|
>
|
||||||
<div className="mx_MPollBody_optionDescription">
|
<div className="mx_MPollBody_optionDescription">
|
||||||
<div className="mx_MPollBody_optionText">
|
<div className="mx_MPollBody_optionText">
|
||||||
{ props.answer[TEXT_NODE_TYPE.name] }
|
{ props.answer.text }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_MPollBody_optionVoteCount">
|
<div className="mx_MPollBody_optionVoteCount">
|
||||||
{ props.votesText }
|
{ props.votesText }
|
||||||
|
@ -502,21 +518,23 @@ export class UserVote {
|
||||||
}
|
}
|
||||||
|
|
||||||
function userResponseFromPollResponseEvent(event: MatrixEvent): UserVote {
|
function userResponseFromPollResponseEvent(event: MatrixEvent): UserVote {
|
||||||
const pr = event.getContent() as IPollResponseContent;
|
const response = event.unstableExtensibleEvent as PollResponseEvent;
|
||||||
const answers = pr[POLL_RESPONSE_EVENT_TYPE.name].answers;
|
if (!response?.isEquivalentTo(M_POLL_RESPONSE)) {
|
||||||
|
throw new Error("Failed to parse Poll Response Event to determine user response");
|
||||||
|
}
|
||||||
|
|
||||||
return new UserVote(
|
return new UserVote(
|
||||||
event.getTs(),
|
event.getTs(),
|
||||||
event.getSender(),
|
event.getSender(),
|
||||||
answers,
|
response.answerIds,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function allVotes(
|
export function allVotes(
|
||||||
pollEvent: MatrixEvent,
|
pollEvent: MatrixEvent,
|
||||||
matrixClient: MatrixClient,
|
matrixClient: MatrixClient,
|
||||||
voteRelations: Relations,
|
voteRelations: RelatedRelations,
|
||||||
endRelations: Relations,
|
endRelations: RelatedRelations,
|
||||||
): Array<UserVote> {
|
): Array<UserVote> {
|
||||||
const endTs = pollEndTs(pollEvent, matrixClient, endRelations);
|
const endTs = pollEndTs(pollEvent, matrixClient, endRelations);
|
||||||
|
|
||||||
|
@ -546,7 +564,7 @@ export function allVotes(
|
||||||
export function pollEndTs(
|
export function pollEndTs(
|
||||||
pollEvent: MatrixEvent,
|
pollEvent: MatrixEvent,
|
||||||
matrixClient: MatrixClient,
|
matrixClient: MatrixClient,
|
||||||
endRelations: Relations,
|
endRelations: RelatedRelations,
|
||||||
): number | null {
|
): number | null {
|
||||||
if (!endRelations) {
|
if (!endRelations) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -575,10 +593,7 @@ export function pollEndTs(
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPollResponse(responseEvent: MatrixEvent): boolean {
|
function isPollResponse(responseEvent: MatrixEvent): boolean {
|
||||||
return (
|
return responseEvent.unstableExtensibleEvent?.isEquivalentTo(M_POLL_RESPONSE);
|
||||||
POLL_RESPONSE_EVENT_TYPE.matches(responseEvent.getType()) &&
|
|
||||||
POLL_RESPONSE_EVENT_TYPE.findIn(responseEvent.getContent())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -608,24 +623,15 @@ function collectUserVotes(
|
||||||
|
|
||||||
function countVotes(
|
function countVotes(
|
||||||
userVotes: Map<string, UserVote>,
|
userVotes: Map<string, UserVote>,
|
||||||
pollStart: IPollContent,
|
pollStart: PollStartEvent,
|
||||||
): Map<string, number> {
|
): Map<string, number> {
|
||||||
const collected = new Map<string, number>();
|
const collected = new Map<string, number>();
|
||||||
|
|
||||||
const pollInfo = pollStart[POLL_START_EVENT_TYPE.name];
|
|
||||||
const maxSelections = 1; // See MSC3381 - later this will be in pollInfo
|
|
||||||
|
|
||||||
const allowedAnswerIds = pollInfo.answers.map((ans: IPollAnswer) => ans.id);
|
|
||||||
function isValidAnswer(answerId: string) {
|
|
||||||
return allowedAnswerIds.includes(answerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const response of userVotes.values()) {
|
for (const response of userVotes.values()) {
|
||||||
if (response.answers.every(isValidAnswer)) {
|
const tempResponse = PollResponseEvent.from(response.answers, "$irrelevant");
|
||||||
for (const [index, answerId] of response.answers.entries()) {
|
tempResponse.validateAgainst(pollStart);
|
||||||
if (index >= maxSelections) {
|
if (!tempResponse.spoiled) {
|
||||||
break;
|
for (const answerId of tempResponse.answerIds) {
|
||||||
}
|
|
||||||
if (collected.has(answerId)) {
|
if (collected.has(answerId)) {
|
||||||
collected.set(answerId, collected.get(answerId) + 1);
|
collected.set(answerId, collected.get(answerId) + 1);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -17,8 +17,8 @@ limitations under the License.
|
||||||
import React, { createRef } from 'react';
|
import React, { createRef } from 'react';
|
||||||
import { EventType, MsgType } from "matrix-js-sdk/src/@types/event";
|
import { EventType, MsgType } from "matrix-js-sdk/src/@types/event";
|
||||||
import { Relations } from 'matrix-js-sdk/src/models/relations';
|
import { Relations } from 'matrix-js-sdk/src/models/relations';
|
||||||
import { POLL_START_EVENT_TYPE } from "matrix-js-sdk/src/@types/polls";
|
|
||||||
import { LOCATION_EVENT_TYPE } from 'matrix-js-sdk/src/@types/location';
|
import { LOCATION_EVENT_TYPE } from 'matrix-js-sdk/src/@types/location';
|
||||||
|
import { M_POLL_START } from "matrix-events-sdk";
|
||||||
|
|
||||||
import * as sdk from '../../../index';
|
import * as sdk from '../../../index';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
@ -125,7 +125,7 @@ export default class MessageEvent extends React.Component<IProps> implements IMe
|
||||||
BodyType = UnknownBody;
|
BodyType = UnknownBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type && type === POLL_START_EVENT_TYPE.name) {
|
if (M_POLL_START.matches(type)) {
|
||||||
// TODO: this can all disappear when Polls comes out of labs -
|
// TODO: this can all disappear when Polls comes out of labs -
|
||||||
// instead, add something like this into this.evTypes:
|
// instead, add something like this into this.evTypes:
|
||||||
// [EventType.Poll]: "messages.MPollBody"
|
// [EventType.Poll]: "messages.MPollBody"
|
||||||
|
|
|
@ -18,7 +18,7 @@ import React, { createRef, SyntheticEvent } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import highlight from 'highlight.js';
|
import highlight from 'highlight.js';
|
||||||
import { MsgType } from "matrix-js-sdk/src/@types/event";
|
import { MsgType } from "matrix-js-sdk/src/@types/event";
|
||||||
import { isEventLike, LegacyMsgType, MessageEvent } from "matrix-events-sdk";
|
import { isEventLike, LegacyMsgType, M_MESSAGE, MessageEvent } from "matrix-events-sdk";
|
||||||
|
|
||||||
import * as HtmlUtils from '../../../HtmlUtils';
|
import * as HtmlUtils from '../../../HtmlUtils';
|
||||||
import { formatDate } from '../../../DateUtils';
|
import { formatDate } from '../../../DateUtils';
|
||||||
|
@ -542,8 +542,8 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
|
||||||
const stripReply = !mxEvent.replacingEvent() && !!ReplyChain.getParentEventId(mxEvent);
|
const stripReply = !mxEvent.replacingEvent() && !!ReplyChain.getParentEventId(mxEvent);
|
||||||
let body;
|
let body;
|
||||||
if (SettingsStore.isEnabled("feature_extensible_events")) {
|
if (SettingsStore.isEnabled("feature_extensible_events")) {
|
||||||
const extev = this.props.mxEvent.unstableExtensibleEvent;
|
const extev = this.props.mxEvent.unstableExtensibleEvent as MessageEvent;
|
||||||
if (extev && extev instanceof MessageEvent) {
|
if (extev?.isEquivalentTo(M_MESSAGE)) {
|
||||||
isEmote = isEventLike(extev.wireFormat, LegacyMsgType.Emote);
|
isEmote = isEventLike(extev.wireFormat, LegacyMsgType.Emote);
|
||||||
isNotice = isEventLike(extev.wireFormat, LegacyMsgType.Notice);
|
isNotice = isEventLike(extev.wireFormat, LegacyMsgType.Notice);
|
||||||
body = HtmlUtils.bodyToHtml({
|
body = HtmlUtils.bodyToHtml({
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||||
import { Thread, ThreadEvent } from 'matrix-js-sdk/src/models/thread';
|
import { Thread, ThreadEvent } from 'matrix-js-sdk/src/models/thread';
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { NotificationCountType, Room } from 'matrix-js-sdk/src/models/room';
|
import { NotificationCountType, Room } from 'matrix-js-sdk/src/models/room';
|
||||||
import { POLL_START_EVENT_TYPE } from "matrix-js-sdk/src/@types/polls";
|
import { M_POLL_START } from "matrix-events-sdk";
|
||||||
|
|
||||||
import ReplyChain from "../elements/ReplyChain";
|
import ReplyChain from "../elements/ReplyChain";
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
@ -78,7 +78,8 @@ import { CardContext } from '../right_panel/BaseCard';
|
||||||
const eventTileTypes = {
|
const eventTileTypes = {
|
||||||
[EventType.RoomMessage]: 'messages.MessageEvent',
|
[EventType.RoomMessage]: 'messages.MessageEvent',
|
||||||
[EventType.Sticker]: 'messages.MessageEvent',
|
[EventType.Sticker]: 'messages.MessageEvent',
|
||||||
[POLL_START_EVENT_TYPE.name]: 'messages.MessageEvent',
|
[M_POLL_START.name]: 'messages.MessageEvent',
|
||||||
|
[M_POLL_START.altName]: 'messages.MessageEvent',
|
||||||
[EventType.KeyVerificationCancel]: 'messages.MKeyVerificationConclusion',
|
[EventType.KeyVerificationCancel]: 'messages.MKeyVerificationConclusion',
|
||||||
[EventType.KeyVerificationDone]: 'messages.MKeyVerificationConclusion',
|
[EventType.KeyVerificationDone]: 'messages.MKeyVerificationConclusion',
|
||||||
[EventType.CallInvite]: 'messages.CallEvent',
|
[EventType.CallInvite]: 'messages.CallEvent',
|
||||||
|
@ -178,7 +179,7 @@ export function getHandlerTile(ev: MatrixEvent): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
POLL_START_EVENT_TYPE.matches(type) &&
|
M_POLL_START.matches(type) &&
|
||||||
!SettingsStore.getValue("feature_polls")
|
!SettingsStore.getValue("feature_polls")
|
||||||
) {
|
) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { MatrixEvent, IEventRelation } from "matrix-js-sdk/src/models/event";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||||
import { RelationType } from 'matrix-js-sdk/src/@types/event';
|
import { RelationType } from 'matrix-js-sdk/src/@types/event';
|
||||||
import { POLL_START_EVENT_TYPE } from "matrix-js-sdk/src/@types/polls";
|
import { M_POLL_START } from "matrix-events-sdk";
|
||||||
|
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||||
|
@ -197,7 +197,7 @@ interface IPollButtonProps extends Pick<ICollapsibleButtonProps, "narrowMode"> {
|
||||||
class PollButton extends React.PureComponent<IPollButtonProps> {
|
class PollButton extends React.PureComponent<IPollButtonProps> {
|
||||||
private onCreateClick = () => {
|
private onCreateClick = () => {
|
||||||
const canSend = this.props.room.currentState.maySendEvent(
|
const canSend = this.props.room.currentState.maySendEvent(
|
||||||
POLL_START_EVENT_TYPE.name,
|
M_POLL_START.name,
|
||||||
MatrixClientPeg.get().getUserId(),
|
MatrixClientPeg.get().getUserId(),
|
||||||
);
|
);
|
||||||
if (!canSend) {
|
if (!canSend) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
|
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
import { POLL_START_EVENT_TYPE } from "matrix-js-sdk/src/@types/polls";
|
import { M_POLL_START } from "matrix-events-sdk";
|
||||||
|
|
||||||
import { ActionPayload } from "../../dispatcher/payloads";
|
import { ActionPayload } from "../../dispatcher/payloads";
|
||||||
import { AsyncStoreWithClient } from "../AsyncStoreWithClient";
|
import { AsyncStoreWithClient } from "../AsyncStoreWithClient";
|
||||||
|
@ -68,7 +68,11 @@ function previews(): Object {
|
||||||
// TODO: when polls comes out of labs, add this to PREVIEWS
|
// TODO: when polls comes out of labs, add this to PREVIEWS
|
||||||
if (SettingsStore.getValue("feature_polls")) {
|
if (SettingsStore.getValue("feature_polls")) {
|
||||||
return {
|
return {
|
||||||
[POLL_START_EVENT_TYPE.name]: {
|
[M_POLL_START.name]: {
|
||||||
|
isState: false,
|
||||||
|
previewer: new PollStartEventPreview(),
|
||||||
|
},
|
||||||
|
[M_POLL_START.altName]: {
|
||||||
isState: false,
|
isState: false,
|
||||||
previewer: new PollStartEventPreview(),
|
previewer: new PollStartEventPreview(),
|
||||||
},
|
},
|
||||||
|
|
|
@ -15,8 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
import { POLL_START_EVENT_TYPE } from "matrix-js-sdk/src/@types/polls";
|
import { InvalidEventError, M_POLL_START_EVENT_CONTENT, PollStartEvent } from "matrix-events-sdk";
|
||||||
import { TEXT_NODE_TYPE } from "matrix-js-sdk/src/@types/extensible_events";
|
|
||||||
|
|
||||||
import { IPreview } from "./IPreview";
|
import { IPreview } from "./IPreview";
|
||||||
import { TagID } from "../models";
|
import { TagID } from "../models";
|
||||||
|
@ -37,25 +36,31 @@ export class PollStartEventPreview implements IPreview {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check we have the information we need, and bail out if not
|
// Check we have the information we need, and bail out if not
|
||||||
if (!eventContent || !eventContent[POLL_START_EVENT_TYPE.name]) {
|
if (!eventContent) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let question =
|
try {
|
||||||
eventContent[POLL_START_EVENT_TYPE.name].question[TEXT_NODE_TYPE.name];
|
const poll = new PollStartEvent({
|
||||||
question = (question || '').trim();
|
type: event.getType(),
|
||||||
question = sanitizeForTranslation(question);
|
content: eventContent as M_POLL_START_EVENT_CONTENT,
|
||||||
|
});
|
||||||
|
|
||||||
if (
|
let question = poll.question.text.trim();
|
||||||
isThread ||
|
question = sanitizeForTranslation(question);
|
||||||
isSelf(event) ||
|
|
||||||
!shouldPrefixMessagesIn(event.getRoomId(), tagId)
|
if (isThread || isSelf(event) || !shouldPrefixMessagesIn(event.getRoomId(), tagId)) {
|
||||||
) {
|
return question;
|
||||||
return question;
|
} else {
|
||||||
} else {
|
return _t("%(senderName)s: %(message)s",
|
||||||
return _t("%(senderName)s: %(message)s",
|
{ senderName: getSenderName(event), message: question },
|
||||||
{ senderName: getSenderName(event), message: question },
|
);
|
||||||
);
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof InvalidEventError) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw e; // re-throw unknown errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@ import { EventStatus, MatrixEvent } from 'matrix-js-sdk/src/models/event';
|
||||||
import { EventType, EVENT_VISIBILITY_CHANGE_TYPE, MsgType, RelationType } from "matrix-js-sdk/src/@types/event";
|
import { EventType, EVENT_VISIBILITY_CHANGE_TYPE, MsgType, RelationType } from "matrix-js-sdk/src/@types/event";
|
||||||
import { MatrixClient } from 'matrix-js-sdk/src/client';
|
import { MatrixClient } from 'matrix-js-sdk/src/client';
|
||||||
import { logger } from 'matrix-js-sdk/src/logger';
|
import { logger } from 'matrix-js-sdk/src/logger';
|
||||||
import { POLL_START_EVENT_TYPE } from "matrix-js-sdk/src/@types/polls";
|
|
||||||
import { LOCATION_EVENT_TYPE } from 'matrix-js-sdk/src/@types/location';
|
import { LOCATION_EVENT_TYPE } from 'matrix-js-sdk/src/@types/location';
|
||||||
|
import { M_POLL_START } from "matrix-events-sdk";
|
||||||
|
|
||||||
import { MatrixClientPeg } from '../MatrixClientPeg';
|
import { MatrixClientPeg } from '../MatrixClientPeg';
|
||||||
import shouldHideEvent from "../shouldHideEvent";
|
import shouldHideEvent from "../shouldHideEvent";
|
||||||
|
@ -48,7 +48,7 @@ export function isContentActionable(mxEvent: MatrixEvent): boolean {
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
mxEvent.getType() === 'm.sticker' ||
|
mxEvent.getType() === 'm.sticker' ||
|
||||||
POLL_START_EVENT_TYPE.matches(mxEvent.getType())
|
M_POLL_START.matches(mxEvent.getType())
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -228,11 +228,11 @@ export function getEventDisplayInfo(mxEvent: MatrixEvent): {
|
||||||
eventType !== EventType.RoomMessage &&
|
eventType !== EventType.RoomMessage &&
|
||||||
eventType !== EventType.Sticker &&
|
eventType !== EventType.Sticker &&
|
||||||
eventType !== EventType.RoomCreate &&
|
eventType !== EventType.RoomCreate &&
|
||||||
!POLL_START_EVENT_TYPE.matches(eventType)
|
!M_POLL_START.matches(eventType)
|
||||||
);
|
);
|
||||||
// Some non-info messages want to be rendered in the appropriate bubble column but without the bubble background
|
// Some non-info messages want to be rendered in the appropriate bubble column but without the bubble background
|
||||||
const noBubbleEvent = (
|
const noBubbleEvent = (
|
||||||
POLL_START_EVENT_TYPE.matches(eventType) ||
|
M_POLL_START.matches(eventType) ||
|
||||||
LOCATION_EVENT_TYPE.matches(eventType) ||
|
LOCATION_EVENT_TYPE.matches(eventType) ||
|
||||||
(
|
(
|
||||||
eventType === EventType.RoomMessage &&
|
eventType === EventType.RoomMessage &&
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
Copyright 2021 - 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -19,13 +19,16 @@ import { mount, ReactWrapper } from "enzyme";
|
||||||
import { Callback, IContent, MatrixClient, MatrixEvent, Room } from "matrix-js-sdk";
|
import { Callback, IContent, MatrixClient, MatrixEvent, Room } from "matrix-js-sdk";
|
||||||
import { ISendEventResponse } from "matrix-js-sdk/src/@types/requests";
|
import { ISendEventResponse } from "matrix-js-sdk/src/@types/requests";
|
||||||
import { Relations } from "matrix-js-sdk/src/models/relations";
|
import { Relations } from "matrix-js-sdk/src/models/relations";
|
||||||
|
import { RelatedRelations } from "matrix-js-sdk/src/models/related-relations";
|
||||||
import {
|
import {
|
||||||
IPollAnswer,
|
M_POLL_END,
|
||||||
IPollContent,
|
M_POLL_KIND_DISCLOSED,
|
||||||
POLL_END_EVENT_TYPE,
|
M_POLL_RESPONSE,
|
||||||
POLL_RESPONSE_EVENT_TYPE,
|
M_POLL_START,
|
||||||
} from "matrix-js-sdk/src/@types/polls";
|
M_POLL_START_EVENT_CONTENT,
|
||||||
import { TEXT_NODE_TYPE } from "matrix-js-sdk/src/@types/extensible_events";
|
M_TEXT,
|
||||||
|
POLL_ANSWER,
|
||||||
|
} from "matrix-events-sdk";
|
||||||
|
|
||||||
import * as TestUtils from "../../../test-utils";
|
import * as TestUtils from "../../../test-utils";
|
||||||
import sdk from "../../../skinned-sdk";
|
import sdk from "../../../skinned-sdk";
|
||||||
|
@ -56,8 +59,8 @@ describe("MPollBody", () => {
|
||||||
allVotes(
|
allVotes(
|
||||||
{ getRoomId: () => "$room" } as MatrixEvent,
|
{ getRoomId: () => "$room" } as MatrixEvent,
|
||||||
MatrixClientPeg.get(),
|
MatrixClientPeg.get(),
|
||||||
newVoteRelations([]),
|
new RelatedRelations([newVoteRelations([])]),
|
||||||
newEndRelations([]),
|
new RelatedRelations([newEndRelations([])]),
|
||||||
),
|
),
|
||||||
).toEqual([]);
|
).toEqual([]);
|
||||||
});
|
});
|
||||||
|
@ -67,34 +70,43 @@ describe("MPollBody", () => {
|
||||||
const ev2 = responseEvent();
|
const ev2 = responseEvent();
|
||||||
const badEvent = badResponseEvent();
|
const badEvent = badResponseEvent();
|
||||||
|
|
||||||
const voteRelations = newVoteRelations([ev1, badEvent, ev2]);
|
const voteRelations = new RelatedRelations([
|
||||||
|
newVoteRelations([ev1, badEvent, ev2]),
|
||||||
|
]);
|
||||||
expect(
|
expect(
|
||||||
allVotes(
|
allVotes(
|
||||||
{ getRoomId: () => "$room" } as MatrixEvent,
|
{ getRoomId: () => "$room" } as MatrixEvent,
|
||||||
MatrixClientPeg.get(),
|
MatrixClientPeg.get(),
|
||||||
voteRelations,
|
voteRelations,
|
||||||
newEndRelations([]),
|
new RelatedRelations([newEndRelations([])]),
|
||||||
),
|
),
|
||||||
).toEqual([
|
).toEqual([
|
||||||
new UserVote(
|
new UserVote(
|
||||||
ev1.getTs(),
|
ev1.getTs(),
|
||||||
ev1.getSender(),
|
ev1.getSender(),
|
||||||
ev1.getContent()[POLL_RESPONSE_EVENT_TYPE.name].answers,
|
ev1.getContent()[M_POLL_RESPONSE.name].answers,
|
||||||
|
),
|
||||||
|
new UserVote(
|
||||||
|
badEvent.getTs(),
|
||||||
|
badEvent.getSender(),
|
||||||
|
[], // should be spoiled
|
||||||
),
|
),
|
||||||
new UserVote(
|
new UserVote(
|
||||||
ev2.getTs(),
|
ev2.getTs(),
|
||||||
ev2.getSender(),
|
ev2.getSender(),
|
||||||
ev2.getContent()[POLL_RESPONSE_EVENT_TYPE.name].answers,
|
ev2.getContent()[M_POLL_RESPONSE.name].answers,
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("finds the first end poll event", () => {
|
it("finds the first end poll event", () => {
|
||||||
const endRelations = newEndRelations([
|
const endRelations = new RelatedRelations([
|
||||||
endEvent("@me:example.com", 25),
|
newEndRelations([
|
||||||
endEvent("@me:example.com", 12),
|
endEvent("@me:example.com", 25),
|
||||||
endEvent("@me:example.com", 45),
|
endEvent("@me:example.com", 12),
|
||||||
endEvent("@me:example.com", 13),
|
endEvent("@me:example.com", 45),
|
||||||
|
endEvent("@me:example.com", 13),
|
||||||
|
]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const matrixClient = TestUtils.createTestClient();
|
const matrixClient = TestUtils.createTestClient();
|
||||||
|
@ -110,11 +122,13 @@ describe("MPollBody", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("ignores unauthorised end poll event when finding end ts", () => {
|
it("ignores unauthorised end poll event when finding end ts", () => {
|
||||||
const endRelations = newEndRelations([
|
const endRelations = new RelatedRelations([
|
||||||
endEvent("@me:example.com", 25),
|
newEndRelations([
|
||||||
endEvent("@unauthorised:example.com", 12),
|
endEvent("@me:example.com", 25),
|
||||||
endEvent("@me:example.com", 45),
|
endEvent("@unauthorised:example.com", 12),
|
||||||
endEvent("@me:example.com", 13),
|
endEvent("@me:example.com", 45),
|
||||||
|
endEvent("@me:example.com", 13),
|
||||||
|
]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const matrixClient = TestUtils.createTestClient();
|
const matrixClient = TestUtils.createTestClient();
|
||||||
|
@ -130,15 +144,19 @@ describe("MPollBody", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("counts only votes before the end poll event", () => {
|
it("counts only votes before the end poll event", () => {
|
||||||
const voteRelations = newVoteRelations([
|
const voteRelations = new RelatedRelations([
|
||||||
responseEvent("sf@matrix.org", "wings", 13),
|
newVoteRelations([
|
||||||
responseEvent("jr@matrix.org", "poutine", 40),
|
responseEvent("sf@matrix.org", "wings", 13),
|
||||||
responseEvent("ak@matrix.org", "poutine", 37),
|
responseEvent("jr@matrix.org", "poutine", 40),
|
||||||
responseEvent("id@matrix.org", "wings", 13),
|
responseEvent("ak@matrix.org", "poutine", 37),
|
||||||
responseEvent("ps@matrix.org", "wings", 19),
|
responseEvent("id@matrix.org", "wings", 13),
|
||||||
|
responseEvent("ps@matrix.org", "wings", 19),
|
||||||
|
]),
|
||||||
]);
|
]);
|
||||||
const endRelations = newEndRelations([
|
const endRelations = new RelatedRelations([
|
||||||
endEvent("@me:example.com", 25),
|
newEndRelations([
|
||||||
|
endEvent("@me:example.com", 25),
|
||||||
|
]),
|
||||||
]);
|
]);
|
||||||
expect(
|
expect(
|
||||||
allVotes(
|
allVotes(
|
||||||
|
@ -298,7 +316,7 @@ describe("MPollBody", () => {
|
||||||
const body = newMPollBody(votes);
|
const body = newMPollBody(votes);
|
||||||
const props: IBodyProps = body.instance().props as IBodyProps;
|
const props: IBodyProps = body.instance().props as IBodyProps;
|
||||||
const voteRelations: Relations = props.getRelationsForEvent(
|
const voteRelations: Relations = props.getRelationsForEvent(
|
||||||
"$mypoll", "m.reference", POLL_RESPONSE_EVENT_TYPE.name);
|
"$mypoll", "m.reference", M_POLL_RESPONSE.name);
|
||||||
clickRadio(body, "pizza");
|
clickRadio(body, "pizza");
|
||||||
|
|
||||||
// When a new vote from me comes in
|
// When a new vote from me comes in
|
||||||
|
@ -319,7 +337,7 @@ describe("MPollBody", () => {
|
||||||
const body = newMPollBody(votes);
|
const body = newMPollBody(votes);
|
||||||
const props: IBodyProps = body.instance().props as IBodyProps;
|
const props: IBodyProps = body.instance().props as IBodyProps;
|
||||||
const voteRelations: Relations = props.getRelationsForEvent(
|
const voteRelations: Relations = props.getRelationsForEvent(
|
||||||
"$mypoll", "m.reference", POLL_RESPONSE_EVENT_TYPE.name);
|
"$mypoll", "m.reference", M_POLL_RESPONSE.name);
|
||||||
clickRadio(body, "pizza");
|
clickRadio(body, "pizza");
|
||||||
|
|
||||||
// When a new vote from someone else comes in
|
// When a new vote from someone else comes in
|
||||||
|
@ -400,7 +418,7 @@ describe("MPollBody", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("treats any invalid answer as a spoiled ballot", () => {
|
it("treats any invalid answer as a spoiled ballot", () => {
|
||||||
// Note that tr's second vote has a valid first answer, but
|
// Note that uy's second vote has a valid first answer, but
|
||||||
// the ballot is still spoiled because the second answer is
|
// the ballot is still spoiled because the second answer is
|
||||||
// invalid, even though we would ignore it if we continued.
|
// invalid, even though we would ignore it if we continued.
|
||||||
const votes = [
|
const votes = [
|
||||||
|
@ -442,14 +460,16 @@ describe("MPollBody", () => {
|
||||||
expect(body.html()).toBe("");
|
expect(body.html()).toBe("");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders nothing if poll has more than 20 answers", () => {
|
it("renders the first 20 answers if 21 were given", () => {
|
||||||
const answers = [...Array(21).keys()].map((i) => {
|
const answers = Array.from(Array(21).keys()).map((i) => {
|
||||||
return { "id": `id${i}`, "org.matrix.msc1767.text": `Name ${i}` };
|
return { "id": `id${i}`, [M_TEXT.name]: `Name ${i}` };
|
||||||
});
|
});
|
||||||
const votes = [];
|
const votes = [];
|
||||||
const ends = [];
|
const ends = [];
|
||||||
const body = newMPollBody(votes, ends, answers);
|
const body = newMPollBody(votes, ends, answers);
|
||||||
expect(body.html()).toBe("");
|
expect(
|
||||||
|
body.find('.mx_MPollBody_option').length,
|
||||||
|
).toBe(20);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sends a vote event when I choose an option", () => {
|
it("sends a vote event when I choose an option", () => {
|
||||||
|
@ -835,7 +855,7 @@ describe("MPollBody", () => {
|
||||||
(eventId: string, relationType: string, eventType: string) => {
|
(eventId: string, relationType: string, eventType: string) => {
|
||||||
expect(eventId).toBe("$mypoll");
|
expect(eventId).toBe("$mypoll");
|
||||||
expect(relationType).toBe("m.reference");
|
expect(relationType).toBe("m.reference");
|
||||||
expect(eventType).toBe(POLL_END_EVENT_TYPE.name);
|
expect(M_POLL_END.matches(eventType)).toBe(true);
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
expect(
|
expect(
|
||||||
|
@ -926,11 +946,11 @@ describe("MPollBody", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function newVoteRelations(relationEvents: Array<MatrixEvent>): Relations {
|
function newVoteRelations(relationEvents: Array<MatrixEvent>): Relations {
|
||||||
return newRelations(relationEvents, POLL_RESPONSE_EVENT_TYPE.name);
|
return newRelations(relationEvents, M_POLL_RESPONSE.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function newEndRelations(relationEvents: Array<MatrixEvent>): Relations {
|
function newEndRelations(relationEvents: Array<MatrixEvent>): Relations {
|
||||||
return newRelations(relationEvents, POLL_END_EVENT_TYPE.name);
|
return newRelations(relationEvents, M_POLL_END.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function newRelations(
|
function newRelations(
|
||||||
|
@ -947,22 +967,14 @@ function newRelations(
|
||||||
function newMPollBody(
|
function newMPollBody(
|
||||||
relationEvents: Array<MatrixEvent>,
|
relationEvents: Array<MatrixEvent>,
|
||||||
endEvents: Array<MatrixEvent> = [],
|
endEvents: Array<MatrixEvent> = [],
|
||||||
answers?: IPollAnswer[],
|
answers?: POLL_ANSWER[],
|
||||||
): ReactWrapper {
|
): ReactWrapper {
|
||||||
const voteRelations = new Relations(
|
const voteRelations = newVoteRelations(relationEvents);
|
||||||
"m.reference", POLL_RESPONSE_EVENT_TYPE.name, null);
|
const endRelations = newEndRelations(endEvents);
|
||||||
for (const ev of relationEvents) {
|
|
||||||
voteRelations.addEvent(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
const endRelations = new Relations(
|
|
||||||
"m.reference", POLL_END_EVENT_TYPE.name, null);
|
|
||||||
for (const ev of endEvents) {
|
|
||||||
endRelations.addEvent(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mount(<MPollBody
|
return mount(<MPollBody
|
||||||
mxEvent={new MatrixEvent({
|
mxEvent={new MatrixEvent({
|
||||||
|
"type": M_POLL_START.name,
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
"content": newPollStart(answers),
|
"content": newPollStart(answers),
|
||||||
|
@ -971,9 +983,9 @@ function newMPollBody(
|
||||||
(eventId: string, relationType: string, eventType: string) => {
|
(eventId: string, relationType: string, eventType: string) => {
|
||||||
expect(eventId).toBe("$mypoll");
|
expect(eventId).toBe("$mypoll");
|
||||||
expect(relationType).toBe("m.reference");
|
expect(relationType).toBe("m.reference");
|
||||||
if (POLL_RESPONSE_EVENT_TYPE.matches(eventType)) {
|
if (M_POLL_RESPONSE.matches(eventType)) {
|
||||||
return voteRelations;
|
return voteRelations;
|
||||||
} else if (POLL_END_EVENT_TYPE.matches(eventType)) {
|
} else if (M_POLL_END.matches(eventType)) {
|
||||||
return endRelations;
|
return endRelations;
|
||||||
} else {
|
} else {
|
||||||
fail("Unexpected eventType: " + eventType);
|
fail("Unexpected eventType: " + eventType);
|
||||||
|
@ -1023,25 +1035,25 @@ function endedVotesCount(wrapper: ReactWrapper, value: string): string {
|
||||||
).text();
|
).text();
|
||||||
}
|
}
|
||||||
|
|
||||||
function newPollStart(answers?: IPollAnswer[]): IPollContent {
|
function newPollStart(answers?: POLL_ANSWER[]): M_POLL_START_EVENT_CONTENT {
|
||||||
if (!answers) {
|
if (!answers) {
|
||||||
answers = [
|
answers = [
|
||||||
{ "id": "pizza", "org.matrix.msc1767.text": "Pizza" },
|
{ "id": "pizza", [M_TEXT.name]: "Pizza" },
|
||||||
{ "id": "poutine", "org.matrix.msc1767.text": "Poutine" },
|
{ "id": "poutine", [M_TEXT.name]: "Poutine" },
|
||||||
{ "id": "italian", "org.matrix.msc1767.text": "Italian" },
|
{ "id": "italian", [M_TEXT.name]: "Italian" },
|
||||||
{ "id": "wings", "org.matrix.msc1767.text": "Wings" },
|
{ "id": "wings", [M_TEXT.name]: "Wings" },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"org.matrix.msc3381.poll.start": {
|
[M_POLL_START.name]: {
|
||||||
"question": {
|
"question": {
|
||||||
"org.matrix.msc1767.text": "What should we order for the party?",
|
[M_TEXT.name]: "What should we order for the party?",
|
||||||
},
|
},
|
||||||
"kind": "org.matrix.msc3381.poll.disclosed",
|
"kind": M_POLL_KIND_DISCLOSED.name,
|
||||||
"answers": answers,
|
"answers": answers,
|
||||||
},
|
},
|
||||||
"org.matrix.msc1767.text": "What should we order for the party?\n" +
|
[M_TEXT.name]: "What should we order for the party?\n" +
|
||||||
"1. Pizza\n2. Poutine\n3. Italian\n4. Wings",
|
"1. Pizza\n2. Poutine\n3. Italian\n4. Wings",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1050,7 +1062,8 @@ function badResponseEvent(): MatrixEvent {
|
||||||
return new MatrixEvent(
|
return new MatrixEvent(
|
||||||
{
|
{
|
||||||
"event_id": nextId(),
|
"event_id": nextId(),
|
||||||
"type": POLL_RESPONSE_EVENT_TYPE.name,
|
"type": M_POLL_RESPONSE.name,
|
||||||
|
"sender": "@malicious:example.com",
|
||||||
"content": {
|
"content": {
|
||||||
"m.relates_to": {
|
"m.relates_to": {
|
||||||
"rel_type": "m.reference",
|
"rel_type": "m.reference",
|
||||||
|
@ -1073,14 +1086,14 @@ function responseEvent(
|
||||||
"event_id": nextId(),
|
"event_id": nextId(),
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
"origin_server_ts": ts,
|
"origin_server_ts": ts,
|
||||||
"type": POLL_RESPONSE_EVENT_TYPE.name,
|
"type": M_POLL_RESPONSE.name,
|
||||||
"sender": sender,
|
"sender": sender,
|
||||||
"content": {
|
"content": {
|
||||||
"m.relates_to": {
|
"m.relates_to": {
|
||||||
"rel_type": "m.reference",
|
"rel_type": "m.reference",
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
},
|
},
|
||||||
[POLL_RESPONSE_EVENT_TYPE.name]: {
|
[M_POLL_RESPONSE.name]: {
|
||||||
"answers": ans,
|
"answers": ans,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1091,7 +1104,7 @@ function responseEvent(
|
||||||
function expectedResponseEvent(answer: string) {
|
function expectedResponseEvent(answer: string) {
|
||||||
return {
|
return {
|
||||||
"content": {
|
"content": {
|
||||||
[POLL_RESPONSE_EVENT_TYPE.name]: {
|
[M_POLL_RESPONSE.name]: {
|
||||||
"answers": [answer],
|
"answers": [answer],
|
||||||
},
|
},
|
||||||
"m.relates_to": {
|
"m.relates_to": {
|
||||||
|
@ -1099,7 +1112,7 @@ function expectedResponseEvent(answer: string) {
|
||||||
"rel_type": "m.reference",
|
"rel_type": "m.reference",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"eventType": POLL_RESPONSE_EVENT_TYPE.name,
|
"eventType": M_POLL_RESPONSE.name,
|
||||||
"roomId": "#myroom:example.com",
|
"roomId": "#myroom:example.com",
|
||||||
"txnId": undefined,
|
"txnId": undefined,
|
||||||
"callback": undefined,
|
"callback": undefined,
|
||||||
|
@ -1115,15 +1128,15 @@ function endEvent(
|
||||||
"event_id": nextId(),
|
"event_id": nextId(),
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
"origin_server_ts": ts,
|
"origin_server_ts": ts,
|
||||||
"type": POLL_END_EVENT_TYPE.name,
|
"type": M_POLL_END.name,
|
||||||
"sender": sender,
|
"sender": sender,
|
||||||
"content": {
|
"content": {
|
||||||
"m.relates_to": {
|
"m.relates_to": {
|
||||||
"rel_type": "m.reference",
|
"rel_type": "m.reference",
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
},
|
},
|
||||||
[POLL_END_EVENT_TYPE.name]: {},
|
[M_POLL_END.name]: {},
|
||||||
[TEXT_NODE_TYPE.name]: "The poll has ended. Something.",
|
[M_TEXT.name]: "The poll has ended. Something.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1133,6 +1146,7 @@ function runIsPollEnded(ends: MatrixEvent[]) {
|
||||||
const pollEvent = new MatrixEvent({
|
const pollEvent = new MatrixEvent({
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": M_POLL_START.name,
|
||||||
"content": newPollStart(),
|
"content": newPollStart(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1143,7 +1157,7 @@ function runIsPollEnded(ends: MatrixEvent[]) {
|
||||||
(eventId: string, relationType: string, eventType: string) => {
|
(eventId: string, relationType: string, eventType: string) => {
|
||||||
expect(eventId).toBe("$mypoll");
|
expect(eventId).toBe("$mypoll");
|
||||||
expect(relationType).toBe("m.reference");
|
expect(relationType).toBe("m.reference");
|
||||||
expect(eventType).toBe(POLL_END_EVENT_TYPE.name);
|
expect(M_POLL_END.matches(eventType)).toBe(true);
|
||||||
return newEndRelations(ends);
|
return newEndRelations(ends);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1154,6 +1168,7 @@ function runFindTopAnswer(votes: MatrixEvent[], ends: MatrixEvent[]) {
|
||||||
const pollEvent = new MatrixEvent({
|
const pollEvent = new MatrixEvent({
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": M_POLL_START.name,
|
||||||
"content": newPollStart(),
|
"content": newPollStart(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1161,9 +1176,9 @@ function runFindTopAnswer(votes: MatrixEvent[], ends: MatrixEvent[]) {
|
||||||
(eventId: string, relationType: string, eventType: string) => {
|
(eventId: string, relationType: string, eventType: string) => {
|
||||||
expect(eventId).toBe("$mypoll");
|
expect(eventId).toBe("$mypoll");
|
||||||
expect(relationType).toBe("m.reference");
|
expect(relationType).toBe("m.reference");
|
||||||
if (POLL_RESPONSE_EVENT_TYPE.matches(eventType)) {
|
if (M_POLL_RESPONSE.matches(eventType)) {
|
||||||
return newVoteRelations(votes);
|
return newVoteRelations(votes);
|
||||||
} else if (POLL_END_EVENT_TYPE.matches(eventType)) {
|
} else if (M_POLL_END.matches(eventType)) {
|
||||||
return newEndRelations(ends);
|
return newEndRelations(ends);
|
||||||
} else {
|
} else {
|
||||||
fail(`eventType should be end or vote but was ${eventType}`);
|
fail(`eventType should be end or vote but was ${eventType}`);
|
||||||
|
|
|
@ -38,6 +38,7 @@ exports[`MPollBody renders a finished poll 1`] = `
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -78,6 +79,7 @@ exports[`MPollBody renders a finished poll 1`] = `
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -97,9 +99,23 @@ exports[`MPollBody renders a finished poll 1`] = `
|
||||||
>
|
>
|
||||||
<EndedPollOption
|
<EndedPollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "pizza",
|
"id": "pizza",
|
||||||
"org.matrix.msc1767.text": "Pizza",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Pizza",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Pizza",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "pizza",
|
||||||
|
"org.matrix.msc1767.text": "Pizza",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -145,9 +161,23 @@ exports[`MPollBody renders a finished poll 1`] = `
|
||||||
>
|
>
|
||||||
<EndedPollOption
|
<EndedPollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "poutine",
|
"id": "poutine",
|
||||||
"org.matrix.msc1767.text": "Poutine",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Poutine",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Poutine",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "poutine",
|
||||||
|
"org.matrix.msc1767.text": "Poutine",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -193,9 +223,23 @@ exports[`MPollBody renders a finished poll 1`] = `
|
||||||
>
|
>
|
||||||
<EndedPollOption
|
<EndedPollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "italian",
|
"id": "italian",
|
||||||
"org.matrix.msc1767.text": "Italian",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Italian",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Italian",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "italian",
|
||||||
|
"org.matrix.msc1767.text": "Italian",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={true}
|
checked={true}
|
||||||
|
@ -241,9 +285,23 @@ exports[`MPollBody renders a finished poll 1`] = `
|
||||||
>
|
>
|
||||||
<EndedPollOption
|
<EndedPollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "wings",
|
"id": "wings",
|
||||||
"org.matrix.msc1767.text": "Wings",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Wings",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Wings",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "wings",
|
||||||
|
"org.matrix.msc1767.text": "Wings",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -331,6 +389,7 @@ exports[`MPollBody renders a finished poll with multiple winners 1`] = `
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -371,6 +430,7 @@ exports[`MPollBody renders a finished poll with multiple winners 1`] = `
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -390,9 +450,23 @@ exports[`MPollBody renders a finished poll with multiple winners 1`] = `
|
||||||
>
|
>
|
||||||
<EndedPollOption
|
<EndedPollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "pizza",
|
"id": "pizza",
|
||||||
"org.matrix.msc1767.text": "Pizza",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Pizza",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Pizza",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "pizza",
|
||||||
|
"org.matrix.msc1767.text": "Pizza",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={true}
|
checked={true}
|
||||||
|
@ -438,9 +512,23 @@ exports[`MPollBody renders a finished poll with multiple winners 1`] = `
|
||||||
>
|
>
|
||||||
<EndedPollOption
|
<EndedPollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "poutine",
|
"id": "poutine",
|
||||||
"org.matrix.msc1767.text": "Poutine",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Poutine",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Poutine",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "poutine",
|
||||||
|
"org.matrix.msc1767.text": "Poutine",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -486,9 +574,23 @@ exports[`MPollBody renders a finished poll with multiple winners 1`] = `
|
||||||
>
|
>
|
||||||
<EndedPollOption
|
<EndedPollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "italian",
|
"id": "italian",
|
||||||
"org.matrix.msc1767.text": "Italian",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Italian",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Italian",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "italian",
|
||||||
|
"org.matrix.msc1767.text": "Italian",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -534,9 +636,23 @@ exports[`MPollBody renders a finished poll with multiple winners 1`] = `
|
||||||
>
|
>
|
||||||
<EndedPollOption
|
<EndedPollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "wings",
|
"id": "wings",
|
||||||
"org.matrix.msc1767.text": "Wings",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Wings",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Wings",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "wings",
|
||||||
|
"org.matrix.msc1767.text": "Wings",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={true}
|
checked={true}
|
||||||
|
@ -624,6 +740,7 @@ exports[`MPollBody renders a finished poll with no votes 1`] = `
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -664,6 +781,7 @@ exports[`MPollBody renders a finished poll with no votes 1`] = `
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -683,9 +801,23 @@ exports[`MPollBody renders a finished poll with no votes 1`] = `
|
||||||
>
|
>
|
||||||
<EndedPollOption
|
<EndedPollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "pizza",
|
"id": "pizza",
|
||||||
"org.matrix.msc1767.text": "Pizza",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Pizza",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Pizza",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "pizza",
|
||||||
|
"org.matrix.msc1767.text": "Pizza",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -731,9 +863,23 @@ exports[`MPollBody renders a finished poll with no votes 1`] = `
|
||||||
>
|
>
|
||||||
<EndedPollOption
|
<EndedPollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "poutine",
|
"id": "poutine",
|
||||||
"org.matrix.msc1767.text": "Poutine",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Poutine",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Poutine",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "poutine",
|
||||||
|
"org.matrix.msc1767.text": "Poutine",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -779,9 +925,23 @@ exports[`MPollBody renders a finished poll with no votes 1`] = `
|
||||||
>
|
>
|
||||||
<EndedPollOption
|
<EndedPollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "italian",
|
"id": "italian",
|
||||||
"org.matrix.msc1767.text": "Italian",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Italian",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Italian",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "italian",
|
||||||
|
"org.matrix.msc1767.text": "Italian",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -827,9 +987,23 @@ exports[`MPollBody renders a finished poll with no votes 1`] = `
|
||||||
>
|
>
|
||||||
<EndedPollOption
|
<EndedPollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "wings",
|
"id": "wings",
|
||||||
"org.matrix.msc1767.text": "Wings",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Wings",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Wings",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "wings",
|
||||||
|
"org.matrix.msc1767.text": "Wings",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -917,6 +1091,7 @@ exports[`MPollBody renders a poll that I have not voted in 1`] = `
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -957,6 +1132,7 @@ exports[`MPollBody renders a poll that I have not voted in 1`] = `
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -976,9 +1152,23 @@ exports[`MPollBody renders a poll that I have not voted in 1`] = `
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "pizza",
|
"id": "pizza",
|
||||||
"org.matrix.msc1767.text": "Pizza",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Pizza",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Pizza",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "pizza",
|
||||||
|
"org.matrix.msc1767.text": "Pizza",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -1049,9 +1239,23 @@ exports[`MPollBody renders a poll that I have not voted in 1`] = `
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "poutine",
|
"id": "poutine",
|
||||||
"org.matrix.msc1767.text": "Poutine",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Poutine",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Poutine",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "poutine",
|
||||||
|
"org.matrix.msc1767.text": "Poutine",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -1122,9 +1326,23 @@ exports[`MPollBody renders a poll that I have not voted in 1`] = `
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "italian",
|
"id": "italian",
|
||||||
"org.matrix.msc1767.text": "Italian",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Italian",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Italian",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "italian",
|
||||||
|
"org.matrix.msc1767.text": "Italian",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -1195,9 +1413,23 @@ exports[`MPollBody renders a poll that I have not voted in 1`] = `
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "wings",
|
"id": "wings",
|
||||||
"org.matrix.msc1767.text": "Wings",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Wings",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Wings",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "wings",
|
||||||
|
"org.matrix.msc1767.text": "Wings",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -1310,6 +1542,7 @@ exports[`MPollBody renders a poll with local, non-local and invalid votes 1`] =
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -1350,6 +1583,7 @@ exports[`MPollBody renders a poll with local, non-local and invalid votes 1`] =
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -1369,9 +1603,23 @@ exports[`MPollBody renders a poll with local, non-local and invalid votes 1`] =
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "pizza",
|
"id": "pizza",
|
||||||
"org.matrix.msc1767.text": "Pizza",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Pizza",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Pizza",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "pizza",
|
||||||
|
"org.matrix.msc1767.text": "Pizza",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -1444,9 +1692,23 @@ exports[`MPollBody renders a poll with local, non-local and invalid votes 1`] =
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "poutine",
|
"id": "poutine",
|
||||||
"org.matrix.msc1767.text": "Poutine",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Poutine",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Poutine",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "poutine",
|
||||||
|
"org.matrix.msc1767.text": "Poutine",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -1519,9 +1781,23 @@ exports[`MPollBody renders a poll with local, non-local and invalid votes 1`] =
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "italian",
|
"id": "italian",
|
||||||
"org.matrix.msc1767.text": "Italian",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Italian",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Italian",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "italian",
|
||||||
|
"org.matrix.msc1767.text": "Italian",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={true}
|
checked={true}
|
||||||
|
@ -1594,9 +1870,23 @@ exports[`MPollBody renders a poll with local, non-local and invalid votes 1`] =
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "wings",
|
"id": "wings",
|
||||||
"org.matrix.msc1767.text": "Wings",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Wings",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Wings",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "wings",
|
||||||
|
"org.matrix.msc1767.text": "Wings",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -1711,6 +2001,7 @@ exports[`MPollBody renders a poll with no votes 1`] = `
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -1751,6 +2042,7 @@ exports[`MPollBody renders a poll with no votes 1`] = `
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -1770,9 +2062,23 @@ exports[`MPollBody renders a poll with no votes 1`] = `
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "pizza",
|
"id": "pizza",
|
||||||
"org.matrix.msc1767.text": "Pizza",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Pizza",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Pizza",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "pizza",
|
||||||
|
"org.matrix.msc1767.text": "Pizza",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -1843,9 +2149,23 @@ exports[`MPollBody renders a poll with no votes 1`] = `
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "poutine",
|
"id": "poutine",
|
||||||
"org.matrix.msc1767.text": "Poutine",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Poutine",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Poutine",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "poutine",
|
||||||
|
"org.matrix.msc1767.text": "Poutine",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -1916,9 +2236,23 @@ exports[`MPollBody renders a poll with no votes 1`] = `
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "italian",
|
"id": "italian",
|
||||||
"org.matrix.msc1767.text": "Italian",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Italian",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Italian",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "italian",
|
||||||
|
"org.matrix.msc1767.text": "Italian",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -1989,9 +2323,23 @@ exports[`MPollBody renders a poll with no votes 1`] = `
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "wings",
|
"id": "wings",
|
||||||
"org.matrix.msc1767.text": "Wings",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Wings",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Wings",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "wings",
|
||||||
|
"org.matrix.msc1767.text": "Wings",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -2104,6 +2452,7 @@ exports[`MPollBody renders a poll with only non-local votes 1`] = `
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -2144,6 +2493,7 @@ exports[`MPollBody renders a poll with only non-local votes 1`] = `
|
||||||
},
|
},
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
|
"type": "org.matrix.msc3381.poll.start",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -2163,9 +2513,23 @@ exports[`MPollBody renders a poll with only non-local votes 1`] = `
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "pizza",
|
"id": "pizza",
|
||||||
"org.matrix.msc1767.text": "Pizza",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Pizza",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Pizza",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "pizza",
|
||||||
|
"org.matrix.msc1767.text": "Pizza",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -2238,9 +2602,23 @@ exports[`MPollBody renders a poll with only non-local votes 1`] = `
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "poutine",
|
"id": "poutine",
|
||||||
"org.matrix.msc1767.text": "Poutine",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Poutine",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Poutine",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "poutine",
|
||||||
|
"org.matrix.msc1767.text": "Poutine",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -2313,9 +2691,23 @@ exports[`MPollBody renders a poll with only non-local votes 1`] = `
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "italian",
|
"id": "italian",
|
||||||
"org.matrix.msc1767.text": "Italian",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Italian",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Italian",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "italian",
|
||||||
|
"org.matrix.msc1767.text": "Italian",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={false}
|
checked={false}
|
||||||
|
@ -2388,9 +2780,23 @@ exports[`MPollBody renders a poll with only non-local votes 1`] = `
|
||||||
>
|
>
|
||||||
<LivePollOption
|
<LivePollOption
|
||||||
answer={
|
answer={
|
||||||
Object {
|
PollAnswerSubevent {
|
||||||
|
"html": undefined,
|
||||||
"id": "wings",
|
"id": "wings",
|
||||||
"org.matrix.msc1767.text": "Wings",
|
"renderings": Array [
|
||||||
|
Object {
|
||||||
|
"body": "Wings",
|
||||||
|
"mimetype": "text/plain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Wings",
|
||||||
|
"wireFormat": Object {
|
||||||
|
"content": Object {
|
||||||
|
"id": "wings",
|
||||||
|
"org.matrix.msc1767.text": "Wings",
|
||||||
|
},
|
||||||
|
"type": "org.matrix.sdk.poll.answer",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checked={true}
|
checked={true}
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { MatrixEvent } from "matrix-js-sdk";
|
import { MatrixEvent } from "matrix-js-sdk";
|
||||||
import { IPollAnswer } from "matrix-js-sdk/src/@types/polls";
|
import { POLL_ANSWER, M_TEXT, M_POLL_KIND_DISCLOSED, M_POLL_START } from "matrix-events-sdk";
|
||||||
|
|
||||||
import { PollStartEventPreview } from "../../../../src/stores/room-list/previews/PollStartEventPreview";
|
import { PollStartEventPreview } from "../../../../src/stores/room-list/previews/PollStartEventPreview";
|
||||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||||
|
@ -41,12 +41,12 @@ describe("PollStartEventPreview", () => {
|
||||||
function newPollStartEvent(
|
function newPollStartEvent(
|
||||||
question: string,
|
question: string,
|
||||||
sender: string,
|
sender: string,
|
||||||
answers?: IPollAnswer[],
|
answers?: POLL_ANSWER[],
|
||||||
): MatrixEvent {
|
): MatrixEvent {
|
||||||
if (!answers) {
|
if (!answers) {
|
||||||
answers = [
|
answers = [
|
||||||
{ "id": "socks", "org.matrix.msc1767.text": "Socks" },
|
{ "id": "socks", [M_TEXT.name]: "Socks" },
|
||||||
{ "id": "shoes", "org.matrix.msc1767.text": "Shoes" },
|
{ "id": "shoes", [M_TEXT.name]: "Shoes" },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,15 +55,16 @@ function newPollStartEvent(
|
||||||
"event_id": "$mypoll",
|
"event_id": "$mypoll",
|
||||||
"room_id": "#myroom:example.com",
|
"room_id": "#myroom:example.com",
|
||||||
"sender": sender,
|
"sender": sender,
|
||||||
|
"type": M_POLL_START.name,
|
||||||
"content": {
|
"content": {
|
||||||
"org.matrix.msc3381.poll.start": {
|
[M_POLL_START.name]: {
|
||||||
"question": {
|
"question": {
|
||||||
"org.matrix.msc1767.text": question,
|
[M_TEXT.name]: question,
|
||||||
},
|
},
|
||||||
"kind": "org.matrix.msc3381.poll.disclosed",
|
"kind": M_POLL_KIND_DISCLOSED.name,
|
||||||
"answers": answers,
|
"answers": answers,
|
||||||
},
|
},
|
||||||
"org.matrix.msc1767.text": `${question}: answers`,
|
[M_TEXT.name]: `${question}: answers`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -6163,10 +6163,10 @@ mathml-tag-names@^2.1.3:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://github.com/matrix-org/matrix-analytics-events.git#1eab4356548c97722a183912fda1ceabbe8cc7c1"
|
resolved "https://github.com/matrix-org/matrix-analytics-events.git#1eab4356548c97722a183912fda1ceabbe8cc7c1"
|
||||||
|
|
||||||
matrix-events-sdk@^0.0.1-beta.2:
|
matrix-events-sdk@^0.0.1-beta.6:
|
||||||
version "0.0.1-beta.2"
|
version "0.0.1-beta.6"
|
||||||
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.2.tgz#28efdcc3259152c4d53094cedb72b3843e5f772e"
|
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.6.tgz#9001090ed2e2bf29efc113d6b29871bcc6520749"
|
||||||
integrity sha512-a3VIZeb9IxxxPrvFnUbt4pjP7A6irv7eWLv1GBoq+80m7v5n3QhzT/mmeUGJx2KNt7jLboFau4g1iIU82H3wEg==
|
integrity sha512-VMqPXe3Bg4R9yC9PNqGv6bDFwWlVYadYxp0Ke1ihhXUCpGcx7e28kOYcqK2T3RxLXK4KK7VH4JRbY53Do3r+Fw==
|
||||||
|
|
||||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop":
|
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop":
|
||||||
version "15.3.0"
|
version "15.3.0"
|
||||||
|
|
Loading…
Reference in a new issue