diff --git a/.gitignore b/.gitignore index 33e8bfc7ac..e1dd7726e1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ package-lock.json /src/component-index.js .DS_Store +*.tmp diff --git a/CHANGELOG.md b/CHANGELOG.md index c87f1c62e6..c31eedf93b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,81 @@ +Changes in [3.15.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.15.0) (2021-03-01) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.15.0-rc.1...v3.15.0) + +## Security notice + +matrix-react-sdk 3.15.0 fixes a low severity issue (CVE-2021-21320) where the +user content sandbox can be abused to trick users into opening unexpected +documents. The content is opened with a `blob` origin that cannot access Matrix +user data, so messages and secrets are not at risk. Thanks to @keerok for +responsibly disclosing this via Matrix's Security Disclosure Policy. + +## All changes + + * Upgrade to JS SDK 9.8.0 + +Changes in [3.15.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.15.0-rc.1) (2021-02-24) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.14.0...v3.15.0-rc.1) + + * Upgrade to JS SDK 9.8.0-rc.1 + * Translations update from Weblate + [\#5683](https://github.com/matrix-org/matrix-react-sdk/pull/5683) + * Fix object diffing when objects have different keys + [\#5681](https://github.com/matrix-org/matrix-react-sdk/pull/5681) + * Add if it's missing + [\#5673](https://github.com/matrix-org/matrix-react-sdk/pull/5673) + * Add email only if the verification is complete + [\#5629](https://github.com/matrix-org/matrix-react-sdk/pull/5629) + * Fix portrait videocalls + [\#5676](https://github.com/matrix-org/matrix-react-sdk/pull/5676) + * Tweak code block icon positions + [\#5643](https://github.com/matrix-org/matrix-react-sdk/pull/5643) + * Revert "Improve URL preview formatting and image upload thumbnail size" + [\#5677](https://github.com/matrix-org/matrix-react-sdk/pull/5677) + * Fix context menu leaving visible area + [\#5644](https://github.com/matrix-org/matrix-react-sdk/pull/5644) + * Jitsi conferences names, take 3 + [\#5675](https://github.com/matrix-org/matrix-react-sdk/pull/5675) + * Update isUserOnDarkTheme to take use_system_theme in account + [\#5670](https://github.com/matrix-org/matrix-react-sdk/pull/5670) + * Discard some dead code + [\#5665](https://github.com/matrix-org/matrix-react-sdk/pull/5665) + * Add developer tool to explore and edit settings + [\#5664](https://github.com/matrix-org/matrix-react-sdk/pull/5664) + * Use and create new room helpers + [\#5663](https://github.com/matrix-org/matrix-react-sdk/pull/5663) + * Clear message previews when the maximum limit is reached for history + [\#5661](https://github.com/matrix-org/matrix-react-sdk/pull/5661) + * VoIP virtual rooms, mk II + [\#5639](https://github.com/matrix-org/matrix-react-sdk/pull/5639) + * Disable chat effects when reduced motion preferred + [\#5660](https://github.com/matrix-org/matrix-react-sdk/pull/5660) + * Improve URL preview formatting and image upload thumbnail size + [\#5637](https://github.com/matrix-org/matrix-react-sdk/pull/5637) + * Fix border radius when the panel is collapsed + [\#5641](https://github.com/matrix-org/matrix-react-sdk/pull/5641) + * Use a more generic layout setting - useIRCLayout → layout + [\#5571](https://github.com/matrix-org/matrix-react-sdk/pull/5571) + * Remove redundant lockOrigin parameter from usercontent + [\#5657](https://github.com/matrix-org/matrix-react-sdk/pull/5657) + * Set ICE candidate pool size option + [\#5655](https://github.com/matrix-org/matrix-react-sdk/pull/5655) + * Prepare to encrypt when a call arrives + [\#5654](https://github.com/matrix-org/matrix-react-sdk/pull/5654) + * Use config for host signup branding + [\#5650](https://github.com/matrix-org/matrix-react-sdk/pull/5650) + * Use randomly generated conference names for Jitsi + [\#5649](https://github.com/matrix-org/matrix-react-sdk/pull/5649) + * Modified regex to account for an immediate new line after slash commands + [\#5647](https://github.com/matrix-org/matrix-react-sdk/pull/5647) + * Fix codeblock scrollbar color for non-Firefox + [\#5642](https://github.com/matrix-org/matrix-react-sdk/pull/5642) + * Fix codeblock scrollbar colors + [\#5630](https://github.com/matrix-org/matrix-react-sdk/pull/5630) + * Added loading and disabled the button while searching for server + [\#5634](https://github.com/matrix-org/matrix-react-sdk/pull/5634) + Changes in [3.14.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.14.0) (2021-02-16) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.14.0-rc.1...v3.14.0) diff --git a/babel.config.js b/babel.config.js index d5a97d56ce..0a3a34a391 100644 --- a/babel.config.js +++ b/babel.config.js @@ -3,12 +3,15 @@ module.exports = { "presets": [ ["@babel/preset-env", { "targets": [ - "last 2 Chrome versions", "last 2 Firefox versions", "last 2 Safari versions" + "last 2 Chrome versions", + "last 2 Firefox versions", + "last 2 Safari versions", + "last 2 Edge versions", ], }], "@babel/preset-typescript", "@babel/preset-flow", - "@babel/preset-react" + "@babel/preset-react", ], "plugins": [ ["@babel/plugin-proposal-decorators", {legacy: true}], @@ -18,6 +21,6 @@ module.exports = { "@babel/plugin-proposal-object-rest-spread", "@babel/plugin-transform-flow-comments", "@babel/plugin-syntax-dynamic-import", - "@babel/plugin-transform-runtime" - ] + "@babel/plugin-transform-runtime", + ], }; diff --git a/package.json b/package.json index d4f931d811..7ed1b272da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.14.0", + "version": "3.15.0", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { @@ -101,7 +101,7 @@ "tar-js": "^0.3.0", "text-encoding-utf-8": "^1.0.2", "url": "^0.11.0", - "velocity-animate": "^1.5.2", + "velocity-animate": "^2.0.6", "what-input": "^5.2.10", "zxcvbn": "^4.4.2" }, diff --git a/res/css/_components.scss b/res/css/_components.scss index 006bac09c9..d894688cac 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -27,6 +27,9 @@ @import "./structures/_RoomView.scss"; @import "./structures/_ScrollPanel.scss"; @import "./structures/_SearchBox.scss"; +@import "./structures/_SpacePanel.scss"; +@import "./structures/_SpaceRoomDirectory.scss"; +@import "./structures/_SpaceRoomView.scss"; @import "./structures/_TabbedView.scss"; @import "./structures/_ToastContainer.scss"; @import "./structures/_UploadBar.scss"; @@ -56,6 +59,7 @@ @import "./views/context_menus/_MessageContextMenu.scss"; @import "./views/context_menus/_StatusMessageContextMenu.scss"; @import "./views/context_menus/_TagTileContextMenu.scss"; +@import "./views/dialogs/_AddExistingToSpaceDialog.scss"; @import "./views/dialogs/_AddressPickerDialog.scss"; @import "./views/dialogs/_Analytics.scss"; @import "./views/dialogs/_BugReportDialog.scss"; @@ -89,6 +93,7 @@ @import "./views/dialogs/_SettingsDialog.scss"; @import "./views/dialogs/_ShareDialog.scss"; @import "./views/dialogs/_SlashCommandHelpDialog.scss"; +@import "./views/dialogs/_SpaceSettingsDialog.scss"; @import "./views/dialogs/_TabbedIntegrationManagerDialog.scss"; @import "./views/dialogs/_TermsDialog.scss"; @import "./views/dialogs/_UploadConfirmDialog.scss"; @@ -212,6 +217,7 @@ @import "./views/settings/_DevicesPanel.scss"; @import "./views/settings/_E2eAdvancedPanel.scss"; @import "./views/settings/_EmailAddresses.scss"; +@import "./views/settings/_SpellCheckLanguages.scss"; @import "./views/settings/_IntegrationManager.scss"; @import "./views/settings/_Notifications.scss"; @import "./views/settings/_PhoneNumbers.scss"; @@ -232,6 +238,9 @@ @import "./views/settings/tabs/user/_PreferencesUserSettingsTab.scss"; @import "./views/settings/tabs/user/_SecurityUserSettingsTab.scss"; @import "./views/settings/tabs/user/_VoiceUserSettingsTab.scss"; +@import "./views/spaces/_SpaceBasicSettings.scss"; +@import "./views/spaces/_SpaceCreateMenu.scss"; +@import "./views/spaces/_SpacePublicShare.scss"; @import "./views/terms/_InlineTermsAgreement.scss"; @import "./views/toasts/_AnalyticsToast.scss"; @import "./views/toasts/_NonUrgentEchoFailureToast.scss"; diff --git a/res/css/structures/_LeftPanel.scss b/res/css/structures/_LeftPanel.scss index 168590502d..f1f27014ee 100644 --- a/res/css/structures/_LeftPanel.scss +++ b/res/css/structures/_LeftPanel.scss @@ -15,6 +15,7 @@ limitations under the License. */ $groupFilterPanelWidth: 56px; // only applies in this file, used for calculations +$roomListCollapsedWidth: 68px; .mx_LeftPanel { background-color: $roomlist-bg-color; @@ -37,18 +38,12 @@ $groupFilterPanelWidth: 56px; // only applies in this file, used for calculation // GroupFilterPanel handles its own CSS } - &:not(.mx_LeftPanel_hasGroupFilterPanel) { - .mx_LeftPanel_roomListContainer { - width: 100%; - } - } - // Note: The 'room list' in this context is actually everything that isn't the tag // panel, such as the menu options, breadcrumbs, filtering, etc .mx_LeftPanel_roomListContainer { - width: calc(100% - $groupFilterPanelWidth); background-color: $roomlist-bg-color; - + flex: 1 0 0; + min-width: 0; // Create another flexbox (this time a column) for the room list components display: flex; flex-direction: column; @@ -168,17 +163,10 @@ $groupFilterPanelWidth: 56px; // only applies in this file, used for calculation // These styles override the defaults for the minimized (66px) layout &.mx_LeftPanel_minimized { min-width: unset; - - // We have to forcefully set the width to override the resizer's style attribute. - &.mx_LeftPanel_hasGroupFilterPanel { - width: calc(68px + $groupFilterPanelWidth) !important; - } - &:not(.mx_LeftPanel_hasGroupFilterPanel) { - width: 68px !important; - } + width: unset !important; .mx_LeftPanel_roomListContainer { - width: 68px; + width: $roomListCollapsedWidth; .mx_LeftPanel_userHeader { flex-direction: row; diff --git a/res/css/structures/_MainSplit.scss b/res/css/structures/_MainSplit.scss index ad1656efbb..8199121420 100644 --- a/res/css/structures/_MainSplit.scss +++ b/res/css/structures/_MainSplit.scss @@ -18,6 +18,7 @@ limitations under the License. display: flex; flex-direction: row; min-width: 0; + min-height: 0; height: 100%; } diff --git a/res/css/structures/_RightPanel.scss b/res/css/structures/_RightPanel.scss index 5bf0d953f3..5515fe4060 100644 --- a/res/css/structures/_RightPanel.scss +++ b/res/css/structures/_RightPanel.scss @@ -160,3 +160,20 @@ limitations under the License. mask-position: center; } } + +.mx_RightPanel_scopeHeader { + margin: 24px; + text-align: center; + font-weight: $font-semi-bold; + font-size: $font-18px; + line-height: $font-22px; + + .mx_BaseAvatar { + margin-right: 8px; + vertical-align: middle; + } + + .mx_BaseAvatar_image { + border-radius: 8px; + } +} diff --git a/res/css/structures/_RoomView.scss b/res/css/structures/_RoomView.scss index 36bf96359b..26382b55e8 100644 --- a/res/css/structures/_RoomView.scss +++ b/res/css/structures/_RoomView.scss @@ -20,35 +20,54 @@ limitations under the License. flex-direction: column; } + +@keyframes mx_RoomView_fileDropTarget_animation { + from { + opacity: 0; + } + to { + opacity: 0.95; + } +} + .mx_RoomView_fileDropTarget { min-width: 0px; width: 100%; + height: 100%; + font-size: $font-18px; text-align: center; pointer-events: none; - padding-left: 12px; - padding-right: 12px; - margin-left: -12px; + background-color: $primary-bg-color; + opacity: 0.95; - border-top-left-radius: 10px; - border-top-right-radius: 10px; - - background-color: $droptarget-bg-color; - border: 2px #e1dddd solid; - border-bottom: none; position: absolute; - top: 52px; - bottom: 0px; z-index: 3000; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + animation: mx_RoomView_fileDropTarget_animation; + animation-duration: 0.5s; } -.mx_RoomView_fileDropTargetLabel { - top: 50%; - width: 100%; - margin-top: -50px; - position: absolute; +@keyframes mx_RoomView_fileDropTarget_image_animation { + from { + width: 0px; + } + to { + width: 32px; + } +} + +.mx_RoomView_fileDropTarget_image { + animation: mx_RoomView_fileDropTarget_image_animation; + animation-duration: 0.5s; + margin-bottom: 16px; } .mx_RoomView_auxPanel { @@ -117,7 +136,6 @@ limitations under the License. } .mx_RoomView_body { - position: relative; //for .mx_RoomView_auxPanel_fullHeight display: flex; flex-direction: column; flex: 1; diff --git a/res/css/structures/_SpacePanel.scss b/res/css/structures/_SpacePanel.scss new file mode 100644 index 0000000000..9937117086 --- /dev/null +++ b/res/css/structures/_SpacePanel.scss @@ -0,0 +1,349 @@ +/* +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 + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +$topLevelHeight: 32px; +$nestedHeight: 24px; +$gutterSize: 17px; +$activeStripeSize: 4px; +$activeBorderTransparentGap: 2px; + +$activeBackgroundColor: $roomtile-selected-bg-color; +$activeBorderColor: $secondary-fg-color; + +.mx_SpacePanel { + flex: 0 0 auto; + background-color: $groupFilterPanel-bg-color; + padding: 0; + margin: 0; + + // Create another flexbox so the Panel fills the container + display: flex; + flex-direction: column; + overflow-y: auto; + + .mx_SpacePanel_spaceTreeWrapper { + flex: 1; + } + + .mx_SpacePanel_toggleCollapse { + flex: 0 0 auto; + width: 40px; + height: 40px; + mask-position: center; + mask-size: 32px; + mask-repeat: no-repeat; + margin-left: $gutterSize; + margin-bottom: 12px; + background-color: $roomlist-header-color; + mask-image: url('$(res)/img/element-icons/expand-space-panel.svg'); + + &.expanded { + transform: scaleX(-1); + } + } + + ul { + margin: 0; + list-style: none; + padding: 0; + padding-left: 16px; + } + + .mx_AutoHideScrollbar { + padding: 16px 12px 16px 0; + } + + .mx_SpaceButton_toggleCollapse { + cursor: pointer; + } + + .mx_SpaceItem.collapsed { + .mx_SpaceButton { + .mx_NotificationBadge { + right: -4px; + top: -4px; + } + } + + & > .mx_SpaceButton > .mx_SpaceButton_toggleCollapse { + transform: rotate(-90deg); + } + + & > .mx_SpaceTreeLevel { + display: none; + } + } + + .mx_SpaceItem:not(.hasSubSpaces) > .mx_SpaceButton { + margin-left: $gutterSize; + } + + .mx_SpaceButton { + border-radius: 8px; + position: relative; + 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; + margin-left: 8px; + white-space: nowrap; + display: block; + max-width: 150px; + text-overflow: ellipsis; + overflow: hidden; + padding-right: 8px; + font-size: $font-14px; + line-height: $font-18px; + } + + .mx_SpaceButton_toggleCollapse { + width: calc($gutterSize - $activeStripeSize); + margin-left: 1px; + height: 20px; + mask-position: center; + mask-size: 20px; + mask-repeat: no-repeat; + background-color: $roomlist-header-color; + mask-image: url('$(res)/img/feather-customised/chevron-down.svg'); + } + + .mx_SpaceButton_icon { + width: $topLevelHeight; + min-width: $topLevelHeight; + height: $topLevelHeight; + border-radius: 8px; + position: relative; + + &::before { + position: absolute; + content: ''; + width: $topLevelHeight; + height: $topLevelHeight; + top: 0; + left: 0; + mask-position: center; + mask-repeat: no-repeat; + mask-size: 18px; + } + } + + &.mx_SpaceButton_home .mx_SpaceButton_icon { + background-color: #ffffff; + + &::before { + background-color: #3f3d3d; + mask-image: url('$(res)/img/element-icons/home.svg'); + } + } + + .mx_SpaceButton_avatarPlaceholder { + border: $activeBorderTransparentGap transparent solid; + padding: $activeBorderTransparentGap; + } + + &.mx_SpaceButton_new .mx_SpaceButton_icon { + background-color: $accent-color; + transition: all .1s ease-in-out; // TODO transition + + &::before { + background-color: #ffffff; + mask-image: url('$(res)/img/element-icons/plus.svg'); + transition: all .2s ease-in-out; // TODO transition + } + } + + &.mx_SpaceButton_newCancel .mx_SpaceButton_icon { + background-color: $icon-button-color; + + &::before { + transform: rotate(45deg); + } + } + + .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; + } + } + + .mx_SpaceButton_menuButton { + width: 20px; + min-width: 20px; // yay flex + height: 20px; + margin-top: auto; + margin-bottom: auto; + position: relative; + display: none; + + &::before { + top: 2px; + left: 2px; + content: ''; + width: 16px; + height: 16px; + position: absolute; + mask-position: center; + mask-size: contain; + mask-repeat: no-repeat; + mask-image: url('$(res)/img/element-icons/context-menu.svg'); + background: $primary-fg-color; + } + } + } + + .mx_SpacePanel_badgeContainer { + height: 16px; + // don't set width so that it takes no space when there is no badge to show + margin: auto 0; // vertically align + + // Create a flexbox to make aligning dot badges easier + display: flex; + align-items: center; + + .mx_NotificationBadge { + margin: 0 2px; // centering + } + + .mx_NotificationBadge_dot { + // make the smaller dot occupy the same width for centering + margin-left: 7px; + margin-right: 7px; + } + } + + &.collapsed { + .mx_SpaceButton { + .mx_SpacePanel_badgeContainer { + position: absolute; + right: 0px; + top: 2px; + } + } + } + + &:not(.collapsed) { + .mx_SpaceButton:hover, + .mx_SpaceButton:focus-within, + .mx_SpaceButton_hasMenuOpen { + // Hide the badge container on hover because it'll be a menu button + .mx_SpacePanel_badgeContainer { + width: 0; + height: 0; + display: none; + } + + .mx_SpaceButton_menuButton { + display: block; + } + } + } + + /* root space buttons are bigger and not indented */ + & > .mx_AutoHideScrollbar { + & > .mx_SpaceButton { + height: $topLevelHeight; + + &.mx_SpaceButton_active::before { + height: $topLevelHeight; + } + } + + & > ul { + padding-left: 0; + } + } +} + +.mx_SpacePanel_contextMenu { + .mx_SpacePanel_contextMenu_header { + margin: 12px 16px 12px; + font-weight: $font-semi-bold; + font-size: $font-15px; + line-height: $font-18px; + } + + .mx_IconizedContextMenu_optionList .mx_AccessibleButton.mx_SpacePanel_contextMenu_inviteButton { + color: $accent-color; + + .mx_SpacePanel_iconInvite::before { + background-color: $accent-color; + mask-image: url('$(res)/img/element-icons/room/invite.svg'); + } + } + + .mx_SpacePanel_iconSettings::before { + mask-image: url('$(res)/img/element-icons/settings.svg'); + } + + .mx_SpacePanel_iconLeave::before { + mask-image: url('$(res)/img/element-icons/leave.svg'); + } + + .mx_SpacePanel_iconHome::before { + mask-image: url('$(res)/img/element-icons/roomlist/home.svg'); + } + + .mx_SpacePanel_iconMembers::before { + mask-image: url('$(res)/img/element-icons/room/members.svg'); + } + + .mx_SpacePanel_iconPlus::before { + mask-image: url('$(res)/img/element-icons/plus.svg'); + } + + .mx_SpacePanel_iconExplore::before { + mask-image: url('$(res)/img/element-icons/roomlist/explore.svg'); + } +} + + +.mx_SpacePanel_sharePublicSpace { + margin: 0; +} diff --git a/res/css/structures/_SpaceRoomDirectory.scss b/res/css/structures/_SpaceRoomDirectory.scss new file mode 100644 index 0000000000..5cb91820cf --- /dev/null +++ b/res/css/structures/_SpaceRoomDirectory.scss @@ -0,0 +1,231 @@ +/* +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 + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_SpaceRoomDirectory_dialogWrapper > .mx_Dialog { + max-width: 960px; + height: 100%; +} + +.mx_SpaceRoomDirectory { + height: 100%; + margin-bottom: 12px; + color: $primary-fg-color; + word-break: break-word; + display: flex; + flex-direction: column; + + .mx_Dialog_title { + display: flex; + + .mx_BaseAvatar { + margin-right: 16px; + } + + .mx_BaseAvatar_image { + border-radius: 8px; + } + + > div { + > h1 { + font-weight: $font-semi-bold; + font-size: $font-18px; + line-height: $font-22px; + margin: 0; + } + + > div { + color: $secondary-fg-color; + font-size: $font-15px; + line-height: $font-24px; + } + } + } + + .mx_Dialog_content { + // TODO fix scrollbar + //display: flex; + //flex-direction: column; + //height: calc(100% - 80px); + + .mx_AccessibleButton_kind_link { + padding: 0; + } + + .mx_SearchBox { + margin: 24px 0 28px; + } + + .mx_SpaceRoomDirectory_listHeader { + display: flex; + font-size: $font-12px; + line-height: $font-15px; + color: $secondary-fg-color; + + .mx_FormButton { + margin-bottom: 8px; + } + + > span { + margin: auto 0 0 auto; + } + } + } +} + +.mx_SpaceRoomDirectory_list { + margin-top: 8px; + + .mx_SpaceRoomDirectory_roomCount { + > h3 { + display: inline; + font-weight: $font-semi-bold; + font-size: $font-18px; + line-height: $font-22px; + color: $primary-fg-color; + } + + > span { + margin-left: 8px; + font-size: $font-15px; + line-height: $font-24px; + color: $secondary-fg-color; + } + } + + .mx_SpaceRoomDirectory_subspace { + margin-top: 8px; + + .mx_SpaceRoomDirectory_subspace_info { + display: flex; + flex-direction: row; + align-items: center; + margin-bottom: 8px; + color: $secondary-fg-color; + font-weight: $font-semi-bold; + font-size: $font-12px; + line-height: $font-15px; + + .mx_BaseAvatar { + margin-right: 12px; + vertical-align: middle; + } + + .mx_BaseAvatar_image { + border-radius: 8px; + } + + .mx_SpaceRoomDirectory_actions { + text-align: right; + height: min-content; + margin-left: auto; + margin-right: 16px; + } + } + + .mx_SpaceRoomDirectory_subspace_children { + margin-left: 12px; + border-left: 2px solid $space-button-outline-color; + padding-left: 24px; + } + } + + .mx_SpaceRoomDirectory_roomTile { + padding: 16px; + border-radius: 8px; + border: 1px solid $space-button-outline-color; + margin: 8px 0 16px; + display: flex; + min-height: 76px; + box-sizing: border-box; + + &.mx_AccessibleButton:hover { + background-color: rgba(141, 151, 165, 0.1); + } + + .mx_BaseAvatar { + margin-right: 16px; + margin-top: 6px; + } + + .mx_SpaceRoomDirectory_roomTile_info { + display: inline-block; + font-size: $font-15px; + flex-grow: 1; + height: min-content; + margin: auto 0; + + .mx_SpaceRoomDirectory_roomTile_name { + font-weight: $font-semi-bold; + line-height: $font-18px; + } + .mx_SpaceRoomDirectory_roomTile_topic { + line-height: $font-24px; + color: $secondary-fg-color; + } + } + + .mx_SpaceRoomDirectory_roomTile_memberCount { + position: relative; + margin: auto 0 auto 24px; + padding: 0 0 0 28px; + line-height: $font-24px; + display: inline-block; + width: 32px; + + &::before { + position: absolute; + content: ''; + width: 24px; + height: 24px; + top: 0; + left: 0; + mask-position: center; + mask-repeat: no-repeat; + mask-size: contain; + background-color: $secondary-fg-color; + mask-image: url('$(res)/img/element-icons/community-members.svg'); + } + } + + .mx_SpaceRoomDirectory_actions { + width: 180px; + text-align: right; + height: min-content; + margin: auto 0 auto 28px; + + .mx_AccessibleButton { + vertical-align: middle; + + & + .mx_AccessibleButton { + margin-left: 24px; + } + } + } + } + + .mx_SpaceRoomDirectory_actions { + .mx_SpaceRoomDirectory_actionsText { + font-weight: normal; + font-size: $font-12px; + line-height: $font-15px; + color: $secondary-fg-color; + } + + .mx_Checkbox { + display: inline-block; + } + } +} diff --git a/res/css/structures/_SpaceRoomView.scss b/res/css/structures/_SpaceRoomView.scss new file mode 100644 index 0000000000..38310d39a9 --- /dev/null +++ b/res/css/structures/_SpaceRoomView.scss @@ -0,0 +1,336 @@ +/* +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 + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +$SpaceRoomViewInnerWidth: 428px; + +.mx_SpaceRoomView { + .mx_MainSplit > div:first-child { + padding: 80px 60px; + flex-grow: 1; + + h1 { + margin: 0; + font-size: $font-24px; + font-weight: $font-semi-bold; + color: $primary-fg-color; + width: max-content; + } + + .mx_SpaceRoomView_description { + font-size: $font-15px; + color: $secondary-fg-color; + margin-top: 12px; + margin-bottom: 24px; + } + + .mx_SpaceRoomView_buttons { + display: block; + margin-top: 44px; + width: $SpaceRoomViewInnerWidth; + text-align: right; // button alignment right + + .mx_FormButton { + padding: 8px 22px; + margin-left: 16px; + } + } + + .mx_Field { + max-width: $SpaceRoomViewInnerWidth; + + & + .mx_Field { + margin-top: 28px; + } + } + + .mx_SpaceRoomView_errorText { + font-weight: $font-semi-bold; + font-size: $font-12px; + line-height: $font-15px; + color: $notice-primary-color; + margin-bottom: 28px; + } + + .mx_AccessibleButton_disabled { + cursor: not-allowed; + } + } + + .mx_SpaceRoomView_landing { + overflow-y: auto; + + > .mx_BaseAvatar_image, + > .mx_BaseAvatar > .mx_BaseAvatar_image { + border-radius: 12px; + } + + .mx_SpaceRoomView_landing_name { + margin: 24px 0 16px; + font-size: $font-15px; + color: $secondary-fg-color; + + > span { + display: inline-block; + } + + .mx_SpaceRoomView_landing_nameRow { + margin-top: 12px; + + > h1 { + display: inline-block; + } + } + + .mx_SpaceRoomView_landing_inviter { + .mx_BaseAvatar { + margin-right: 4px; + vertical-align: middle; + } + } + + .mx_SpaceRoomView_landing_memberCount { + position: relative; + margin-left: 24px; + padding: 0 0 0 28px; + line-height: $font-24px; + vertical-align: text-bottom; + + &::before { + position: absolute; + content: ''; + width: 24px; + height: 24px; + top: 0; + left: 0; + mask-position: center; + mask-repeat: no-repeat; + mask-size: contain; + background-color: $accent-color; + mask-image: url('$(res)/img/element-icons/community-members.svg'); + } + } + } + + .mx_SpaceRoomView_landing_topic { + font-size: $font-15px; + } + + .mx_SpaceRoomView_landing_joinButtons { + margin-top: 24px; + + .mx_FormButton { + 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_landing_addButton { + &::before { + background-color: #ac3ba8; + } + + &::after { + mask-image: url('$(res)/img/element-icons/roomlist/explore.svg'); + } + } + + &.mx_SpaceRoomView_landing_createButton { + &::before { + background-color: #368bd6; + } + + &::after { + mask-image: url('$(res)/img/element-icons/roomlist/explore.svg'); + } + } + + &.mx_SpaceRoomView_landing_settingsButton { + &::before { + background-color: #5c56f5; + } + + &::after { + mask-image: url('$(res)/img/element-icons/settings.svg'); + } + } + } + } + + .mx_SpaceRoomDirectory_list { + max-width: 600px; + + .mx_SpaceRoomDirectory_roomTile_actions { + display: none; + } + } + } + + .mx_SpaceRoomView_privateScope { + .mx_RadioButton { + width: $SpaceRoomViewInnerWidth; + border-radius: 8px; + border: 1px solid $space-button-outline-color; + padding: 16px 16px 16px 72px; + margin-top: 36px; + cursor: pointer; + box-sizing: border-box; + position: relative; + + > div:first-of-type { + // hide radio dot + display: none; + } + + .mx_RadioButton_content { + margin: 0; + + > h3 { + margin: 0 0 4px; + font-size: $font-15px; + font-weight: $font-semi-bold; + line-height: $font-18px; + } + + > div { + color: $secondary-fg-color; + font-size: $font-15px; + line-height: $font-24px; + } + } + + &::before { + content: ""; + position: absolute; + height: 32px; + width: 32px; + top: 24px; + left: 20px; + background-color: $secondary-fg-color; + mask-repeat: no-repeat; + mask-position: center; + mask-size: contain; + } + } + + .mx_RadioButton_checked { + border-color: $accent-color; + + .mx_RadioButton_content { + > div { + color: $primary-fg-color; + } + } + + &::before { + background-color: $accent-color; + } + } + + .mx_SpaceRoomView_privateScope_justMeButton::before { + mask-image: url('$(res)/img/element-icons/room/members.svg'); + } + + .mx_SpaceRoomView_privateScope_meAndMyTeammatesButton::before { + mask-image: url('$(res)/img/element-icons/community-members.svg'); + } + } + + .mx_SpaceRoomView_inviteTeammates { + .mx_SpaceRoomView_inviteTeammates_buttons { + color: $secondary-fg-color; + margin-top: 28px; + + .mx_AccessibleButton { + position: relative; + display: inline-block; + padding-left: 32px; + line-height: 24px; // to center icons + + &::before { + content: ""; + position: absolute; + height: 24px; + width: 24px; + top: 0; + left: 0; + background-color: $secondary-fg-color; + mask-repeat: no-repeat; + mask-position: center; + mask-size: contain; + } + + & + .mx_AccessibleButton { + margin-left: 32px; + } + } + + .mx_SpaceRoomView_inviteTeammates_inviteDialogButton::before { + mask-image: url('$(res)/img/element-icons/room/invite.svg'); + } + } + } +} diff --git a/res/css/structures/_UserMenu.scss b/res/css/structures/_UserMenu.scss index 2a4453df70..3badb0850c 100644 --- a/res/css/structures/_UserMenu.scss +++ b/res/css/structures/_UserMenu.scss @@ -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 diff --git a/res/css/views/context_menus/_IconizedContextMenu.scss b/res/css/views/context_menus/_IconizedContextMenu.scss index d911ac6dfe..204435995f 100644 --- a/res/css/views/context_menus/_IconizedContextMenu.scss +++ b/res/css/views/context_menus/_IconizedContextMenu.scss @@ -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; diff --git a/res/css/views/dialogs/_AddExistingToSpaceDialog.scss b/res/css/views/dialogs/_AddExistingToSpaceDialog.scss new file mode 100644 index 0000000000..0c9d8e3840 --- /dev/null +++ b/res/css/views/dialogs/_AddExistingToSpaceDialog.scss @@ -0,0 +1,185 @@ +/* +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 + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_AddExistingToSpaceDialog_wrapper { + .mx_Dialog { + display: flex; + flex-direction: column; + } +} + +.mx_AddExistingToSpaceDialog { + width: 480px; + color: $primary-fg-color; + display: flex; + flex-direction: column; + flex-wrap: nowrap; + min-height: 0; + + .mx_Dialog_title { + display: flex; + + .mx_BaseAvatar { + display: inline-flex; + margin: 5px 16px 5px 5px; + vertical-align: middle; + } + + .mx_BaseAvatar_image { + border-radius: 8px; + margin: 0; + vertical-align: unset; + } + + > div { + > h1 { + font-weight: $font-semi-bold; + font-size: $font-18px; + line-height: $font-22px; + margin: 0; + } + + .mx_AddExistingToSpaceDialog_onlySpace { + color: $secondary-fg-color; + font-size: $font-15px; + line-height: $font-24px; + } + } + + .mx_Dropdown_input { + border: none; + + > .mx_Dropdown_option { + padding-left: 0; + flex: unset; + height: unset; + color: $secondary-fg-color; + font-size: $font-15px; + line-height: $font-24px; + + .mx_BaseAvatar { + display: none; + } + } + + .mx_Dropdown_menu { + .mx_AddExistingToSpaceDialog_dropdownOptionActive { + color: $accent-color; + padding-right: 32px; + position: relative; + + &::before { + content: ''; + width: 20px; + height: 20px; + top: 8px; + right: 0; + position: absolute; + mask-position: center; + mask-size: contain; + mask-repeat: no-repeat; + background-color: $accent-color; + mask-image: url('$(res)/img/element-icons/roomlist/checkmark.svg'); + } + } + } + } + } + + .mx_SearchBox { + margin: 0; + } + + .mx_AddExistingToSpaceDialog_errorText { + font-weight: $font-semi-bold; + font-size: $font-12px; + line-height: $font-15px; + color: $notice-primary-color; + margin-bottom: 28px; + } + + .mx_AddExistingToSpaceDialog_content { + .mx_AddExistingToSpaceDialog_noResults { + margin-top: 24px; + } + } + + .mx_AddExistingToSpaceDialog_section { + margin-top: 24px; + + > h3 { + margin: 0; + color: $secondary-fg-color; + font-size: $font-12px; + font-weight: $font-semi-bold; + line-height: $font-15px; + } + + .mx_AddExistingToSpaceDialog_entry { + display: flex; + margin-top: 12px; + + .mx_BaseAvatar { + margin-right: 12px; + } + + .mx_AddExistingToSpaceDialog_entry_name { + font-size: $font-15px; + line-height: 30px; + flex-grow: 1; + } + + .mx_FormButton { + min-width: 92px; + font-weight: normal; + box-sizing: border-box; + } + } + } + + .mx_AddExistingToSpaceDialog_section_spaces { + .mx_BaseAvatar_image { + border-radius: 8px; + } + } + + .mx_AddExistingToSpaceDialog_footer { + display: flex; + margin-top: 32px; + + > span { + flex-grow: 1; + font-size: $font-12px; + line-height: $font-15px; + + > * { + vertical-align: middle; + } + } + + .mx_AccessibleButton { + display: inline-block; + } + + .mx_AccessibleButton_kind_link { + padding: 0; + } + } + + .mx_FormButton { + padding: 8px 22px; + } +} diff --git a/res/css/views/dialogs/_HostSignupDialog.scss b/res/css/views/dialogs/_HostSignupDialog.scss index 1378ac9053..ac4bc41951 100644 --- a/res/css/views/dialogs/_HostSignupDialog.scss +++ b/res/css/views/dialogs/_HostSignupDialog.scss @@ -19,6 +19,11 @@ limitations under the License. max-width: 580px; height: 80vh; max-height: 600px; + // Ensure dialog borders are always white as the HostSignupDialog + // does not yet support dark mode or theming in general. + // In the future we might want to pass the theme to the called + // iframe, should some hosting provider have that need. + background-color: #ffffff; .mx_HostSignupDialog_info { text-align: center; diff --git a/res/css/views/dialogs/_SpaceSettingsDialog.scss b/res/css/views/dialogs/_SpaceSettingsDialog.scss new file mode 100644 index 0000000000..c1fa539e9b --- /dev/null +++ b/res/css/views/dialogs/_SpaceSettingsDialog.scss @@ -0,0 +1,55 @@ +/* +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 + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_SpaceSettingsDialog { + width: 480px; + color: $primary-fg-color; + + .mx_SpaceSettings_errorText { + font-weight: $font-semi-bold; + font-size: $font-12px; + line-height: $font-15px; + color: $notice-primary-color; + margin-bottom: 28px; + } + + .mx_ToggleSwitch { + display: inline-block; + vertical-align: middle; + margin-left: 16px; + } + + .mx_AccessibleButton_kind_danger { + margin-top: 28px; + } + + .mx_SpaceSettingsDialog_buttons { + display: flex; + margin-top: 64px; + + .mx_AccessibleButton { + display: inline-block; + } + + .mx_AccessibleButton_kind_link { + margin-left: auto; + } + } + + .mx_FormButton { + padding: 8px 22px; + } +} diff --git a/res/css/views/rooms/_AuxPanel.scss b/res/css/views/rooms/_AuxPanel.scss index 34ef5e01d4..17a6294bf0 100644 --- a/res/css/views/rooms/_AuxPanel.scss +++ b/res/css/views/rooms/_AuxPanel.scss @@ -17,7 +17,7 @@ limitations under the License. .m_RoomView_auxPanel_stateViews { padding: 5px; padding-left: 19px; - border-bottom: 1px solid #e5e5e5; + border-bottom: 1px solid $primary-hairline-color; } .m_RoomView_auxPanel_stateViews_span a { diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 60b7bb08d8..5841cf2853 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -257,17 +257,13 @@ $left-gutter: 64px; display: inline-block; width: 14px; height: 14px; - top: 29px; + // This aligns the avatar with the last line of the + // message. We want to move it one line up - 2.2rem + top: -2.2rem; user-select: none; z-index: 1; } -.mx_EventTile_continuation .mx_EventTile_readAvatars, -.mx_EventTile_info .mx_EventTile_readAvatars, -.mx_EventTile_emote .mx_EventTile_readAvatars { - top: 7px; -} - .mx_EventTile_readAvatars .mx_BaseAvatar { position: absolute; display: inline-block; diff --git a/res/css/views/rooms/_GroupLayout.scss b/res/css/views/rooms/_GroupLayout.scss index 543e6ed685..903fabc8fd 100644 --- a/res/css/views/rooms/_GroupLayout.scss +++ b/res/css/views/rooms/_GroupLayout.scss @@ -105,16 +105,9 @@ $left-gutter: 64px; } .mx_EventTile_readAvatars { - top: 27px; - } - - &.mx_EventTile_continuation .mx_EventTile_readAvatars, - &.mx_EventTile_emote .mx_EventTile_readAvatars { - top: 5px; - } - - &.mx_EventTile_info .mx_EventTile_readAvatars { - top: 4px; + // This aligns the avatar with the last line of the + // message. We want to move it one line up - 2rem + top: -2rem; } .mx_EventTile_content .markdown-body { diff --git a/res/css/views/rooms/_MemberInfo.scss b/res/css/views/rooms/_MemberInfo.scss index 182c280217..3f7f83d334 100644 --- a/res/css/views/rooms/_MemberInfo.scss +++ b/res/css/views/rooms/_MemberInfo.scss @@ -19,6 +19,7 @@ limitations under the License. flex-direction: column; flex: 1; overflow-y: auto; + margin-top: 8px; } .mx_MemberInfo_name { diff --git a/res/css/views/rooms/_MemberList.scss b/res/css/views/rooms/_MemberList.scss index 1e3506e371..075e9ff585 100644 --- a/res/css/views/rooms/_MemberList.scss +++ b/res/css/views/rooms/_MemberList.scss @@ -44,6 +44,12 @@ limitations under the License. .mx_AutoHideScrollbar { flex: 1 1 0; } + + .mx_RightPanel_scopeHeader { + // vertically align with position on other right panel cards + // to prevent it bouncing as user navigates right panel + margin-top: -8px; + } } .mx_GroupMemberList_query, diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index 71c0db947e..dea1b58741 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -227,18 +227,6 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/room/composer/attach.svg'); } -.mx_MessageComposer_hangup::before { - mask-image: url('$(res)/img/element-icons/call/hangup.svg'); -} - -.mx_MessageComposer_voicecall::before { - mask-image: url('$(res)/img/element-icons/call/voice-call.svg'); -} - -.mx_MessageComposer_videocall::before { - mask-image: url('$(res)/img/element-icons/call/video-call.svg'); -} - .mx_MessageComposer_emoji::before { mask-image: url('$(res)/img/element-icons/room/composer/emoji.svg'); } @@ -247,6 +235,32 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/room/composer/sticker.svg'); } +.mx_MessageComposer_sendMessage { + cursor: pointer; + position: relative; + margin-right: 6px; + width: 32px; + height: 32px; + border-radius: 100%; + background-color: $button-bg-color; + + &::before { + position: absolute; + height: 16px; + width: 16px; + top: 8px; + left: 9px; + + mask-image: url('$(res)/img/element-icons/send-message.svg'); + mask-repeat: no-repeat; + mask-size: contain; + mask-position: center; + + background-color: $button-fg-color; + content: ''; + } +} + .mx_MessageComposer_formatting { cursor: pointer; margin: 0 11px; diff --git a/res/css/views/rooms/_RoomHeader.scss b/res/css/views/rooms/_RoomHeader.scss index a23a44906f..387d1588a3 100644 --- a/res/css/views/rooms/_RoomHeader.scss +++ b/res/css/views/rooms/_RoomHeader.scss @@ -252,6 +252,19 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/room/search-inset.svg'); } +.mx_RoomHeader_voiceCallButton::before { + mask-image: url('$(res)/img/element-icons/call/voice-call.svg'); + + // The call button SVG is padded slightly differently, so match it up to the size + // of the other icons + mask-size: 20px; + mask-position: center; +} + +.mx_RoomHeader_videoCallButton::before { + mask-image: url('$(res)/img/element-icons/call/video-call.svg'); +} + .mx_RoomHeader_showPanel { height: 16px; } diff --git a/res/css/views/rooms/_RoomList.scss b/res/css/views/rooms/_RoomList.scss index 66e1b827d0..d49ed4b736 100644 --- a/res/css/views/rooms/_RoomList.scss +++ b/res/css/views/rooms/_RoomList.scss @@ -19,7 +19,10 @@ limitations under the License. } .mx_RoomList_iconPlus::before { - mask-image: url('$(res)/img/element-icons/roomlist/plus.svg'); + mask-image: url('$(res)/img/element-icons/roomlist/plus-circle.svg'); +} +.mx_RoomList_iconHash::before { + mask-image: url('$(res)/img/element-icons/roomlist/hash-circle.svg'); } .mx_RoomList_iconExplore::before { mask-image: url('$(res)/img/element-icons/roomlist/explore.svg'); diff --git a/res/css/views/settings/_SpellCheckLanguages.scss b/res/css/views/settings/_SpellCheckLanguages.scss new file mode 100644 index 0000000000..bb322c983f --- /dev/null +++ b/res/css/views/settings/_SpellCheckLanguages.scss @@ -0,0 +1,35 @@ +/* +Copyright 2021 Šimon Brandner + +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 + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_ExistingSpellCheckLanguage { + display: flex; + align-items: center; + margin-bottom: 5px; +} + +.mx_ExistingSpellCheckLanguage_language { + flex: 1; + margin-right: 10px; +} + +.mx_GeneralUserSettingsTab_spellCheckLanguageInput { + margin-top: 1em; + margin-bottom: 1em; +} + +.mx_SpellCheckLanguages { + @mixin mx_Settings_fullWidthField; +} diff --git a/res/css/views/spaces/_SpaceBasicSettings.scss b/res/css/views/spaces/_SpaceBasicSettings.scss new file mode 100644 index 0000000000..204ccab2b7 --- /dev/null +++ b/res/css/views/spaces/_SpaceBasicSettings.scss @@ -0,0 +1,86 @@ +/* +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 + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_SpaceBasicSettings { + .mx_Field { + margin: 32px 0; + } + + .mx_SpaceBasicSettings_avatarContainer { + display: flex; + margin-top: 24px; + + .mx_SpaceBasicSettings_avatar { + position: relative; + height: 80px; + width: 80px; + background-color: $tertiary-fg-color; + border-radius: 16px; + } + + img.mx_SpaceBasicSettings_avatar { + width: 80px; + height: 80px; + object-fit: cover; + border-radius: 16px; + } + + // only show it when the button is a div and not an img (has avatar) + div.mx_SpaceBasicSettings_avatar { + cursor: pointer; + + &::before { + content: ""; + position: absolute; + height: 80px; + width: 80px; + top: 0; + left: 0; + background-color: #ffffff; // white icon fill + mask-repeat: no-repeat; + mask-position: center; + mask-size: 20px; + mask-image: url('$(res)/img/element-icons/camera.svg'); + } + } + + > input[type="file"] { + display: none; + } + + > .mx_AccessibleButton_kind_link { + display: inline-block; + padding: 0; + margin: auto 16px; + color: #368bd6; + } + + > .mx_SpaceBasicSettings_avatar_remove { + color: $notice-primary-color; + } + } + + .mx_FormButton { + padding: 8px 22px; + margin-left: auto; + display: block; + width: min-content; + } + + .mx_AccessibleButton_disabled { + cursor: not-allowed; + } +} diff --git a/res/css/views/spaces/_SpaceCreateMenu.scss b/res/css/views/spaces/_SpaceCreateMenu.scss new file mode 100644 index 0000000000..2a11ec9f23 --- /dev/null +++ b/res/css/views/spaces/_SpaceCreateMenu.scss @@ -0,0 +1,138 @@ +/* +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 + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// TODO: the space panel currently does not have a fixed width, +// just the headers at each level have a max-width of 150px +// so this will look slightly off for now. We should probably use css grid for the whole main layout... +$spacePanelWidth: 200px; + +.mx_SpaceCreateMenu_wrapper { + // background blur everything except SpacePanel + .mx_ContextualMenu_background { + background-color: $dialog-backdrop-color; + opacity: 0.6; + left: $spacePanelWidth; + } + + .mx_ContextualMenu { + padding: 24px; + width: 480px; + box-sizing: border-box; + background-color: $primary-bg-color; + + > div { + > h2 { + font-weight: $font-semi-bold; + font-size: $font-18px; + margin-top: 4px; + } + + > p { + font-size: $font-15px; + color: $secondary-fg-color; + margin: 0; + } + } + + .mx_SpaceCreateMenuType { + position: relative; + padding: 16px 32px 16px 72px; + width: 432px; + box-sizing: border-box; + border-radius: 8px; + border: 1px solid $input-darker-bg-color; + font-size: $font-15px; + margin: 20px 0; + + > h3 { + font-weight: $font-semi-bold; + margin: 0 0 4px; + } + + > span { + color: $secondary-fg-color; + } + + &::before { + position: absolute; + content: ''; + width: 32px; + height: 32px; + top: 24px; + left: 20px; + mask-position: center; + mask-repeat: no-repeat; + mask-size: 32px; + background-color: $tertiary-fg-color; + } + + &:hover { + border-color: $accent-color; + + &::before { + background-color: $accent-color; + } + + > span { + color: $primary-fg-color; + } + } + } + + .mx_SpaceCreateMenuType_public::before { + mask-image: url('$(res)/img/globe.svg'); + mask-size: 26px; + } + .mx_SpaceCreateMenuType_private::before { + mask-image: url('$(res)/img/element-icons/lock.svg'); + } + + .mx_SpaceCreateMenu_back { + width: 28px; + height: 28px; + position: relative; + background-color: $theme-button-bg-color; + border-radius: 14px; + margin-bottom: 12px; + + &::before { + content: ""; + position: absolute; + height: 28px; + width: 28px; + top: 0; + left: 0; + background-color: $muted-fg-color; + transform: rotate(90deg); + mask-repeat: no-repeat; + mask-position: 2px 3px; + mask-size: 24px; + mask-image: url('$(res)/img/feather-customised/chevron-down.svg'); + } + } + + .mx_FormButton { + padding: 8px 22px; + margin-left: auto; + display: block; + width: min-content; + } + + .mx_AccessibleButton_disabled { + cursor: not-allowed; + } + } +} diff --git a/res/css/views/spaces/_SpacePublicShare.scss b/res/css/views/spaces/_SpacePublicShare.scss new file mode 100644 index 0000000000..9ba0549ae3 --- /dev/null +++ b/res/css/views/spaces/_SpacePublicShare.scss @@ -0,0 +1,60 @@ +/* +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 + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_SpacePublicShare { + .mx_AccessibleButton { + border: 1px solid $space-button-outline-color; + box-sizing: border-box; + border-radius: 8px; + padding: 12px 24px 12px 52px; + margin-top: 16px; + width: $SpaceRoomViewInnerWidth; + font-size: $font-15px; + line-height: $font-24px; + position: relative; + display: flex; + + > span { + color: #368bd6; + margin-left: auto; + } + + &:hover { + background-color: rgba(141, 151, 165, 0.1); + } + + &::before { + content: ""; + position: absolute; + width: 30px; + height: 30px; + mask-repeat: no-repeat; + mask-size: contain; + mask-position: center; + background: $muted-fg-color; + left: 12px; + top: 9px; + } + + &.mx_SpacePublicShare_shareButton::before { + mask-image: url('$(res)/img/element-icons/link.svg'); + } + + &.mx_SpacePublicShare_inviteButton::before { + mask-image: url('$(res)/img/element-icons/room/invite.svg'); + } + } +} diff --git a/res/img/element-icons/expand-space-panel.svg b/res/img/element-icons/expand-space-panel.svg new file mode 100644 index 0000000000..11232acd58 --- /dev/null +++ b/res/img/element-icons/expand-space-panel.svg @@ -0,0 +1,4 @@ + + + + diff --git a/res/img/element-icons/link.svg b/res/img/element-icons/link.svg new file mode 100644 index 0000000000..ab3d54b838 --- /dev/null +++ b/res/img/element-icons/link.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/element-icons/lock.svg b/res/img/element-icons/lock.svg new file mode 100644 index 0000000000..06fe52a391 --- /dev/null +++ b/res/img/element-icons/lock.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/element-icons/plus.svg b/res/img/element-icons/plus.svg new file mode 100644 index 0000000000..ea1972237d --- /dev/null +++ b/res/img/element-icons/plus.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/element-icons/room/invite.svg b/res/img/element-icons/room/invite.svg index 655f9f118a..d2ecb837b2 100644 --- a/res/img/element-icons/room/invite.svg +++ b/res/img/element-icons/room/invite.svg @@ -1,3 +1,3 @@ - + diff --git a/res/img/element-icons/roomlist/hash-circle.svg b/res/img/element-icons/roomlist/hash-circle.svg new file mode 100644 index 0000000000..924b22cf32 --- /dev/null +++ b/res/img/element-icons/roomlist/hash-circle.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/res/img/element-icons/roomlist/plus-circle.svg b/res/img/element-icons/roomlist/plus-circle.svg new file mode 100644 index 0000000000..251ded225c --- /dev/null +++ b/res/img/element-icons/roomlist/plus-circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/element-icons/send-message.svg b/res/img/element-icons/send-message.svg new file mode 100644 index 0000000000..ce35bf8bc8 --- /dev/null +++ b/res/img/element-icons/send-message.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/upload-big.svg b/res/img/upload-big.svg index 6099c2e976..9a6a265fdb 100644 --- a/res/img/upload-big.svg +++ b/res/img/upload-big.svg @@ -1,19 +1,3 @@ - - - - icons_upload_drop - Created with bin/sketchtool. - - - - - - - - - - - - - + + diff --git a/res/themes/dark/css/_dark.scss b/res/themes/dark/css/_dark.scss index a878aa3cdd..0de5e69782 100644 --- a/res/themes/dark/css/_dark.scss +++ b/res/themes/dark/css/_dark.scss @@ -123,6 +123,7 @@ $roomsublist-divider-color: $primary-fg-color; $roomsublist-skeleton-ui-bg: linear-gradient(180deg, #3e444c 0%, #3e444c00 100%); $groupFilterPanel-divider-color: $roomlist-header-color; +$space-button-outline-color: rgba(141, 151, 165, 0.2); $roomtile-preview-color: $secondary-fg-color; $roomtile-default-badge-bg-color: #61708b; diff --git a/res/themes/legacy-dark/css/_legacy-dark.scss b/res/themes/legacy-dark/css/_legacy-dark.scss index 3e3c299af9..8c5f20178b 100644 --- a/res/themes/legacy-dark/css/_legacy-dark.scss +++ b/res/themes/legacy-dark/css/_legacy-dark.scss @@ -120,6 +120,7 @@ $roomsublist-divider-color: $primary-fg-color; $roomsublist-skeleton-ui-bg: linear-gradient(180deg, #3e444c 0%, #3e444c00 100%); $groupFilterPanel-divider-color: $roomlist-header-color; +$space-button-outline-color: rgba(141, 151, 165, 0.2); $roomtile-preview-color: #9e9e9e; $roomtile-default-badge-bg-color: #61708b; diff --git a/res/themes/legacy-light/css/_legacy-light.scss b/res/themes/legacy-light/css/_legacy-light.scss index a740ba155c..3ba10a68ea 100644 --- a/res/themes/legacy-light/css/_legacy-light.scss +++ b/res/themes/legacy-light/css/_legacy-light.scss @@ -187,6 +187,7 @@ $roomsublist-divider-color: $primary-fg-color; $roomsublist-skeleton-ui-bg: linear-gradient(180deg, #ffffff 0%, #ffffff00 100%); $groupFilterPanel-divider-color: $roomlist-header-color; +$space-button-outline-color: #E3E8F0; $roomtile-preview-color: #9e9e9e; $roomtile-default-badge-bg-color: #61708b; diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss index 1c89d83c01..b6906d16be 100644 --- a/res/themes/light/css/_light.scss +++ b/res/themes/light/css/_light.scss @@ -67,9 +67,6 @@ $groupFilterPanel-bg-color: rgba(232, 232, 232, 0.77); // used by RoomDirectory permissions $plinth-bg-color: $secondary-accent-color; -// used by RoomDropTarget -$droptarget-bg-color: rgba(255,255,255,0.5); - // used by AddressSelector $selected-color: $secondary-accent-color; @@ -181,6 +178,7 @@ $roomsublist-divider-color: $primary-fg-color; $roomsublist-skeleton-ui-bg: linear-gradient(180deg, #ffffff 0%, #ffffff00 100%); $groupFilterPanel-divider-color: $roomlist-header-color; +$space-button-outline-color: #E3E8F0; $roomtile-preview-color: $secondary-fg-color; $roomtile-default-badge-bg-color: #61708b; diff --git a/res/themes/light/css/_mods.scss b/res/themes/light/css/_mods.scss index 30aaeedf8f..fbca58dfb1 100644 --- a/res/themes/light/css/_mods.scss +++ b/res/themes/light/css/_mods.scss @@ -16,6 +16,10 @@ backdrop-filter: blur($groupFilterPanel-background-blur-amount); } + .mx_SpacePanel { + backdrop-filter: blur($groupFilterPanel-background-blur-amount); + } + .mx_LeftPanel .mx_LeftPanel_roomListContainer { backdrop-filter: blur($roomlist-background-blur-amount); } diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 28f22780a2..4aa6df5488 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -38,6 +38,7 @@ import UserActivity from "../UserActivity"; import {ModalWidgetStore} from "../stores/ModalWidgetStore"; import { WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore"; import VoipUserMapper from "../VoipUserMapper"; +import {SpaceStoreClass} from "../stores/SpaceStore"; declare global { interface Window { @@ -68,6 +69,7 @@ declare global { mxUserActivity: UserActivity; mxModalWidgetStore: ModalWidgetStore; mxVoipUserMapper: VoipUserMapper; + mxSpaceStore: SpaceStoreClass; } interface Document { diff --git a/src/Avatar.ts b/src/Avatar.ts index 60bdfdcf75..e2557e21a8 100644 --- a/src/Avatar.ts +++ b/src/Avatar.ts @@ -165,6 +165,9 @@ export function avatarUrlForRoom(room: Room, width: number, height: number, resi return explicitRoomAvatar; } + // space rooms cannot be DMs so skip the rest + if (room.isSpaceRoom()) return null; + let otherMember = null; const otherUserId = DMRoomMap.shared().getUserIdForRoomId(room.roomId); if (otherUserId) { diff --git a/src/BasePlatform.ts b/src/BasePlatform.ts index d0d5e60ce8..9d7077097b 100644 --- a/src/BasePlatform.ts +++ b/src/BasePlatform.ts @@ -131,6 +131,14 @@ export default abstract class BasePlatform { hideUpdateToast(); } + /** + * Return true if platform supports multi-language + * spell-checking, otherwise false. + */ + supportsMultiLanguageSpellCheck(): boolean { + return false; + } + /** * Returns true if the platform supports displaying * notifications, otherwise false. @@ -240,6 +248,16 @@ export default abstract class BasePlatform { setLanguage(preferredLangs: string[]) {} + setSpellCheckLanguages(preferredLangs: string[]) {} + + getSpellCheckLanguages(): Promise | null { + return null; + } + + getAvailableSpellCheckLanguages(): Promise | null { + return null; + } + protected getSSOCallbackUrl(fragmentAfterLogin: string): URL { const url = new URL(window.location.href); url.hash = fragmentAfterLogin || ""; diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index ab3a601d93..8621f441de 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -629,6 +629,8 @@ export default class CallHandler { const mappedRoomId = (await VoipUserMapper.sharedInstance().getOrCreateVirtualRoomForRoom(roomId)) || roomId; logger.debug("Mapped real room " + roomId + " to room ID " + mappedRoomId); + const timeUntilTurnCresExpire = MatrixClientPeg.get().getTurnServersExpiry() - Date.now(); + console.log("Current turn creds expire in " + timeUntilTurnCresExpire + " seconds"); const call = createNewMatrixCall(MatrixClientPeg.get(), mappedRoomId); this.calls.set(roomId, call); @@ -704,6 +706,14 @@ export default class CallHandler { return; } + if (this.getCallForRoom(room.roomId)) { + Modal.createTrackedDialog('Call Handler', 'Existing Call with user', ErrorDialog, { + title: _t('Already in call'), + description: _t("You're already in a call with this person."), + }); + return; + } + const members = room.getJoinedMembers(); if (members.length <= 1) { Modal.createTrackedDialog('Call Handler', 'Cannot place call with self', ErrorDialog, { diff --git a/src/RoomInvite.js b/src/RoomInvite.js index 06d3fb04e8..503411d2b3 100644 --- a/src/RoomInvite.js +++ b/src/RoomInvite.js @@ -22,7 +22,7 @@ import MultiInviter from './utils/MultiInviter'; import Modal from './Modal'; import * as sdk from './'; import { _t } from './languageHandler'; -import {KIND_DM, KIND_INVITE} from "./components/views/dialogs/InviteDialog"; +import InviteDialog, {KIND_DM, KIND_INVITE, KIND_SPACE_INVITE} from "./components/views/dialogs/InviteDialog"; import CommunityPrototypeInviteDialog from "./components/views/dialogs/CommunityPrototypeInviteDialog"; import {CommunityPrototypeStore} from "./stores/CommunityPrototypeStore"; @@ -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, ); } diff --git a/src/SecurityManager.ts b/src/SecurityManager.ts index 220320470a..03cbe88c22 100644 --- a/src/SecurityManager.ts +++ b/src/SecurityManager.ts @@ -98,11 +98,27 @@ async function getSecretStorageKey( { keys: keyInfos }: { keys: Record }, ssssItemName, ): Promise<[string, Uint8Array]> { - const keyInfoEntries = Object.entries(keyInfos); - if (keyInfoEntries.length > 1) { - throw new Error("Multiple storage key requests not implemented"); + const cli = MatrixClientPeg.get(); + let keyId = await cli.getDefaultSecretStorageKeyId(); + let keyInfo; + if (keyId) { + // use the default SSSS key if set + keyInfo = keyInfos[keyId]; + if (!keyInfo) { + // if the default key is not available, pretend the default key + // isn't set + keyId = undefined; + } + } + if (!keyId) { + // if no default SSSS key is set, fall back to a heuristic of using the + // only available key, if only one key is set + const keyInfoEntries = Object.entries(keyInfos); + if (keyInfoEntries.length > 1) { + throw new Error("Multiple storage key requests not implemented"); + } + [keyId, keyInfo] = keyInfoEntries[0]; } - const [keyId, keyInfo] = keyInfoEntries[0]; // Check the in-memory cache if (isCachingAllowed() && secretStorageKeys[keyId]) { diff --git a/src/Velociraptor.js b/src/Velociraptor.js index ce52f60dbd..2da54babe5 100644 --- a/src/Velociraptor.js +++ b/src/Velociraptor.js @@ -118,25 +118,10 @@ export default class Velociraptor extends React.Component { domNode.style.visibility = restingStyle.visibility; }); - /* - console.log("enter:", - JSON.stringify(transitionOpts[i-1]), - "->", - JSON.stringify(restingStyle)); - */ - } else if (node === null) { - // Velocity stores data on elements using the jQuery .data() - // method, and assumes you'll be using jQuery's .remove() to - // remove the element, but we don't use jQuery, so we need to - // blow away the element's data explicitly otherwise it will leak. - // This uses Velocity's internal jQuery compatible wrapper. - // See the bug at - // https://github.com/julianshapiro/velocity/issues/300 - // and the FAQ entry, "Preventing memory leaks when - // creating/destroying large numbers of elements" - // (https://github.com/julianshapiro/velocity/issues/47) - const domNode = ReactDom.findDOMNode(this.nodes[k]); - if (domNode) Velocity.Utilities.removeData(domNode); + // console.log("enter:", + // JSON.stringify(transitionOpts[i-1]), + // "->", + // JSON.stringify(restingStyle)); } this.nodes[k] = node; } diff --git a/src/accessibility/context_menu/MenuItem.tsx b/src/accessibility/context_menu/MenuItem.tsx index 0bb169abf8..9a7c1d1f0a 100644 --- a/src/accessibility/context_menu/MenuItem.tsx +++ b/src/accessibility/context_menu/MenuItem.tsx @@ -19,14 +19,23 @@ limitations under the License. import React from "react"; import AccessibleButton from "../../components/views/elements/AccessibleButton"; +import AccessibleTooltipButton from "../../components/views/elements/AccessibleTooltipButton"; interface IProps extends React.ComponentProps { label?: string; + tooltip?: string; } // Semantic component for representing a role=menuitem -export const MenuItem: React.FC = ({children, label, ...props}) => { +export const MenuItem: React.FC = ({children, label, tooltip, ...props}) => { const ariaLabel = props["aria-label"] || label; + + if (tooltip) { + return + { children } + ; + } + return ( { children } diff --git a/src/autocomplete/UserProvider.tsx b/src/autocomplete/UserProvider.tsx index 32eea55b0b..7fc01daef9 100644 --- a/src/autocomplete/UserProvider.tsx +++ b/src/autocomplete/UserProvider.tsx @@ -155,6 +155,7 @@ export default class UserProvider extends AutocompleteProvider { const currentUserId = MatrixClientPeg.get().credentials.userId; this.users = this.room.getJoinedMembers().filter(({userId}) => userId !== currentUserId); + this.users = this.users.concat(this.room.getMembersWithMembership("invite")); this.users = sortBy(this.users, (member) => 1E20 - lastSpoken[member.userId] || 1E20); diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index b5e5966d91..726ff547ff 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -76,6 +76,7 @@ export interface IProps extends IPosition { hasBackground?: boolean; // whether this context menu should be focus managed. If false it must handle itself managed?: boolean; + wrapperClassName?: string; // Function to be called on menu close onFinished(); @@ -365,7 +366,7 @@ export class ContextMenu extends React.PureComponent { return (
{ } public render(): React.ReactNode { - const groupFilterPanel = !this.state.showGroupFilterPanel ? null : ( -
- - {SettingsStore.getValue("feature_custom_tags") ? : null} -
- ); + let leftLeftPanel; + // Currently TagPanel.enableTagPanel is disabled when Legacy Communities are disabled so for now + // ignore it and force the rendering of SpacePanel if that Labs flag is enabled. + if (SettingsStore.getValue("feature_spaces")) { + leftLeftPanel = ; + } else if (this.state.showGroupFilterPanel) { + leftLeftPanel = ( +
+ + {SettingsStore.getValue("feature_custom_tags") ? : null} +
+ ); + } const roomList = { const containerClasses = classNames({ "mx_LeftPanel": true, - "mx_LeftPanel_hasGroupFilterPanel": !!groupFilterPanel, "mx_LeftPanel_minimized": this.props.isMinimized, }); @@ -417,7 +424,7 @@ export default class LeftPanel extends React.Component { return (
- {groupFilterPanel} + {leftLeftPanel}