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

Commit 488a08a

Browse files
authored
Allow reactions for broadcasts (#9856)
1 parent 720bf05 commit 488a08a

File tree

7 files changed

+57
-7
lines changed

7 files changed

+57
-7
lines changed

src/components/views/messages/MessageActionBar.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ import { Action } from "../../../dispatcher/actions";
5959
import { ShowThreadPayload } from "../../../dispatcher/payloads/ShowThreadPayload";
6060
import useFavouriteMessages from "../../../hooks/useFavouriteMessages";
6161
import { GetRelationsForEvent } from "../rooms/EventTile";
62+
import { VoiceBroadcastInfoEventType } from "../../../voice-broadcast/types";
6263

6364
interface IOptionsButtonProps {
6465
mxEvent: MatrixEvent;
@@ -394,7 +395,8 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
394395
* until cross-platform support
395396
* (PSF-1041)
396397
*/
397-
!M_BEACON_INFO.matches(this.props.mxEvent.getType());
398+
!M_BEACON_INFO.matches(this.props.mxEvent.getType()) &&
399+
!(this.props.mxEvent.getType() === VoiceBroadcastInfoEventType);
398400

399401
return inNotThreadTimeline && isAllowedMessageType;
400402
}

src/events/forward/getForwardableEvent.ts

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { M_BEACON_INFO } from "matrix-js-sdk/src/@types/beacon";
1919
import { MatrixEvent, MatrixClient } from "matrix-js-sdk/src/matrix";
2020

2121
import { getShareableLocationEventForBeacon } from "../../utils/beacon/getShareableLocation";
22+
import { VoiceBroadcastInfoEventType } from "../../voice-broadcast/types";
2223

2324
/**
2425
* Get forwardable event for a given event
@@ -29,6 +30,8 @@ export const getForwardableEvent = (event: MatrixEvent, cli: MatrixClient): Matr
2930
return null;
3031
}
3132

33+
if (event.getType() === VoiceBroadcastInfoEventType) return null;
34+
3235
// Live location beacons should forward their latest location as a static pin location
3336
// If the beacon is not live, or doesn't have a location forwarding is not allowed
3437
if (M_BEACON_INFO.matches(event.getType())) {

src/utils/EventUtils.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { TimelineRenderingType } from "../contexts/RoomContext";
3232
import { launchPollEditor } from "../components/views/messages/MPollBody";
3333
import { Action } from "../dispatcher/actions";
3434
import { ViewRoomPayload } from "../dispatcher/payloads/ViewRoomPayload";
35+
import { VoiceBroadcastInfoEventType, VoiceBroadcastInfoState } from "../voice-broadcast/types";
3536

3637
/**
3738
* Returns whether an event should allow actions like reply, reactions, edit, etc.
@@ -56,7 +57,9 @@ export function isContentActionable(mxEvent: MatrixEvent): boolean {
5657
} else if (
5758
mxEvent.getType() === "m.sticker" ||
5859
M_POLL_START.matches(mxEvent.getType()) ||
59-
M_BEACON_INFO.matches(mxEvent.getType())
60+
M_BEACON_INFO.matches(mxEvent.getType()) ||
61+
(mxEvent.getType() === VoiceBroadcastInfoEventType &&
62+
mxEvent.getContent()?.state === VoiceBroadcastInfoState.Started)
6063
) {
6164
return true;
6265
}

test/components/views/context_menus/MessageContextMenu-test.tsx

+14-2
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,15 @@ import dispatcher from "../../../../src/dispatcher/dispatcher";
4242
import SettingsStore from "../../../../src/settings/SettingsStore";
4343
import { ReadPinsEventId } from "../../../../src/components/views/right_panel/types";
4444
import { Action } from "../../../../src/dispatcher/actions";
45+
import { mkVoiceBroadcastInfoStateEvent } from "../../../voice-broadcast/utils/test-utils";
46+
import { VoiceBroadcastInfoState } from "../../../../src/voice-broadcast";
4547

4648
jest.mock("../../../../src/utils/strings", () => ({
4749
copyPlaintext: jest.fn(),
4850
getSelectedText: jest.fn(),
4951
}));
5052
jest.mock("../../../../src/utils/EventUtils", () => ({
51-
// @ts-ignore don't mock everything
52-
...jest.requireActual("../../../../src/utils/EventUtils"),
53+
...(jest.requireActual("../../../../src/utils/EventUtils") as object),
5354
canEditContent: jest.fn(),
5455
}));
5556
jest.mock("../../../../src/dispatcher/dispatcher");
@@ -241,6 +242,17 @@ describe("MessageContextMenu", () => {
241242
expect(menu.find('div[aria-label="Forward"]')).toHaveLength(0);
242243
});
243244

245+
it("should not allow forwarding a voice broadcast", () => {
246+
const broadcastStartEvent = mkVoiceBroadcastInfoStateEvent(
247+
roomId,
248+
VoiceBroadcastInfoState.Started,
249+
"@user:example.com",
250+
"ABC123",
251+
);
252+
const menu = createMenu(broadcastStartEvent);
253+
expect(menu.find('div[aria-label="Forward"]')).toHaveLength(0);
254+
});
255+
244256
describe("forwarding beacons", () => {
245257
const aliceId = "@alice:server.org";
246258

test/components/views/messages/MessageActionBar-test.tsx

+14-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ limitations under the License.
1515
*/
1616

1717
import React from "react";
18-
import { render, fireEvent } from "@testing-library/react";
19-
import { act } from "react-test-renderer";
18+
import { act, render, fireEvent } from "@testing-library/react";
2019
import { EventType, EventStatus, MatrixEvent, MatrixEventEvent, MsgType, Room } from "matrix-js-sdk/src/matrix";
2120
import { FeatureSupport, Thread } from "matrix-js-sdk/src/models/thread";
2221

@@ -34,6 +33,8 @@ import dispatcher from "../../../../src/dispatcher/dispatcher";
3433
import SettingsStore from "../../../../src/settings/SettingsStore";
3534
import { Action } from "../../../../src/dispatcher/actions";
3635
import { UserTab } from "../../../../src/components/views/dialogs/UserTab";
36+
import { mkVoiceBroadcastInfoStateEvent } from "../../../voice-broadcast/utils/test-utils";
37+
import { VoiceBroadcastInfoState } from "../../../../src/voice-broadcast";
3738

3839
jest.mock("../../../../src/dispatcher/dispatcher");
3940

@@ -405,6 +406,17 @@ describe("<MessageActionBar />", () => {
405406
expect(queryByLabelText("Reply in thread")).toBeTruthy();
406407
});
407408

409+
it("does not render thread button for a voice broadcast", () => {
410+
const broadcastEvent = mkVoiceBroadcastInfoStateEvent(
411+
roomId,
412+
VoiceBroadcastInfoState.Started,
413+
userId,
414+
"ABC123",
415+
);
416+
const { queryByLabelText } = getComponent({ mxEvent: broadcastEvent });
417+
expect(queryByLabelText("Reply in thread")).not.toBeInTheDocument();
418+
});
419+
408420
it("opens user settings on click", () => {
409421
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
410422
const { getByLabelText } = getComponent({ mxEvent: alicesMessageEvent });

test/utils/EventUtils-test.ts

+18
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ import {
4343
import { getMockClientWithEventEmitter, makeBeaconInfoEvent, makePollStartEvent, stubClient } from "../test-utils";
4444
import dis from "../../src/dispatcher/dispatcher";
4545
import { Action } from "../../src/dispatcher/actions";
46+
import { mkVoiceBroadcastInfoStateEvent } from "../voice-broadcast/utils/test-utils";
47+
import { VoiceBroadcastInfoState } from "../../src/voice-broadcast/types";
4648

4749
jest.mock("../../src/dispatcher/dispatcher");
4850

@@ -151,6 +153,20 @@ describe("EventUtils", () => {
151153
},
152154
});
153155

156+
const voiceBroadcastStart = mkVoiceBroadcastInfoStateEvent(
157+
"!room:example.com",
158+
VoiceBroadcastInfoState.Started,
159+
"@user:example.com",
160+
"ABC123",
161+
);
162+
163+
const voiceBroadcastStop = mkVoiceBroadcastInfoStateEvent(
164+
"!room:example.com",
165+
VoiceBroadcastInfoState.Stopped,
166+
"@user:example.com",
167+
"ABC123",
168+
);
169+
154170
describe("isContentActionable()", () => {
155171
type TestCase = [string, MatrixEvent];
156172
it.each<TestCase>([
@@ -161,6 +177,7 @@ describe("EventUtils", () => {
161177
["room member event", roomMemberEvent],
162178
["event without msgtype", noMsgType],
163179
["event without content body property", noContentBody],
180+
["broadcast stop event", voiceBroadcastStop],
164181
])("returns false for %s", (_description, event) => {
165182
expect(isContentActionable(event)).toBe(false);
166183
});
@@ -171,6 +188,7 @@ describe("EventUtils", () => {
171188
["event with empty content body", emptyContentBody],
172189
["event with a content body", niceTextMessage],
173190
["beacon_info event", beaconInfoEvent],
191+
["broadcast start event", voiceBroadcastStart],
174192
])("returns true for %s", (_description, event) => {
175193
expect(isContentActionable(event)).toBe(true);
176194
});

test/voice-broadcast/utils/test-utils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
VoiceBroadcastChunkEventType,
2222
VoiceBroadcastInfoEventType,
2323
VoiceBroadcastInfoState,
24-
} from "../../../src/voice-broadcast";
24+
} from "../../../src/voice-broadcast/types";
2525
import { mkEvent } from "../../test-utils";
2626

2727
// timestamp incremented on each call to prevent duplicate timestamp

0 commit comments

Comments
 (0)