From eff0e6fcc3da69b55c0a05c3279725d02758fa9e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 26 Mar 2021 13:11:57 +0000 Subject: [PATCH] Add facepile to Space landing page and tweak layout slightly --- res/css/structures/_SpaceRoomView.scss | 178 ++++++++++++-------- src/components/structures/SpaceRoomView.tsx | 121 +++++++------ src/components/views/elements/FacePile.tsx | 35 ++-- 3 files changed, 189 insertions(+), 145 deletions(-) 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 }) } + }
};