diff --git a/.eslintrc.js b/.eslintrc.js
index fc82e75ce2..bc2a142c2d 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -19,7 +19,7 @@ module.exports = {
},
overrides: [{
- "files": ["src/**/*.{ts, tsx}"],
+ "files": ["src/**/*.{ts,tsx}"],
"extends": ["matrix-org/ts"],
"rules": {
// We disable this while we're transitioning
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 29cbb040f4..47bffe432f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,72 @@
+Changes in [3.3.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.3.0) (2020-09-01)
+===================================================================================================
+[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.3.0-rc.1...v3.3.0)
+
+ * Upgrade to JS SDK 8.2.0
+
+Changes in [3.3.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.3.0-rc.1) (2020-08-26)
+=============================================================================================================
+[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.2.0...v3.3.0-rc.1)
+
+ * Upgrade to JS SDK 8.2.0-rc.1
+ * Update from Weblate
+ [\#5146](https://github.com/matrix-org/matrix-react-sdk/pull/5146)
+ * BaseAvatar avoid initial render with default avatar
+ [\#5142](https://github.com/matrix-org/matrix-react-sdk/pull/5142)
+ * Enforce Secure Backup completion when requested by HS
+ [\#5130](https://github.com/matrix-org/matrix-react-sdk/pull/5130)
+ * Communities v2 prototype: Explore rooms, global state, and default room
+ [\#5139](https://github.com/matrix-org/matrix-react-sdk/pull/5139)
+ * Add communities v2 prototyping feature flag + initial tag panel prototypes
+ [\#5133](https://github.com/matrix-org/matrix-react-sdk/pull/5133)
+ * Remove some unused components
+ [\#5134](https://github.com/matrix-org/matrix-react-sdk/pull/5134)
+ * Allow avatar image view for 1:1 rooms
+ [\#5137](https://github.com/matrix-org/matrix-react-sdk/pull/5137)
+ * Send mx_local_settings in rageshake
+ [\#5136](https://github.com/matrix-org/matrix-react-sdk/pull/5136)
+ * Run all room leaving behaviour through a single function
+ [\#5132](https://github.com/matrix-org/matrix-react-sdk/pull/5132)
+ * Add clarifying comment in media device selection
+ [\#5131](https://github.com/matrix-org/matrix-react-sdk/pull/5131)
+ * Settings v3: Feature flag changes
+ [\#5124](https://github.com/matrix-org/matrix-react-sdk/pull/5124)
+ * Clear url previews if they all get edited out of the event
+ [\#5129](https://github.com/matrix-org/matrix-react-sdk/pull/5129)
+ * Consider tab completions as modifications for editing purposes to unlock
+ sending
+ [\#5128](https://github.com/matrix-org/matrix-react-sdk/pull/5128)
+ * Use matrix-doc for SAS emoji translations
+ [\#5125](https://github.com/matrix-org/matrix-react-sdk/pull/5125)
+ * Add a rageshake function to download the logs locally
+ [\#3849](https://github.com/matrix-org/matrix-react-sdk/pull/3849)
+ * Room List filtering visual tweaks
+ [\#5123](https://github.com/matrix-org/matrix-react-sdk/pull/5123)
+ * Make reply preview not an overlay so you can see new messages
+ [\#5072](https://github.com/matrix-org/matrix-react-sdk/pull/5072)
+ * Allow room tile context menu when minimized using right click
+ [\#5113](https://github.com/matrix-org/matrix-react-sdk/pull/5113)
+ * Add null guard to group inviter for corrupted groups
+ [\#5121](https://github.com/matrix-org/matrix-react-sdk/pull/5121)
+ * Room List styling tweaks
+ [\#5118](https://github.com/matrix-org/matrix-react-sdk/pull/5118)
+ * Fix corner rounding on images not always affecting right side
+ [\#5120](https://github.com/matrix-org/matrix-react-sdk/pull/5120)
+ * Change add room action for rooms to context menu
+ [\#5108](https://github.com/matrix-org/matrix-react-sdk/pull/5108)
+ * Switch out the globe icon and colour it depending on theme
+ [\#5106](https://github.com/matrix-org/matrix-react-sdk/pull/5106)
+ * Message Action Bar watch for event send changes
+ [\#5115](https://github.com/matrix-org/matrix-react-sdk/pull/5115)
+ * Put message previews for Emoji behind Labs
+ [\#5110](https://github.com/matrix-org/matrix-react-sdk/pull/5110)
+ * Fix styling for selected community marker
+ [\#5107](https://github.com/matrix-org/matrix-react-sdk/pull/5107)
+ * Fix action bar safe area regression
+ [\#5111](https://github.com/matrix-org/matrix-react-sdk/pull/5111)
+ * Fix /op slash command
+ [\#5109](https://github.com/matrix-org/matrix-react-sdk/pull/5109)
+
Changes in [3.2.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.2.0) (2020-08-17)
===================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.2.0-rc.1...v3.2.0)
diff --git a/package.json b/package.json
index ab71f68b08..9b7d80ca73 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "matrix-react-sdk",
- "version": "3.2.0",
+ "version": "3.3.0",
"description": "SDK for matrix.org using React",
"author": "matrix.org",
"repository": {
@@ -61,7 +61,6 @@
"classnames": "^2.2.6",
"commonmark": "^0.29.1",
"counterpart": "^0.18.6",
- "create-react-class": "^15.6.3",
"diff-dom": "^4.1.6",
"diff-match-patch": "^1.0.5",
"emojibase-data": "^5.0.1",
@@ -163,9 +162,7 @@
"stylelint-config-standard": "^18.3.0",
"stylelint-scss": "^3.18.0",
"typescript": "^3.9.7",
- "walk": "^2.3.14",
- "webpack": "^4.43.0",
- "webpack-cli": "^3.3.12"
+ "walk": "^2.3.14"
},
"jest": {
"testMatch": [
diff --git a/res/css/_components.scss b/res/css/_components.scss
index 24d2ffa2b0..45ed6b3300 100644
--- a/res/css/_components.scss
+++ b/res/css/_components.scss
@@ -68,6 +68,7 @@
@import "./views/dialogs/_CreateRoomDialog.scss";
@import "./views/dialogs/_DeactivateAccountDialog.scss";
@import "./views/dialogs/_DevtoolsDialog.scss";
+@import "./views/dialogs/_EditCommunityPrototypeDialog.scss";
@import "./views/dialogs/_GroupAddressPicker.scss";
@import "./views/dialogs/_IncomingSasDialog.scss";
@import "./views/dialogs/_InviteDialog.scss";
diff --git a/res/css/structures/_UserMenu.scss b/res/css/structures/_UserMenu.scss
index 78795c85a2..6fa2f2578e 100644
--- a/res/css/structures/_UserMenu.scss
+++ b/res/css/structures/_UserMenu.scss
@@ -16,9 +16,33 @@ limitations under the License.
.mx_UserMenu {
- // to make the ... button sort of aligned with the explore button below
+ // to make the menu button sort of aligned with the explore button below
padding-right: 6px;
+ &.mx_UserMenu_prototype {
+ // The margin & padding combination between here and the ::after is to
+ // align the border line with the tag panel.
+ margin-bottom: 6px;
+
+ padding-right: 0; // make the right edge line up with the explore button
+
+ .mx_UserMenu_headerButtons {
+ // considering we've eliminated right padding on the menu itself, we need to
+ // push the chevron in slightly (roughly lining up with the center of the
+ // plus buttons)
+ margin-right: 2px;
+ }
+
+ // we cheat opacity on the theme colour with an after selector here
+ &::after {
+ content: '';
+ border-bottom: 1px solid $primary-fg-color; // XXX: Variable abuse
+ opacity: 0.2;
+ display: block;
+ padding-top: 8px;
+ }
+ }
+
.mx_UserMenu_headerButtons {
width: 16px;
height: 16px;
@@ -36,7 +60,7 @@ limitations under the License.
mask-size: contain;
mask-repeat: no-repeat;
background: $primary-fg-color;
- mask-image: url('$(res)/img/element-icons/context-menu.svg');
+ mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
}
}
@@ -56,6 +80,28 @@ limitations under the License.
}
}
+ .mx_UserMenu_doubleName {
+ flex: 1;
+ min-width: 0; // make flexbox aware that it can crush this to a tiny width
+
+ .mx_UserMenu_userName,
+ .mx_UserMenu_subUserName {
+ display: block;
+ }
+
+ .mx_UserMenu_subUserName {
+ color: $muted-fg-color;
+ font-size: $font-13px;
+ line-height: $font-18px;
+ flex: 1;
+
+ // Ellipsize any text overflow
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ }
+ }
+
.mx_UserMenu_userName {
font-weight: 600;
font-size: $font-15px;
@@ -89,6 +135,44 @@ limitations under the License.
.mx_UserMenu_contextMenu {
width: 247px;
+ // These override the styles already present on the user menu rather than try to
+ // define a new menu. They are specifically for the stacked menu when a community
+ // is being represented as a prototype.
+ &.mx_UserMenu_contextMenu_prototype {
+ padding-bottom: 16px;
+
+ .mx_UserMenu_contextMenu_header {
+ padding-bottom: 0;
+ padding-top: 16px;
+
+ &:nth-child(n + 2) {
+ padding-top: 8px;
+ }
+ }
+
+ hr {
+ width: 85%;
+ opacity: 0.2;
+ border: none;
+ border-bottom: 1px solid $primary-fg-color; // XXX: Variable abuse
+ }
+
+ &.mx_IconizedContextMenu {
+ > .mx_IconizedContextMenu_optionList {
+ margin-top: 4px;
+
+ &::before {
+ border: none;
+ }
+
+ > .mx_AccessibleButton {
+ padding-top: 2px;
+ padding-bottom: 2px;
+ }
+ }
+ }
+ }
+
&.mx_IconizedContextMenu .mx_IconizedContextMenu_optionList_red {
.mx_AccessibleButton {
padding-top: 16px;
@@ -193,4 +277,12 @@ limitations under the License.
.mx_UserMenu_iconSignOut::before {
mask-image: url('$(res)/img/element-icons/leave.svg');
}
+
+ .mx_UserMenu_iconMembers::before {
+ mask-image: url('$(res)/img/element-icons/room/members.svg');
+ }
+
+ .mx_UserMenu_iconInvite::before {
+ mask-image: url('$(res)/img/element-icons/room/invite.svg');
+ }
}
diff --git a/res/css/views/dialogs/_EditCommunityPrototypeDialog.scss b/res/css/views/dialogs/_EditCommunityPrototypeDialog.scss
new file mode 100644
index 0000000000..75a56bf6b3
--- /dev/null
+++ b/res/css/views/dialogs/_EditCommunityPrototypeDialog.scss
@@ -0,0 +1,77 @@
+/*
+Copyright 2020 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.
+*/
+
+// XXX: many of these styles are shared with the create dialog
+.mx_EditCommunityPrototypeDialog {
+ &.mx_Dialog_fixedWidth {
+ width: 360px;
+ }
+
+ .mx_Dialog_content {
+ margin-bottom: 12px;
+
+ .mx_AccessibleButton.mx_AccessibleButton_kind_primary {
+ display: block;
+ height: 32px;
+ font-size: $font-16px;
+ line-height: 32px;
+ }
+
+ .mx_EditCommunityPrototypeDialog_rowAvatar {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ }
+
+ .mx_EditCommunityPrototypeDialog_avatarContainer {
+ margin-top: 20px;
+ margin-bottom: 20px;
+
+ .mx_EditCommunityPrototypeDialog_avatar,
+ .mx_EditCommunityPrototypeDialog_placeholderAvatar {
+ width: 96px;
+ height: 96px;
+ border-radius: 96px;
+ }
+
+ .mx_EditCommunityPrototypeDialog_placeholderAvatar {
+ background-color: #368bd6; // hardcoded for both themes
+
+ &::before {
+ display: inline-block;
+ background-color: #fff; // hardcoded because the background is
+ mask-repeat: no-repeat;
+ mask-size: 96px;
+ width: 96px;
+ height: 96px;
+ mask-position: center;
+ content: '';
+ vertical-align: middle;
+ mask-image: url('$(res)/img/element-icons/add-photo.svg');
+ }
+ }
+ }
+
+ .mx_EditCommunityPrototypeDialog_tip {
+ margin-left: 20px;
+
+ & > b, & > span {
+ display: block;
+ color: $muted-fg-color;
+ }
+ }
+ }
+}
diff --git a/res/css/views/dialogs/_InviteDialog.scss b/res/css/views/dialogs/_InviteDialog.scss
index a77d0bfbba..b9063f46b9 100644
--- a/res/css/views/dialogs/_InviteDialog.scss
+++ b/res/css/views/dialogs/_InviteDialog.scss
@@ -89,6 +89,13 @@ limitations under the License.
font-weight: bold;
text-transform: uppercase;
}
+
+ .mx_InviteDialog_subname {
+ margin-bottom: 10px;
+ margin-top: -10px; // HACK: Positioning with margins is bad
+ font-size: $font-12px;
+ color: $muted-fg-color;
+ }
}
.mx_InviteDialog_roomTile {
@@ -226,3 +233,7 @@ limitations under the License.
.mx_InviteDialog_addressBar {
margin-right: 45px;
}
+
+.mx_InviteDialog_helpText .mx_AccessibleButton_kind_link {
+ padding: 0;
+}
diff --git a/res/css/views/settings/tabs/_SettingsTab.scss b/res/css/views/settings/tabs/_SettingsTab.scss
index e3a61e6825..5f00ed86f7 100644
--- a/res/css/views/settings/tabs/_SettingsTab.scss
+++ b/res/css/views/settings/tabs/_SettingsTab.scss
@@ -1,5 +1,5 @@
/*
-Copyright 2019 New Vector Ltd
+Copyright 2019, 2020 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ limitations under the License.
font-size: $font-20px;
font-weight: 600;
color: $primary-fg-color;
+ margin-bottom: 10px;
}
.mx_SettingsTab_heading:nth-child(n + 2) {
diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts
index 84340d8219..1a361e7b55 100644
--- a/src/@types/global.d.ts
+++ b/src/@types/global.d.ts
@@ -28,6 +28,7 @@ import SettingsStore from "../settings/SettingsStore";
import {ActiveRoomObserver} from "../ActiveRoomObserver";
import {Notifier} from "../Notifier";
import type {Renderer} from "react-dom";
+import RightPanelStore from "../stores/RightPanelStore";
declare global {
interface Window {
@@ -49,6 +50,7 @@ declare global {
singletonModalManager: ModalManager;
mxSettingsStore: SettingsStore;
mxNotifier: typeof Notifier;
+ mxRightPanelStore: RightPanelStore;
}
interface Document {
diff --git a/src/AsyncWrapper.js b/src/AsyncWrapper.js
index 94de5df214..359828b312 100644
--- a/src/AsyncWrapper.js
+++ b/src/AsyncWrapper.js
@@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import createReactClass from 'create-react-class';
+import React from "react";
import * as sdk from './index';
import PropTypes from 'prop-types';
import { _t } from './languageHandler';
@@ -24,21 +24,19 @@ import { _t } from './languageHandler';
* Wrap an asynchronous loader function with a react component which shows a
* spinner until the real component loads.
*/
-export default createReactClass({
- propTypes: {
+export default class AsyncWrapper extends React.Component {
+ static propTypes = {
/** A promise which resolves with the real component
*/
prom: PropTypes.object.isRequired,
- },
+ };
- getInitialState: function() {
- return {
- component: null,
- error: null,
- };
- },
+ state = {
+ component: null,
+ error: null,
+ };
- componentDidMount: function() {
+ componentDidMount() {
this._unmounted = false;
// XXX: temporary logging to try to diagnose
// https://github.com/vector-im/element-web/issues/3148
@@ -56,17 +54,17 @@ export default createReactClass({
console.warn('AsyncWrapper promise failed', e);
this.setState({error: e});
});
- },
+ }
- componentWillUnmount: function() {
+ componentWillUnmount() {
this._unmounted = true;
- },
+ }
- _onWrapperCancelClick: function() {
+ _onWrapperCancelClick = () => {
this.props.onFinished(false);
- },
+ };
- render: function() {
+ render() {
if (this.state.component) {
const Component = this.state.component;
return
{_t( - "Sorry, your browser is not able to run %(brand)s.", - { - brand, - }, - { - 'b': (sub) => {sub}, - }) - }
-- { _t( - "%(brand)s uses many advanced browser features, some of which are not available " + - "or experimental in your current browser.", - { brand }, - ) } -
-
- { _t(
- 'Please install
- { _t( - "With your current browser, the look and feel of the application may be " + - "completely incorrect, and some or all features may not function. " + - "If you want to try it anyway you can continue, but you are on your own in terms " + - "of any issues you may encounter!", - ) } -
- -{_t(
"Private rooms can be found and joined by invitation only. Public rooms can be " +
"found and joined by anyone in this community.",
@@ -239,9 +238,8 @@ export default createReactClass({
}
let title = this.state.isPublic ? _t('Create a public room') : _t('Create a private room');
- if (TagOrderStore.getSelectedPrototypeTag()) {
- const summary = GroupStore.getSummary(TagOrderStore.getSelectedPrototypeTag());
- const name = summary?.profile?.name || TagOrderStore.getSelectedPrototypeTag();
+ if (CommunityPrototypeStore.instance.getSelectedCommunityId()) {
+ const name = CommunityPrototypeStore.instance.getSelectedCommunityName();
title = _t("Create a room in %(communityName)s", {communityName: name});
}
return (
@@ -275,5 +273,5 @@ export default createReactClass({
onCancel={this.onCancel} />
);
- },
-});
+ }
+}
diff --git a/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx b/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx
new file mode 100644
index 0000000000..3071854b3e
--- /dev/null
+++ b/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx
@@ -0,0 +1,167 @@
+/*
+Copyright 2020 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.
+*/
+
+import React, { ChangeEvent } from 'react';
+import BaseDialog from "./BaseDialog";
+import { _t } from "../../../languageHandler";
+import { IDialogProps } from "./IDialogProps";
+import Field from "../elements/Field";
+import AccessibleButton from "../elements/AccessibleButton";
+import { MatrixClientPeg } from "../../../MatrixClientPeg";
+import { CommunityPrototypeStore } from "../../../stores/CommunityPrototypeStore";
+import FlairStore from "../../../stores/FlairStore";
+
+interface IProps extends IDialogProps {
+ communityId: string;
+}
+
+interface IState {
+ name: string;
+ error: string;
+ busy: boolean;
+ currentAvatarUrl: string;
+ avatarFile: File;
+ avatarPreview: string;
+}
+
+// XXX: This is a lot of duplication from the create dialog, just in a different shape
+export default class EditCommunityPrototypeDialog extends React.PureComponent {sectionSubname};
+ if (!this.state.avatarPreview) {
+ if (this.state.currentAvatarUrl) {
+ const url = MatrixClientPeg.get().mxcUrlToHttp(this.state.currentAvatarUrl);
+ preview =
;
+ } else {
+ preview =
+ }
+ }
+
+ return (
+
{sectionName}
+ {sectionSubname ?
{_t("Messages in this room are end-to-end encrypted.")}
-{_t("Your messages are secured and only you and the recipient have the unique keys to unlock them.")}
+{_t("Your messages are secured and only you and the recipient have " + + "the unique keys to unlock them.")}
{_t("Messages in this room are not end-to-end encrypted.")}
-{_t("In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.")}
+{_t("In encrypted rooms, your messages are secured and only you and the recipient have " + + "the unique keys to unlock them.")}
{_t("Compare unique emoji")}
- {_t("Compare a unique set of emoji if you don't have a camera on either device")} -{_t("Compare unique emoji")}
+ + {_t("Compare a unique set of emoji if you don't have a camera on either device")} + +{_t( "Your homeserver does not support cross-signing.", diff --git a/src/components/views/settings/E2eAdvancedPanel.js b/src/components/views/settings/E2eAdvancedPanel.js index 2ba6190a9b..0650630901 100644 --- a/src/components/views/settings/E2eAdvancedPanel.js +++ b/src/components/views/settings/E2eAdvancedPanel.js @@ -25,7 +25,7 @@ const SETTING_MANUALLY_VERIFY_ALL_SESSIONS = "e2ee.manuallyVerifyAllSessions"; const E2eAdvancedPanel = props => { const SettingsFlag = sdk.getComponent('views.elements.SettingsFlag'); return