Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render unknown events and message types so users don't miss messages #1197

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/domain/session/room/timeline/tiles/ITile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export enum TileShape {
DateHeader = "date-header",
Call = "call",
Verification = "verification",
UnknownMessage = "unknown-message",
UnknownEvent = "unknown-event",
}

// TODO: should we imply inheriting from view model here?
Expand Down
28 changes: 28 additions & 0 deletions src/domain/session/room/timeline/tiles/UnknownEventTile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
Copyright 2024 Mirian Margiani <[email protected]>

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 {SimpleTile} from "./SimpleTile";

export class UnknownEventTile extends SimpleTile {

get shape() {
return "unknown-event";
}

get announcement() {
return this.i18n`You received a message that this app cannot display (event “${this._entry.eventType}”). Please report this issue.`
}
}
48 changes: 48 additions & 0 deletions src/domain/session/room/timeline/tiles/UnknownMessageTile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Copyright 2020 Bruno Windels <[email protected]>
Copyright 2024 Mirian Margiani <[email protected]>

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 {TextTile} from "./TextTile.js";
import {BodyFormat} from "./BaseTextTile.js";
import {parsePlainBody} from "../MessageBody.js";
import {parseHTMLBody} from "../deserialize.js";

export class UnknownMessageTile extends TextTile {
get shape() {
return "unknown-message";
}

get body() {
let body = this._getPlainBody();

// body is a string, so we can check for difference by just
// doing an equality check
if (!this._messageBody || this._messageBody.sourceString !== body) {
const msgtype = this._getContentString('msgtype');
const notice = this.i18n`This app cannot properly display this message (type “${msgtype}”). Please report this issue.`
body = `<em>${notice}</em><br><code>${body}</code>`;

// body with markup is an array of parts,
// so we should not recreate it for the same body string,
// or else the equality check in the binding will always fail.
// So cache it here.
this._messageBody = this._parseBody(body, BodyFormat.Html);
this._format = BodyFormat.Html;
}

return this._messageBody;
}
}
34 changes: 30 additions & 4 deletions src/domain/session/room/timeline/tiles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import {EncryptionEnabledTile} from "./EncryptionEnabledTile.js";
import {MissingAttachmentTile} from "./MissingAttachmentTile.js";
import {CallTile} from "./CallTile.js";
import {VerificationTile} from "./VerificationTile.js";
import {UnknownMessageTile} from "./UnknownMessageTile.js";
import {UnknownEventTile} from "./UnknownEventTile.js";

import type {ITile, TileShape} from "./ITile";
import type {Room} from "../../../../../matrix/room/Room";
Expand Down Expand Up @@ -82,8 +84,10 @@ export function tileClassForEntry(entry: TimelineEntry, options: Options): TileC
}
return VerificationTile as unknown as TileConstructor;
default:
// unknown msgtype not rendered
return undefined;
// Unknown messages are rendered using the fallback plain text
// representation, including a notice that the message is not
// supported.
return UnknownMessageTile;
}
}
case "m.room.name":
Expand All @@ -105,9 +109,31 @@ export function tileClassForEntry(entry: TimelineEntry, options: Options): TileC
}
return undefined;
}
default:
// unknown type not rendered

// These events are handled separately and don't need an extra timeline entry.
case "m.reaction":
case "m.room.redaction":
return undefined;

// Displaying these events is not supported but they can safely be
// hidden instead of spamming rooms with warning messages.
case "m.room.create":
case "m.room.power_levels":
case "m.room.join_rules":
case "m.room.history_visibility":
case "m.room.guest_access":
case "m.room.topic":
case "m.room.avatar":
case "m.bridge":
case "uk.half-shot.bridge":
return undefined;

// Unknown events are rendered as a placeholder so users notice that
// there is something that they are missing. Ideally, all events
// are either added to the "safe-to-ignore" list above, or rendered
// with proper tile implementations.
default:
return UnknownEventTile;
}
}
}
2 changes: 2 additions & 0 deletions src/platform/web/ui/session/room/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ export function viewClassForTile(vm: ITile): TileViewConstructor {
case TileShape.Gap:
return GapView;
case TileShape.Announcement:
case TileShape.UnknownEvent:
return AnnouncementView;
case TileShape.Message:
case TileShape.MessageStatus:
case TileShape.UnknownMessage:
return TextMessageView;
case TileShape.Image:
return ImageView;
Expand Down