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

Commit

Permalink
Implement broadcast message preview
Browse files Browse the repository at this point in the history
  • Loading branch information
weeman1337 committed Dec 14, 2022
1 parent 8a0b62c commit 6282ff7
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,8 @@
"Someone else is already recording a voice broadcast. Wait for their voice broadcast to end to start a new one.": "Someone else is already recording a voice broadcast. Wait for their voice broadcast to end to start a new one.",
"You ended a <a>voice broadcast</a>": "You ended a <a>voice broadcast</a>",
"%(senderName)s ended a <a>voice broadcast</a>": "%(senderName)s ended a <a>voice broadcast</a>",
"You ended a voice broadcast": "You ended a voice broadcast",
"%(senderName)s ended a voice broadcast": "%(senderName)s ended a voice broadcast",
"Stop live broadcasting?": "Stop live broadcasting?",
"Are you sure you want to stop your live broadcast?This will end the broadcast and the full recording will be available in the room.": "Are you sure you want to stop your live broadcast?This will end the broadcast and the full recording will be available in the room.",
"Yes, stop broadcast": "Yes, stop broadcast",
Expand Down
6 changes: 6 additions & 0 deletions src/stores/room-list/MessagePreviewStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import { StickerEventPreview } from "./previews/StickerEventPreview";
import { ReactionEventPreview } from "./previews/ReactionEventPreview";
import { UPDATE_EVENT } from "../AsyncStore";
import { IPreview } from "./previews/IPreview";
import { VoiceBroadcastInfoEventType } from "../../voice-broadcast";
import { VoiceBroadcastPreview } from "./previews/VoiceBroadcastPreview";

// Emitted event for when a room's preview has changed. First argument will the room for which
// the change happened.
Expand Down Expand Up @@ -76,6 +78,10 @@ const PREVIEWS: Record<
isState: false,
previewer: new PollStartEventPreview(),
},
[VoiceBroadcastInfoEventType]: {
isState: true,
previewer: new VoiceBroadcastPreview(),
},
};

// The maximum number of events we're willing to look back on to get a preview.
Expand Down
3 changes: 3 additions & 0 deletions src/stores/room-list/previews/MessageEventPreview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ export class MessageEventPreview implements IPreview {
public getTextFor(event: MatrixEvent, tagId?: TagID, isThread?: boolean): string {
let eventContent = event.getContent();

// no preview for broadcast chunks
if (eventContent["io.element.voice_broadcast_chunk"]) return null;

if (event.isRelation(RelationType.Replace)) {
// It's an edit, generate the preview on the new text
eventContent = event.getContent()["m.new_content"];
Expand Down
30 changes: 30 additions & 0 deletions src/stores/room-list/previews/VoiceBroadcastPreview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import { MatrixEvent } from "matrix-js-sdk/src/matrix";

import { textForVoiceBroadcastStoppedEventWithoutLink, VoiceBroadcastInfoState } from "../../../voice-broadcast";
import { IPreview } from "./IPreview";

export class VoiceBroadcastPreview implements IPreview {
getTextFor(event: MatrixEvent, tagId?: string, isThread?: boolean): string | null {
if (!event.isRedacted() && event.getContent()?.state === VoiceBroadcastInfoState.Stopped) {
return textForVoiceBroadcastStoppedEventWithoutLink(event);
}

return null;
}
}
1 change: 1 addition & 0 deletions src/voice-broadcast/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export * from "./utils/shouldDisplayAsVoiceBroadcastTile";
export * from "./utils/shouldDisplayAsVoiceBroadcastStoppedText";
export * from "./utils/startNewVoiceBroadcastRecording";
export * from "./utils/textForVoiceBroadcastStoppedEvent";
export * from "./utils/textForVoiceBroadcastStoppedEventWithoutLink";
export * from "./utils/VoiceBroadcastResumer";

export const VoiceBroadcastInfoEventType = "io.element.voice_broadcast_info";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import { MatrixEvent } from "matrix-js-sdk/src/matrix";

import { _t } from "../../languageHandler";
import { MatrixClientPeg } from "../../MatrixClientPeg";
import { getSenderName } from "../../TextForEvent";

export const textForVoiceBroadcastStoppedEventWithoutLink = (event: MatrixEvent): string => {
const ownUserId = MatrixClientPeg.get()?.getUserId();

if (ownUserId && ownUserId === event.getSender()) {
return _t("You ended a voice broadcast", {});
}

return _t("%(senderName)s ended a voice broadcast", { senderName: getSenderName(event) });
};
96 changes: 96 additions & 0 deletions test/stores/room-list/previews/MessageEventPreview-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import { RelationType } from "matrix-js-sdk/src/matrix";

import { MessageEventPreview } from "../../../../src/stores/room-list/previews/MessageEventPreview";
import { mkEvent, stubClient } from "../../../test-utils";

describe("MessageEventPreview", () => {
const preview = new MessageEventPreview();
const userId = "@user:example.com";

beforeAll(() => {
stubClient();
});

describe("getTextFor", () => {
it("when called with an event with empty content should return null", () => {
const event = mkEvent({
event: true,
content: {},
user: userId,
type: "m.room.message",
});
expect(preview.getTextFor(event)).toBeNull();
});

it("when called with an event with empty body should return null", () => {
const event = mkEvent({
event: true,
content: {
body: "",
},
user: userId,
type: "m.room.message",
});
expect(preview.getTextFor(event)).toBeNull();
});

it("when called with an event with body should return »user: body«", () => {
const event = mkEvent({
event: true,
content: {
body: "test body",
},
user: userId,
type: "m.room.message",
});
expect(preview.getTextFor(event)).toBe(`${userId}: test body`);
});

it("when called for a replaced event with new content should return the new content body", () => {
const event = mkEvent({
event: true,
content: {
["m.new_content"]: {
body: "test new content body",
},
["m.relates_to"]: {
rel_type: RelationType.Replace,
event_id: "$asd123",
},
},
user: userId,
type: "m.room.message",
});
expect(preview.getTextFor(event)).toBe(`${userId}: test new content body`);
});

it("when called with a broadcast chunk event it should return null", () => {
const event = mkEvent({
event: true,
content: {
body: "test body",
["io.element.voice_broadcast_chunk"]: {},
},
user: userId,
type: "m.room.message",
});
expect(preview.getTextFor(event)).toBeNull();
});
});
});
1 change: 1 addition & 0 deletions test/test-utils/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export function createTestClient(): MatrixClient {
getIdentityServerUrl: jest.fn(),
getDomain: jest.fn().mockReturnValue("matrix.org"),
getUserId: jest.fn().mockReturnValue("@userId:matrix.org"),
getSafeUserId: jest.fn().mockReturnValue("@userId:matrix.org"),
getUserIdLocalpart: jest.fn().mockResolvedValue("userId"),
getUser: jest.fn().mockReturnValue({ on: jest.fn() }),
getDeviceId: jest.fn().mockReturnValue("ABCDEFGHI"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import { mocked } from "jest-mock";
import { MatrixClient } from "matrix-js-sdk/src/client";

import { textForVoiceBroadcastStoppedEventWithoutLink, VoiceBroadcastInfoState } from "../../../src/voice-broadcast";
import { stubClient } from "../../test-utils";
import { mkVoiceBroadcastInfoStateEvent } from "./test-utils";

describe("textForVoiceBroadcastStoppedEventWithoutLink", () => {
const otherUserId = "@other:example.com";
const roomId = "!room:example.com";
let client: MatrixClient;

beforeAll(() => {
client = stubClient();
});

const getText = (senderId: string, startEventId?: string) => {
const event = mkVoiceBroadcastInfoStateEvent(
roomId,
VoiceBroadcastInfoState.Stopped,
senderId,
client.deviceId!,
);
return textForVoiceBroadcastStoppedEventWithoutLink(event);
};

it("when called for an own broadcast it should return the expected text", () => {
expect(getText(client.getUserId()!)).toBe("You ended a voice broadcast");
});

it("when called for other ones broadcast it should return the expected text", () => {
expect(getText(otherUserId)).toBe(`${otherUserId} ended a voice broadcast`);
});

it("when not logged in it should return the exptected text", () => {
mocked(client.getUserId).mockReturnValue(null);
expect(getText(otherUserId)).toBe(`${otherUserId} ended a voice broadcast`);
});
});

0 comments on commit 6282ff7

Please sign in to comment.