Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 3099a75

Browse files
authored
Allow pinning polls (#7922)
* Allow pinning polls Signed-off-by: Robin Townsend <[email protected]> * Show responses to pinned polls Signed-off-by: Robin Townsend <[email protected]> * Use enums more Signed-off-by: Robin Townsend <[email protected]>
1 parent 881307e commit 3099a75

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/components/views/rooms/PinnedEventTile.tsx

+50
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ limitations under the License.
1717

1818
import React from "react";
1919
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
20+
import { Relations } from "matrix-js-sdk/src/models/relations";
21+
import { EventType, RelationType } from "matrix-js-sdk/src/@types/event";
22+
import { logger } from "matrix-js-sdk/src/logger";
23+
import { M_POLL_START, M_POLL_RESPONSE, M_POLL_END } from "matrix-events-sdk";
2024

2125
import dis from "../../../dispatcher/dispatcher";
2226
import { Action } from "../../../dispatcher/actions";
@@ -52,6 +56,51 @@ export default class PinnedEventTile extends React.Component<IProps> {
5256
});
5357
};
5458

59+
// For event types like polls that use relations, we fetch those manually on
60+
// mount and store them here, exposing them through getRelationsForEvent
61+
private relations = new Map<string, Map<string, Relations>>();
62+
private getRelationsForEvent = (
63+
eventId: string,
64+
relationType: RelationType | string,
65+
eventType: EventType | string,
66+
): Relations => {
67+
if (eventId === this.props.event.getId()) {
68+
return this.relations.get(relationType)?.get(eventType);
69+
}
70+
};
71+
72+
async componentDidMount() {
73+
// Fetch poll responses
74+
if (M_POLL_START.matches(this.props.event.getType())) {
75+
const eventId = this.props.event.getId();
76+
const roomId = this.props.event.getRoomId();
77+
const room = this.context.getRoom(roomId);
78+
79+
try {
80+
await Promise.all(
81+
[M_POLL_RESPONSE.name, M_POLL_RESPONSE.altName, M_POLL_END.name, M_POLL_END.altName]
82+
.map(async eventType => {
83+
const { events } = await this.context.relations(
84+
roomId, eventId, RelationType.Reference, eventType,
85+
);
86+
87+
const relations = new Relations(RelationType.Reference, eventType, room);
88+
if (!this.relations.has(RelationType.Reference)) {
89+
this.relations.set(RelationType.Reference, new Map<string, Relations>());
90+
}
91+
this.relations.get(RelationType.Reference).set(eventType, relations);
92+
93+
relations.setTargetEvent(this.props.event);
94+
events.forEach(event => relations.addEvent(event));
95+
}),
96+
);
97+
} catch (err) {
98+
logger.error(`Error fetching responses to pinned poll ${eventId} in room ${roomId}`);
99+
logger.error(err);
100+
}
101+
}
102+
}
103+
55104
render() {
56105
const sender = this.props.event.getSender();
57106

@@ -84,6 +133,7 @@ export default class PinnedEventTile extends React.Component<IProps> {
84133
<div className="mx_PinnedEventTile_message">
85134
<MessageEvent
86135
mxEvent={this.props.event}
136+
getRelationsForEvent={this.getRelationsForEvent}
87137
// @ts-ignore - complaining that className is invalid when it's not
88138
className="mx_PinnedEventTile_body"
89139
maxImageHeight={150}

src/utils/PinningUtils.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,27 @@ limitations under the License.
1515
*/
1616

1717
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
18+
import { EventType } from "matrix-js-sdk/src/@types/event";
19+
import { M_POLL_START } from "matrix-events-sdk";
1820

1921
export default class PinningUtils {
22+
/**
23+
* Event types that may be pinned.
24+
*/
25+
static pinnableEventTypes: (EventType | string)[] = [
26+
EventType.RoomMessage,
27+
M_POLL_START.name,
28+
M_POLL_START.altName,
29+
];
30+
2031
/**
2132
* Determines if the given event may be pinned.
2233
* @param {MatrixEvent} event The event to check.
2334
* @return {boolean} True if the event may be pinned, false otherwise.
2435
*/
2536
static isPinnable(event: MatrixEvent): boolean {
2637
if (!event) return false;
27-
if (event.getType() !== "m.room.message") return false;
38+
if (!this.pinnableEventTypes.includes(event.getType())) return false;
2839
if (event.isRedacted()) return false;
2940

3041
return true;

0 commit comments

Comments
 (0)