Add ignore user confirmation dialog (#6116)
Signed-off-by: Robin Townsend <robin@robin.town>
This commit is contained in:
parent
269d1622b9
commit
43c67ce4bf
3 changed files with 85 additions and 13 deletions
|
@ -353,25 +353,42 @@ export const UserOptionsSection: React.FC<{
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const unignore = useCallback(() => {
|
||||||
|
const ignoredUsers = cli.getIgnoredUsers();
|
||||||
|
const index = ignoredUsers.indexOf(member.userId);
|
||||||
|
if (index !== -1) ignoredUsers.splice(index, 1);
|
||||||
|
cli.setIgnoredUsers(ignoredUsers);
|
||||||
|
}, [cli, member]);
|
||||||
|
|
||||||
|
const ignore = useCallback(async () => {
|
||||||
|
const { finished } = Modal.createDialog(QuestionDialog, {
|
||||||
|
title: _t("Ignore %(user)s", { user: member.name }),
|
||||||
|
description: (
|
||||||
|
<div>
|
||||||
|
{_t(
|
||||||
|
"All messages and invites from this user will be hidden. " +
|
||||||
|
"Are you sure you want to ignore them?",
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
button: _t("Ignore"),
|
||||||
|
});
|
||||||
|
const [confirmed] = await finished;
|
||||||
|
|
||||||
|
if (confirmed) {
|
||||||
|
const ignoredUsers = cli.getIgnoredUsers();
|
||||||
|
ignoredUsers.push(member.userId);
|
||||||
|
cli.setIgnoredUsers(ignoredUsers);
|
||||||
|
}
|
||||||
|
}, [cli, member]);
|
||||||
|
|
||||||
// Only allow the user to ignore the user if its not ourselves
|
// Only allow the user to ignore the user if its not ourselves
|
||||||
// same goes for jumping to read receipt
|
// same goes for jumping to read receipt
|
||||||
if (!isMe) {
|
if (!isMe) {
|
||||||
const onIgnoreToggle = (): void => {
|
|
||||||
const ignoredUsers = cli.getIgnoredUsers();
|
|
||||||
if (isIgnored) {
|
|
||||||
const index = ignoredUsers.indexOf(member.userId);
|
|
||||||
if (index !== -1) ignoredUsers.splice(index, 1);
|
|
||||||
} else {
|
|
||||||
ignoredUsers.push(member.userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
cli.setIgnoredUsers(ignoredUsers);
|
|
||||||
};
|
|
||||||
|
|
||||||
ignoreButton = (
|
ignoreButton = (
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
|
onClick={isIgnored ? unignore : ignore}
|
||||||
kind="link"
|
kind="link"
|
||||||
onClick={onIgnoreToggle}
|
|
||||||
className={classNames("mx_UserInfo_field", { mx_UserInfo_destructive: !isIgnored })}
|
className={classNames("mx_UserInfo_field", { mx_UserInfo_destructive: !isIgnored })}
|
||||||
>
|
>
|
||||||
{isIgnored ? _t("Unignore") : _t("Ignore")}
|
{isIgnored ? _t("Unignore") : _t("Ignore")}
|
||||||
|
|
|
@ -2235,6 +2235,8 @@
|
||||||
"%(count)s sessions|one": "%(count)s session",
|
"%(count)s sessions|one": "%(count)s session",
|
||||||
"Hide sessions": "Hide sessions",
|
"Hide sessions": "Hide sessions",
|
||||||
"Message": "Message",
|
"Message": "Message",
|
||||||
|
"Ignore %(user)s": "Ignore %(user)s",
|
||||||
|
"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?",
|
||||||
"Jump to read receipt": "Jump to read receipt",
|
"Jump to read receipt": "Jump to read receipt",
|
||||||
"Mention": "Mention",
|
"Mention": "Mention",
|
||||||
"Share Link to User": "Share Link to User",
|
"Share Link to User": "Share Link to User",
|
||||||
|
|
|
@ -72,6 +72,7 @@ const mockRoom = mocked({
|
||||||
getMxcAvatarUrl: jest.fn().mockReturnValue("mock-avatar-url"),
|
getMxcAvatarUrl: jest.fn().mockReturnValue("mock-avatar-url"),
|
||||||
name: "test room",
|
name: "test room",
|
||||||
on: jest.fn(),
|
on: jest.fn(),
|
||||||
|
off: jest.fn(),
|
||||||
currentState: {
|
currentState: {
|
||||||
getStateEvents: jest.fn(),
|
getStateEvents: jest.fn(),
|
||||||
on: jest.fn(),
|
on: jest.fn(),
|
||||||
|
@ -83,9 +84,12 @@ const mockClient = mocked({
|
||||||
getUser: jest.fn(),
|
getUser: jest.fn(),
|
||||||
isGuest: jest.fn().mockReturnValue(false),
|
isGuest: jest.fn().mockReturnValue(false),
|
||||||
isUserIgnored: jest.fn(),
|
isUserIgnored: jest.fn(),
|
||||||
|
getIgnoredUsers: jest.fn(),
|
||||||
|
setIgnoredUsers: jest.fn(),
|
||||||
isCryptoEnabled: jest.fn(),
|
isCryptoEnabled: jest.fn(),
|
||||||
getUserId: jest.fn(),
|
getUserId: jest.fn(),
|
||||||
on: jest.fn(),
|
on: jest.fn(),
|
||||||
|
off: jest.fn(),
|
||||||
isSynapseAdministrator: jest.fn().mockResolvedValue(false),
|
isSynapseAdministrator: jest.fn().mockResolvedValue(false),
|
||||||
isRoomEncrypted: jest.fn().mockReturnValue(false),
|
isRoomEncrypted: jest.fn().mockReturnValue(false),
|
||||||
doesServerSupportUnstableFeature: jest.fn().mockReturnValue(false),
|
doesServerSupportUnstableFeature: jest.fn().mockReturnValue(false),
|
||||||
|
@ -386,8 +390,11 @@ describe("<UserOptionsSection />", () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
inviteSpy.mockReset();
|
inviteSpy.mockReset();
|
||||||
|
mockClient.setIgnoredUsers.mockClear();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => Modal.closeCurrentModal("End of test"));
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
inviteSpy.mockRestore();
|
inviteSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
@ -543,6 +550,52 @@ describe("<UserOptionsSection />", () => {
|
||||||
expect(screen.getByText(/operation failed/i)).toBeInTheDocument();
|
expect(screen.getByText(/operation failed/i)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("shows a modal before ignoring the user", async () => {
|
||||||
|
const originalCreateDialog = Modal.createDialog;
|
||||||
|
const modalSpy = (Modal.createDialog = jest.fn().mockReturnValue({
|
||||||
|
finished: Promise.resolve([true]),
|
||||||
|
close: () => {},
|
||||||
|
}));
|
||||||
|
|
||||||
|
try {
|
||||||
|
mockClient.getIgnoredUsers.mockReturnValue([]);
|
||||||
|
renderComponent({ isIgnored: false });
|
||||||
|
|
||||||
|
await userEvent.click(screen.getByRole("button", { name: "Ignore" }));
|
||||||
|
expect(modalSpy).toHaveBeenCalled();
|
||||||
|
expect(mockClient.setIgnoredUsers).toHaveBeenLastCalledWith([member.userId]);
|
||||||
|
} finally {
|
||||||
|
Modal.createDialog = originalCreateDialog;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("cancels ignoring the user", async () => {
|
||||||
|
const originalCreateDialog = Modal.createDialog;
|
||||||
|
const modalSpy = (Modal.createDialog = jest.fn().mockReturnValue({
|
||||||
|
finished: Promise.resolve([false]),
|
||||||
|
close: () => {},
|
||||||
|
}));
|
||||||
|
|
||||||
|
try {
|
||||||
|
mockClient.getIgnoredUsers.mockReturnValue([]);
|
||||||
|
renderComponent({ isIgnored: false });
|
||||||
|
|
||||||
|
await userEvent.click(screen.getByRole("button", { name: "Ignore" }));
|
||||||
|
expect(modalSpy).toHaveBeenCalled();
|
||||||
|
expect(mockClient.setIgnoredUsers).not.toHaveBeenCalled();
|
||||||
|
} finally {
|
||||||
|
Modal.createDialog = originalCreateDialog;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("unignores the user", async () => {
|
||||||
|
mockClient.getIgnoredUsers.mockReturnValue([member.userId]);
|
||||||
|
renderComponent({ isIgnored: true });
|
||||||
|
|
||||||
|
await userEvent.click(screen.getByRole("button", { name: "Unignore" }));
|
||||||
|
expect(mockClient.setIgnoredUsers).toHaveBeenCalledWith([]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("<PowerLevelEditor />", () => {
|
describe("<PowerLevelEditor />", () => {
|
||||||
|
|
Loading…
Reference in a new issue