mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-15 20:54:59 +08:00
Fix start DM via right panel (#10278)
This commit is contained in:
parent
8d9fdc3b41
commit
6746ce2da3
@ -121,13 +121,17 @@ export const getE2EStatus = (cli: MatrixClient, userId: string, devices: IDevice
|
|||||||
return anyDeviceUnverified ? E2EStatus.Warning : E2EStatus.Verified;
|
return anyDeviceUnverified ? E2EStatus.Warning : E2EStatus.Verified;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function openDMForUser(matrixClient: MatrixClient, user: RoomMember): Promise<void> {
|
/**
|
||||||
const startDMUser = new DirectoryMember({
|
* Converts the member to a DirectoryMember and starts a DM with them.
|
||||||
|
*/
|
||||||
|
async function openDmForUser(matrixClient: MatrixClient, user: Member): Promise<void> {
|
||||||
|
const avatarUrl = user instanceof User ? user.avatarUrl : user.getMxcAvatarUrl();
|
||||||
|
const startDmUser = new DirectoryMember({
|
||||||
user_id: user.userId,
|
user_id: user.userId,
|
||||||
display_name: user.rawDisplayName,
|
display_name: user.rawDisplayName,
|
||||||
avatar_url: user.getMxcAvatarUrl(),
|
avatar_url: avatarUrl,
|
||||||
});
|
});
|
||||||
startDmOnFirstMessage(matrixClient, [startDMUser]);
|
startDmOnFirstMessage(matrixClient, [startDmUser]);
|
||||||
}
|
}
|
||||||
|
|
||||||
type SetUpdating = (updating: boolean) => void;
|
type SetUpdating = (updating: boolean) => void;
|
||||||
@ -310,7 +314,7 @@ function DevicesSection({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const MessageButton = ({ member }: { member: RoomMember }): JSX.Element => {
|
const MessageButton = ({ member }: { member: Member }): JSX.Element => {
|
||||||
const cli = useContext(MatrixClientContext);
|
const cli = useContext(MatrixClientContext);
|
||||||
const [busy, setBusy] = useState(false);
|
const [busy, setBusy] = useState(false);
|
||||||
|
|
||||||
@ -320,7 +324,7 @@ const MessageButton = ({ member }: { member: RoomMember }): JSX.Element => {
|
|||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
if (busy) return;
|
if (busy) return;
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
await openDMForUser(cli, member);
|
await openDmForUser(cli, member);
|
||||||
setBusy(false);
|
setBusy(false);
|
||||||
}}
|
}}
|
||||||
className="mx_UserInfo_field"
|
className="mx_UserInfo_field"
|
||||||
@ -332,7 +336,7 @@ const MessageButton = ({ member }: { member: RoomMember }): JSX.Element => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const UserOptionsSection: React.FC<{
|
export const UserOptionsSection: React.FC<{
|
||||||
member: RoomMember;
|
member: Member;
|
||||||
isIgnored: boolean;
|
isIgnored: boolean;
|
||||||
canInvite: boolean;
|
canInvite: boolean;
|
||||||
isSpace?: boolean;
|
isSpace?: boolean;
|
||||||
@ -360,8 +364,9 @@ export const UserOptionsSection: React.FC<{
|
|||||||
}, [cli, member]);
|
}, [cli, member]);
|
||||||
|
|
||||||
const ignore = useCallback(async () => {
|
const ignore = useCallback(async () => {
|
||||||
|
const name = (member instanceof User ? member.displayName : member.name) || member.userId;
|
||||||
const { finished } = Modal.createDialog(QuestionDialog, {
|
const { finished } = Modal.createDialog(QuestionDialog, {
|
||||||
title: _t("Ignore %(user)s", { user: member.name }),
|
title: _t("Ignore %(user)s", { user: name }),
|
||||||
description: (
|
description: (
|
||||||
<div>
|
<div>
|
||||||
{_t(
|
{_t(
|
||||||
@ -394,7 +399,7 @@ export const UserOptionsSection: React.FC<{
|
|||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (member.roomId && !isSpace) {
|
if (member instanceof RoomMember && member.roomId && !isSpace) {
|
||||||
const onReadReceiptButton = function (): void {
|
const onReadReceiptButton = function (): void {
|
||||||
const room = cli.getRoom(member.roomId);
|
const room = cli.getRoom(member.roomId);
|
||||||
dis.dispatch<ViewRoomPayload>({
|
dis.dispatch<ViewRoomPayload>({
|
||||||
@ -415,7 +420,7 @@ export const UserOptionsSection: React.FC<{
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const room = cli.getRoom(member.roomId);
|
const room = member instanceof RoomMember ? cli.getRoom(member.roomId) : undefined;
|
||||||
if (room?.getEventReadUpTo(member.userId)) {
|
if (room?.getEventReadUpTo(member.userId)) {
|
||||||
readReceiptButton = (
|
readReceiptButton = (
|
||||||
<AccessibleButton kind="link" onClick={onReadReceiptButton} className="mx_UserInfo_field">
|
<AccessibleButton kind="link" onClick={onReadReceiptButton} className="mx_UserInfo_field">
|
||||||
@ -431,7 +436,12 @@ export const UserOptionsSection: React.FC<{
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canInvite && (member?.membership ?? "leave") === "leave" && shouldShowComponent(UIComponent.InviteUsers)) {
|
if (
|
||||||
|
member instanceof RoomMember &&
|
||||||
|
canInvite &&
|
||||||
|
(member?.membership ?? "leave") === "leave" &&
|
||||||
|
shouldShowComponent(UIComponent.InviteUsers)
|
||||||
|
) {
|
||||||
const roomId = member && member.roomId ? member.roomId : SdkContextClass.instance.roomViewStore.getRoomId();
|
const roomId = member && member.roomId ? member.roomId : SdkContextClass.instance.roomViewStore.getRoomId();
|
||||||
const onInviteUserButton = async (ev: ButtonEvent): Promise<void> => {
|
const onInviteUserButton = async (ev: ButtonEvent): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
|
@ -43,6 +43,12 @@ import MultiInviter from "../../../../src/utils/MultiInviter";
|
|||||||
import * as mockVerification from "../../../../src/verification";
|
import * as mockVerification from "../../../../src/verification";
|
||||||
import Modal from "../../../../src/Modal";
|
import Modal from "../../../../src/Modal";
|
||||||
import { E2EStatus } from "../../../../src/utils/ShieldUtils";
|
import { E2EStatus } from "../../../../src/utils/ShieldUtils";
|
||||||
|
import { DirectoryMember, startDmOnFirstMessage } from "../../../../src/utils/direct-messages";
|
||||||
|
|
||||||
|
jest.mock("../../../../src/utils/direct-messages", () => ({
|
||||||
|
...jest.requireActual("../../../../src/utils/direct-messages"),
|
||||||
|
startDmOnFirstMessage: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
jest.mock("../../../../src/dispatcher/dispatcher");
|
jest.mock("../../../../src/dispatcher/dispatcher");
|
||||||
|
|
||||||
@ -121,7 +127,7 @@ const mockClient = mocked({
|
|||||||
setPowerLevel: jest.fn(),
|
setPowerLevel: jest.fn(),
|
||||||
} as unknown as MatrixClient);
|
} as unknown as MatrixClient);
|
||||||
|
|
||||||
const defaultUserId = "@test:test";
|
const defaultUserId = "@user:example.com";
|
||||||
const defaultUser = new User(defaultUserId);
|
const defaultUser = new User(defaultUserId);
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -550,23 +556,6 @@ describe("<UserOptionsSection />", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("calling .invite with a null roomId still calls .invite and shows default error message", async () => {
|
|
||||||
inviteSpy.mockRejectedValue({ this: "could be anything" });
|
|
||||||
|
|
||||||
// render the component and click the button
|
|
||||||
renderComponent({ canInvite: true, member: { ...member, roomId: null } });
|
|
||||||
const inviteButton = screen.getByRole("button", { name: /invite/i });
|
|
||||||
expect(inviteButton).toBeInTheDocument();
|
|
||||||
await userEvent.click(inviteButton);
|
|
||||||
|
|
||||||
expect(inviteSpy).toHaveBeenCalledTimes(1);
|
|
||||||
|
|
||||||
// check that the default test error message is displayed
|
|
||||||
await waitFor(() => {
|
|
||||||
expect(screen.getByText(/operation failed/i)).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("shows a modal before ignoring the user", async () => {
|
it("shows a modal before ignoring the user", async () => {
|
||||||
const originalCreateDialog = Modal.createDialog;
|
const originalCreateDialog = Modal.createDialog;
|
||||||
const modalSpy = (Modal.createDialog = jest.fn().mockReturnValue({
|
const modalSpy = (Modal.createDialog = jest.fn().mockReturnValue({
|
||||||
@ -612,6 +601,24 @@ describe("<UserOptionsSection />", () => {
|
|||||||
await userEvent.click(screen.getByRole("button", { name: "Unignore" }));
|
await userEvent.click(screen.getByRole("button", { name: "Unignore" }));
|
||||||
expect(mockClient.setIgnoredUsers).toHaveBeenCalledWith([]);
|
expect(mockClient.setIgnoredUsers).toHaveBeenCalledWith([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
["for a RoomMember", member, member.getMxcAvatarUrl()],
|
||||||
|
["for a User", defaultUser, defaultUser.avatarUrl],
|
||||||
|
])(
|
||||||
|
"clicking »message« %s should start a DM",
|
||||||
|
async (test: string, member: RoomMember | User, expectedAvatarUrl: string | undefined) => {
|
||||||
|
renderComponent({ member });
|
||||||
|
await userEvent.click(screen.getByText("Message"));
|
||||||
|
expect(startDmOnFirstMessage).toHaveBeenCalledWith(mockClient, [
|
||||||
|
new DirectoryMember({
|
||||||
|
user_id: member.userId,
|
||||||
|
display_name: member.rawDisplayName,
|
||||||
|
avatar_url: expectedAvatarUrl,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("<PowerLevelEditor />", () => {
|
describe("<PowerLevelEditor />", () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user