From f420c8598516b4f939b7ab90f5fa263db2aaa94a Mon Sep 17 00:00:00 2001 From: Jaiwanth Date: Mon, 15 Feb 2021 19:13:09 +0530 Subject: [PATCH 01/35] Added invite option to room's context menu Signed-off-by: Jaiwanth --- res/css/views/rooms/_RoomTile.scss | 4 ++++ src/components/views/rooms/RoomTile.tsx | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/res/css/views/rooms/_RoomTile.scss b/res/css/views/rooms/_RoomTile.scss index 8eca3f1efa..377b207490 100644 --- a/res/css/views/rooms/_RoomTile.scss +++ b/res/css/views/rooms/_RoomTile.scss @@ -188,6 +188,10 @@ limitations under the License. .mx_RoomTile_iconSettings::before { mask-image: url('$(res)/img/element-icons/settings.svg'); } + + .mx_RoomTile_iconInvite::before { + mask-image: url('$(res)/img/element-icons/room/invite.svg'); + } .mx_RoomTile_iconSignOut::before { mask-image: url('$(res)/img/element-icons/leave.svg'); diff --git a/src/components/views/rooms/RoomTile.tsx b/src/components/views/rooms/RoomTile.tsx index 835447dc18..3a34a0daaa 100644 --- a/src/components/views/rooms/RoomTile.tsx +++ b/src/components/views/rooms/RoomTile.tsx @@ -331,6 +331,17 @@ export default class RoomTile extends React.PureComponent { this.setState({generalMenuPosition: null}); // hide the menu }; + private onInviteClick = (ev: ButtonEvent) => { + ev.preventDefault(); + ev.stopPropagation(); + + dis.dispatch({ + action: 'view_invite', + roomId: this.props.room.roomId, + }); + this.setState({generalMenuPosition: null}); // hide the menu + }; + private async saveNotifState(ev: ButtonEvent, newState: Volume) { ev.preventDefault(); ev.stopPropagation(); @@ -470,7 +481,11 @@ export default class RoomTile extends React.PureComponent { label={lowPriorityLabel} iconClassName="mx_RoomTile_iconArrowDown" /> - + Date: Mon, 15 Feb 2021 20:52:19 +0530 Subject: [PATCH 02/35] Check whether user has permission to invite Signed-off-by: Jaiwanth --- res/css/views/rooms/_RoomTile.scss | 2 +- src/components/views/rooms/RoomTile.tsx | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/res/css/views/rooms/_RoomTile.scss b/res/css/views/rooms/_RoomTile.scss index 377b207490..72d29dfd4c 100644 --- a/res/css/views/rooms/_RoomTile.scss +++ b/res/css/views/rooms/_RoomTile.scss @@ -188,7 +188,7 @@ limitations under the License. .mx_RoomTile_iconSettings::before { mask-image: url('$(res)/img/element-icons/settings.svg'); } - + .mx_RoomTile_iconInvite::before { mask-image: url('$(res)/img/element-icons/room/invite.svg'); } diff --git a/src/components/views/rooms/RoomTile.tsx b/src/components/views/rooms/RoomTile.tsx index 3a34a0daaa..f168235335 100644 --- a/src/components/views/rooms/RoomTile.tsx +++ b/src/components/views/rooms/RoomTile.tsx @@ -462,6 +462,16 @@ export default class RoomTile extends React.PureComponent { const isLowPriority = roomTags.includes(DefaultTagID.LowPriority); const lowPriorityLabel = _t("Low Priority"); + const inRoom = this.props.room && this.props.room.getMyMembership() === "join"; + const userId = MatrixClientPeg.get().getUserId(); + let canInvite = inRoom; + const powerLevels = this.props.room.currentState + .getStateEvents("m.room.power_levels", "") + ?.getContent(); + const me = this.props.room.getMember(userId); + if (powerLevels && me && powerLevels.invite > me.powerLevel) { + canInvite = false; + } contextMenu = { label={lowPriorityLabel} iconClassName="mx_RoomTile_iconArrowDown" /> - + {canInvite ? ( + + ) : null} Date: Tue, 16 Feb 2021 18:59:22 +0530 Subject: [PATCH 03/35] Update src/components/views/rooms/RoomTile.tsx --- src/components/views/rooms/RoomTile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomTile.tsx b/src/components/views/rooms/RoomTile.tsx index f168235335..3894f557fc 100644 --- a/src/components/views/rooms/RoomTile.tsx +++ b/src/components/views/rooms/RoomTile.tsx @@ -462,7 +462,7 @@ export default class RoomTile extends React.PureComponent { const isLowPriority = roomTags.includes(DefaultTagID.LowPriority); const lowPriorityLabel = _t("Low Priority"); - const inRoom = this.props.room && this.props.room.getMyMembership() === "join"; + const inRoom = this.props.room.getMyMembership() === "join"; const userId = MatrixClientPeg.get().getUserId(); let canInvite = inRoom; const powerLevels = this.props.room.currentState From 21b9ab9d8595ffbdb881e8c4e4ae33d9829d0dcb Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 16 Feb 2021 15:17:51 -0700 Subject: [PATCH 04/35] Add an optional config option to make the welcome page the login page This is commonly requested by deployments with custom setups or those using SSO. Instead of having them all ship the same welcome.html with redirect code in it, we can offer a built-in redirect. Note that this doesn't actually redirect and instead just replaces the view. This is to make the change less invasive as otherwise it involves changing the routing layers. --- src/components/structures/MatrixChat.tsx | 6 ++++-- src/utils/{pages.js => pages.ts} | 17 +++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) rename src/utils/{pages.js => pages.ts} (68%) diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 5045e44182..35e08e8d37 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -82,6 +82,7 @@ import {UIFeature} from "../../settings/UIFeature"; import { CommunityPrototypeStore } from "../../stores/CommunityPrototypeStore"; import DialPadModal from "../views/voip/DialPadModal"; import { showToast as showMobileGuideToast } from '../../toasts/MobileGuideToast'; +import { shouldUseLoginForWelcome } from "../../utils/pages"; /** constants for MatrixChat.state.view */ export enum Views { @@ -1988,7 +1989,7 @@ export default class MatrixChat extends React.PureComponent { ); } - } else if (this.state.view === Views.WELCOME) { + } else if (this.state.view === Views.WELCOME && !shouldUseLoginForWelcome(SdkConfig.get())) { const Welcome = sdk.getComponent('auth.Welcome'); view = ; } else if (this.state.view === Views.REGISTER && SettingsStore.getValue(UIFeature.Registration)) { @@ -2020,7 +2021,8 @@ export default class MatrixChat extends React.PureComponent { {...this.getServerProperties()} /> ); - } else if (this.state.view === Views.LOGIN) { + } else if (this.state.view === Views.LOGIN + || (this.state.view === Views.WELCOME && shouldUseLoginForWelcome(SdkConfig.get()))) { const showPasswordReset = SettingsStore.getValue(UIFeature.PasswordReset); const Login = sdk.getComponent('structures.auth.Login'); view = ( diff --git a/src/utils/pages.js b/src/utils/pages.ts similarity index 68% rename from src/utils/pages.js rename to src/utils/pages.ts index d63ca3f2c7..bae76be29d 100644 --- a/src/utils/pages.js +++ b/src/utils/pages.ts @@ -1,5 +1,5 @@ /* -Copyright 2019 New Vector Ltd +Copyright 2019, 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. @@ -14,12 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -export function getHomePageUrl(appConfig) { +import { ConfigOptions } from "../SdkConfig"; + +export function getHomePageUrl(appConfig: ConfigOptions): string | null { const pagesConfig = appConfig.embeddedPages; - let pageUrl = null; - if (pagesConfig) { - pageUrl = pagesConfig.homeUrl; - } + let pageUrl = pagesConfig?.homeUrl; + if (!pageUrl) { // This is a deprecated config option for the home page // (despite the name, given we also now have a welcome @@ -29,3 +29,8 @@ export function getHomePageUrl(appConfig) { return pageUrl; } + +export function shouldUseLoginForWelcome(appConfig: ConfigOptions): boolean { + const pagesConfig = appConfig.embeddedPages; + return pagesConfig?.loginForWelcome === true; +} From 6106e01ab496f16ac4c36911f67f8df817cf2025 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 8 Mar 2021 09:39:07 +0000 Subject: [PATCH 05/35] Collapse redactions into an event list summary --- src/components/structures/MessagePanel.js | 93 ++++++++++++++++++++++- src/i18n/strings/en_EN.json | 2 + 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 161227a139..28214aada9 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -1001,6 +1001,97 @@ class CreationGrouper { } } +class RedactionGrouper { + static canStartGroup = function(panel, ev) { + return panel._shouldShowEvent(ev) && ev.isRedacted(); + } + + constructor(panel, ev, prevEvent, lastShownEvent) { + this.panel = panel; + this.readMarker = panel._readMarkerForEvent( + ev.getId(), + ev === lastShownEvent, + ); + this.events = [ev]; + this.prevEvent = prevEvent; + this.lastShownEvent = lastShownEvent; + } + + shouldGroup(ev) { + if (this.panel._wantsDateSeparator(this.events[0], ev.getDate())) { + return false; + } + return ev.isRedacted(); + } + + add(ev) { + this.readMarker = this.readMarker || this.panel._readMarkerForEvent( + ev.getId(), + ev === this.lastShownEvent, + ); + this.events.push(ev); + } + + getTiles() { + if (!this.events || !this.events.length) return []; + + const DateSeparator = sdk.getComponent('messages.DateSeparator'); + const EventListSummary = sdk.getComponent('views.elements.EventListSummary'); + + const panel = this.panel; + const ret = []; + const lastShownEvent = this.lastShownEvent; + + if (panel._wantsDateSeparator(this.prevEvent, this.events[0].getDate())) { + const ts = this.events[0].getTs(); + ret.push( +
  • , + ); + } + + const key = "redactioneventlistsummary-" + ( + this.prevEvent ? this.events[0].getId() : "initial" + ); + + const senders = new Set(); + let eventTiles = this.events.map((e) => { + senders.add(e.sender); + // In order to prevent DateSeparators from appearing in the expanded form, + // render each member event as if the previous one was itself. + // This way, the timestamp of the previous event === the + // timestamp of the current event, and no DateSeparator is inserted. + return panel._getTilesForEvent(e, e, e === lastShownEvent); + }).reduce((a, b) => a.concat(b), []); + + if (eventTiles.length === 0) { + eventTiles = null; + } + + ret.push( + + { eventTiles } + , + ); + + if (this.readMarker) { + ret.push(this.readMarker); + } + + return ret; + } + + getNewPrevEvent() { + return this.events[0]; + } +} + // Wrap consecutive member events in a ListSummary, ignore if redacted class MemberGrouper { static canStartGroup = function(panel, ev) { @@ -1111,4 +1202,4 @@ class MemberGrouper { } // all the grouper classes that we use -const groupers = [CreationGrouper, MemberGrouper]; +const groupers = [CreationGrouper, MemberGrouper, RedactionGrouper]; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index daa38b9b3e..e78792ec51 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2541,6 +2541,8 @@ "Logout": "Logout", "%(creator)s created this DM.": "%(creator)s created this DM.", "%(creator)s created and configured the room.": "%(creator)s created and configured the room.", + "%(count)s messages deleted.|other": "%(count)s messages deleted.", + "%(count)s messages deleted.|one": "%(count)s message deleted.", "Your Communities": "Your Communities", "Did you know: you can use communities to filter your %(brand)s experience!": "Did you know: you can use communities to filter your %(brand)s experience!", "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.", From 02051a39ff126d8ea4f328ed705ec5d2fc573d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 12 Mar 2021 13:55:14 +0100 Subject: [PATCH 06/35] Hangup all calls on logout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/CallHandler.tsx | 5 +++++ src/components/structures/MatrixChat.tsx | 1 + 2 files changed, 6 insertions(+) diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index d2564e637b..ce779f12a5 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -788,6 +788,11 @@ export default class CallHandler { // don't remove the call yet: let the hangup event handler do it (otherwise it will throw // the hangup event away) break; + case 'hangup_all': + for (const call of this.calls.values()) { + call.hangup(CallErrorCode.UserHangup, false); + } + break; case 'answer': { if (!this.calls.has(payload.room_id)) { return; // no call to answer diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 0272633e8f..f0a3778a2b 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -582,6 +582,7 @@ export default class MatrixChat extends React.PureComponent { } break; case 'logout': + dis.dispatch({action: "hangup_all"}); Lifecycle.logout(); break; case 'require_registration': From 6210614ce7138f871818df4941cdd04d65e6cc1d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 12 Mar 2021 17:37:15 +0000 Subject: [PATCH 07/35] Rebuild space panel layout to resolve weirdness with selections and nesting --- res/css/structures/_SpacePanel.scss | 42 ++++++++--------------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/res/css/structures/_SpacePanel.scss b/res/css/structures/_SpacePanel.scss index 9937117086..4ced807f66 100644 --- a/res/css/structures/_SpacePanel.scss +++ b/res/css/structures/_SpacePanel.scss @@ -16,9 +16,8 @@ limitations under the License. $topLevelHeight: 32px; $nestedHeight: 24px; -$gutterSize: 17px; -$activeStripeSize: 4px; -$activeBorderTransparentGap: 2px; +$gutterSize: 16px; +$activeBorderTransparentGap: 1px; $activeBackgroundColor: $roomtile-selected-bg-color; $activeBorderColor: $secondary-fg-color; @@ -102,14 +101,11 @@ $activeBorderColor: $secondary-fg-color; &.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_narrow .mx_SpaceButton_selectionWrapper { + padding: $activeBorderTransparentGap; + border: 3px $activeBorderColor solid; } } @@ -117,6 +113,8 @@ $activeBorderColor: $secondary-fg-color; display: flex; flex: 1; align-items: center; + border-radius: 12px; + padding: 4px; } .mx_SpaceButton_name { @@ -133,8 +131,8 @@ $activeBorderColor: $secondary-fg-color; } .mx_SpaceButton_toggleCollapse { - width: calc($gutterSize - $activeStripeSize); - margin-left: 1px; + width: $gutterSize; + margin-right: -4px; height: 20px; mask-position: center; mask-size: 20px; @@ -172,11 +170,6 @@ $activeBorderColor: $secondary-fg-color; } } - .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 @@ -196,21 +189,8 @@ $activeBorderColor: $secondary-fg-color; } } - .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_BaseAvatar_image { + border-radius: 8px; } .mx_SpaceButton_menuButton { From c8d7b0e1b9baca45b0c1570370403b037b64d728 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 12 Mar 2021 14:56:47 -0700 Subject: [PATCH 08/35] Collapse copyright --- src/components/structures/MatrixChat.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 99397640ed..d3e0778e82 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -1,8 +1,5 @@ /* -Copyright 2015, 2016 OpenMarket Ltd -Copyright 2017 Vector Creations Ltd -Copyright 2017-2019 New Vector Ltd -Copyright 2019, 2020 The Matrix.org Foundation C.I.C. +Copyright 2015-2019-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. From 75cfd9a8f596af114f20011896d47a00a4c4082e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 12 Mar 2021 15:01:05 -0700 Subject: [PATCH 09/35] Redirect to login properly --- src/components/structures/MatrixChat.tsx | 31 +++++++++++++----------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index d3e0778e82..dab75be46e 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -604,12 +604,7 @@ export default class MatrixChat extends React.PureComponent { if (payload.screenAfterLogin) { this.screenAfterLogin = payload.screenAfterLogin; } - this.setStateForNewView({ - view: Views.LOGIN, - }); - this.notifyNewScreen('login'); - ThemeController.isLogin = true; - this.themeWatcher.recheck(); + this.viewLogin(); break; case 'start_password_recovery': this.setStateForNewView({ @@ -973,6 +968,9 @@ export default class MatrixChat extends React.PureComponent { } private viewWelcome() { + if (shouldUseLoginForWelcome(SdkConfig.get())) { + return this.viewLogin(); + } this.setStateForNewView({ view: Views.WELCOME, }); @@ -981,6 +979,16 @@ export default class MatrixChat extends React.PureComponent { this.themeWatcher.recheck(); } + private viewLogin(otherState?: any) { + this.setStateForNewView({ + view: Views.LOGIN, + ...otherState, + }); + this.notifyNewScreen('login'); + ThemeController.isLogin = true; + this.themeWatcher.recheck(); + } + private viewHome(justRegistered = false) { // The home page requires the "logged in" view, so we'll set that. this.setStateForNewView({ @@ -1296,17 +1304,13 @@ export default class MatrixChat extends React.PureComponent { * Called when the session is logged out */ private onLoggedOut() { - this.notifyNewScreen('login'); - this.setStateForNewView({ - view: Views.LOGIN, + this.viewLogin({ ready: false, collapseLhs: false, currentRoomId: null, }); this.subTitleStatus = ''; this.setPageSubtitle(); - ThemeController.isLogin = true; - this.themeWatcher.recheck(); } /** @@ -2011,7 +2015,7 @@ export default class MatrixChat extends React.PureComponent { ); } - } else if (this.state.view === Views.WELCOME && !shouldUseLoginForWelcome(SdkConfig.get())) { + } else if (this.state.view === Views.WELCOME) { const Welcome = sdk.getComponent('auth.Welcome'); view = ; } else if (this.state.view === Views.REGISTER && SettingsStore.getValue(UIFeature.Registration)) { @@ -2043,8 +2047,7 @@ export default class MatrixChat extends React.PureComponent { {...this.getServerProperties()} /> ); - } else if (this.state.view === Views.LOGIN - || (this.state.view === Views.WELCOME && shouldUseLoginForWelcome(SdkConfig.get()))) { + } else if (this.state.view === Views.LOGIN) { const showPasswordReset = SettingsStore.getValue(UIFeature.PasswordReset); const Login = sdk.getComponent('structures.auth.Login'); view = ( From 9b6d9b3bf1a81926658dd8a6c59c385c85575c66 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 12 Mar 2021 15:02:39 -0700 Subject: [PATCH 10/35] years are difficult --- src/components/structures/MatrixChat.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index dab75be46e..c5620c7ba2 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -1,5 +1,5 @@ /* -Copyright 2015-2019-2021 The Matrix.org Foundation C.I.C. +Copyright 2015-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. From 4811154f25db75bbba8ee3dfd0ba09256a81c496 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 12 Mar 2021 15:24:16 -0700 Subject: [PATCH 11/35] Remove now-unused assets and CSS from CompleteSecurity step --- .../structures/auth/_CompleteSecurity.scss | 44 ------------------- res/img/feather-customised/monitor.svg | 5 --- res/img/feather-customised/smartphone.svg | 4 -- 3 files changed, 53 deletions(-) delete mode 100644 res/img/feather-customised/monitor.svg delete mode 100644 res/img/feather-customised/smartphone.svg diff --git a/res/css/structures/auth/_CompleteSecurity.scss b/res/css/structures/auth/_CompleteSecurity.scss index f742be70e4..80e7aaada0 100644 --- a/res/css/structures/auth/_CompleteSecurity.scss +++ b/res/css/structures/auth/_CompleteSecurity.scss @@ -26,50 +26,6 @@ limitations under the License. position: relative; } -.mx_CompleteSecurity_clients { - width: max-content; - margin: 36px auto 0; - - .mx_CompleteSecurity_clients_desktop, .mx_CompleteSecurity_clients_mobile { - position: relative; - width: 160px; - text-align: center; - padding-top: 64px; - display: inline-block; - - &::before { - content: ''; - position: absolute; - height: 48px; - width: 48px; - left: 56px; - top: 0; - background-color: $muted-fg-color; - mask-repeat: no-repeat; - mask-size: contain; - } - } - - .mx_CompleteSecurity_clients_desktop { - margin-right: 56px; - } - - .mx_CompleteSecurity_clients_desktop::before { - mask-image: url('$(res)/img/feather-customised/monitor.svg'); - } - - .mx_CompleteSecurity_clients_mobile::before { - mask-image: url('$(res)/img/feather-customised/smartphone.svg'); - } - - p { - margin-top: 16px; - font-size: $font-12px; - color: $muted-fg-color; - text-align: center; - } -} - .mx_CompleteSecurity_heroIcon { width: 128px; height: 128px; diff --git a/res/img/feather-customised/monitor.svg b/res/img/feather-customised/monitor.svg deleted file mode 100644 index 231811d5a6..0000000000 --- a/res/img/feather-customised/monitor.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/res/img/feather-customised/smartphone.svg b/res/img/feather-customised/smartphone.svg deleted file mode 100644 index fde78c82e2..0000000000 --- a/res/img/feather-customised/smartphone.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - From f9eace1729bbe52d65378c8d66d02820d59d357a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 15 Mar 2021 11:59:46 +0000 Subject: [PATCH 12/35] Rebuild alignment of the menu buttons and notification badges --- res/css/structures/_SpacePanel.scss | 63 +++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/res/css/structures/_SpacePanel.scss b/res/css/structures/_SpacePanel.scss index 4ced807f66..f489d7b8b5 100644 --- a/res/css/structures/_SpacePanel.scss +++ b/res/css/structures/_SpacePanel.scss @@ -62,21 +62,26 @@ $activeBorderColor: $secondary-fg-color; } .mx_AutoHideScrollbar { - padding: 16px 12px 16px 0; + padding: 16px 0; } .mx_SpaceButton_toggleCollapse { cursor: pointer; } - .mx_SpaceItem.collapsed { - .mx_SpaceButton { - .mx_NotificationBadge { - right: -4px; - top: -4px; - } - } + .mx_SpaceTreeLevel { + display: flex; + flex-direction: column; + max-width: 250px; + flex-grow: 1; + } + .mx_SpaceItem { + display: inline-flex; + flex-flow: wrap; + } + + .mx_SpaceItem.collapsed { & > .mx_SpaceButton > .mx_SpaceButton_toggleCollapse { transform: rotate(-90deg); } @@ -88,15 +93,16 @@ $activeBorderColor: $secondary-fg-color; .mx_SpaceItem:not(.hasSubSpaces) > .mx_SpaceButton { margin-left: $gutterSize; + min-width: 40px; } .mx_SpaceButton { border-radius: 8px; - position: relative; margin-bottom: 2px; display: flex; align-items: center; - padding: 4px; + padding: 4px 4px 4px 0; + width: 100%; &.mx_SpaceButton_active { &:not(.mx_SpaceButton_narrow) .mx_SpaceButton_selectionWrapper { @@ -110,6 +116,7 @@ $activeBorderColor: $secondary-fg-color; } .mx_SpaceButton_selectionWrapper { + position: relative; display: flex; flex: 1; align-items: center; @@ -117,12 +124,23 @@ $activeBorderColor: $secondary-fg-color; padding: 4px; } + &:not(.mx_SpaceButton_narrow) { + .mx_SpaceButton_selectionWrapper { + width: 100%; + padding-right: 16px; + overflow: hidden; + } + } + + &.mx_SpaceButton_narrow { + margin-right: 10px; + } + .mx_SpaceButton_name { flex: 1; margin-left: 8px; white-space: nowrap; display: block; - max-width: 150px; text-overflow: ellipsis; overflow: hidden; padding-right: 8px; @@ -199,8 +217,9 @@ $activeBorderColor: $secondary-fg-color; height: 20px; margin-top: auto; margin-bottom: auto; - position: relative; display: none; + position: absolute; + right: 4px; &::before { top: 2px; @@ -219,9 +238,8 @@ $activeBorderColor: $secondary-fg-color; } .mx_SpacePanel_badgeContainer { + position: absolute; 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; @@ -241,14 +259,25 @@ $activeBorderColor: $secondary-fg-color; &.collapsed { .mx_SpaceButton { .mx_SpacePanel_badgeContainer { - position: absolute; - right: 0px; - top: 2px; + right: -3px; + top: -3px; + } + + &.mx_SpaceButton_active .mx_SpacePanel_badgeContainer { + // when we draw the selection border we move the relative bounds of our parent + // so update our position within the bounds of the parent to maintain position overall + right: -6px; + top: -6px; } } } &:not(.collapsed) { + .mx_SpacePanel_badgeContainer { + position: absolute; + right: 4px; + } + .mx_SpaceButton:hover, .mx_SpaceButton:focus-within, .mx_SpaceButton_hasMenuOpen { From 272f06d57a84c714f92ad6570a6f8d506aeccec9 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 15 Mar 2021 12:16:48 +0000 Subject: [PATCH 13/35] Fix Space Panel exploding with cyclic hierarchies --- .../views/spaces/SpaceTreeLevel.tsx | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/components/views/spaces/SpaceTreeLevel.tsx b/src/components/views/spaces/SpaceTreeLevel.tsx index 04d6c02208..83bc2296e7 100644 --- a/src/components/views/spaces/SpaceTreeLevel.tsx +++ b/src/components/views/spaces/SpaceTreeLevel.tsx @@ -51,6 +51,7 @@ interface IItemProps { isNested?: boolean; isPanelCollapsed?: boolean; onExpand?: Function; + parents?: Set; } interface IItemState { @@ -299,7 +300,8 @@ export class SpaceItem extends React.PureComponent { const isNarrow = this.props.isPanelCollapsed; const collapsed = this.state.collapsed || forceCollapsed; - const childSpaces = SpaceStore.instance.getChildSpaces(space.roomId); + const childSpaces = SpaceStore.instance.getChildSpaces(space.roomId) + .filter(s => !this.props.parents?.has(s.roomId)); const isActive = activeSpaces.includes(space); const itemClasses = classNames({ "mx_SpaceItem": true, @@ -312,11 +314,17 @@ export class SpaceItem extends React.PureComponent { mx_SpaceButton_narrow: isNarrow, }); const notificationState = SpaceStore.instance.getNotificationState(space.roomId); - const childItems = childSpaces && !collapsed ? : null; + + let childItems; + if (childSpaces && !collapsed) { + childItems = ; + } + let notifBadge; if (notificationState) { notifBadge =
    @@ -383,12 +391,14 @@ interface ITreeLevelProps { spaces: Room[]; activeSpaces: Room[]; isNested?: boolean; + parents: Set; } const SpaceTreeLevel: React.FC = ({ spaces, activeSpaces, isNested, + parents, }) => { return
      {spaces.map(s => { @@ -397,6 +407,7 @@ const SpaceTreeLevel: React.FC = ({ activeSpaces={activeSpaces} space={s} isNested={isNested} + parents={parents} />); })}
    ; From 62983ca48efd4ec4087a5d29cce3b11acce6d34a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 15 Mar 2021 12:57:35 +0000 Subject: [PATCH 14/35] Fix space panel alignments when no scrollbar is present --- res/css/structures/_SpacePanel.scss | 5 +---- res/css/structures/_SpaceRoomDirectory.scss | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/res/css/structures/_SpacePanel.scss b/res/css/structures/_SpacePanel.scss index f489d7b8b5..afcf48ec4d 100644 --- a/res/css/structures/_SpacePanel.scss +++ b/res/css/structures/_SpacePanel.scss @@ -35,6 +35,7 @@ $activeBorderColor: $secondary-fg-color; .mx_SpacePanel_spaceTreeWrapper { flex: 1; + overflow-y: scroll; } .mx_SpacePanel_toggleCollapse { @@ -132,10 +133,6 @@ $activeBorderColor: $secondary-fg-color; } } - &.mx_SpaceButton_narrow { - margin-right: 10px; - } - .mx_SpaceButton_name { flex: 1; margin-left: 8px; diff --git a/res/css/structures/_SpaceRoomDirectory.scss b/res/css/structures/_SpaceRoomDirectory.scss index c96398594f..b14e92a1af 100644 --- a/res/css/structures/_SpaceRoomDirectory.scss +++ b/res/css/structures/_SpaceRoomDirectory.scss @@ -132,6 +132,7 @@ limitations under the License. height: min-content; margin-left: auto; margin-right: 16px; + display: inline-flex; } } From f575625c7a5a5ec8984ae40aa5a97b3436249260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Mon, 15 Mar 2021 23:13:16 +0100 Subject: [PATCH 15/35] fix: make room directory correct when using a homeserver with explicit port Server names are allowed to contain ':' to specify a port, see https://matrix.org/docs/spec/appendices#server-name User ids on the other hand are not allowed to contain ':', even historical user ids, see https://matrix.org/docs/spec/appendices#historical-user-ids Therefore we can use change the regex to make sure the localpart is not allowed to contain ':'. --- src/MatrixClientPeg.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index 98ca446532..de1d573d40 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -261,7 +261,7 @@ class _MatrixClientPeg implements IMatrixClientPeg { } public getHomeserverName(): string { - const matches = /^@.+:(.+)$/.exec(this.matrixClient.credentials.userId); + const matches = /^@[^:]+:(.+)$/.exec(this.matrixClient.credentials.userId); if (matches === null || matches.length < 1) { throw new Error("Failed to derive homeserver name from user ID!"); } From baaceccfdaeae98bd08cf477356aea6ceed0b12e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 16 Mar 2021 10:53:27 +0000 Subject: [PATCH 16/35] Rearrange dom hierarchy to put space panel at same level as LeftPanel so they don't steal horizontal space from each other --- res/css/structures/_LeftPanel.scss | 2 +- res/css/structures/_MatrixChat.scss | 2 +- src/components/structures/LeftPanel.tsx | 7 +------ src/components/structures/LoggedInView.tsx | 23 +++++++--------------- 4 files changed, 10 insertions(+), 24 deletions(-) diff --git a/res/css/structures/_LeftPanel.scss b/res/css/structures/_LeftPanel.scss index f1f27014ee..c4bbdefb44 100644 --- a/res/css/structures/_LeftPanel.scss +++ b/res/css/structures/_LeftPanel.scss @@ -19,7 +19,7 @@ $roomListCollapsedWidth: 68px; .mx_LeftPanel { background-color: $roomlist-bg-color; - min-width: 260px; + min-width: 200px; max-width: 50%; // Create a row-based flexbox for the GroupFilterPanel and the room list diff --git a/res/css/structures/_MatrixChat.scss b/res/css/structures/_MatrixChat.scss index 812a7f8472..a220c5d505 100644 --- a/res/css/structures/_MatrixChat.scss +++ b/res/css/structures/_MatrixChat.scss @@ -66,7 +66,7 @@ limitations under the License. } /* not the left panel, and not the resize handle, so the roomview/groupview/... */ -.mx_MatrixChat > :not(.mx_LeftPanel):not(.mx_ResizeHandle) { +.mx_MatrixChat > :not(.mx_LeftPanel):not(.mx_SpacePanel):not(.mx_ResizeHandle) { background-color: $primary-bg-color; flex: 1 1 0; diff --git a/src/components/structures/LeftPanel.tsx b/src/components/structures/LeftPanel.tsx index 82dd9443cc..077dbbb29c 100644 --- a/src/components/structures/LeftPanel.tsx +++ b/src/components/structures/LeftPanel.tsx @@ -39,7 +39,6 @@ import { OwnProfileStore } from "../../stores/OwnProfileStore"; import { MatrixClientPeg } from "../../MatrixClientPeg"; import RoomListNumResults from "../views/rooms/RoomListNumResults"; import LeftPanelWidget from "./LeftPanelWidget"; -import SpacePanel from "../views/spaces/SpacePanel"; interface IProps { isMinimized: boolean; @@ -390,11 +389,7 @@ export default class LeftPanel extends React.Component { public render(): React.ReactNode { 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) { + if (this.state.showGroupFilterPanel) { leftLeftPanel = (
    diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 3e6d56fd54..b7212ddb25 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -56,6 +56,7 @@ import Modal from "../../Modal"; import { ICollapseConfig } from "../../resizer/distributors/collapse"; import HostSignupContainer from '../views/host_signup/HostSignupContainer'; import { IOpts } from "../../createRoom"; +import SpacePanel from "../views/spaces/SpacePanel"; // We need to fetch each pinned message individually (if we don't already have it) // so each pinned message may trigger a request. Limit the number per room for sanity. @@ -227,14 +228,7 @@ class LoggedInView extends React.Component { let size; let collapsed; const collapseConfig: ICollapseConfig = { - // TODO: the space panel currently does not have a fixed width, - // just the headers at each level have a max-width of 150px - // Taking 222px for the space panel for now, - // so this will look slightly off for now, - // depending on the depth of your space tree. - // To fix this, we'll need to turn toggleSize - // into a callback so it can be measured when starting the resize operation - toggleSize: 222 + 68, + toggleSize: 200, onCollapsed: (_collapsed) => { collapsed = _collapsed; if (_collapsed) { @@ -668,13 +662,6 @@ class LoggedInView extends React.Component { bodyClasses += ' mx_MatrixChat_useCompactLayout'; } - const leftPanel = ( - - ); - return (
    {
    - { leftPanel } + { SettingsStore.getValue("feature_spaces") ? : null } + { pageElement }
    From 11cd791c7606ecafa2af93826d69b36cc48c1d27 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 16 Mar 2021 11:11:44 +0000 Subject: [PATCH 17/35] Tweak left panel min widths for better flexibility --- res/css/structures/_LeftPanel.scss | 3 ++- src/components/structures/LoggedInView.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/res/css/structures/_LeftPanel.scss b/res/css/structures/_LeftPanel.scss index c4bbdefb44..10357117da 100644 --- a/res/css/structures/_LeftPanel.scss +++ b/res/css/structures/_LeftPanel.scss @@ -19,7 +19,8 @@ $roomListCollapsedWidth: 68px; .mx_LeftPanel { background-color: $roomlist-bg-color; - min-width: 200px; + // TODO decrease this once Spaces launches as it'll no longer need to include the 56px Community Panel + min-width: 206px; max-width: 50%; // Create a row-based flexbox for the GroupFilterPanel and the room list diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index b7212ddb25..3c7e79b89d 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -228,7 +228,8 @@ class LoggedInView extends React.Component { let size; let collapsed; const collapseConfig: ICollapseConfig = { - toggleSize: 200, + // TODO decrease this once Spaces launches as it'll no longer need to include the 56px Community Panel + toggleSize: 206 - 50, onCollapsed: (_collapsed) => { collapsed = _collapsed; if (_collapsed) { From 67e2ae99880aa2d45b6bcf8f1fb8d2b202153f7a Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 Mar 2021 15:42:03 +0000 Subject: [PATCH 18/35] Make some dispatches async It looks like these dispatches were being dispatched while already dispatching, causing soft crashes (although I can't see where the first dispatch was from). Either way, seems like these didn't need to be sync. --- src/components/structures/LoggedInView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 15e90a383a..936eb819ba 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -240,10 +240,10 @@ class LoggedInView extends React.Component { onCollapsed: (_collapsed) => { collapsed = _collapsed; if (_collapsed) { - dis.dispatch({action: "hide_left_panel"}, true); + dis.dispatch({action: "hide_left_panel"}); window.localStorage.setItem("mx_lhs_size", '0'); } else { - dis.dispatch({action: "show_left_panel"}, true); + dis.dispatch({action: "show_left_panel"}); } }, onResized: (_size) => { From 5ce3a05867e839eb41f66773899c176c3cbd80dc Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 16 Mar 2021 16:34:28 +0000 Subject: [PATCH 19/35] Update _SpacePanel.scss --- res/css/structures/_SpacePanel.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/res/css/structures/_SpacePanel.scss b/res/css/structures/_SpacePanel.scss index afcf48ec4d..d3e7d7efee 100644 --- a/res/css/structures/_SpacePanel.scss +++ b/res/css/structures/_SpacePanel.scss @@ -147,6 +147,8 @@ $activeBorderColor: $secondary-fg-color; .mx_SpaceButton_toggleCollapse { width: $gutterSize; + // negative margin to place it correctly even with the complex + // 4px selection border each space button has when active margin-right: -4px; height: 20px; mask-position: center; From 451a3aaa3f6ccd7679c3bee5a57f2c6c0fb4fc62 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 16 Mar 2021 13:50:43 -0600 Subject: [PATCH 20/35] Work around more cases where a rageshake server might not be present We already do this for a number of other places (slash commands, help section of settings, etc) - these places appear to have been missed, though. --- .../views/dialogs/FeedbackDialog.js | 23 ++++++---- .../views/dialogs/RoomUpgradeWarningDialog.js | 42 ++++++++++++------- src/i18n/strings/en_EN.json | 5 ++- 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/components/views/dialogs/FeedbackDialog.js b/src/components/views/dialogs/FeedbackDialog.js index cbe26af6cc..d80a935573 100644 --- a/src/components/views/dialogs/FeedbackDialog.js +++ b/src/components/views/dialogs/FeedbackDialog.js @@ -100,6 +100,20 @@ export default (props) => { ); } + let bugReports = null; + if (SdkConfig.get().bug_report_endpoint_url) { + bugReports = ( +

    { + _t("PRO TIP: If you start a bug, please submit debug logs " + + "to help us track down the problem.", {}, { + debugLogsLink: sub => ( + {sub} + ), + }) + }

    + ); + } + return ( { }, }) }

    -

    { - _t("PRO TIP: If you start a bug, please submit debug logs " + - "to help us track down the problem.", {}, { - debugLogsLink: sub => ( - {sub} - ), - }) - }

    + {bugReports}
    { countlyFeedbackSection } } diff --git a/src/components/views/dialogs/RoomUpgradeWarningDialog.js b/src/components/views/dialogs/RoomUpgradeWarningDialog.js index 452ac56dff..c6ef2c6ae2 100644 --- a/src/components/views/dialogs/RoomUpgradeWarningDialog.js +++ b/src/components/views/dialogs/RoomUpgradeWarningDialog.js @@ -82,6 +82,33 @@ export default class RoomUpgradeWarningDialog extends React.Component { const title = this.state.isPrivate ? _t("Upgrade private room") : _t("Upgrade public room"); + let bugReports = ( +

    + {_t( + "This usually only affects how the room is processed on the server. If you're " + + "having problems with your %(brand)s, please report a bug.", {brand}, + )} +

    + ); + if (SdkConfig.get().bug_report_endpoint_url) { + bugReports = ( +

    + {_t( + "This usually only affects how the room is processed on the server. If you're " + + "having problems with your %(brand)s, please report a bug.", + { + brand, + }, + { + "a": (sub) => { + return {sub}; + }, + }, + )} +

    + ); + } + return ( -

    - {_t( - "This usually only affects how the room is processed on the server. If you're " + - "having problems with your %(brand)s, please report a bug.", - { - brand, - }, - { - "a": (sub) => { - return {sub}; - }, - }, - )} -

    + {bugReports}

    {_t( "You'll upgrade this room from to .", diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 63449eb99f..07d292a0e7 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2150,10 +2150,10 @@ "Add comment": "Add comment", "Comment": "Comment", "There are two ways you can provide feedback and help us improve %(brand)s.": "There are two ways you can provide feedback and help us improve %(brand)s.", + "PRO TIP: If you start a bug, please submit debug logs to help us track down the problem.": "PRO TIP: If you start a bug, please submit debug logs to help us track down the problem.", "Feedback": "Feedback", "Report a bug": "Report a bug", "Please view existing bugs on Github first. No match? Start a new one.": "Please view existing bugs on Github first. No match? Start a new one.", - "PRO TIP: If you start a bug, please submit debug logs to help us track down the problem.": "PRO TIP: If you start a bug, please submit debug logs to help us track down the problem.", "Send feedback": "Send feedback", "Confirm abort of host creation": "Confirm abort of host creation", "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Are you sure you wish to abort creation of the host? The process cannot be continued.", @@ -2269,8 +2269,9 @@ "Automatically invite users": "Automatically invite users", "Upgrade private room": "Upgrade private room", "Upgrade public room": "Upgrade public room", - "Upgrading a room is an advanced action and is usually recommended when a room is unstable due to bugs, missing features or security vulnerabilities.": "Upgrading a room is an advanced action and is usually recommended when a room is unstable due to bugs, missing features or security vulnerabilities.", + "This usually only affects how the room is processed on the server. If you're having problems with your %(brand)s, please report a bug.": "This usually only affects how the room is processed on the server. If you're having problems with your %(brand)s, please report a bug.", "This usually only affects how the room is processed on the server. If you're having problems with your %(brand)s, please report a bug.": "This usually only affects how the room is processed on the server. If you're having problems with your %(brand)s, please report a bug.", + "Upgrading a room is an advanced action and is usually recommended when a room is unstable due to bugs, missing features or security vulnerabilities.": "Upgrading a room is an advanced action and is usually recommended when a room is unstable due to bugs, missing features or security vulnerabilities.", "You'll upgrade this room from to .": "You'll upgrade this room from to .", "Resend": "Resend", "You're all caught up.": "You're all caught up.", From c285b79a8dedc3a64a428d15cd4a4b8d50b59c97 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 16 Mar 2021 14:19:49 -0600 Subject: [PATCH 21/35] Add possibility to delay rageshake persistence in app startup Even if the app takes a moment to set up persistence, this will still capture any logs before persistence happened. --- src/rageshake/rageshake.js | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/rageshake/rageshake.js b/src/rageshake/rageshake.js index 8eb77bb3ae..b886f369df 100644 --- a/src/rageshake/rageshake.js +++ b/src/rageshake/rageshake.js @@ -434,15 +434,37 @@ function selectQuery(store, keyRange, resultMapper) { /** * Configure rage shaking support for sending bug reports. * Modifies globals. + * @param {boolean} setUpPersistence When true (default), the persistence will + * be set up immediately for the logs. * @return {Promise} Resolves when set up. */ -export function init() { +export function init(setUpPersistence = true) { if (global.mx_rage_initPromise) { return global.mx_rage_initPromise; } global.mx_rage_logger = new ConsoleLogger(); global.mx_rage_logger.monkeyPatch(window.console); + if (setUpPersistence) { + return tryInitStorage(); + } + + global.mx_rage_initPromise = Promise.resolve(); + return global.mx_rage_initPromise; +} + +/** + * Try to start up the rageshake storage for logs. If not possible (client unsupported) + * then this no-ops. + * @return {Promise} Resolves when complete. + */ +export function tryInitStorage() { + if (global.mx_rage_initStoragePromise) { + return global.mx_rage_initStoragePromise; + } + + console.log("Configuring rageshake persistence..."); + // just *accessing* indexedDB throws an exception in firefox with // indexeddb disabled. let indexedDB; @@ -452,11 +474,11 @@ export function init() { if (indexedDB) { global.mx_rage_store = new IndexedDBLogStore(indexedDB, global.mx_rage_logger); - global.mx_rage_initPromise = global.mx_rage_store.connect(); - return global.mx_rage_initPromise; + global.mx_rage_initStoragePromise = global.mx_rage_store.connect(); + return global.mx_rage_initStoragePromise; } - global.mx_rage_initPromise = Promise.resolve(); - return global.mx_rage_initPromise; + global.mx_rage_initStoragePromise = Promise.resolve(); + return global.mx_rage_initStoragePromise; } export function flush() { From f6a87386bc2f0b15892920dd19d85820b9eeb647 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 Mar 2021 19:09:43 +0000 Subject: [PATCH 22/35] Fix username showing instead of display name in Jitsi widgets If you opened element and entered a jitsi conference straight away in the room you landed in, your jitsi display name would be your matrix username rather than your display name. This was because OwnProfileStore was still busy fetching your profile from the server while the room, and therefore jitsi widget, was rendered. Blocking these widgets loading on this profile fetch completing isn't really an option, so store the profile data in localstorage and seed OwnProfileStore with the values from there. Bonus: the name in the top left will now be your display name as soon as the app is loaded, rather than being your username for the first several seconds after you load the app. Fixes https://github.com/vector-im/element-web/issues/16577 --- src/stores/OwnProfileStore.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/stores/OwnProfileStore.ts b/src/stores/OwnProfileStore.ts index 8983380fec..15884b8ad6 100644 --- a/src/stores/OwnProfileStore.ts +++ b/src/stores/OwnProfileStore.ts @@ -28,13 +28,22 @@ interface IState { avatarUrl?: string; } +const KEY_DISPLAY_NAME = "mx_profile_displayname"; +const KEY_AVATAR_URL = "mx_profile_avatar_url"; + export class OwnProfileStore extends AsyncStoreWithClient { private static internalInstance = new OwnProfileStore(); private monitoredUser: User; private constructor() { - super(defaultDispatcher, {}); + // seed from localstorage because otherwise we won't get these values until a whole network + // round-trip after the client is ready, and we often load widgets in that time, and we'd + // and up passing them an incorrect display name + super(defaultDispatcher, { + displayName: window.localStorage.getItem(KEY_DISPLAY_NAME), + avatarUrl: window.localStorage.getItem(KEY_AVATAR_URL), + }); } public static get instance(): OwnProfileStore { @@ -73,7 +82,11 @@ export class OwnProfileStore extends AsyncStoreWithClient { public getHttpAvatarUrl(size = 0): string { if (!this.avatarMxc) return null; const adjustedSize = size > 1 ? size : undefined; // don't let negatives or zero through - return this.matrixClient.mxcUrlToHttp(this.avatarMxc, adjustedSize, adjustedSize); + + // XXX: We use MatrixClientPeg here rather than this.matrixClient because otherwise we'll + // race because our data stores aren't set up consistently enough that this will all be + // initialised with a store before these getter methods are called. + return MatrixClientPeg.get().mxcUrlToHttp(this.avatarMxc, adjustedSize, adjustedSize); } protected async onNotReady() { @@ -110,6 +123,8 @@ export class OwnProfileStore extends AsyncStoreWithClient { // We specifically do not use the User object we stored for profile info as it // could easily be wrong (such as per-room instead of global profile). const profileInfo = await this.matrixClient.getProfileInfo(this.matrixClient.getUserId()); + if (profileInfo.displayname) window.localStorage.setItem(KEY_DISPLAY_NAME, profileInfo.displayname); + if (profileInfo.avatar_url) window.localStorage.setItem(KEY_AVATAR_URL, profileInfo.avatar_url); await this.updateState({displayName: profileInfo.displayname, avatarUrl: profileInfo.avatar_url}); }; From 2b608aa919eaa82827a4372ffa1e9dbf6a609f45 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 Mar 2021 19:18:32 +0000 Subject: [PATCH 23/35] Remove blank line --- src/stores/OwnProfileStore.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stores/OwnProfileStore.ts b/src/stores/OwnProfileStore.ts index 6927ecc153..398532a5c8 100644 --- a/src/stores/OwnProfileStore.ts +++ b/src/stores/OwnProfileStore.ts @@ -82,7 +82,6 @@ export class OwnProfileStore extends AsyncStoreWithClient { */ public getHttpAvatarUrl(size = 0): string { if (!this.avatarMxc) return null; - const media = mediaFromMxc(this.avatarMxc); if (!size || size <= 0) { return media.srcHttp; From 84b6027d41e055e342653fab3e5198b37e96396e Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 18 Mar 2021 16:41:22 +0000 Subject: [PATCH 24/35] Log error when failing to list usermedia devices So we can debug why this might be failing --- src/components/views/settings/tabs/user/VoiceUserSettingsTab.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.js b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.js index bc6fe796b8..d8adab55f6 100644 --- a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.js @@ -84,6 +84,7 @@ export default class VoiceUserSettingsTab extends React.Component { } } if (error) { + console.log("Failed to list userMedia devices", error); const brand = SdkConfig.get().brand; const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); Modal.createTrackedDialog('No media permissions', '', ErrorDialog, { From a4a3b4da78d6562e8d1f11e91fe58c8b6d58945c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 18 Mar 2021 18:01:50 +0100 Subject: [PATCH 25/35] jumpToLiveTimeline() on scroll_to_bottom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/structures/TimelinePanel.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index f32b8ed0a9..84193eae4c 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -463,6 +463,9 @@ class TimelinePanel extends React.Component { } }); } + if (payload.action === "scroll_to_bottom") { + this.jumpToLiveTimeline(); + } }; onRoomTimeline = (ev, room, toStartOfTimeline, removed, data) => { From 7ac8fdea6448bd5e1a386fec2ae2fb412b69d689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 18 Mar 2021 18:02:33 +0100 Subject: [PATCH 26/35] Don't call scrollToBottom() on scroll_to_bottom() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/structures/MessagePanel.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 439bdbcef5..f4334ffe87 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -23,7 +23,6 @@ import classNames from 'classnames'; import shouldHideEvent from '../../shouldHideEvent'; import {wantsDateSeparator} from '../../DateUtils'; import * as sdk from '../../index'; -import dis from "../../dispatcher/dispatcher"; import {MatrixClientPeg} from '../../MatrixClientPeg'; import SettingsStore from '../../settings/SettingsStore'; @@ -210,13 +209,11 @@ export default class MessagePanel extends React.Component { componentDidMount() { this._isMounted = true; - this.dispatcherRef = dis.register(this.onAction); } componentWillUnmount() { this._isMounted = false; SettingsStore.unwatchSetting(this._showTypingNotificationsWatcherRef); - dis.unregister(this.dispatcherRef); } componentDidUpdate(prevProps, prevState) { @@ -229,14 +226,6 @@ export default class MessagePanel extends React.Component { } } - onAction = (payload) => { - switch (payload.action) { - case "scroll_to_bottom": - this.scrollToBottom(); - break; - } - } - onShowTypingNotificationsChange = () => { this.setState({ showTypingNotifications: SettingsStore.getValue("showTypingNotifications"), From 720ac9d837332dc4ba6db9371b39c013d774d0ef Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 18 Mar 2021 14:45:14 -0600 Subject: [PATCH 27/35] Replace type declaration in Registration.tsx --- src/components/structures/auth/Registration.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/auth/Registration.tsx b/src/components/structures/auth/Registration.tsx index 32bdddb82a..9d004de2ec 100644 --- a/src/components/structures/auth/Registration.tsx +++ b/src/components/structures/auth/Registration.tsx @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import Matrix from 'matrix-js-sdk'; +import {createClient} from 'matrix-js-sdk/src/matrix'; import React, {ReactNode} from 'react'; import {MatrixClient} from "matrix-js-sdk/src/client"; @@ -181,7 +181,7 @@ export default class Registration extends React.Component { } const {hsUrl, isUrl} = serverConfig; - const cli = Matrix.createClient({ + const cli = createClient({ baseUrl: hsUrl, idBaseUrl: isUrl, }); From 1d9d0cd7be99f49da2b8a46f11d3777aca223fff Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 18 Mar 2021 20:50:34 -0600 Subject: [PATCH 28/35] Convert a bunch more js-sdk imports to absolute paths Turns out a lot of the typescript warnings about improper warnings were correct. TypeScript appears to be pulling in two copies of the js-sdk when we do this, which can lead to type conflicts (or worse: the wrong code entirely). We fix this at the webpack level by explicitly importing from `src`, but some alternative build structures have broken tests because of this - jest ends up pulling in the "wrong" js-sdk, breaking things. --- src/CallMediaHandler.js | 14 +++++++------- src/IdentityAuthClient.js | 3 ++- src/Lifecycle.ts | 7 +++---- src/Login.ts | 6 +++--- src/PasswordReset.js | 4 ++-- src/Resend.js | 2 +- src/ScalarAuthClient.js | 4 ++-- src/ScalarMessaging.js | 2 +- .../views/dialogs/security/ExportE2eKeysDialog.js | 2 +- .../views/dialogs/security/ImportE2eKeysDialog.js | 2 +- src/components/structures/FilePanel.js | 2 +- src/components/structures/GroupView.js | 2 +- src/components/structures/InteractiveAuth.js | 2 +- src/components/structures/MatrixChat.tsx | 5 ++--- src/components/structures/RoomStatusBar.js | 4 ++-- src/components/structures/TimelinePanel.js | 6 +++--- src/components/structures/UserView.js | 7 ++++--- .../context_menus/GroupInviteTileContextMenu.js | 2 +- .../views/context_menus/MessageContextMenu.js | 2 +- .../views/dialogs/ConfirmUserActionDialog.js | 2 +- src/components/views/dialogs/DevtoolsDialog.js | 3 ++- src/components/views/dialogs/ReportEventDialog.js | 2 +- .../dialogs/TabbedIntegrationManagerDialog.js | 2 +- src/components/views/dialogs/TermsDialog.js | 10 +++++----- .../dialogs/security/RestoreKeyBackupDialog.js | 2 +- src/components/views/elements/Pill.js | 3 ++- src/components/views/elements/ReplyThread.js | 2 +- .../views/messages/EditHistoryMessage.js | 2 +- src/components/views/messages/MessageActionBar.js | 2 +- .../views/room_settings/RelatedGroupSettings.js | 2 +- src/components/views/rooms/EditMessageComposer.js | 2 +- src/components/views/rooms/EventTile.js | 2 +- src/components/views/rooms/ThirdPartyMemberInfo.js | 2 +- .../settings/tabs/user/GeneralUserSettingsTab.js | 2 +- src/indexing/EventIndex.js | 3 ++- src/utils/AutoDiscoveryUtils.js | 2 +- src/utils/EventUtils.js | 2 +- src/utils/IdentityServerUtils.js | 2 +- src/utils/StorageManager.js | 7 ++++--- src/utils/createMatrixClient.js | 13 ++++++++----- 40 files changed, 77 insertions(+), 70 deletions(-) diff --git a/src/CallMediaHandler.js b/src/CallMediaHandler.js index 8d56467c57..7c7940cab5 100644 --- a/src/CallMediaHandler.js +++ b/src/CallMediaHandler.js @@ -14,9 +14,9 @@ limitations under the License. */ -import * as Matrix from 'matrix-js-sdk'; import SettingsStore from "./settings/SettingsStore"; import {SettingLevel} from "./settings/SettingLevel"; +import {setMatrixCallAudioInput, setMatrixCallAudioOutput, setMatrixCallVideoInput} from "matrix-js-sdk/src/matrix"; export default { hasAnyLabeledDevices: async function() { @@ -54,24 +54,24 @@ export default { const audioDeviceId = SettingsStore.getValue("webrtc_audioinput"); const videoDeviceId = SettingsStore.getValue("webrtc_videoinput"); - Matrix.setMatrixCallAudioOutput(audioOutDeviceId); - Matrix.setMatrixCallAudioInput(audioDeviceId); - Matrix.setMatrixCallVideoInput(videoDeviceId); + setMatrixCallAudioOutput(audioOutDeviceId); + setMatrixCallAudioInput(audioDeviceId); + setMatrixCallVideoInput(videoDeviceId); }, setAudioOutput: function(deviceId) { SettingsStore.setValue("webrtc_audiooutput", null, SettingLevel.DEVICE, deviceId); - Matrix.setMatrixCallAudioOutput(deviceId); + setMatrixCallAudioOutput(deviceId); }, setAudioInput: function(deviceId) { SettingsStore.setValue("webrtc_audioinput", null, SettingLevel.DEVICE, deviceId); - Matrix.setMatrixCallAudioInput(deviceId); + setMatrixCallAudioInput(deviceId); }, setVideoInput: function(deviceId) { SettingsStore.setValue("webrtc_videoinput", null, SettingLevel.DEVICE, deviceId); - Matrix.setMatrixCallVideoInput(deviceId); + setMatrixCallVideoInput(deviceId); }, getAudioOutput: function() { diff --git a/src/IdentityAuthClient.js b/src/IdentityAuthClient.js index d3bfee2380..9c6449f1e3 100644 --- a/src/IdentityAuthClient.js +++ b/src/IdentityAuthClient.js @@ -14,7 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { createClient, SERVICE_TYPES } from 'matrix-js-sdk'; +import { SERVICE_TYPES } from 'matrix-js-sdk/src/service-types'; +import { createClient } from 'matrix-js-sdk/src/matrix' import {MatrixClientPeg} from './MatrixClientPeg'; import Modal from './Modal'; diff --git a/src/Lifecycle.ts b/src/Lifecycle.ts index 7780d4c87a..b0a1292ba1 100644 --- a/src/Lifecycle.ts +++ b/src/Lifecycle.ts @@ -17,8 +17,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// @ts-ignore - XXX: tsc doesn't like this: our js-sdk imports are complex so this isn't surprising -import Matrix from 'matrix-js-sdk'; +import { createClient } from 'matrix-js-sdk/src/matrix'; import { InvalidStoreError } from "matrix-js-sdk/src/errors"; import { MatrixClient } from "matrix-js-sdk/src/client"; import {decryptAES, encryptAES} from "matrix-js-sdk/src/crypto/aes"; @@ -219,7 +218,7 @@ export function attemptTokenLogin( button: _t("Try again"), onFinished: tryAgain => { if (tryAgain) { - const cli = Matrix.createClient({ + const cli = createClient({ baseUrl: homeserver, idBaseUrl: identityServer, }); @@ -276,7 +275,7 @@ function registerAsGuest( console.log(`Doing guest login on ${hsUrl}`); // create a temporary MatrixClient to do the login - const client = Matrix.createClient({ + const client = createClient({ baseUrl: hsUrl, }); diff --git a/src/Login.ts b/src/Login.ts index aecc0493c7..db3c4c11e4 100644 --- a/src/Login.ts +++ b/src/Login.ts @@ -19,7 +19,7 @@ limitations under the License. */ // @ts-ignore - XXX: tsc doesn't like this: our js-sdk imports are complex so this isn't surprising -import Matrix from "matrix-js-sdk"; +import {createClient} from "matrix-js-sdk/src/matrix"; import { MatrixClient } from "matrix-js-sdk/src/client"; import { IMatrixClientCreds } from "./MatrixClientPeg"; import SecurityCustomisations from "./customisations/Security"; @@ -115,7 +115,7 @@ export default class Login { */ public createTemporaryClient(): MatrixClient { if (this.tempClient) return this.tempClient; // use memoization - return this.tempClient = Matrix.createClient({ + return this.tempClient = createClient({ baseUrl: this.hsUrl, idBaseUrl: this.isUrl, }); @@ -210,7 +210,7 @@ export async function sendLoginRequest( loginType: string, loginParams: ILoginParams, ): Promise { - const client = Matrix.createClient({ + const client = createClient({ baseUrl: hsUrl, idBaseUrl: isUrl, }); diff --git a/src/PasswordReset.js b/src/PasswordReset.js index b38a9de960..6fe6ca82cc 100644 --- a/src/PasswordReset.js +++ b/src/PasswordReset.js @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import * as Matrix from 'matrix-js-sdk'; +import { createClient } from 'matrix-js-sdk/src/matrix'; import { _t } from './languageHandler'; /** @@ -32,7 +32,7 @@ export default class PasswordReset { * @param {string} identityUrl The URL to the IS which has linked the email -> mxid mapping. */ constructor(homeserverUrl, identityUrl) { - this.client = Matrix.createClient({ + this.client = createClient({ baseUrl: homeserverUrl, idBaseUrl: identityUrl, }); diff --git a/src/Resend.js b/src/Resend.js index 5638313306..bf69e59c1a 100644 --- a/src/Resend.js +++ b/src/Resend.js @@ -17,7 +17,7 @@ limitations under the License. import {MatrixClientPeg} from './MatrixClientPeg'; import dis from './dispatcher/dispatcher'; -import { EventStatus } from 'matrix-js-sdk'; +import { EventStatus } from 'matrix-js-sdk/src/models/event'; export default class Resend { static resendUnsentEvents(room) { diff --git a/src/ScalarAuthClient.js b/src/ScalarAuthClient.js index 1ea9d39e2f..200b4fd7b9 100644 --- a/src/ScalarAuthClient.js +++ b/src/ScalarAuthClient.js @@ -21,9 +21,9 @@ import { Service, startTermsFlow, TermsNotSignedError } from './Terms'; import {MatrixClientPeg} from "./MatrixClientPeg"; import request from "browser-request"; -import * as Matrix from 'matrix-js-sdk'; import SdkConfig from "./SdkConfig"; import {WidgetType} from "./widgets/WidgetType"; +import {SERVICE_TYPES} from "matrix-js-sdk/src/service-types"; // The version of the integration manager API we're intending to work with const imApiVersion = "1.1"; @@ -153,7 +153,7 @@ export default class ScalarAuthClient { parsedImRestUrl.path = ''; parsedImRestUrl.pathname = ''; return startTermsFlow([new Service( - Matrix.SERVICE_TYPES.IM, + SERVICE_TYPES.IM, parsedImRestUrl.format(), token, )], this.termsInteractionCallback).then(() => { diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 896e27d92c..3f75b3788c 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -237,7 +237,7 @@ Example: */ import {MatrixClientPeg} from './MatrixClientPeg'; -import { MatrixEvent } from 'matrix-js-sdk'; +import { MatrixEvent } from 'matrix-js-sdk/src/models/event'; import dis from './dispatcher/dispatcher'; import WidgetUtils from './utils/WidgetUtils'; import RoomViewStore from './stores/RoomViewStore'; diff --git a/src/async-components/views/dialogs/security/ExportE2eKeysDialog.js b/src/async-components/views/dialogs/security/ExportE2eKeysDialog.js index 4dd296a8f1..eeb68b94bd 100644 --- a/src/async-components/views/dialogs/security/ExportE2eKeysDialog.js +++ b/src/async-components/views/dialogs/security/ExportE2eKeysDialog.js @@ -19,7 +19,7 @@ import React, {createRef} from 'react'; import PropTypes from 'prop-types'; import { _t } from '../../../../languageHandler'; -import { MatrixClient } from 'matrix-js-sdk'; +import { MatrixClient } from 'matrix-js-sdk/src/client'; import * as MegolmExportEncryption from '../../../../utils/MegolmExportEncryption'; import * as sdk from '../../../../index'; diff --git a/src/async-components/views/dialogs/security/ImportE2eKeysDialog.js b/src/async-components/views/dialogs/security/ImportE2eKeysDialog.js index e7bae3578b..670cb28b94 100644 --- a/src/async-components/views/dialogs/security/ImportE2eKeysDialog.js +++ b/src/async-components/views/dialogs/security/ImportE2eKeysDialog.js @@ -17,7 +17,7 @@ limitations under the License. import React, {createRef} from 'react'; import PropTypes from 'prop-types'; -import { MatrixClient } from 'matrix-js-sdk'; +import { MatrixClient } from 'matrix-js-sdk/src/client'; import * as MegolmExportEncryption from '../../../../utils/MegolmExportEncryption'; import * as sdk from '../../../../index'; import { _t } from '../../../../languageHandler'; diff --git a/src/components/structures/FilePanel.js b/src/components/structures/FilePanel.js index 9f5a0b6211..32db5c251c 100644 --- a/src/components/structures/FilePanel.js +++ b/src/components/structures/FilePanel.js @@ -18,7 +18,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import {Filter} from 'matrix-js-sdk'; +import {Filter} from 'matrix-js-sdk/src/filter'; import * as sdk from '../../index'; import {MatrixClientPeg} from '../../MatrixClientPeg'; import EventIndexPeg from "../../indexing/EventIndexPeg"; diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index f05d8d0758..b006b323fb 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -35,7 +35,7 @@ import GroupStore from '../../stores/GroupStore'; import FlairStore from '../../stores/FlairStore'; import { showGroupAddRoomDialog } from '../../GroupAddressPicker'; import {makeGroupPermalink, makeUserPermalink} from "../../utils/permalinks/Permalinks"; -import {Group} from "matrix-js-sdk"; +import {Group} from "matrix-js-sdk/src/models/group"; import {allSettled, sleep} from "../../utils/promise"; import RightPanelStore from "../../stores/RightPanelStore"; import AutoHideScrollbar from "./AutoHideScrollbar"; diff --git a/src/components/structures/InteractiveAuth.js b/src/components/structures/InteractiveAuth.js index 9b61f71fd7..d419c9de6e 100644 --- a/src/components/structures/InteractiveAuth.js +++ b/src/components/structures/InteractiveAuth.js @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {InteractiveAuth} from "matrix-js-sdk"; +import {InteractiveAuth} from "matrix-js-sdk/src/interactive-auth"; import React, {createRef} from 'react'; import PropTypes from 'prop-types'; diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index f0a3778a2b..a1117551fd 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -18,8 +18,7 @@ limitations under the License. */ import React, { createRef } from 'react'; -// @ts-ignore - XXX: no idea why this import fails -import * as Matrix from "matrix-js-sdk"; +import { createClient } from "matrix-js-sdk/src/matrix"; import { InvalidStoreError } from "matrix-js-sdk/src/errors"; import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { MatrixEvent } from "matrix-js-sdk/src/models/event"; @@ -1649,7 +1648,7 @@ export default class MatrixChat extends React.PureComponent { let cli = MatrixClientPeg.get(); if (!cli) { const {hsUrl, isUrl} = this.props.serverConfig; - cli = Matrix.createClient({ + cli = createClient({ baseUrl: hsUrl, idBaseUrl: isUrl, }); diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index 8b70998be0..54b6fee233 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -16,7 +16,6 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import Matrix from 'matrix-js-sdk'; import { _t, _td } from '../../languageHandler'; import {MatrixClientPeg} from '../../MatrixClientPeg'; import Resend from '../../Resend'; @@ -24,6 +23,7 @@ import dis from '../../dispatcher/dispatcher'; import {messageForResourceLimitError, messageForSendError} from '../../utils/ErrorUtils'; import {Action} from "../../dispatcher/actions"; import {replaceableComponent} from "../../utils/replaceableComponent"; +import {EventStatus} from "matrix-js-sdk/src/models/event"; const STATUS_BAR_HIDDEN = 0; const STATUS_BAR_EXPANDED = 1; @@ -32,7 +32,7 @@ const STATUS_BAR_EXPANDED_LARGE = 2; function getUnsentMessages(room) { if (!room) { return []; } return room.getPendingEvents().filter(function(ev) { - return ev.status === Matrix.EventStatus.NOT_SENT; + return ev.status === EventStatus.NOT_SENT; }); } diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index f32b8ed0a9..ce13bb43fa 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -22,8 +22,8 @@ import {LayoutPropType} from "../../settings/Layout"; import React, {createRef} from 'react'; import ReactDOM from "react-dom"; import PropTypes from 'prop-types'; -import {EventTimeline} from "matrix-js-sdk"; -import * as Matrix from "matrix-js-sdk"; +import {EventTimeline} from "matrix-js-sdk/src/models/event-timeline"; +import {TimelineWindow} from "matrix-js-sdk/src/timeline-window"; import { _t } from '../../languageHandler'; import {MatrixClientPeg} from "../../MatrixClientPeg"; import UserActivity from "../../UserActivity"; @@ -1007,7 +1007,7 @@ class TimelinePanel extends React.Component { * returns a promise which will resolve when the load completes. */ _loadTimeline(eventId, pixelOffset, offsetBase) { - this._timelineWindow = new Matrix.TimelineWindow( + this._timelineWindow = new TimelineWindow( MatrixClientPeg.get(), this.props.timelineSet, {windowLimit: this.props.timelineCap}); diff --git a/src/components/structures/UserView.js b/src/components/structures/UserView.js index dc05193ece..6b472783bb 100644 --- a/src/components/structures/UserView.js +++ b/src/components/structures/UserView.js @@ -17,13 +17,14 @@ limitations under the License. import React from "react"; import PropTypes from "prop-types"; -import Matrix from "matrix-js-sdk"; import {MatrixClientPeg} from "../../MatrixClientPeg"; import * as sdk from "../../index"; import Modal from '../../Modal'; import { _t } from '../../languageHandler'; import HomePage from "./HomePage"; import {replaceableComponent} from "../../utils/replaceableComponent"; +import {MatrixEvent} from "matrix-js-sdk/src/models/event"; +import {RoomMember} from "matrix-js-sdk/src/models/room-member"; @replaceableComponent("structures.UserView") export default class UserView extends React.Component { @@ -68,8 +69,8 @@ export default class UserView extends React.Component { this.setState({loading: false}); return; } - const fakeEvent = new Matrix.MatrixEvent({type: "m.room.member", content: profileInfo}); - const member = new Matrix.RoomMember(null, this.props.userId); + const fakeEvent = new MatrixEvent({type: "m.room.member", content: profileInfo}); + const member = new RoomMember(null, this.props.userId); member.setMembershipEvent(fakeEvent); this.setState({member, loading: false}); } diff --git a/src/components/views/context_menus/GroupInviteTileContextMenu.js b/src/components/views/context_menus/GroupInviteTileContextMenu.js index 11a9d90ac2..15078326b3 100644 --- a/src/components/views/context_menus/GroupInviteTileContextMenu.js +++ b/src/components/views/context_menus/GroupInviteTileContextMenu.js @@ -20,7 +20,7 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import Modal from '../../../Modal'; -import {Group} from 'matrix-js-sdk'; +import {Group} from 'matrix-js-sdk/src/models/group'; import GroupStore from "../../../stores/GroupStore"; import {MenuItem} from "../../structures/ContextMenu"; import {replaceableComponent} from "../../../utils/replaceableComponent"; diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index daabf224dc..56f070ba36 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -19,7 +19,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import {EventStatus} from 'matrix-js-sdk'; +import {EventStatus} from 'matrix-js-sdk/src/models/event'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import dis from '../../../dispatcher/dispatcher'; diff --git a/src/components/views/dialogs/ConfirmUserActionDialog.js b/src/components/views/dialogs/ConfirmUserActionDialog.js index 8cfd28986b..8059b9172a 100644 --- a/src/components/views/dialogs/ConfirmUserActionDialog.js +++ b/src/components/views/dialogs/ConfirmUserActionDialog.js @@ -16,7 +16,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import { MatrixClient } from 'matrix-js-sdk'; +import { MatrixClient } from 'matrix-js-sdk/src/client'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import { GroupMemberType } from '../../../groups'; diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index dfcc5d6dfb..9f5513e0a3 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -19,7 +19,6 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import SyntaxHighlight from '../elements/SyntaxHighlight'; import { _t } from '../../../languageHandler'; -import { Room, MatrixEvent } from "matrix-js-sdk"; import Field from "../elements/Field"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import {useEventEmitter} from "../../../hooks/useEventEmitter"; @@ -39,6 +38,8 @@ import SettingsStore, {LEVEL_ORDER} from "../../../settings/SettingsStore"; import Modal from "../../../Modal"; import ErrorDialog from "./ErrorDialog"; import {replaceableComponent} from "../../../utils/replaceableComponent"; +import {Room} from "matrix-js-sdk/src/models/room"; +import {MatrixEvent} from "matrix-js-sdk/src/models/event"; class GenericEditor extends React.PureComponent { // static propTypes = {onBack: PropTypes.func.isRequired}; diff --git a/src/components/views/dialogs/ReportEventDialog.js b/src/components/views/dialogs/ReportEventDialog.js index 67ed0f8f53..5454b97287 100644 --- a/src/components/views/dialogs/ReportEventDialog.js +++ b/src/components/views/dialogs/ReportEventDialog.js @@ -18,7 +18,7 @@ import React, {PureComponent} from 'react'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import PropTypes from "prop-types"; -import {MatrixEvent} from "matrix-js-sdk"; +import {MatrixEvent} from "matrix-js-sdk/src/models/event"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import SdkConfig from '../../../SdkConfig'; import Markdown from '../../../Markdown'; diff --git a/src/components/views/dialogs/TabbedIntegrationManagerDialog.js b/src/components/views/dialogs/TabbedIntegrationManagerDialog.js index 07e29adcff..618b0b4347 100644 --- a/src/components/views/dialogs/TabbedIntegrationManagerDialog.js +++ b/src/components/views/dialogs/TabbedIntegrationManagerDialog.js @@ -17,7 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import {IntegrationManagers} from "../../../integrations/IntegrationManagers"; -import {Room} from "matrix-js-sdk"; +import {Room} from "matrix-js-sdk/src/models/room"; import * as sdk from '../../../index'; import {dialogTermsInteractionCallback, TermsNotSignedError} from "../../../Terms"; import classNames from 'classnames'; diff --git a/src/components/views/dialogs/TermsDialog.js b/src/components/views/dialogs/TermsDialog.js index 72e6c3f3a0..e8625ec6cb 100644 --- a/src/components/views/dialogs/TermsDialog.js +++ b/src/components/views/dialogs/TermsDialog.js @@ -20,8 +20,8 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t, pickBestLanguage } from '../../../languageHandler'; -import Matrix from 'matrix-js-sdk'; import {replaceableComponent} from "../../../utils/replaceableComponent"; +import {SERVICE_TYPES} from "matrix-js-sdk/src/service-types"; class TermsCheckbox extends React.PureComponent { static propTypes = { @@ -85,22 +85,22 @@ export default class TermsDialog extends React.PureComponent { _nameForServiceType(serviceType, host) { switch (serviceType) { - case Matrix.SERVICE_TYPES.IS: + case SERVICE_TYPES.IS: return

    {_t("Identity Server")}
    ({host})
    ; - case Matrix.SERVICE_TYPES.IM: + case SERVICE_TYPES.IM: return
    {_t("Integration Manager")}
    ({host})
    ; } } _summaryForServiceType(serviceType) { switch (serviceType) { - case Matrix.SERVICE_TYPES.IS: + case SERVICE_TYPES.IS: return
    {_t("Find others by phone or email")}
    {_t("Be found by phone or email")}
    ; - case Matrix.SERVICE_TYPES.IM: + case SERVICE_TYPES.IM: return
    {_t("Use bots, bridges, widgets and sticker packs")}
    ; diff --git a/src/components/views/dialogs/security/RestoreKeyBackupDialog.js b/src/components/views/dialogs/security/RestoreKeyBackupDialog.js index ca28ca094c..1fafe03d95 100644 --- a/src/components/views/dialogs/security/RestoreKeyBackupDialog.js +++ b/src/components/views/dialogs/security/RestoreKeyBackupDialog.js @@ -19,7 +19,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../../index'; import {MatrixClientPeg} from '../../../../MatrixClientPeg'; -import { MatrixClient } from 'matrix-js-sdk'; +import { MatrixClient } from 'matrix-js-sdk/src/client'; import { _t } from '../../../../languageHandler'; import { accessSecretStorage } from '../../../../SecurityManager'; diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js index e61d312305..d6c8aeb811 100644 --- a/src/components/views/elements/Pill.js +++ b/src/components/views/elements/Pill.js @@ -17,7 +17,8 @@ import React from 'react'; import * as sdk from '../../../index'; import dis from '../../../dispatcher/dispatcher'; import classNames from 'classnames'; -import { Room, RoomMember } from 'matrix-js-sdk'; +import { Room } from 'matrix-js-sdk/src/models/room'; +import { RoomMember } from 'matrix-js-sdk/src/models/room-member' import PropTypes from 'prop-types'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import FlairStore from "../../../stores/FlairStore"; diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 2e0cc50435..870803995d 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -21,7 +21,7 @@ import {_t} from '../../../languageHandler'; import PropTypes from 'prop-types'; import dis from '../../../dispatcher/dispatcher'; import {wantsDateSeparator} from '../../../DateUtils'; -import {MatrixEvent} from 'matrix-js-sdk'; +import {MatrixEvent} from 'matrix-js-sdk/src/models/event'; import {makeUserPermalink, RoomPermalinkCreator} from "../../../utils/permalinks/Permalinks"; import SettingsStore from "../../../settings/SettingsStore"; import {LayoutPropType} from "../../../settings/Layout"; diff --git a/src/components/views/messages/EditHistoryMessage.js b/src/components/views/messages/EditHistoryMessage.js index a298f7eb68..e2eda1e12a 100644 --- a/src/components/views/messages/EditHistoryMessage.js +++ b/src/components/views/messages/EditHistoryMessage.js @@ -19,7 +19,7 @@ import PropTypes from 'prop-types'; import * as HtmlUtils from '../../../HtmlUtils'; import { editBodyDiffToHtml } from '../../../utils/MessageDiffUtils'; import {formatTime} from '../../../DateUtils'; -import {MatrixEvent} from 'matrix-js-sdk'; +import {MatrixEvent} from 'matrix-js-sdk/src/models/event'; import {pillifyLinks, unmountPills} from '../../../utils/pillify'; import { _t } from '../../../languageHandler'; import * as sdk from '../../../index'; diff --git a/src/components/views/messages/MessageActionBar.js b/src/components/views/messages/MessageActionBar.js index c33debe3f5..5a6e7d87b7 100644 --- a/src/components/views/messages/MessageActionBar.js +++ b/src/components/views/messages/MessageActionBar.js @@ -18,7 +18,7 @@ limitations under the License. import React, {useEffect} from 'react'; import PropTypes from 'prop-types'; -import { EventStatus } from 'matrix-js-sdk'; +import { EventStatus } from 'matrix-js-sdk/src/models/event'; import { _t } from '../../../languageHandler'; import * as sdk from '../../../index'; diff --git a/src/components/views/room_settings/RelatedGroupSettings.js b/src/components/views/room_settings/RelatedGroupSettings.js index f82e238722..272ecd1228 100644 --- a/src/components/views/room_settings/RelatedGroupSettings.js +++ b/src/components/views/room_settings/RelatedGroupSettings.js @@ -16,7 +16,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import {MatrixEvent} from 'matrix-js-sdk'; +import {MatrixEvent} from 'matrix-js-sdk/src/models/event'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import Modal from '../../../Modal'; diff --git a/src/components/views/rooms/EditMessageComposer.js b/src/components/views/rooms/EditMessageComposer.js index 6ecb2bd549..be04a50798 100644 --- a/src/components/views/rooms/EditMessageComposer.js +++ b/src/components/views/rooms/EditMessageComposer.js @@ -27,7 +27,7 @@ import {parseEvent} from '../../../editor/deserialize'; import {PartCreator} from '../../../editor/parts'; import EditorStateTransfer from '../../../utils/EditorStateTransfer'; import classNames from 'classnames'; -import {EventStatus} from 'matrix-js-sdk'; +import {EventStatus} from 'matrix-js-sdk/src/models/event'; import BasicMessageComposer from "./BasicMessageComposer"; import {Key, isOnlyCtrlOrCmdKeyEvent} from "../../../Keyboard"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index cbe3252c2b..644d64d322 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -28,7 +28,7 @@ import * as sdk from "../../../index"; import dis from '../../../dispatcher/dispatcher'; import SettingsStore from "../../../settings/SettingsStore"; import {Layout, LayoutPropType} from "../../../settings/Layout"; -import {EventStatus} from 'matrix-js-sdk'; +import {EventStatus} from 'matrix-js-sdk/src/models/event'; import {formatTime} from "../../../DateUtils"; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import {ALL_RULE_TYPES} from "../../../mjolnir/BanList"; diff --git a/src/components/views/rooms/ThirdPartyMemberInfo.js b/src/components/views/rooms/ThirdPartyMemberInfo.js index 5e2d82a1b2..67b86538c9 100644 --- a/src/components/views/rooms/ThirdPartyMemberInfo.js +++ b/src/components/views/rooms/ThirdPartyMemberInfo.js @@ -17,7 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import {MatrixClientPeg} from "../../../MatrixClientPeg"; -import {MatrixEvent} from "matrix-js-sdk"; +import {MatrixEvent} from "matrix-js-sdk/src/models/event"; import {_t} from "../../../languageHandler"; import dis from "../../../dispatcher/dispatcher"; import * as sdk from "../../../index"; diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 314acf5d65..b7dbfa4a3b 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -32,7 +32,7 @@ import * as sdk from "../../../../.."; import Modal from "../../../../../Modal"; import dis from "../../../../../dispatcher/dispatcher"; import {Service, startTermsFlow} from "../../../../../Terms"; -import {SERVICE_TYPES} from "matrix-js-sdk"; +import {SERVICE_TYPES} from "matrix-js-sdk/src/service-types"; import IdentityAuthClient from "../../../../../IdentityAuthClient"; import {abbreviateUrl} from "../../../../../utils/UrlUtils"; import { getThreepidsWithBindStatus } from '../../../../../boundThreepids'; diff --git a/src/indexing/EventIndex.js b/src/indexing/EventIndex.js index fa263a2a55..2dcdb9e3a3 100644 --- a/src/indexing/EventIndex.js +++ b/src/indexing/EventIndex.js @@ -16,7 +16,8 @@ limitations under the License. import PlatformPeg from "../PlatformPeg"; import {MatrixClientPeg} from "../MatrixClientPeg"; -import {EventTimeline, RoomMember} from 'matrix-js-sdk'; +import {RoomMember} from 'matrix-js-sdk/src/models/room-member'; +import {EventTimeline} from 'matrix-js-sdk/src/models/event-timeline'; import {sleep} from "../utils/promise"; import SettingsStore from "../settings/SettingsStore"; import {EventEmitter} from "events"; diff --git a/src/utils/AutoDiscoveryUtils.js b/src/utils/AutoDiscoveryUtils.js index 18b6451d3e..614aa4cea8 100644 --- a/src/utils/AutoDiscoveryUtils.js +++ b/src/utils/AutoDiscoveryUtils.js @@ -16,7 +16,7 @@ limitations under the License. */ import React from 'react'; -import {AutoDiscovery} from "matrix-js-sdk"; +import {AutoDiscovery} from "matrix-js-sdk/src/autodiscovery"; import {_t, _td, newTranslatableError} from "../languageHandler"; import {makeType} from "./TypeUtils"; import SdkConfig from '../SdkConfig'; diff --git a/src/utils/EventUtils.js b/src/utils/EventUtils.js index 6558a11ed4..be21896417 100644 --- a/src/utils/EventUtils.js +++ b/src/utils/EventUtils.js @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { EventStatus } from 'matrix-js-sdk'; +import { EventStatus } from 'matrix-js-sdk/src/models/event'; import {MatrixClientPeg} from '../MatrixClientPeg'; import shouldHideEvent from "../shouldHideEvent"; /** diff --git a/src/utils/IdentityServerUtils.js b/src/utils/IdentityServerUtils.js index 093d4eeabf..5ece308954 100644 --- a/src/utils/IdentityServerUtils.js +++ b/src/utils/IdentityServerUtils.js @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { SERVICE_TYPES } from 'matrix-js-sdk'; +import { SERVICE_TYPES } from 'matrix-js-sdk/src/service-types'; import SdkConfig from '../SdkConfig'; import {MatrixClientPeg} from '../MatrixClientPeg'; diff --git a/src/utils/StorageManager.js b/src/utils/StorageManager.js index c90281bacf..23c27a2d1c 100644 --- a/src/utils/StorageManager.js +++ b/src/utils/StorageManager.js @@ -14,9 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import Matrix from 'matrix-js-sdk'; import {LocalStorageCryptoStore} from 'matrix-js-sdk/src/crypto/store/localStorage-crypto-store'; import Analytics from '../Analytics'; +import {IndexedDBStore} from "matrix-js-sdk/src/store/indexeddb"; +import {IndexedDBCryptoStore} from "matrix-js-sdk/src/crypto/store/indexeddb-crypto-store"; const localStorage = window.localStorage; @@ -132,7 +133,7 @@ export async function checkConsistency() { async function checkSyncStore() { let exists = false; try { - exists = await Matrix.IndexedDBStore.exists( + exists = await IndexedDBStore.exists( indexedDB, SYNC_STORE_NAME, ); log(`Sync store using IndexedDB contains data? ${exists}`); @@ -148,7 +149,7 @@ async function checkSyncStore() { async function checkCryptoStore() { let exists = false; try { - exists = await Matrix.IndexedDBCryptoStore.exists( + exists = await IndexedDBCryptoStore.exists( indexedDB, CRYPTO_STORE_NAME, ); log(`Crypto store using IndexedDB contains data? ${exists}`); diff --git a/src/utils/createMatrixClient.js b/src/utils/createMatrixClient.js index c8ff35a584..f5e196d846 100644 --- a/src/utils/createMatrixClient.js +++ b/src/utils/createMatrixClient.js @@ -14,7 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import * as Matrix from 'matrix-js-sdk'; +import {createClient} from "matrix-js-sdk/src/matrix"; +import {IndexedDBCryptoStore} from "matrix-js-sdk/src/crypto/store/indexeddb-crypto-store"; +import {WebStorageSessionStore} from "matrix-js-sdk/src/store/session/webstorage"; +import {IndexedDBStore} from "matrix-js-sdk/src/store/indexeddb"; const localStorage = window.localStorage; @@ -44,7 +47,7 @@ export default function createMatrixClient(opts) { }; if (indexedDB && localStorage) { - storeOpts.store = new Matrix.IndexedDBStore({ + storeOpts.store = new IndexedDBStore({ indexedDB: indexedDB, dbName: "riot-web-sync", localStorage: localStorage, @@ -53,18 +56,18 @@ export default function createMatrixClient(opts) { } if (localStorage) { - storeOpts.sessionStore = new Matrix.WebStorageSessionStore(localStorage); + storeOpts.sessionStore = new WebStorageSessionStore(localStorage); } if (indexedDB) { - storeOpts.cryptoStore = new Matrix.IndexedDBCryptoStore( + storeOpts.cryptoStore = new IndexedDBCryptoStore( indexedDB, "matrix-js-sdk:crypto", ); } opts = Object.assign(storeOpts, opts); - return Matrix.createClient(opts); + return createClient(opts); } createMatrixClient.indexedDbWorkerScript = null; From be8ee1a576fb9eff9d8753736ae3e6183378110a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 18 Mar 2021 21:05:51 -0600 Subject: [PATCH 29/35] Appease the linter --- src/IdentityAuthClient.js | 2 +- src/components/views/elements/Pill.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/IdentityAuthClient.js b/src/IdentityAuthClient.js index 9c6449f1e3..1687adf13b 100644 --- a/src/IdentityAuthClient.js +++ b/src/IdentityAuthClient.js @@ -15,7 +15,7 @@ limitations under the License. */ import { SERVICE_TYPES } from 'matrix-js-sdk/src/service-types'; -import { createClient } from 'matrix-js-sdk/src/matrix' +import { createClient } from 'matrix-js-sdk/src/matrix'; import {MatrixClientPeg} from './MatrixClientPeg'; import Modal from './Modal'; diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js index d6c8aeb811..a8e16813e6 100644 --- a/src/components/views/elements/Pill.js +++ b/src/components/views/elements/Pill.js @@ -18,7 +18,7 @@ import * as sdk from '../../../index'; import dis from '../../../dispatcher/dispatcher'; import classNames from 'classnames'; import { Room } from 'matrix-js-sdk/src/models/room'; -import { RoomMember } from 'matrix-js-sdk/src/models/room-member' +import { RoomMember } from 'matrix-js-sdk/src/models/room-member'; import PropTypes from 'prop-types'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import FlairStore from "../../../stores/FlairStore"; From c2cc0862179b987fa0367fcbb5169391cb6a50a2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 18 Mar 2021 21:24:02 -0600 Subject: [PATCH 30/35] Import the js-sdk at the index so the `request` object gets set Now that all the imports are replaced, we need to set up the js-sdk somewhere. Might as well do it in the index of the react-sdk where callers will be relying on those skin functions. --- src/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/index.js b/src/index.js index 008e15ad90..e360c04f4f 100644 --- a/src/index.js +++ b/src/index.js @@ -28,3 +28,7 @@ export function resetSkin() { export function getComponent(componentName) { return Skinner.getComponent(componentName); } + +// Import the js-sdk so the proper `request` object can be set. This does some +// magic with the browser injection to make all subsequent imports work fine. +import "matrix-js-sdk"; From 1d43c8b7913690f6558cab26322d8443e3a5f1fd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 18 Mar 2021 23:28:59 -0600 Subject: [PATCH 31/35] Remove forgotten rooms from the room list once forgotten Fixes https://github.com/vector-im/element-web/issues/15559 This isn't exactly perfect as an implementation: if the user refreshes immediately after forgetting then there is a good chance the room re-appears because of the sync accumulator. At the very least this change makes it so in *most* cases the room goes away, which is probably good enough until https://github.com/vector-im/element-web/issues/14038 can be implemented properly. --- src/components/structures/MatrixChat.tsx | 8 ++++++++ src/stores/room-list/RoomListStore.ts | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index f0a3778a2b..98c7421f9d 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -85,6 +85,8 @@ import { showToast as showMobileGuideToast } from '../../toasts/MobileGuideToast import SpaceStore from "../../stores/SpaceStore"; import SpaceRoomDirectory from "./SpaceRoomDirectory"; import {replaceableComponent} from "../../utils/replaceableComponent"; +import RoomListStore from "../../stores/room-list/RoomListStore"; +import {RoomUpdateCause} from "../../stores/room-list/models"; /** constants for MatrixChat.state.view */ export enum Views { @@ -1140,11 +1142,17 @@ export default class MatrixChat extends React.PureComponent { } private forgetRoom(roomId: string) { + const room = MatrixClientPeg.get().getRoom(roomId); MatrixClientPeg.get().forget(roomId).then(() => { // Switch to home page if we're currently viewing the forgotten room if (this.state.currentRoomId === roomId) { dis.dispatch({ action: "view_home_page" }); } + + // We have to manually update the room list because the forgotten room will not + // be notified to us, therefore the room list will have no other way of knowing + // the room is forgotten. + RoomListStore.instance.manualRoomUpdate(room, RoomUpdateCause.RoomRemoved); }).catch((err) => { const errCode = err.errcode || _td("unknown error code"); Modal.createTrackedDialog("Failed to forget room", '', ErrorDialog, { diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts index 3f415f946d..074c2e569d 100644 --- a/src/stores/room-list/RoomListStore.ts +++ b/src/stores/room-list/RoomListStore.ts @@ -655,6 +655,18 @@ export class RoomListStoreClass extends AsyncStoreWithClient { if (!algorithmTags) return [DefaultTagID.Untagged]; return algorithmTags; } + + /** + * Manually update a room with a given cause. This should only be used if the + * room list store would otherwise be incapable of doing the update itself. Note + * that this may race with the room list's regular operation. + * @param {Room} room The room to update. + * @param {RoomUpdateCause} cause The cause to update for. + */ + public async manualRoomUpdate(room: Room, cause: RoomUpdateCause) { + await this.handleRoomUpdate(room, cause); + this.updateFn.trigger(); + } } export default class RoomListStore { From 4a734ef70ba322bbd726a711eb4e0f1d802f0677 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 19 Mar 2021 11:29:14 +0000 Subject: [PATCH 32/35] Clear displayname / vatar if they're unset --- src/stores/OwnProfileStore.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/stores/OwnProfileStore.ts b/src/stores/OwnProfileStore.ts index 398532a5c8..bb45456f1e 100644 --- a/src/stores/OwnProfileStore.ts +++ b/src/stores/OwnProfileStore.ts @@ -124,8 +124,16 @@ export class OwnProfileStore extends AsyncStoreWithClient { // We specifically do not use the User object we stored for profile info as it // could easily be wrong (such as per-room instead of global profile). const profileInfo = await this.matrixClient.getProfileInfo(this.matrixClient.getUserId()); - if (profileInfo.displayname) window.localStorage.setItem(KEY_DISPLAY_NAME, profileInfo.displayname); - if (profileInfo.avatar_url) window.localStorage.setItem(KEY_AVATAR_URL, profileInfo.avatar_url); + if (profileInfo.displayname) { + window.localStorage.setItem(KEY_DISPLAY_NAME, profileInfo.displayname); + } else { + window.localStorage.removeItem(KEY_DISPLAY_NAME); + } + if (profileInfo.avatar_url) { + window.localStorage.setItem(KEY_AVATAR_URL, profileInfo.avatar_url); + } else { + window.localStorage.removeItem(KEY_AVATAR_URL); + } await this.updateState({displayName: profileInfo.displayname, avatarUrl: profileInfo.avatar_url}); }; From 70e0b77fc4db3f9ac6a83b903e15fa25fa0be907 Mon Sep 17 00:00:00 2001 From: Jaiwanth Date: Fri, 19 Mar 2021 21:12:47 +0530 Subject: [PATCH 33/35] Changed invite phrases in context menu and invite dialog --- src/components/views/dialogs/InviteDialog.tsx | 4 +++- src/components/views/rooms/RoomTile.tsx | 2 +- src/i18n/strings/en_EN.json | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index 9aef421d5a..de0b5b237b 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -1256,7 +1256,9 @@ export default class InviteDialog extends React.PureComponent { {canInvite ? ( ) : null} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 07d292a0e7..34a346fef0 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1601,6 +1601,7 @@ "Favourited": "Favourited", "Favourite": "Favourite", "Low Priority": "Low Priority", + "Invite People": "Invite People", "Leave Room": "Leave Room", "Room options": "Room options", "%(count)s unread messages including mentions.|other": "%(count)s unread messages including mentions.", @@ -2201,6 +2202,7 @@ "Go": "Go", "Invite to %(spaceName)s": "Invite to %(spaceName)s", "Unnamed Space": "Unnamed Space", + "Invite to %(roomName)s": "Invite to %(roomName)s", "Invite someone using their name, email address, username (like ) or share this space.": "Invite someone using their name, email address, username (like ) or share this space.", "Invite someone using their name, username (like ) or share this space.": "Invite someone using their name, username (like ) or share this space.", "Invite someone using their name, email address, username (like ) or share this room.": "Invite someone using their name, email address, username (like ) or share this room.", From 495cbadb08f7ab9cf7f961459d3dc843297e9faf Mon Sep 17 00:00:00 2001 From: Jaiwanth Date: Fri, 19 Mar 2021 22:46:19 +0530 Subject: [PATCH 34/35] Update src/components/views/rooms/RoomTile.tsx --- src/components/views/rooms/RoomTile.tsx | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/components/views/rooms/RoomTile.tsx b/src/components/views/rooms/RoomTile.tsx index 7eaad9e204..79db460275 100644 --- a/src/components/views/rooms/RoomTile.tsx +++ b/src/components/views/rooms/RoomTile.tsx @@ -464,16 +464,8 @@ export default class RoomTile extends React.PureComponent { const isLowPriority = roomTags.includes(DefaultTagID.LowPriority); const lowPriorityLabel = _t("Low Priority"); - const inRoom = this.props.room.getMyMembership() === "join"; const userId = MatrixClientPeg.get().getUserId(); - let canInvite = inRoom; - const powerLevels = this.props.room.currentState - .getStateEvents("m.room.power_levels", "") - ?.getContent(); - const me = this.props.room.getMember(userId); - if (powerLevels && me && powerLevels.invite > me.powerLevel) { - canInvite = false; - } + const canInvite = this.props.room.canInvite(userId); contextMenu = Date: Sun, 21 Mar 2021 14:11:45 +0200 Subject: [PATCH 35/35] fix make btns in verify dailog respect system font --- res/css/_common.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/_common.scss b/res/css/_common.scss index 36a81e6651..0093bde0ab 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -395,6 +395,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus { border: 1px solid $accent-color; color: $accent-color; background-color: $button-secondary-bg-color; + font-family: inherit; } .mx_Dialog button:last-child {