Allow hiding invite and kick messages from timeline

This commit is contained in:
Ondřej Hošek 2024-10-19 22:17:45 +02:00
parent 7de5c84b3d
commit 590ef74cc9
9 changed files with 52 additions and 0 deletions

View file

@ -217,6 +217,7 @@ export interface IRoomState {
showReadReceipts: boolean; showReadReceipts: boolean;
showRedactions: boolean; showRedactions: boolean;
showJoinLeaves: boolean; showJoinLeaves: boolean;
showInviteKicks: boolean;
showAvatarChanges: boolean; showAvatarChanges: boolean;
showDisplaynameChanges: boolean; showDisplaynameChanges: boolean;
matrixClientIsReady: boolean; matrixClientIsReady: boolean;
@ -406,6 +407,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
showReadReceipts: true, showReadReceipts: true,
showRedactions: true, showRedactions: true,
showJoinLeaves: true, showJoinLeaves: true,
showInviteKicks: true,
showAvatarChanges: true, showAvatarChanges: true,
showDisplaynameChanges: true, showDisplaynameChanges: true,
matrixClientIsReady: context.client?.isInitialSyncComplete(), matrixClientIsReady: context.client?.isInitialSyncComplete(),
@ -608,6 +610,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
showReadReceipts: SettingsStore.getValue("showReadReceipts", roomId), showReadReceipts: SettingsStore.getValue("showReadReceipts", roomId),
showRedactions: SettingsStore.getValue("showRedactions", roomId), showRedactions: SettingsStore.getValue("showRedactions", roomId),
showJoinLeaves: SettingsStore.getValue("showJoinLeaves", roomId), showJoinLeaves: SettingsStore.getValue("showJoinLeaves", roomId),
showInviteKicks: SettingsStore.getValue("showInviteKicks", roomId),
showAvatarChanges: SettingsStore.getValue("showAvatarChanges", roomId), showAvatarChanges: SettingsStore.getValue("showAvatarChanges", roomId),
showDisplaynameChanges: SettingsStore.getValue("showDisplaynameChanges", roomId), showDisplaynameChanges: SettingsStore.getValue("showDisplaynameChanges", roomId),
wasContextSwitch: this.context.roomViewStore.getWasContextSwitch(), wasContextSwitch: this.context.roomViewStore.getWasContextSwitch(),
@ -679,6 +682,9 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
SettingsStore.watchSetting("showJoinLeaves", roomId, (...[, , , value]) => SettingsStore.watchSetting("showJoinLeaves", roomId, (...[, , , value]) =>
this.setState({ showJoinLeaves: value as boolean }), this.setState({ showJoinLeaves: value as boolean }),
), ),
SettingsStore.watchSetting("showInviteKicks", roomId, (...[, , , value]) =>
this.setState({ showInviteKicks: value as boolean }),
),
SettingsStore.watchSetting("showAvatarChanges", roomId, (...[, , , value]) => SettingsStore.watchSetting("showAvatarChanges", roomId, (...[, , , value]) =>
this.setState({ showAvatarChanges: value as boolean }), this.setState({ showAvatarChanges: value as boolean }),
), ),

View file

@ -150,6 +150,7 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
"showRedactions", "showRedactions",
"showReadReceipts", "showReadReceipts",
"showJoinLeaves", "showJoinLeaves",
"showInviteKicks",
"showDisplaynameChanges", "showDisplaynameChanges",
"showChatEffects", "showChatEffects",
"showAvatarChanges", "showAvatarChanges",

View file

@ -61,6 +61,7 @@ const RoomContext = createContext<
showReadReceipts: true, showReadReceipts: true,
showRedactions: true, showRedactions: true,
showJoinLeaves: true, showJoinLeaves: true,
showInviteKicks: true,
showAvatarChanges: true, showAvatarChanges: true,
showDisplaynameChanges: true, showDisplaynameChanges: true,
matrixClientIsReady: false, matrixClientIsReady: false,

View file

@ -2900,6 +2900,7 @@
"show_breadcrumbs": "Show shortcuts to recently viewed rooms above the room list", "show_breadcrumbs": "Show shortcuts to recently viewed rooms above the room list",
"show_chat_effects": "Show chat effects (animations when receiving e.g. confetti)", "show_chat_effects": "Show chat effects (animations when receiving e.g. confetti)",
"show_displayname_changes": "Show display name changes", "show_displayname_changes": "Show display name changes",
"show_invite_kick": "Show invite/remove messages",
"show_join_leave": "Show join/leave messages (invites/removes/bans unaffected)", "show_join_leave": "Show join/leave messages (invites/removes/bans unaffected)",
"show_nsfw_content": "Show NSFW content", "show_nsfw_content": "Show NSFW content",
"show_read_receipts": "Show read receipts sent by other users", "show_read_receipts": "Show read receipts sent by other users",

View file

@ -599,6 +599,12 @@ export const SETTINGS: { [setting: string]: ISetting } = {
default: true, default: true,
invertedSettingName: "hideJoinLeaves", invertedSettingName: "hideJoinLeaves",
}, },
"showInviteKicks": {
supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM,
displayName: _td("settings|show_invite_kick"),
default: true,
invertedSettingName: "hideInviteKicks",
},
"showAvatarChanges": { "showAvatarChanges": {
supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM, supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM,
displayName: _td("settings|show_avatar_changes"), displayName: _td("settings|show_avatar_changes"),

View file

@ -18,6 +18,8 @@ interface IDiff {
isPart?: boolean; isPart?: boolean;
isDisplaynameChange?: boolean; isDisplaynameChange?: boolean;
isAvatarChange?: boolean; isAvatarChange?: boolean;
isInvite?: boolean;
isKick?: boolean;
} }
function memberEventDiff(ev: MatrixEvent): IDiff { function memberEventDiff(ev: MatrixEvent): IDiff {
@ -35,6 +37,9 @@ function memberEventDiff(ev: MatrixEvent): IDiff {
diff.isJoin = isMembershipChanged && content.membership === KnownMembership.Join; diff.isJoin = isMembershipChanged && content.membership === KnownMembership.Join;
diff.isPart = diff.isPart =
isMembershipChanged && content.membership === KnownMembership.Leave && ev.getStateKey() === ev.getSender(); isMembershipChanged && content.membership === KnownMembership.Leave && ev.getStateKey() === ev.getSender();
diff.isInvite = isMembershipChanged && content.membership === KnownMembership.Invite;
diff.isKick =
isMembershipChanged && content.membership === KnownMembership.Leave && ev.getStateKey() !== ev.getSender();
const isJoinToJoin = !isMembershipChanged && content.membership === KnownMembership.Join; const isJoinToJoin = !isMembershipChanged && content.membership === KnownMembership.Join;
diff.isDisplaynameChange = isJoinToJoin && content.displayname !== prevContent.displayname; diff.isDisplaynameChange = isJoinToJoin && content.displayname !== prevContent.displayname;
@ -67,6 +72,7 @@ export default function shouldHideEvent(ev: MatrixEvent, ctx?: IRoomState): bool
if (eventDiff.isMemberEvent) { if (eventDiff.isMemberEvent) {
if ((eventDiff.isJoin || eventDiff.isPart) && !isEnabled("showJoinLeaves")) return true; if ((eventDiff.isJoin || eventDiff.isPart) && !isEnabled("showJoinLeaves")) return true;
if ((eventDiff.isInvite || eventDiff.isKick) && !isEnabled("showInviteKicks")) return true;
if (eventDiff.isAvatarChange && !isEnabled("showAvatarChanges")) return true; if (eventDiff.isAvatarChange && !isEnabled("showAvatarChanges")) return true;
if (eventDiff.isDisplaynameChange && !isEnabled("showDisplaynameChanges")) return true; if (eventDiff.isDisplaynameChange && !isEnabled("showDisplaynameChanges")) return true;
} }

View file

@ -71,6 +71,7 @@ export function getRoomContext(room: Room, override: Partial<IRoomState>): IRoom
showReadReceipts: true, showReadReceipts: true,
showRedactions: true, showRedactions: true,
showJoinLeaves: true, showJoinLeaves: true,
showInviteKicks: true,
showAvatarChanges: true, showAvatarChanges: true,
showDisplaynameChanges: true, showDisplaynameChanges: true,
matrixClientIsReady: false, matrixClientIsReady: false,

View file

@ -82,6 +82,7 @@ describe("MessagePanel", function () {
showReadReceipts: true, showReadReceipts: true,
showRedactions: false, showRedactions: false,
showJoinLeaves: false, showJoinLeaves: false,
showInviteKicks: true,
showAvatarChanges: false, showAvatarChanges: false,
showDisplaynameChanges: true, showDisplaynameChanges: true,
showHiddenEvents: false, showHiddenEvents: false,
@ -463,6 +464,34 @@ describe("MessagePanel", function () {
expect(summaryEventTiles.length).toEqual(tiles.length - 3); expect(summaryEventTiles.length).toEqual(tiles.length - 3);
}); });
it("shows invite events if the user wishes to see them", function () {
const events = mkCreationEvents();
const inviteEvent = events.find(
(event) =>
event.getType() === "m.room.member"
&& event.getContent()?.membership === "invite"
)!;
const { container } = render(getComponent({ events }, { showInviteKicks: true }));
// there must be an invite event
const inviteEventTiles = container.querySelectorAll(`.mx_EventTile[data-event-id=\"${inviteEvent.getId()}\"]`);
expect(inviteEventTiles.length).toBeGreaterThan(0);
});
it("hides invite events if the user does not wish to see them", function () {
const events = mkCreationEvents();
const inviteEvent = events.find(
(event) =>
event.getType() === "m.room.member"
&& event.getContent()?.membership === "invite"
)!;
const { container } = render(getComponent({ events }, { showInviteKicks: false }));
// our invite event must not exist
const inviteEventTiles = container.querySelectorAll(`.mx_EventTile[data-event-id=\"${inviteEvent.getId()}\"]`);
expect(inviteEventTiles.length).toBe(0);
});
it("should not collapse beacons as part of creation events", function () { it("should not collapse beacons as part of creation events", function () {
const events = mkCreationEvents(); const events = mkCreationEvents();
const creationEvent = events.find((event) => event.getType() === "m.room.create")!; const creationEvent = events.find((event) => event.getType() === "m.room.create")!;

View file

@ -64,6 +64,7 @@ describe("<SendMessageComposer/>", () => {
showReadReceipts: true, showReadReceipts: true,
showRedactions: true, showRedactions: true,
showJoinLeaves: true, showJoinLeaves: true,
showInviteKicks: true,
showAvatarChanges: true, showAvatarChanges: true,
showDisplaynameChanges: true, showDisplaynameChanges: true,
matrixClientIsReady: false, matrixClientIsReady: false,