diff --git a/res/css/structures/_SpaceRoomView.scss b/res/css/structures/_SpaceRoomView.scss index 559f405e59..946856eed3 100644 --- a/res/css/structures/_SpaceRoomView.scss +++ b/res/css/structures/_SpaceRoomView.scss @@ -135,6 +135,60 @@ $SpaceRoomViewInnerWidth: 428px; padding: 8px 22px; } } + + .mx_SpaceRoomView_landing_adminButtons { + margin-top: 32px; + + .mx_AccessibleButton { + position: relative; + width: 160px; + height: 124px; + box-sizing: border-box; + padding: 72px 16px 0; + border-radius: 12px; + border: 1px solid $space-button-outline-color; + margin-right: 28px; + margin-bottom: 28px; + font-size: $font-14px; + display: inline-block; + vertical-align: bottom; + + &:last-child { + margin-right: 0; + } + + &:hover { + background-color: rgba(141, 151, 165, 0.1); + } + + &::before, &::after { + position: absolute; + content: ""; + left: 16px; + top: 16px; + height: 40px; + width: 40px; + border-radius: 20px; + } + + &::after { + mask-position: center; + mask-size: 30px; + mask-repeat: no-repeat; + background: #ffffff; // white icon fill + } + + &.mx_SpaceRoomView_landing_inviteButton { + &::before { + background-color: $accent-color; + } + + &::after { + mask-image: url('$(res)/img/element-icons/room/invite.svg'); + } + } + } + } } .mx_SpaceRoomView_privateScope { diff --git a/src/RoomInvite.js b/src/RoomInvite.js index 728ae11e79..503411d2b3 100644 --- a/src/RoomInvite.js +++ b/src/RoomInvite.js @@ -50,10 +50,13 @@ export function showStartChatInviteDialog(initialText) { } export function showRoomInviteDialog(roomId) { + const isSpace = MatrixClientPeg.get()?.getRoom(roomId)?.isSpaceRoom(); // This dialog handles the room creation internally - we don't need to worry about it. - const InviteDialog = sdk.getComponent("dialogs.InviteDialog"); Modal.createTrackedDialog( - 'Invite Users', '', InviteDialog, {kind: KIND_INVITE, roomId}, + "Invite Users", isSpace ? "Space" : "Room", InviteDialog, { + kind: isSpace ? KIND_SPACE_INVITE : KIND_INVITE, + roomId, + }, /*className=*/null, /*isPriority=*/false, /*isStatic=*/true, ); } @@ -75,13 +78,6 @@ export function showCommunityInviteDialog(communityId) { } } -export const showSpaceInviteDialog = (roomId) => { - Modal.createTrackedDialog("Invite Users", "Space", InviteDialog, { - kind: KIND_SPACE_INVITE, - roomId, - }, /*className=*/null, /*isPriority=*/false, /*isStatic=*/true); -}; - /** * Checks if the given MatrixEvent is a valid 3rd party user invite. * @param {MatrixEvent} event The event to check diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx index 6c64df31eb..9e73b97d5a 100644 --- a/src/components/structures/SpaceRoomView.tsx +++ b/src/components/structures/SpaceRoomView.tsx @@ -25,7 +25,7 @@ import AccessibleButton from "../views/elements/AccessibleButton"; import RoomName from "../views/elements/RoomName"; import RoomTopic from "../views/elements/RoomTopic"; import FormButton from "../views/elements/FormButton"; -import {inviteMultipleToRoom, showSpaceInviteDialog} from "../../RoomInvite"; +import {inviteMultipleToRoom, showRoomInviteDialog} from "../../RoomInvite"; import {useRoomMembers} from "../../hooks/useRoomMembers"; import createRoom, {IOpts, Preset} from "../../createRoom"; import Field from "../views/elements/Field"; @@ -108,6 +108,17 @@ const SpaceLanding = ({ space, onJoinButtonClicked, onRejectButtonClicked }) => </div>; } + let inviteButton; + if (myMembership === "join" && space.canInvite(userId)) { + inviteButton = ( + <AccessibleButton className="mx_SpaceRoomView_landing_inviteButton" onClick={() => { + showRoomInviteDialog(space.roomId); + }}> + { _t("Invite people") } + </AccessibleButton> + ); + } + return <div className="mx_SpaceRoomView_landing"> <RoomAvatar room={space} height={80} width={80} viewAvatarOnClick={true} /> <div className="mx_SpaceRoomView_landing_name"> @@ -167,6 +178,9 @@ const SpaceLanding = ({ space, onJoinButtonClicked, onRejectButtonClicked }) => <RoomTopic room={space} /> </div> { joinButtons } + <div className="mx_SpaceRoomView_landing_adminButtons"> + { inviteButton } + </div> </div>; }; @@ -361,7 +375,7 @@ const SpaceSetupPrivateInvite = ({ space, onFinished }) => { <div className="mx_SpaceRoomView_inviteTeammates_buttons"> <AccessibleButton className="mx_SpaceRoomView_inviteTeammates_inviteDialogButton" - onClick={() => showSpaceInviteDialog(space.roomId)} + onClick={() => showRoomInviteDialog(space.roomId)} > { _t("Invite by username") } </AccessibleButton> diff --git a/src/components/views/spaces/SpacePublicShare.tsx b/src/components/views/spaces/SpacePublicShare.tsx index 064d1640a2..3930c1db16 100644 --- a/src/components/views/spaces/SpacePublicShare.tsx +++ b/src/components/views/spaces/SpacePublicShare.tsx @@ -22,7 +22,7 @@ import AccessibleButton from "../elements/AccessibleButton"; import {copyPlaintext} from "../../../utils/strings"; import {sleep} from "../../../utils/promise"; import {RoomPermalinkCreator} from "../../../utils/permalinks/Permalinks"; -import {showSpaceInviteDialog} from "../../../RoomInvite"; +import {showRoomInviteDialog} from "../../../RoomInvite"; interface IProps { space: Room; @@ -53,7 +53,7 @@ const SpacePublicShare = ({ space, onFinished }: IProps) => { <AccessibleButton className="mx_SpacePublicShare_inviteButton" onClick={() => { - showSpaceInviteDialog(space.roomId); + showRoomInviteDialog(space.roomId); onFinished(); }} > diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6603a83496..5f3d293571 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2561,6 +2561,7 @@ "You have %(count)s unread notifications in a prior version of this room.|other": "You have %(count)s unread notifications in a prior version of this room.", "You have %(count)s unread notifications in a prior version of this room.|one": "You have %(count)s unread notification in a prior version of this room.", "Accept Invite": "Accept Invite", + "Invite people": "Invite people", "%(count)s members|other": "%(count)s members", "%(count)s members|one": "%(count)s member", "<inviter/> invited you to <name/>": "<inviter/> invited you to <name/>",