Merge pull request #5702 from matrix-org/t3chguy/spaces4.1

Iterate Space Panel
pull/21833/head
Michael Telatynski 2021-03-01 23:56:54 +00:00 committed by GitHub
commit 7b7c89e854
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 120 additions and 62 deletions

View File

@ -2,8 +2,6 @@
Copyright 2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
@ -18,8 +16,12 @@ limitations under the License.
$topLevelHeight: 32px;
$nestedHeight: 24px;
$gutterSize: 21px;
$gutterSize: 17px;
$activeStripeSize: 4px;
$activeBorderTransparentGap: 2px;
$activeBackgroundColor: $roomtile-selected-bg-color;
$activeBorderColor: $secondary-fg-color;
.mx_SpacePanel {
flex: 0 0 auto;
@ -68,11 +70,14 @@ $activeStripeSize: 4px;
cursor: pointer;
}
.mx_SpaceItem {
position: relative;
}
.mx_SpaceItem.collapsed {
.mx_SpaceButton {
.mx_NotificationBadge {
right: -4px;
top: -4px;
}
}
& > .mx_SpaceButton > .mx_SpaceButton_toggleCollapse {
transform: rotate(-90deg);
}
@ -84,20 +89,35 @@ $activeStripeSize: 4px;
.mx_SpaceItem:not(.hasSubSpaces) > .mx_SpaceButton {
margin-left: $gutterSize;
&.mx_SpaceButton_active {
&::before {
left: -$gutterSize;
}
}
}
.mx_SpaceButton {
border-radius: 8px;
position: relative;
margin-bottom: 16px;
margin-bottom: 2px;
display: flex;
align-items: center;
padding: 4px;
&.mx_SpaceButton_active {
&:not(.mx_SpaceButton_narrow) .mx_SpaceButton_selectionWrapper {
background-color: $activeBackgroundColor;
border-radius: 8px;
}
&.mx_SpaceButton_narrow {
.mx_BaseAvatar, .mx_SpaceButton_avatarPlaceholder {
border: 2px $activeBorderColor solid;
border-radius: 11px;
}
}
}
.mx_SpaceButton_selectionWrapper {
display: flex;
flex: 1;
align-items: center;
}
.mx_SpaceButton_name {
flex: 1;
@ -107,7 +127,7 @@ $activeStripeSize: 4px;
max-width: 150px;
text-overflow: ellipsis;
overflow: hidden;
padding-right: 8px;
font-size: $font-14px;
line-height: $font-18px;
}
@ -123,24 +143,12 @@ $activeStripeSize: 4px;
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
}
&.mx_SpaceButton_active {
&::before {
position: absolute;
content: '';
width: $activeStripeSize;
top: 0;
left: 0;
bottom: 0;
background-color: $accent-color;
border-radius: 0 4px 4px 0;
}
}
.mx_SpaceButton_avatarPlaceholder {
.mx_SpaceButton_icon {
width: $topLevelHeight;
min-width: $topLevelHeight;
height: $topLevelHeight;
border-radius: 8px;
position: relative;
&::before {
position: absolute;
@ -155,7 +163,7 @@ $activeStripeSize: 4px;
}
}
&.mx_SpaceButton_home .mx_SpaceButton_avatarPlaceholder {
&.mx_SpaceButton_home .mx_SpaceButton_icon {
background-color: #ffffff;
&::before {
@ -164,16 +172,26 @@ $activeStripeSize: 4px;
}
}
&.mx_SpaceButton_newCancel .mx_SpaceButton_avatarPlaceholder {
background-color: $icon-button-color;
&::before {
transform: rotate(45deg);
}
.mx_SpaceButton_avatarPlaceholder {
border: $activeBorderTransparentGap transparent solid;
padding: $activeBorderTransparentGap;
}
.mx_BaseAvatar_image {
border-radius: 8px;
.mx_BaseAvatar {
/* moving the border-radius to this element from _image
element so we can add a border to it without the initials being displaced */
overflow: hidden;
border: 2px transparent solid;
padding: $activeBorderTransparentGap;
.mx_BaseAvatar_initial {
top: $activeBorderTransparentGap;
left: $activeBorderTransparentGap;
}
.mx_BaseAvatar_image {
border-radius: 8px;
}
}
}
@ -201,8 +219,8 @@ $activeStripeSize: 4px;
.mx_SpaceButton {
.mx_SpacePanel_badgeContainer {
position: absolute;
right: -8px;
top: -4px;
right: 0px;
top: 2px;
}
}
}

View File

@ -72,6 +72,7 @@ limitations under the License.
position: relative; // to make default avatars work
margin-right: 8px;
height: 32px; // to remove the unknown 4px gap the browser puts below it
padding: 3px 0; // to align with and without using doubleName
.mx_UserMenu_userAvatar {
border-radius: 32px; // should match avatar size

View File

@ -75,6 +75,11 @@ limitations under the License.
background-color: $menu-selected-color;
}
&.mx_AccessibleButton_disabled {
opacity: 0.5;
cursor: not-allowed;
}
img, .mx_IconizedContextMenu_icon { // icons
width: 16px;
min-width: 16px;

View File

@ -1,3 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg width="24" height="24" viewBox="-0.4 1 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.1001 9C18.7779 9 18.5168 8.73883 18.5168 8.41667V6.08333H16.1834C15.8613 6.08333 15.6001 5.82217 15.6001 5.5C15.6001 5.17783 15.8613 4.91667 16.1834 4.91667H18.5168V2.58333C18.5168 2.26117 18.7779 2 19.1001 2C19.4223 2 19.6834 2.26117 19.6834 2.58333V4.91667H22.0168C22.3389 4.91667 22.6001 5.17783 22.6001 5.5C22.6001 5.82217 22.3389 6.08333 22.0168 6.08333H19.6834V8.41667C19.6834 8.73883 19.4223 9 19.1001 9ZM19.6001 11C20.0669 11 20.5212 10.9467 20.9574 10.8458C21.1161 11.5383 21.2 12.2594 21.2 13C21.2 16.1409 19.6917 18.9294 17.3598 20.6808V20.6807C16.0014 21.7011 14.3635 22.3695 12.5815 22.5505C12.2588 22.5832 11.9314 22.6 11.6 22.6C6.29807 22.6 2 18.302 2 13C2 7.69809 6.29807 3.40002 11.6 3.40002C12.3407 3.40002 13.0618 3.48391 13.7543 3.64268C13.6534 4.07884 13.6001 4.53319 13.6001 5C13.6001 8.31371 16.2864 11 19.6001 11ZM11.5999 20.68C13.6754 20.68 15.5585 19.8567 16.9407 18.5189C16.0859 16.4086 14.0167 14.92 11.5998 14.92C9.18298 14.92 7.11378 16.4086 6.25901 18.5189C7.64115 19.8567 9.52436 20.68 11.5999 20.68ZM11.7426 7.41172C10.3168 7.54168 9.2 8.74043 9.2 10.2C9.2 11.7464 10.4536 13 12 13C13.0308 13 13.9315 12.443 14.4176 11.6135C13.0673 10.6058 12.0929 9.12248 11.7426 7.41172Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -15,13 +15,18 @@ limitations under the License.
*/
import React, { createRef } from "react";
import { Room } from "matrix-js-sdk/src/models/room";
import classNames from "classnames";
import * as fbEmitter from "fbemitter";
import { MatrixClientPeg } from "../../MatrixClientPeg";
import defaultDispatcher from "../../dispatcher/dispatcher";
import dis from "../../dispatcher/dispatcher";
import { ActionPayload } from "../../dispatcher/payloads";
import { Action } from "../../dispatcher/actions";
import { _t } from "../../languageHandler";
import { ContextMenuButton } from "./ContextMenu";
import {USER_NOTIFICATIONS_TAB, USER_SECURITY_TAB} from "../views/dialogs/UserSettingsDialog";
import { USER_NOTIFICATIONS_TAB, USER_SECURITY_TAB } from "../views/dialogs/UserSettingsDialog";
import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
import FeedbackDialog from "../views/dialogs/FeedbackDialog";
import Modal from "../../Modal";
@ -30,11 +35,10 @@ import SettingsStore from "../../settings/SettingsStore";
import {getCustomTheme} from "../../theme";
import AccessibleButton, {ButtonEvent} from "../views/elements/AccessibleButton";
import SdkConfig from "../../SdkConfig";
import {getHomePageUrl} from "../../utils/pages";
import { getHomePageUrl } from "../../utils/pages";
import { OwnProfileStore } from "../../stores/OwnProfileStore";
import { UPDATE_EVENT } from "../../stores/AsyncStore";
import BaseAvatar from '../views/avatars/BaseAvatar';
import classNames from "classnames";
import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton";
import { SettingLevel } from "../../settings/SettingLevel";
import IconizedContextMenu, {
@ -42,16 +46,16 @@ import IconizedContextMenu, {
IconizedContextMenuOptionList,
} from "../views/context_menus/IconizedContextMenu";
import { CommunityPrototypeStore } from "../../stores/CommunityPrototypeStore";
import * as fbEmitter from "fbemitter";
import GroupFilterOrderStore from "../../stores/GroupFilterOrderStore";
import { showCommunityInviteDialog } from "../../RoomInvite";
import dis from "../../dispatcher/dispatcher";
import { RightPanelPhases } from "../../stores/RightPanelStorePhases";
import ErrorDialog from "../views/dialogs/ErrorDialog";
import EditCommunityPrototypeDialog from "../views/dialogs/EditCommunityPrototypeDialog";
import {UIFeature} from "../../settings/UIFeature";
import { UIFeature } from "../../settings/UIFeature";
import HostSignupAction from "./HostSignupAction";
import {IHostSignupConfig} from "../views/dialogs/HostSignupDialogTypes";
import { IHostSignupConfig } from "../views/dialogs/HostSignupDialogTypes";
import SpaceStore, { UPDATE_SELECTED_SPACE } from "../../stores/SpaceStore";
import RoomName from "../views/elements/RoomName";
interface IProps {
isMinimized: boolean;
@ -62,6 +66,7 @@ type PartialDOMRect = Pick<DOMRect, "width" | "left" | "top" | "height">;
interface IState {
contextMenuPosition: PartialDOMRect;
isDarkTheme: boolean;
selectedSpace?: Room;
}
export default class UserMenu extends React.Component<IProps, IState> {
@ -79,6 +84,9 @@ export default class UserMenu extends React.Component<IProps, IState> {
};
OwnProfileStore.instance.on(UPDATE_EVENT, this.onProfileUpdate);
if (SettingsStore.getValue("feature_spaces")) {
SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.onSelectedSpaceUpdate);
}
}
private get hasHomePage(): boolean {
@ -96,6 +104,9 @@ export default class UserMenu extends React.Component<IProps, IState> {
if (this.dispatcherRef) defaultDispatcher.unregister(this.dispatcherRef);
OwnProfileStore.instance.off(UPDATE_EVENT, this.onProfileUpdate);
this.tagStoreRef.remove();
if (SettingsStore.getValue("feature_spaces")) {
SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.onSelectedSpaceUpdate);
}
}
private onTagStoreUpdate = () => {
@ -120,6 +131,10 @@ export default class UserMenu extends React.Component<IProps, IState> {
this.forceUpdate();
};
private onSelectedSpaceUpdate = async (selectedSpace?: Room) => {
this.setState({ selectedSpace });
};
private onThemeChanged = () => {
this.setState({isDarkTheme: this.isUserOnDarkTheme()});
};
@ -517,7 +532,16 @@ export default class UserMenu extends React.Component<IProps, IState> {
{/* masked image in CSS */}
</span>
);
if (prototypeCommunityName) {
if (this.state.selectedSpace) {
name = (
<div className="mx_UserMenu_doubleName">
<span className="mx_UserMenu_userName">{displayName}</span>
<RoomName room={this.state.selectedSpace}>
{(roomName) => <span className="mx_UserMenu_subUserName">{roomName}</span>}
</RoomName>
</div>
);
} else if (prototypeCommunityName) {
name = (
<div className="mx_UserMenu_doubleName">
<span className="mx_UserMenu_userName">{prototypeCommunityName}</span>

View File

@ -56,9 +56,10 @@ const SpaceButton: React.FC<IButtonProps> = ({
}) => {
const classes = classNames("mx_SpaceButton", className, {
mx_SpaceButton_active: selected,
mx_SpaceButton_narrow: isNarrow,
});
let avatar = <div className="mx_SpaceButton_avatarPlaceholder" />;
let avatar = <div className="mx_SpaceButton_avatarPlaceholder"><div className="mx_SpaceButton_icon" /></div>;
if (space) {
avatar = <RoomAvatar width={32} height={32} room={space} />;
}
@ -74,18 +75,22 @@ const SpaceButton: React.FC<IButtonProps> = ({
if (isNarrow) {
button = (
<RovingAccessibleTooltipButton className={classes} title={tooltip} onClick={onClick} role="treeitem">
{ avatar }
{ notifBadge }
{ children }
<div className="mx_SpaceButton_selectionWrapper">
{ avatar }
{ notifBadge }
{ children }
</div>
</RovingAccessibleTooltipButton>
);
} else {
button = (
<RovingAccessibleButton className={classes} onClick={onClick} role="treeitem">
{ avatar }
<span className="mx_SpaceButton_name">{ tooltip }</span>
{ notifBadge }
{ children }
<div className="mx_SpaceButton_selectionWrapper">
{ avatar }
<span className="mx_SpaceButton_name">{ tooltip }</span>
{ notifBadge }
{ children }
</div>
</RovingAccessibleButton>
);
}

View File

@ -95,6 +95,7 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
const classes = classNames("mx_SpaceButton", {
mx_SpaceButton_active: isActive,
mx_SpaceButton_hasMenuOpen: !!this.state.contextMenuPosition,
mx_SpaceButton_narrow: isNarrow,
});
const notificationState = SpaceStore.instance.getNotificationState(space.roomId);
const childItems = childSpaces && !collapsed ? <SpaceTreeLevel
@ -129,8 +130,10 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
role="treeitem"
>
{ toggleCollapseButton }
<RoomAvatar width={avatarSize} height={avatarSize} room={space} />
{ notifBadge }
<div className="mx_SpaceButton_selectionWrapper">
<RoomAvatar width={avatarSize} height={avatarSize} room={space} />
{ notifBadge }
</div>
</RovingAccessibleTooltipButton>
);
} else {
@ -142,9 +145,11 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
role="treeitem"
>
{ toggleCollapseButton }
<RoomAvatar width={avatarSize} height={avatarSize} room={space} />
<span className="mx_SpaceButton_name">{ space.name }</span>
{ notifBadge }
<div className="mx_SpaceButton_selectionWrapper">
<RoomAvatar width={avatarSize} height={avatarSize} room={space} />
<span className="mx_SpaceButton_name">{ space.name }</span>
{ notifBadge }
</div>
</RovingAccessibleButton>
);
}