mirror of
https://github.com/Novaloop-AG/healthchat-web.git
synced 2026-11-06 22:48:21 +00:00
Improve rendering of empty topics in the timeline (#29152)
* Improve display of empty topic events in the timeline. * Use topic parser for topic events. * Revert changes i18n for the moment * Use the correct import pattern * Add tests for topic rendering
This commit is contained in:
+10
-4
@@ -17,6 +17,7 @@ import {
|
|||||||
MsgType,
|
MsgType,
|
||||||
M_POLL_START,
|
M_POLL_START,
|
||||||
M_POLL_END,
|
M_POLL_END,
|
||||||
|
ContentHelpers,
|
||||||
} from "matrix-js-sdk/src/matrix";
|
} from "matrix-js-sdk/src/matrix";
|
||||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
@@ -227,11 +228,16 @@ function textForMemberEvent(
|
|||||||
|
|
||||||
function textForTopicEvent(ev: MatrixEvent): (() => string) | null {
|
function textForTopicEvent(ev: MatrixEvent): (() => string) | null {
|
||||||
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||||
|
const topic = ContentHelpers.parseTopicContent(ev.getContent()).text;
|
||||||
return () =>
|
return () =>
|
||||||
_t("timeline|m.room.topic", {
|
topic
|
||||||
senderDisplayName,
|
? _t("timeline|m.room.topic|changed", {
|
||||||
topic: ev.getContent().topic,
|
senderDisplayName,
|
||||||
});
|
topic,
|
||||||
|
})
|
||||||
|
: _t("timeline|m.room.topic|removed", {
|
||||||
|
senderDisplayName,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function textForRoomAvatarEvent(ev: MatrixEvent): (() => string) | null {
|
function textForRoomAvatarEvent(ev: MatrixEvent): (() => string) | null {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
|
|||||||
|
|
||||||
import React, { createRef } from "react";
|
import React, { createRef } from "react";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { EventType } from "matrix-js-sdk/src/matrix";
|
import { ContentHelpers, EventType } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||||
@@ -51,7 +51,7 @@ export default class RoomProfileSettings extends React.Component<IProps, IState>
|
|||||||
const avatarUrl = avatarEvent?.getContent()["url"] ?? null;
|
const avatarUrl = avatarEvent?.getContent()["url"] ?? null;
|
||||||
|
|
||||||
const topicEvent = room.currentState.getStateEvents(EventType.RoomTopic, "");
|
const topicEvent = room.currentState.getStateEvents(EventType.RoomTopic, "");
|
||||||
const topic = topicEvent && topicEvent.getContent() ? topicEvent.getContent()["topic"] : "";
|
const topic = (topicEvent && ContentHelpers.parseTopicContent(topicEvent.getContent()).text) || "";
|
||||||
|
|
||||||
const nameEvent = room.currentState.getStateEvents(EventType.RoomName, "");
|
const nameEvent = room.currentState.getStateEvents(EventType.RoomName, "");
|
||||||
const name = nameEvent && nameEvent.getContent() ? nameEvent.getContent()["name"] : "";
|
const name = nameEvent && nameEvent.getContent() ? nameEvent.getContent()["name"] : "";
|
||||||
@@ -145,6 +145,8 @@ export default class RoomProfileSettings extends React.Component<IProps, IState>
|
|||||||
|
|
||||||
if (this.state.originalTopic !== this.state.topic) {
|
if (this.state.originalTopic !== this.state.topic) {
|
||||||
const html = htmlSerializeFromMdIfNeeded(this.state.topic, { forceHTML: false });
|
const html = htmlSerializeFromMdIfNeeded(this.state.topic, { forceHTML: false });
|
||||||
|
// XXX: Note that we deliberately send an empty string on an empty topic rather
|
||||||
|
// than a clearer `undefined` value. Synapse still requires a string in a topic.
|
||||||
await client.setRoomTopic(this.props.roomId, this.state.topic, html);
|
await client.setRoomTopic(this.props.roomId, this.state.topic, html);
|
||||||
newState.originalTopic = this.state.topic;
|
newState.originalTopic = this.state.topic;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3493,7 +3493,10 @@
|
|||||||
"sent": "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room."
|
"sent": "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room."
|
||||||
},
|
},
|
||||||
"m.room.tombstone": "%(senderDisplayName)s upgraded this room.",
|
"m.room.tombstone": "%(senderDisplayName)s upgraded this room.",
|
||||||
"m.room.topic": "%(senderDisplayName)s changed the topic to \"%(topic)s\".",
|
"m.room.topic": {
|
||||||
|
"changed": "%(senderDisplayName)s changed the topic to \"%(topic)s\".",
|
||||||
|
"removed": "%(senderDisplayName)s removed the topic."
|
||||||
|
},
|
||||||
"m.sticker": "%(senderDisplayName)s sent a sticker.",
|
"m.sticker": "%(senderDisplayName)s sent a sticker.",
|
||||||
"m.video": {
|
"m.video": {
|
||||||
"error_decrypting": "Error decrypting video"
|
"error_decrypting": "Error decrypting video"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
JoinRule,
|
JoinRule,
|
||||||
MatrixClient,
|
MatrixClient,
|
||||||
MatrixEvent,
|
MatrixEvent,
|
||||||
|
MRoomTopicEventContent,
|
||||||
Room,
|
Room,
|
||||||
RoomMember,
|
RoomMember,
|
||||||
} from "matrix-js-sdk/src/matrix";
|
} from "matrix-js-sdk/src/matrix";
|
||||||
@@ -613,4 +614,47 @@ describe("TextForEvent", () => {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("textForTopicEvent()", () => {
|
||||||
|
type TestCase = [string, MRoomTopicEventContent, { result: string }];
|
||||||
|
const testCases: TestCase[] = [
|
||||||
|
["the legacy key", { topic: "My topic" }, { result: '@a changed the topic to "My topic".' }],
|
||||||
|
[
|
||||||
|
"the legacy key with an empty m.topic key",
|
||||||
|
{ "topic": "My topic", "m.topic": [] },
|
||||||
|
{ result: '@a changed the topic to "My topic".' },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"the m.topic key",
|
||||||
|
{ "topic": "Ignore this", "m.topic": [{ mimetype: "text/plain", body: "My topic" }] },
|
||||||
|
{ result: '@a changed the topic to "My topic".' },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"the m.topic key and the legacy key undefined",
|
||||||
|
{ "topic": undefined, "m.topic": [{ mimetype: "text/plain", body: "My topic" }] },
|
||||||
|
{ result: '@a changed the topic to "My topic".' },
|
||||||
|
],
|
||||||
|
["the legacy key undefined", { topic: undefined }, { result: "@a removed the topic." }],
|
||||||
|
["the legacy key empty string", { topic: "" }, { result: "@a removed the topic." }],
|
||||||
|
[
|
||||||
|
"both the legacy and new keys removed",
|
||||||
|
{ "topic": undefined, "m.topic": [] },
|
||||||
|
{ result: "@a removed the topic." },
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
it.each(testCases)("returns correct message for topic event with %s", (_caseName, content, { result }) => {
|
||||||
|
expect(
|
||||||
|
textForEvent(
|
||||||
|
new MatrixEvent({
|
||||||
|
type: "m.room.topic",
|
||||||
|
sender: "@a",
|
||||||
|
content: content,
|
||||||
|
state_key: "",
|
||||||
|
}),
|
||||||
|
mockClient,
|
||||||
|
),
|
||||||
|
).toEqual(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user