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

Commit 43c67ce

Browse files
authored
Add ignore user confirmation dialog (#6116)
Signed-off-by: Robin Townsend <[email protected]>
1 parent 269d162 commit 43c67ce

File tree

3 files changed

+85
-13
lines changed

3 files changed

+85
-13
lines changed

src/components/views/right_panel/UserInfo.tsx

+30-13
Original file line numberDiff line numberDiff line change
@@ -353,25 +353,42 @@ export const UserOptionsSection: React.FC<{
353353
});
354354
};
355355

356-
// Only allow the user to ignore the user if its not ourselves
357-
// same goes for jumping to read receipt
358-
if (!isMe) {
359-
const onIgnoreToggle = (): void => {
360-
const ignoredUsers = cli.getIgnoredUsers();
361-
if (isIgnored) {
362-
const index = ignoredUsers.indexOf(member.userId);
363-
if (index !== -1) ignoredUsers.splice(index, 1);
364-
} else {
365-
ignoredUsers.push(member.userId);
366-
}
356+
const unignore = useCallback(() => {
357+
const ignoredUsers = cli.getIgnoredUsers();
358+
const index = ignoredUsers.indexOf(member.userId);
359+
if (index !== -1) ignoredUsers.splice(index, 1);
360+
cli.setIgnoredUsers(ignoredUsers);
361+
}, [cli, member]);
362+
363+
const ignore = useCallback(async () => {
364+
const { finished } = Modal.createDialog(QuestionDialog, {
365+
title: _t("Ignore %(user)s", { user: member.name }),
366+
description: (
367+
<div>
368+
{_t(
369+
"All messages and invites from this user will be hidden. " +
370+
"Are you sure you want to ignore them?",
371+
)}
372+
</div>
373+
),
374+
button: _t("Ignore"),
375+
});
376+
const [confirmed] = await finished;
367377

378+
if (confirmed) {
379+
const ignoredUsers = cli.getIgnoredUsers();
380+
ignoredUsers.push(member.userId);
368381
cli.setIgnoredUsers(ignoredUsers);
369-
};
382+
}
383+
}, [cli, member]);
370384

385+
// Only allow the user to ignore the user if its not ourselves
386+
// same goes for jumping to read receipt
387+
if (!isMe) {
371388
ignoreButton = (
372389
<AccessibleButton
390+
onClick={isIgnored ? unignore : ignore}
373391
kind="link"
374-
onClick={onIgnoreToggle}
375392
className={classNames("mx_UserInfo_field", { mx_UserInfo_destructive: !isIgnored })}
376393
>
377394
{isIgnored ? _t("Unignore") : _t("Ignore")}

src/i18n/strings/en_EN.json

+2
Original file line numberDiff line numberDiff line change
@@ -2235,6 +2235,8 @@
22352235
"%(count)s sessions|one": "%(count)s session",
22362236
"Hide sessions": "Hide sessions",
22372237
"Message": "Message",
2238+
"Ignore %(user)s": "Ignore %(user)s",
2239+
"All messages and invites from this user will be hidden. Are you sure you want to ignore them?": "All messages and invites from this user will be hidden. Are you sure you want to ignore them?",
22382240
"Jump to read receipt": "Jump to read receipt",
22392241
"Mention": "Mention",
22402242
"Share Link to User": "Share Link to User",

test/components/views/right_panel/UserInfo-test.tsx

+53
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ const mockRoom = mocked({
7272
getMxcAvatarUrl: jest.fn().mockReturnValue("mock-avatar-url"),
7373
name: "test room",
7474
on: jest.fn(),
75+
off: jest.fn(),
7576
currentState: {
7677
getStateEvents: jest.fn(),
7778
on: jest.fn(),
@@ -83,9 +84,12 @@ const mockClient = mocked({
8384
getUser: jest.fn(),
8485
isGuest: jest.fn().mockReturnValue(false),
8586
isUserIgnored: jest.fn(),
87+
getIgnoredUsers: jest.fn(),
88+
setIgnoredUsers: jest.fn(),
8689
isCryptoEnabled: jest.fn(),
8790
getUserId: jest.fn(),
8891
on: jest.fn(),
92+
off: jest.fn(),
8993
isSynapseAdministrator: jest.fn().mockResolvedValue(false),
9094
isRoomEncrypted: jest.fn().mockReturnValue(false),
9195
doesServerSupportUnstableFeature: jest.fn().mockReturnValue(false),
@@ -386,8 +390,11 @@ describe("<UserOptionsSection />", () => {
386390

387391
beforeEach(() => {
388392
inviteSpy.mockReset();
393+
mockClient.setIgnoredUsers.mockClear();
389394
});
390395

396+
afterEach(() => Modal.closeCurrentModal("End of test"));
397+
391398
afterAll(() => {
392399
inviteSpy.mockRestore();
393400
});
@@ -543,6 +550,52 @@ describe("<UserOptionsSection />", () => {
543550
expect(screen.getByText(/operation failed/i)).toBeInTheDocument();
544551
});
545552
});
553+
554+
it("shows a modal before ignoring the user", async () => {
555+
const originalCreateDialog = Modal.createDialog;
556+
const modalSpy = (Modal.createDialog = jest.fn().mockReturnValue({
557+
finished: Promise.resolve([true]),
558+
close: () => {},
559+
}));
560+
561+
try {
562+
mockClient.getIgnoredUsers.mockReturnValue([]);
563+
renderComponent({ isIgnored: false });
564+
565+
await userEvent.click(screen.getByRole("button", { name: "Ignore" }));
566+
expect(modalSpy).toHaveBeenCalled();
567+
expect(mockClient.setIgnoredUsers).toHaveBeenLastCalledWith([member.userId]);
568+
} finally {
569+
Modal.createDialog = originalCreateDialog;
570+
}
571+
});
572+
573+
it("cancels ignoring the user", async () => {
574+
const originalCreateDialog = Modal.createDialog;
575+
const modalSpy = (Modal.createDialog = jest.fn().mockReturnValue({
576+
finished: Promise.resolve([false]),
577+
close: () => {},
578+
}));
579+
580+
try {
581+
mockClient.getIgnoredUsers.mockReturnValue([]);
582+
renderComponent({ isIgnored: false });
583+
584+
await userEvent.click(screen.getByRole("button", { name: "Ignore" }));
585+
expect(modalSpy).toHaveBeenCalled();
586+
expect(mockClient.setIgnoredUsers).not.toHaveBeenCalled();
587+
} finally {
588+
Modal.createDialog = originalCreateDialog;
589+
}
590+
});
591+
592+
it("unignores the user", async () => {
593+
mockClient.getIgnoredUsers.mockReturnValue([member.userId]);
594+
renderComponent({ isIgnored: true });
595+
596+
await userEvent.click(screen.getByRole("button", { name: "Unignore" }));
597+
expect(mockClient.setIgnoredUsers).toHaveBeenCalledWith([]);
598+
});
546599
});
547600

548601
describe("<PowerLevelEditor />", () => {

0 commit comments

Comments
 (0)