diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 59906c5a748..d1b569ccfa3 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -2205,6 +2205,7 @@ export class RoomView extends React.Component { knocked={myMembership === "knock" || this.state.knocked} onSubmitAskToJoin={this.onSubmitAskToJoin} onCancelAskToJoin={this.onCancelAskToJoin} + onForgetClick={this.onForgetClick} /> diff --git a/src/components/views/rooms/RoomPreviewBar.tsx b/src/components/views/rooms/RoomPreviewBar.tsx index 5f610c344e6..ee1a9a69fb7 100644 --- a/src/components/views/rooms/RoomPreviewBar.tsx +++ b/src/components/views/rooms/RoomPreviewBar.tsx @@ -62,6 +62,7 @@ enum MessageCase { OtherError = "OtherError", PromptAskToJoin = "PromptAskToJoin", Knocked = "Knocked", + RequestDenied = "requestDenied", } interface IProps { @@ -188,7 +189,11 @@ export default class RoomPreviewBar extends React.Component { const myMember = this.getMyMember(); if (myMember) { + const previousMembership = myMember.events.member?.getPrevContent().membership; if (myMember.isKicked()) { + if (previousMembership === "knock") { + return MessageCase.RequestDenied; + } return MessageCase.Kicked; } else if (myMember.membership === "ban") { return MessageCase.Banned; @@ -397,6 +402,21 @@ export default class RoomPreviewBar extends React.Component { } break; } + case MessageCase.RequestDenied: { + title = _t("You have been denied access"); + + subTitle = _t( + "As you have been denied access, you cannot rejoin unless you are invited by the admin or moderator of the group.", + ); + + if (isSpace) { + primaryActionLabel = _t("Forget this space"); + } else { + primaryActionLabel = _t("Forget this room"); + } + primaryActionHandler = this.props.onForgetClick; + break; + } case MessageCase.Banned: { const { memberName, reason } = this.getKickOrBanInfo(); if (roomName) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 39e957832c8..5be75775b88 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2150,6 +2150,8 @@ "Forget this space": "Forget this space", "Forget this room": "Forget this room", "Re-join": "Re-join", + "You have been denied access": "You have been denied access", + "As you have been denied access, you cannot rejoin unless you are invited by the admin or moderator of the group.": "As you have been denied access, you cannot rejoin unless you are invited by the admin or moderator of the group.", "You were banned from %(roomName)s by %(memberName)s": "You were banned from %(roomName)s by %(memberName)s", "You were banned by %(memberName)s": "You were banned by %(memberName)s", "Something went wrong with your invite to %(roomName)s": "Something went wrong with your invite to %(roomName)s", diff --git a/test/components/views/rooms/RoomPreviewBar-test.tsx b/test/components/views/rooms/RoomPreviewBar-test.tsx index b2ed656924f..6f2805d164f 100644 --- a/test/components/views/rooms/RoomPreviewBar-test.tsx +++ b/test/components/views/rooms/RoomPreviewBar-test.tsx @@ -45,23 +45,27 @@ const makeMockRoomMember = ({ membership, content, memberContent, + oldMembership, }: { userId?: string; isKicked?: boolean; - membership?: "invite" | "ban"; + membership?: "invite" | "ban" | "leave"; content?: Partial; memberContent?: Partial; + oldMembership?: "join" | "knock"; }) => ({ userId, rawDisplayName: `${userId} name`, isKicked: jest.fn().mockReturnValue(!!isKicked), getContent: jest.fn().mockReturnValue(content || {}), + getPrevContent: jest.fn().mockReturnValue(content || {}), membership, events: { member: { getSender: jest.fn().mockReturnValue("@kicker:test.com"), getContent: jest.fn().mockReturnValue({ reason: "test reason", ...memberContent }), + getPrevContent: jest.fn().mockReturnValue({ membership: oldMembership, ...memberContent }), }, }, } as unknown as RoomMember); @@ -168,11 +172,33 @@ describe("", () => { it("renders kicked message", () => { const room = createRoom(roomId, otherUserId); jest.spyOn(room, "getMember").mockReturnValue(makeMockRoomMember({ isKicked: true })); - const component = getComponent({ loading: true, room }); + const component = getComponent({ room, promptAskToJoin: true }); + + expect(getMessage(component)).toMatchSnapshot(); + }); + + it("renders denied request message", () => { + const room = createRoom(roomId, otherUserId); + jest.spyOn(room, "getMember").mockReturnValue( + makeMockRoomMember({ isKicked: true, membership: "leave", oldMembership: "knock" }), + ); + const component = getComponent({ room, promptAskToJoin: true }); expect(getMessage(component)).toMatchSnapshot(); }); + it("triggers the primary action callback for denied request", () => { + const onForgetClick = jest.fn(); + const room = createRoom(roomId, otherUserId); + jest.spyOn(room, "getMember").mockReturnValue( + makeMockRoomMember({ isKicked: true, membership: "leave", oldMembership: "knock" }), + ); + const component = getComponent({ room, promptAskToJoin: true, onForgetClick }); + + fireEvent.click(getPrimaryActionButton(component)!); + expect(onForgetClick).toHaveBeenCalled(); + }); + it("renders banned message", () => { const room = createRoom(roomId, otherUserId); jest.spyOn(room, "getMember").mockReturnValue(makeMockRoomMember({ membership: "ban" })); diff --git a/test/components/views/rooms/__snapshots__/RoomPreviewBar-test.tsx.snap b/test/components/views/rooms/__snapshots__/RoomPreviewBar-test.tsx.snap index d193fbea780..2bd4ebb47dc 100644 --- a/test/components/views/rooms/__snapshots__/RoomPreviewBar-test.tsx.snap +++ b/test/components/views/rooms/__snapshots__/RoomPreviewBar-test.tsx.snap @@ -107,6 +107,19 @@ exports[` renders banned message 1`] = ` `; +exports[` renders denied request message 1`] = ` +
+

+ You have been denied access +

+

+ As you have been denied access, you cannot rejoin unless you are invited by the admin or moderator of the group. +

+
+`; + exports[` renders kicked message 1`] = `