diff --git a/res/css/structures/_SpaceRoomView.scss b/res/css/structures/_SpaceRoomView.scss
index c4ffc5d84c..25a950c285 100644
--- a/res/css/structures/_SpaceRoomView.scss
+++ b/res/css/structures/_SpaceRoomView.scss
@@ -153,53 +153,6 @@ $SpaceRoomViewInnerWidth: 428px;
margin: 20px 0 !important; // override default margin from above
}
- .mx_SpaceRoomView_preview_info {
- color: $tertiary-fg-color;
- font-size: $font-15px;
- line-height: $font-24px;
- margin: 20px 0;
-
- .mx_SpaceRoomView_preview_info_public,
- .mx_SpaceRoomView_preview_info_private {
- padding-left: 20px;
- position: relative;
-
- &::before {
- position: absolute;
- content: "";
- width: 20px;
- height: 20px;
- top: 0;
- left: -2px;
- mask-position: center;
- mask-repeat: no-repeat;
- background-color: $tertiary-fg-color;
- }
- }
-
- .mx_SpaceRoomView_preview_info_public::before {
- mask-size: 12px;
- mask-image: url("$(res)/img/globe.svg");
- }
-
- .mx_SpaceRoomView_preview_info_private::before {
- mask-size: 14px;
- mask-image: url("$(res)/img/element-icons/lock.svg");
- }
-
- .mx_AccessibleButton_kind_link {
- color: inherit;
- position: relative;
- padding-left: 16px;
-
- &::before {
- content: "·"; // visual separator
- position: absolute;
- left: 6px;
- }
- }
- }
-
.mx_SpaceRoomView_preview_topic {
font-size: $font-14px;
line-height: $font-22px;
@@ -253,32 +206,80 @@ $SpaceRoomViewInnerWidth: 428px;
vertical-align: middle;
}
}
+ }
- .mx_SpaceRoomView_landing_memberCount {
+ .mx_SpaceRoomView_landing_info {
+ display: flex;
+ margin-right: 60px;
+ align-items: center;
+
+ .mx_SpaceRoomView_info {
+ display: inline-block;
+ margin: 0;
+ }
+
+ .mx_FacePile {
+ display: inline-block;
+ margin-left: auto;
+ margin-right: 12px;
+
+ .mx_FacePile_faces {
+ cursor: pointer;
+
+ > span:hover {
+ .mx_BaseAvatar {
+ filter: brightness(0.8);
+ }
+ }
+
+ > span:first-child {
+ position: relative;
+
+ .mx_BaseAvatar {
+ filter: brightness(0.8);
+ }
+
+ &::before {
+ content: "";
+ z-index: 1;
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 30px;
+ width: 30px;
+ background: #ffffff; // white icon fill
+ mask-position: center;
+ mask-size: 24px;
+ mask-repeat: no-repeat;
+ mask-image: url('$(res)/img/element-icons/room/ellipsis.svg');
+ }
+ }
+ }
+ }
+
+ .mx_SpaceRoomView_landing_inviteButton {
position: relative;
- margin-left: 24px;
- padding: 0 0 0 28px;
- line-height: $font-24px;
- vertical-align: text-bottom;
+ padding-left: 40px;
+ height: min-content;
&::before {
position: absolute;
- content: '';
- width: 24px;
- height: 24px;
- top: 0;
- left: 0;
+ content: "";
+ left: 8px;
+ height: 16px;
+ width: 16px;
+ background: #ffffff; // white icon fill
mask-position: center;
+ mask-size: 16px;
mask-repeat: no-repeat;
- mask-size: contain;
- background-color: $accent-color;
- mask-image: url('$(res)/img/element-icons/community-members.svg');
+ mask-image: url('$(res)/img/element-icons/room/invite.svg');
}
}
}
.mx_SpaceRoomView_landing_topic {
font-size: $font-15px;
+ margin-top: 12px;
}
.mx_SpaceRoomView_landing_adminButtons {
@@ -323,16 +324,6 @@ $SpaceRoomViewInnerWidth: 428px;
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_landing_addButton {
&::before {
background-color: #ac3ba8;
@@ -424,3 +415,50 @@ $SpaceRoomViewInnerWidth: 428px;
}
}
}
+
+.mx_SpaceRoomView_info {
+ color: $tertiary-fg-color;
+ font-size: $font-15px;
+ line-height: $font-24px;
+ margin: 20px 0;
+
+ .mx_SpaceRoomView_info_public,
+ .mx_SpaceRoomView_info_private {
+ padding-left: 20px;
+ position: relative;
+
+ &::before {
+ position: absolute;
+ content: "";
+ width: 20px;
+ height: 20px;
+ top: 0;
+ left: -2px;
+ mask-position: center;
+ mask-repeat: no-repeat;
+ background-color: $tertiary-fg-color;
+ }
+ }
+
+ .mx_SpaceRoomView_info_public::before {
+ mask-size: 12px;
+ mask-image: url("$(res)/img/globe.svg");
+ }
+
+ .mx_SpaceRoomView_info_private::before {
+ mask-size: 14px;
+ mask-image: url("$(res)/img/element-icons/lock.svg");
+ }
+
+ .mx_AccessibleButton_kind_link {
+ color: inherit;
+ position: relative;
+ padding-left: 16px;
+
+ &::before {
+ content: "·"; // visual separator
+ position: absolute;
+ left: 6px;
+ }
+ }
+}
diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx
index 8d8986320d..5a7113bf7f 100644
--- a/src/components/structures/SpaceRoomView.tsx
+++ b/src/components/structures/SpaceRoomView.tsx
@@ -92,6 +92,41 @@ const useMyRoomMembership = (room: Room) => {
return membership;
};
+const SpaceInfo = ({ space }) => {
+ const joinRule = space.getJoinRule();
+
+ let visibilitySection;
+ if (joinRule === "public") {
+ visibilitySection =
+ { _t("Public space") }
+ ;
+ } else {
+ visibilitySection =
+ { _t("Private space") }
+ ;
+ }
+
+ return
+ { visibilitySection }
+ { joinRule === "public" &&
+ {(count) => count > 0 ? (
+ {
+ defaultDispatcher.dispatch({
+ action: Action.SetRightPanelPhase,
+ phase: RightPanelPhases.RoomMemberList,
+ refireParams: { space },
+ });
+ }}
+ >
+ { _t("%(count)s members", { count }) }
+
+ ) : null}
+ }
+
+};
+
const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) => {
const cli = useContext(MatrixClientContext);
const myMembership = useMyRoomMembership(space);
@@ -158,45 +193,13 @@ const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
joinButtons = ;
}
- const joinRule = space.getJoinRule();
-
- let visibilitySection;
- if (joinRule === "public") {
- visibilitySection =
- { _t("Public space") }
- ;
- } else {
- visibilitySection =
- { _t("Private space") }
- ;
- }
-
return
{ inviterSection }
-
- { visibilitySection }
- { joinRule === "public" &&
- {(count) => count > 0 ? (
- {
- defaultDispatcher.dispatch({
- action: Action.SetRightPanelPhase,
- phase: RightPanelPhases.RoomMemberList,
- refireParams: { space },
- });
- }}
- >
- { _t("%(count)s members", { count }) }
-
- ) : null}
- }
-
+
{(topic, ref) =>
@@ -204,7 +207,7 @@ const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
}
- { joinRule === "public" &&
}
+ { space.getJoinRule() === "public" &&
}
{ joinButtons }
@@ -219,10 +222,14 @@ const SpaceLanding = ({ space }) => {
let inviteButton;
if (myMembership === "join" && space.canInvite(userId)) {
inviteButton = (
-
{
- showRoomInviteDialog(space.roomId);
- }}>
- { _t("Invite people") }
+ {
+ showRoomInviteDialog(space.roomId);
+ }}
+ >
+ { _t("Invite") }
);
}
@@ -259,6 +266,14 @@ const SpaceLanding = ({ space }) => {
;
}
+ const onMembersClick = () => {
+ defaultDispatcher.dispatch
({
+ action: Action.SetRightPanelPhase,
+ phase: RightPanelPhases.RoomMemberList,
+ refireParams: { space },
+ });
+ };
+
return
@@ -266,40 +281,20 @@ const SpaceLanding = ({ space }) => {
{(name) => {
const tags = { name: () =>
{ name }
-
- {(count) => count > 0 ? (
- {
- defaultDispatcher.dispatch({
- action: Action.SetRightPanelPhase,
- phase: RightPanelPhases.RoomMemberList,
- refireParams: { space },
- });
- }}
- >
- { _t("%(count)s members", { count }) }
-
- ) : null}
-
};
- if (shouldShowSpaceSettings(cli, space)) {
- if (space.getJoinRule() === "public") {
- return _t("Your public space
", {}, tags) as JSX.Element;
- } else {
- return _t("Your private space
", {}, tags) as JSX.Element;
- }
- }
return _t("Welcome to
", {}, tags) as JSX.Element;
}}
+
+
+
+ { inviteButton }
+
- { inviteButton }
{ addRoomButtons }
{ settingsButton }
diff --git a/src/components/views/elements/FacePile.tsx b/src/components/views/elements/FacePile.tsx
index 0051cea94f..e223744352 100644
--- a/src/components/views/elements/FacePile.tsx
+++ b/src/components/views/elements/FacePile.tsx
@@ -14,31 +14,42 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import React from "react";
+import React, { HTMLAttributes } from "react";
import { Room } from "matrix-js-sdk/src/models/room";
+import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { sortBy } from "lodash";
import MemberAvatar from "../avatars/MemberAvatar";
import { _t } from "../../../languageHandler";
import DMRoomMap from "../../../utils/DMRoomMap";
import TextWithTooltip from "../elements/TextWithTooltip";
+import { useRoomMembers } from "../../../hooks/useRoomMembers";
const DEFAULT_NUM_FACES = 5;
-interface IProps {
+interface IProps extends HTMLAttributes
{
room: Room;
+ onlyKnownUsers?: boolean;
numShown?: number;
}
-const FacePile = ({ room, numShown = DEFAULT_NUM_FACES }: IProps) => {
- const knownMembers = sortBy(room.getJoinedMembers().filter(member => {
- return !!DMRoomMap.shared().getDMRoomsForUserId(member.userId)?.length;
- }), member => member.getMxcAvatarUrl() ? 0 : 1); // sort users with an explicit avatar first
+const isKnownMember = (member: RoomMember) => !!DMRoomMap.shared().getDMRoomsForUserId(member.userId)?.length;
- if (knownMembers.length < 1) return null;
- const shownMembers = knownMembers.slice(0, numShown);
+const FacePile = ({ room, onlyKnownUsers = true, numShown = DEFAULT_NUM_FACES, ...props }: IProps) => {
+ let members = useRoomMembers(room);
- return
+ // sort users with an explicit avatar first
+ const iteratees = [member => !!member.getMxcAvatarUrl()];
+ if (onlyKnownUsers) {
+ members = members.filter(isKnownMember);
+ } else {
+ // sort known users first
+ iteratees.unshift(member => isKnownMember(member));
+ }
+ if (members.length < 1) return null;
+
+ const shownMembers = sortBy(members, iteratees).slice(0, numShown);
+ return
{ shownMembers.map(member => {
return
@@ -46,9 +57,9 @@ const FacePile = ({ room, numShown = DEFAULT_NUM_FACES }: IProps) => {
;
}) }
-
- { _t("%(count)s people you know have already joined", { count: knownMembers.length }) }
-
+ { onlyKnownUsers &&
+ { _t("%(count)s people you know have already joined", { count: members.length }) }
+ }
};