Skip to content

Commit

Permalink
Use the same logic in prevews as the timeline to hide events that sho…
Browse files Browse the repository at this point in the history
…uld be hidden (#12434)

* use the same logic in prevews as the timeline to hide events that should not be shown

* skip any events we should hide, don't need to special case Replace events as we should be ignoring them(getContent() will use replacingEvent)

* lint
  • Loading branch information
langleyd authored Apr 17, 2024
1 parent 1ace170 commit 6cec2bb
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 25 deletions.
30 changes: 5 additions & 25 deletions src/stores/room-list/MessagePreviewStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { UPDATE_EVENT } from "../AsyncStore";
import { IPreview } from "./previews/IPreview";
import { VoiceBroadcastInfoEventType } from "../../voice-broadcast";
import { VoiceBroadcastPreview } from "./previews/VoiceBroadcastPreview";
import shouldHideEvent from "../../shouldHideEvent";

// Emitted event for when a room's preview has changed. First argument will the room for which
// the change happened.
Expand Down Expand Up @@ -184,21 +185,6 @@ export class MessagePreviewStore extends AsyncStoreWithClient<IState> {
return previewDef?.previewer.getTextFor(event, undefined, true) ?? "";
}

private shouldSkipPreview(event: MatrixEvent, previousEvent?: MatrixEvent): boolean {
if (event.isRelation(RelationType.Replace)) {
if (previousEvent !== undefined) {
// Ignore edits if they don't apply to the latest event in the room to keep the preview on the latest event
const room = this.matrixClient?.getRoom(event.getRoomId()!);
const relatedEvent = room?.findEventById(event.relationEventId!);
if (relatedEvent !== previousEvent) {
return true;
}
}
}

return false;
}

private async generatePreview(room: Room, tagId?: TagID): Promise<void> {
const events = [...room.getLiveTimeline().getEvents()];

Expand All @@ -221,8 +207,6 @@ export class MessagePreviewStore extends AsyncStoreWithClient<IState> {
this.previews.set(room.roomId, map);
}

const previousEventInAny = map.get(TAG_ANY)?.event;

// Set the tags so we know what to generate
if (!map.has(TAG_ANY)) map.set(TAG_ANY, null);
if (tagId && !map.has(tagId)) map.set(tagId, null);
Expand All @@ -237,24 +221,20 @@ export class MessagePreviewStore extends AsyncStoreWithClient<IState> {
const event = events[i];

await this.matrixClient?.decryptEventIfNeeded(event);

const shouldHide = shouldHideEvent(event);
if (shouldHide) continue;
const previewDef = PREVIEWS[event.getType()];
if (!previewDef) continue;
if (previewDef.isState && isNullOrUndefined(event.getStateKey())) continue;

const anyPreviewText = previewDef.previewer.getTextFor(event);
if (!anyPreviewText) continue; // not previewable for some reason

if (!this.shouldSkipPreview(event, previousEventInAny)) {
changed = changed || anyPreviewText !== map.get(TAG_ANY)?.text;
map.set(TAG_ANY, mkMessagePreview(anyPreviewText, event));
}
changed = changed || anyPreviewText !== map.get(TAG_ANY)?.text;
map.set(TAG_ANY, mkMessagePreview(anyPreviewText, event));

const tagsToGenerate = Array.from(map.keys()).filter((t) => t !== TAG_ANY); // we did the any tag above
for (const genTagId of tagsToGenerate) {
const previousEventInTag = map.get(genTagId)?.event;
if (this.shouldSkipPreview(event, previousEventInTag)) continue;

const realTagId = genTagId === TAG_ANY ? undefined : genTagId;
const preview = previewDef.previewer.getTextFor(event, realTagId);

Expand Down
56 changes: 56 additions & 0 deletions test/stores/room-list/MessagePreviewStore-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,62 @@ describe("MessagePreviewStore", () => {
);
});

it("should not display a redacted edit", async () => {
const firstMessage = mkMessage({
user: "@sender:server",
event: true,
room: room.roomId,
msg: "First message",
});
await addEvent(store, room, firstMessage, false);

expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot(
`"@sender:server: First message"`,
);

const secondMessage = mkMessage({
user: "@sender:server",
event: true,
room: room.roomId,
msg: "Second message",
});
await addEvent(store, room, secondMessage);

expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot(
`"@sender:server: Second message"`,
);

const secondMessageEdit = mkEvent({
event: true,
type: EventType.RoomMessage,
user: "@sender:server",
room: room.roomId,
content: {
"body": "* Second Message Edit",
"m.new_content": {
body: "Second Message Edit",
},
"m.relates_to": {
rel_type: RelationType.Replace,
event_id: secondMessage.getId()!,
},
},
});
await addEvent(store, room, secondMessageEdit);

expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot(
`"@sender:server: Second Message Edit"`,
);

secondMessage.makeRedacted(secondMessage, room);

await addEvent(store, room, secondMessage);

expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot(
`"@sender:server: First message"`,
);
});

it("should ignore edits to unknown events", async () => {
await expect(store.getPreviewForRoom(room, DefaultTagID.DM)).resolves.toBeNull();

Expand Down

0 comments on commit 6cec2bb

Please sign in to comment.