): void => {
this.setState({
- shouldErase: ev.target.checked,
+ shouldErase: ev.currentTarget.checked,
// Disable the auth form because we're going to have to reinitialize the auth
// information. We do this because we can't modify the parameters in the UIA
@@ -123,14 +139,14 @@ export default class DeactivateAccountDialog extends React.Component {
});
// As mentioned above, set up for auth again to get updated UIA session info
- this._initAuth(/* shouldErase= */ev.target.checked);
+ this.initAuth(/* shouldErase= */ev.currentTarget.checked);
};
- _onCancel() {
+ private onCancel(): void {
this.props.onFinished(false);
}
- _initAuth(shouldErase) {
+ private initAuth(shouldErase: boolean): void {
MatrixClientPeg.get().deactivateAccount(null, shouldErase).then(r => {
// If we got here, oops. The server didn't require any auth.
// Our application lifecycle will catch the error and do the logout bits.
@@ -148,7 +164,7 @@ export default class DeactivateAccountDialog extends React.Component {
});
}
- render() {
+ public render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
let error = null;
@@ -166,9 +182,9 @@ export default class DeactivateAccountDialog extends React.Component {
@@ -214,7 +230,7 @@ export default class DeactivateAccountDialog extends React.Component {
{_t(
"Please forget all messages I have sent when my account is deactivated " +
@@ -235,7 +251,3 @@ export default class DeactivateAccountDialog extends React.Component {
);
}
}
-
-DeactivateAccountDialog.propTypes = {
- onFinished: PropTypes.func.isRequired,
-};
From a030c1270a844c40a8120cd41bd209ac4707c6ce Mon Sep 17 00:00:00 2001
From: Germain Souquet
Date: Mon, 14 Jun 2021 21:55:47 +0100
Subject: [PATCH 28/61] Migrate ErrorDialog to TypeScript
---
.../{ErrorDialog.js => ErrorDialog.tsx} | 34 +++++++++----------
1 file changed, 17 insertions(+), 17 deletions(-)
rename src/components/views/dialogs/{ErrorDialog.js => ErrorDialog.tsx} (81%)
diff --git a/src/components/views/dialogs/ErrorDialog.js b/src/components/views/dialogs/ErrorDialog.tsx
similarity index 81%
rename from src/components/views/dialogs/ErrorDialog.js
rename to src/components/views/dialogs/ErrorDialog.tsx
index 5197c68b5a..d50ec7bf36 100644
--- a/src/components/views/dialogs/ErrorDialog.js
+++ b/src/components/views/dialogs/ErrorDialog.tsx
@@ -26,37 +26,37 @@ limitations under the License.
*/
import React from 'react';
-import PropTypes from 'prop-types';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler';
import {replaceableComponent} from "../../../utils/replaceableComponent";
-@replaceableComponent("views.dialogs.ErrorDialog")
-export default class ErrorDialog extends React.Component {
- static propTypes = {
- title: PropTypes.string,
- description: PropTypes.oneOfType([
- PropTypes.element,
- PropTypes.string,
- ]),
- button: PropTypes.string,
- focus: PropTypes.bool,
- onFinished: PropTypes.func.isRequired,
- headerImage: PropTypes.string,
- };
+interface IProps {
+ onFinished: (success: boolean) => void;
+ title?: string;
+ description?: React.ReactNode;
+ button?: string;
+ focus?: boolean;
+ headerImage?: string;
+}
- static defaultProps = {
+interface IState {
+ onFinished: (success: boolean) => void;
+}
+
+@replaceableComponent("views.dialogs.ErrorDialog")
+export default class ErrorDialog extends React.Component {
+ public static defaultProps = {
focus: true,
title: null,
description: null,
button: null,
};
- onClick = () => {
+ private onClick = () => {
this.props.onFinished(true);
};
- render() {
+ public render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
return (
Date: Mon, 14 Jun 2021 23:42:36 +0100
Subject: [PATCH 29/61] Migrate UserSettingsDialog to TypeScript
---
src/components/structures/SpaceRoomView.tsx | 4 +-
src/components/structures/UserMenu.tsx | 6 +-
.../views/dialogs/BetaFeedbackDialog.tsx | 4 +-
...ttingsDialog.js => UserSettingsDialog.tsx} | 75 ++++++++++---------
src/components/views/right_panel/UserInfo.tsx | 4 +-
.../tabs/user/HelpUserSettingsTab.tsx | 2 +-
.../views/spaces/SpaceCreateMenu.tsx | 4 +-
src/toasts/UnverifiedSessionToast.ts | 4 +-
8 files changed, 55 insertions(+), 48 deletions(-)
rename src/components/views/dialogs/{UserSettingsDialog.js => UserSettingsDialog.tsx} (76%)
diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx
index 276f4ae6ca..907a0e8873 100644
--- a/src/components/structures/SpaceRoomView.tsx
+++ b/src/components/structures/SpaceRoomView.tsx
@@ -59,7 +59,7 @@ import IconizedContextMenu, {
} from "../views/context_menus/IconizedContextMenu";
import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton";
import {BetaPill} from "../views/beta/BetaCard";
-import {USER_LABS_TAB} from "../views/dialogs/UserSettingsDialog";
+import { USER_TAB } from "../views/dialogs/UserSettingsDialog";
import SettingsStore from "../../settings/SettingsStore";
import dis from "../../dispatcher/dispatcher";
import Modal from "../../Modal";
@@ -165,7 +165,7 @@ const SpaceInfo = ({ space }) => {
const onBetaClick = () => {
defaultDispatcher.dispatch({
action: Action.ViewUserSettings,
- initialTabId: USER_LABS_TAB,
+ initialTabId: USER_TAB.LABS,
});
};
diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx
index 6a449cf1a2..d942c71c4a 100644
--- a/src/components/structures/UserMenu.tsx
+++ b/src/components/structures/UserMenu.tsx
@@ -26,7 +26,7 @@ import { ActionPayload } from "../../dispatcher/payloads";
import { Action } from "../../dispatcher/actions";
import { _t } from "../../languageHandler";
import { ContextMenuButton } from "./ContextMenu";
-import { USER_NOTIFICATIONS_TAB, USER_SECURITY_TAB } from "../views/dialogs/UserSettingsDialog";
+import { USER_TAB } from "../views/dialogs/UserSettingsDialog";
import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
import FeedbackDialog from "../views/dialogs/FeedbackDialog";
import Modal from "../../Modal";
@@ -408,12 +408,12 @@ export default class UserMenu extends React.Component {
this.onSettingsOpen(e, USER_NOTIFICATIONS_TAB)}
+ onClick={(e) => this.onSettingsOpen(e, USER_TAB.NOTIFICATIONS)}
/>
this.onSettingsOpen(e, USER_SECURITY_TAB)}
+ onClick={(e) => this.onSettingsOpen(e, USER_TAB.SECURITY)}
/>
= ({featureId, onFinished}) => {
onFinished(false);
defaultDispatcher.dispatch({
action: Action.ViewUserSettings,
- initialTabId: USER_LABS_TAB,
+ initialTabId: USER_TAB.LABS,
});
}}>
{ _t("To leave the beta, visit your settings.") }
diff --git a/src/components/views/dialogs/UserSettingsDialog.js b/src/components/views/dialogs/UserSettingsDialog.tsx
similarity index 76%
rename from src/components/views/dialogs/UserSettingsDialog.js
rename to src/components/views/dialogs/UserSettingsDialog.tsx
index fe29b85aea..921aece7f4 100644
--- a/src/components/views/dialogs/UserSettingsDialog.js
+++ b/src/components/views/dialogs/UserSettingsDialog.tsx
@@ -16,7 +16,6 @@ limitations under the License.
*/
import React from 'react';
-import PropTypes from 'prop-types';
import TabbedView, {Tab} from "../../structures/TabbedView";
import {_t, _td} from "../../../languageHandler";
import GeneralUserSettingsTab from "../settings/tabs/user/GeneralUserSettingsTab";
@@ -35,41 +34,49 @@ import MjolnirUserSettingsTab from "../settings/tabs/user/MjolnirUserSettingsTab
import {UIFeature} from "../../../settings/UIFeature";
import {replaceableComponent} from "../../../utils/replaceableComponent";
-export const USER_GENERAL_TAB = "USER_GENERAL_TAB";
-export const USER_APPEARANCE_TAB = "USER_APPEARANCE_TAB";
-export const USER_FLAIR_TAB = "USER_FLAIR_TAB";
-export const USER_NOTIFICATIONS_TAB = "USER_NOTIFICATIONS_TAB";
-export const USER_PREFERENCES_TAB = "USER_PREFERENCES_TAB";
-export const USER_VOICE_TAB = "USER_VOICE_TAB";
-export const USER_SECURITY_TAB = "USER_SECURITY_TAB";
-export const USER_LABS_TAB = "USER_LABS_TAB";
-export const USER_MJOLNIR_TAB = "USER_MJOLNIR_TAB";
-export const USER_HELP_TAB = "USER_HELP_TAB";
+export enum USER_TAB {
+ GENERAL = "USER_GENERAL_TAB",
+ APPEARANCE = "USER_APPEARANCE_TAB",
+ FLAIR = "USER_FLAIR_TAB",
+ NOTIFICATIONS = "USER_NOTIFICATIONS_TAB",
+ PREFERENCES = "USER_PREFERENCES_TAB",
+ VOICE = "USER_VOICE_TAB",
+ SECURITY = "USER_SECURITY_TAB",
+ LABS = "USER_LABS_TAB",
+ MJOLNIR = "USER_MJOLNIR_TAB",
+ HELP = "USER_HELP_TAB",
+}
+
+interface IProps {
+ onFinished: (success: boolean) => void;
+ initialTabId?: string;
+}
+
+interface IState {
+ mjolnirEnabled: boolean;
+}
@replaceableComponent("views.dialogs.UserSettingsDialog")
-export default class UserSettingsDialog extends React.Component {
- static propTypes = {
- onFinished: PropTypes.func.isRequired,
- initialTabId: PropTypes.string,
- };
+export default class UserSettingsDialog extends React.Component {
+ private mjolnirWatcher: string;
- constructor() {
- super();
+ constructor(props) {
+ super(props);
this.state = {
mjolnirEnabled: SettingsStore.getValue("feature_mjolnir"),
};
}
- componentDidMount(): void {
- this._mjolnirWatcher = SettingsStore.watchSetting("feature_mjolnir", null, this._mjolnirChanged.bind(this));
+ public componentDidMount(): void {
+ this.mjolnirWatcher = SettingsStore.watchSetting("feature_mjolnir", null, this.mjolnirChanged);
}
- componentWillUnmount(): void {
- SettingsStore.unwatchSetting(this._mjolnirWatcher);
+ public componentWillUnmount(): void {
+ SettingsStore.unwatchSetting(this.mjolnirWatcher);
}
- _mjolnirChanged(settingName, roomId, atLevel, newValue) {
+ private mjolnirChanged = (settingName, roomId, atLevel, newValue: boolean) => {
// We can cheat because we know what levels a feature is tracked at, and how it is tracked
this.setState({mjolnirEnabled: newValue});
}
@@ -78,33 +85,33 @@ export default class UserSettingsDialog extends React.Component {
const tabs = [];
tabs.push(new Tab(
- USER_GENERAL_TAB,
+ USER_TAB.GENERAL,
_td("General"),
"mx_UserSettingsDialog_settingsIcon",
,
));
tabs.push(new Tab(
- USER_APPEARANCE_TAB,
+ USER_TAB.APPEARANCE,
_td("Appearance"),
"mx_UserSettingsDialog_appearanceIcon",
,
));
if (SettingsStore.getValue(UIFeature.Flair)) {
tabs.push(new Tab(
- USER_FLAIR_TAB,
+ USER_TAB.FLAIR,
_td("Flair"),
"mx_UserSettingsDialog_flairIcon",
,
));
}
tabs.push(new Tab(
- USER_NOTIFICATIONS_TAB,
+ USER_TAB.NOTIFICATIONS,
_td("Notifications"),
"mx_UserSettingsDialog_bellIcon",
,
));
tabs.push(new Tab(
- USER_PREFERENCES_TAB,
+ USER_TAB.PREFERENCES,
_td("Preferences"),
"mx_UserSettingsDialog_preferencesIcon",
,
@@ -112,7 +119,7 @@ export default class UserSettingsDialog extends React.Component {
if (SettingsStore.getValue(UIFeature.Voip)) {
tabs.push(new Tab(
- USER_VOICE_TAB,
+ USER_TAB.VOICE,
_td("Voice & Video"),
"mx_UserSettingsDialog_voiceIcon",
,
@@ -120,7 +127,7 @@ export default class UserSettingsDialog extends React.Component {
}
tabs.push(new Tab(
- USER_SECURITY_TAB,
+ USER_TAB.SECURITY,
_td("Security & Privacy"),
"mx_UserSettingsDialog_securityIcon",
,
@@ -130,7 +137,7 @@ export default class UserSettingsDialog extends React.Component {
|| SettingsStore.getFeatureSettingNames().some(k => SettingsStore.getBetaInfo(k))
) {
tabs.push(new Tab(
- USER_LABS_TAB,
+ USER_TAB.LABS,
_td("Labs"),
"mx_UserSettingsDialog_labsIcon",
,
@@ -138,17 +145,17 @@ export default class UserSettingsDialog extends React.Component {
}
if (this.state.mjolnirEnabled) {
tabs.push(new Tab(
- USER_MJOLNIR_TAB,
+ USER_TAB.MJOLNIR,
_td("Ignored users"),
"mx_UserSettingsDialog_mjolnirIcon",
,
));
}
tabs.push(new Tab(
- USER_HELP_TAB,
+ USER_TAB.HELP,
_td("Help & About"),
"mx_UserSettingsDialog_helpIcon",
- ,
+ this.props.onFinished(true)} />,
));
return tabs;
diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx
index d6c97f9cf2..ce5a96c8a3 100644
--- a/src/components/views/right_panel/UserInfo.tsx
+++ b/src/components/views/right_panel/UserInfo.tsx
@@ -48,7 +48,7 @@ import EncryptionPanel from "./EncryptionPanel";
import { useAsyncMemo } from '../../../hooks/useAsyncMemo';
import { legacyVerifyUser, verifyDevice, verifyUser } from '../../../verification';
import { Action } from "../../../dispatcher/actions";
-import { USER_SECURITY_TAB } from "../dialogs/UserSettingsDialog";
+import { USER_TAB } from "../dialogs/UserSettingsDialog";
import { useIsEncrypted } from "../../../hooks/useIsEncrypted";
import BaseCard from "./BaseCard";
import { E2EStatus } from "../../../utils/ShieldUtils";
@@ -1381,7 +1381,7 @@ const BasicUserInfo: React.FC<{
{
dis.dispatch({
action: Action.ViewUserSettings,
- initialTabId: USER_SECURITY_TAB,
+ initialTabId: USER_TAB.SECURITY,
});
}}>
{ _t("Edit devices") }
diff --git a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx
index 3fa0be478c..beff033001 100644
--- a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx
+++ b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx
@@ -32,7 +32,7 @@ import * as ContextMenu from "../../../../structures/ContextMenu";
import { toRightOf } from "../../../../structures/ContextMenu";
interface IProps {
- closeSettingsFn: () => {};
+ closeSettingsFn: () => void;
}
interface IState {
diff --git a/src/components/views/spaces/SpaceCreateMenu.tsx b/src/components/views/spaces/SpaceCreateMenu.tsx
index 0ebf511018..29be03eaa4 100644
--- a/src/components/views/spaces/SpaceCreateMenu.tsx
+++ b/src/components/views/spaces/SpaceCreateMenu.tsx
@@ -29,7 +29,7 @@ import AccessibleButton from "../elements/AccessibleButton";
import {BetaPill} from "../beta/BetaCard";
import defaultDispatcher from "../../../dispatcher/dispatcher";
import {Action} from "../../../dispatcher/actions";
-import {USER_LABS_TAB} from "../dialogs/UserSettingsDialog";
+import { USER_TAB } from "../dialogs/UserSettingsDialog";
import Field from "../elements/Field";
import withValidation from "../elements/Validation";
import {SpaceFeedbackPrompt} from "../../structures/SpaceRoomView";
@@ -222,7 +222,7 @@ const SpaceCreateMenu = ({ onFinished }) => {
onFinished();
defaultDispatcher.dispatch({
action: Action.ViewUserSettings,
- initialTabId: USER_LABS_TAB,
+ initialTabId: USER_TAB.LABS,
});
}} />
{ body }
diff --git a/src/toasts/UnverifiedSessionToast.ts b/src/toasts/UnverifiedSessionToast.ts
index c856d39d1f..8e3fa7c8a7 100644
--- a/src/toasts/UnverifiedSessionToast.ts
+++ b/src/toasts/UnverifiedSessionToast.ts
@@ -21,7 +21,7 @@ import DeviceListener from '../DeviceListener';
import ToastStore from "../stores/ToastStore";
import GenericToast from "../components/views/toasts/GenericToast";
import { Action } from "../dispatcher/actions";
-import { USER_SECURITY_TAB } from "../components/views/dialogs/UserSettingsDialog";
+import { USER_TAB } from "../components/views/dialogs/UserSettingsDialog";
function toastKey(deviceId: string) {
return "unverified_session_" + deviceId;
@@ -34,7 +34,7 @@ export const showToast = async (deviceId: string) => {
DeviceListener.sharedInstance().dismissUnverifiedSessions([deviceId]);
dis.dispatch({
action: Action.ViewUserSettings,
- initialTabId: USER_SECURITY_TAB,
+ initialTabId: USER_TAB.SECURITY,
});
};
From 75151b7a6c8bc690fe38c145ab77d27000438ad5 Mon Sep 17 00:00:00 2001
From: Germain Souquet
Date: Mon, 14 Jun 2021 23:50:41 +0100
Subject: [PATCH 30/61] Migrate TermsDialog to TypeScript
---
.../{TermsDialog.js => TermsDialog.tsx} | 100 ++++++++++--------
1 file changed, 53 insertions(+), 47 deletions(-)
rename src/components/views/dialogs/{TermsDialog.js => TermsDialog.tsx} (72%)
diff --git a/src/components/views/dialogs/TermsDialog.js b/src/components/views/dialogs/TermsDialog.tsx
similarity index 72%
rename from src/components/views/dialogs/TermsDialog.js
rename to src/components/views/dialogs/TermsDialog.tsx
index e8625ec6cb..ace5316323 100644
--- a/src/components/views/dialogs/TermsDialog.js
+++ b/src/components/views/dialogs/TermsDialog.tsx
@@ -16,22 +16,21 @@ limitations under the License.
import url from 'url';
import React from 'react';
-import PropTypes from 'prop-types';
import * as sdk from '../../../index';
import { _t, pickBestLanguage } from '../../../languageHandler';
import {replaceableComponent} from "../../../utils/replaceableComponent";
-import {SERVICE_TYPES} from "matrix-js-sdk/src/service-types";
+import { SERVICE_TYPES } from "matrix-js-sdk/src/service-types";
-class TermsCheckbox extends React.PureComponent {
- static propTypes = {
- onChange: PropTypes.func.isRequired,
- url: PropTypes.string.isRequired,
- checked: PropTypes.bool.isRequired,
- }
+interface ITermsCheckboxProps {
+ onChange: (url: string, checked: boolean) => void;
+ url: string;
+ checked: boolean;
+}
- onChange = (ev) => {
- this.props.onChange(this.props.url, ev.target.checked);
+class TermsCheckbox extends React.PureComponent {
+ private onChange = (ev: React.FormEvent): void => {
+ this.props.onChange(this.props.url, ev.currentTarget.checked);
}
render() {
@@ -42,30 +41,34 @@ class TermsCheckbox extends React.PureComponent {
}
}
+interface ITermsDialogProps {
+ /**
+ * Array of [Service, policies] pairs, where policies is the response from the
+ * /terms endpoint for that service
+ */
+ policiesAndServicePairs: any[],
+
+ /**
+ * urls that the user has already agreed to
+ */
+ agreedUrls?: string[],
+
+ /**
+ * Called with:
+ * * success {bool} True if the user accepted any douments, false if cancelled
+ * * agreedUrls {string[]} List of agreed URLs
+ */
+ onFinished: (success: boolean, agreedUrls?: string[]) => void,
+}
+
+interface IState {
+ agreedUrls: any;
+}
+
@replaceableComponent("views.dialogs.TermsDialog")
-export default class TermsDialog extends React.PureComponent {
- static propTypes = {
- /**
- * Array of [Service, policies] pairs, where policies is the response from the
- * /terms endpoint for that service
- */
- policiesAndServicePairs: PropTypes.array.isRequired,
-
- /**
- * urls that the user has already agreed to
- */
- agreedUrls: PropTypes.arrayOf(PropTypes.string),
-
- /**
- * Called with:
- * * success {bool} True if the user accepted any douments, false if cancelled
- * * agreedUrls {string[]} List of agreed URLs
- */
- onFinished: PropTypes.func.isRequired,
- }
-
+export default class TermsDialog extends React.PureComponent {
constructor(props) {
- super();
+ super(props);
this.state = {
// url -> boolean
agreedUrls: {},
@@ -75,15 +78,15 @@ export default class TermsDialog extends React.PureComponent {
}
}
- _onCancelClick = () => {
+ private onCancelClick = (): void => {
this.props.onFinished(false);
}
- _onNextClick = () => {
+ private onNextClick = (): void => {
this.props.onFinished(true, Object.keys(this.state.agreedUrls).filter((url) => this.state.agreedUrls[url]));
}
- _nameForServiceType(serviceType, host) {
+ private nameForServiceType(serviceType: SERVICE_TYPES, host: string): JSX.Element {
switch (serviceType) {
case SERVICE_TYPES.IS:
return {_t("Identity Server")}
({host})
;
@@ -92,7 +95,7 @@ export default class TermsDialog extends React.PureComponent {
}
}
- _summaryForServiceType(serviceType) {
+ private summaryForServiceType(serviceType: SERVICE_TYPES): JSX.Element {
switch (serviceType) {
case SERVICE_TYPES.IS:
return
@@ -107,13 +110,13 @@ export default class TermsDialog extends React.PureComponent {
}
}
- _onTermsCheckboxChange = (url, checked) => {
+ private onTermsCheckboxChange = (url: string, checked: boolean) => {
this.setState({
agreedUrls: Object.assign({}, this.state.agreedUrls, { [url]: checked }),
});
}
- render() {
+ public render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
@@ -128,8 +131,8 @@ export default class TermsDialog extends React.PureComponent {
let serviceName;
let summary;
if (i === 0) {
- serviceName = this._nameForServiceType(policiesAndService.service.serviceType, parsedBaseUrl.host);
- summary = this._summaryForServiceType(
+ serviceName = this.nameForServiceType(policiesAndService.service.serviceType, parsedBaseUrl.host);
+ summary = this.summaryForServiceType(
policiesAndService.service.serviceType,
);
}
@@ -137,12 +140,15 @@ export default class TermsDialog extends React.PureComponent {
rows.push(
{serviceName} |
{summary} |
- {termDoc[termsLang].name}
-
- |
+
+ {termDoc[termsLang].name}
+
+
+
+ |
|
);
@@ -176,7 +182,7 @@ export default class TermsDialog extends React.PureComponent {
return (
From b2f20e052df53cd1a992ab0621a9d723f3891336 Mon Sep 17 00:00:00 2001
From: Germain Souquet
Date: Mon, 14 Jun 2021 23:51:38 +0100
Subject: [PATCH 31/61] remove unused import
---
src/components/views/dialogs/ConfirmWipeDeviceDialog.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/components/views/dialogs/ConfirmWipeDeviceDialog.tsx b/src/components/views/dialogs/ConfirmWipeDeviceDialog.tsx
index 6911c845fb..d95b1fe358 100644
--- a/src/components/views/dialogs/ConfirmWipeDeviceDialog.tsx
+++ b/src/components/views/dialogs/ConfirmWipeDeviceDialog.tsx
@@ -15,7 +15,6 @@ limitations under the License.
*/
import React from 'react';
-import PropTypes from 'prop-types';
import {_t} from "../../../languageHandler";
import * as sdk from "../../../index";
import {replaceableComponent} from "../../../utils/replaceableComponent";
From 07bdaeaf704b02569edfc3c6a33de75923bdbee2 Mon Sep 17 00:00:00 2001
From: Germain Souquet
Date: Mon, 14 Jun 2021 23:55:14 +0100
Subject: [PATCH 32/61] Fix mjolnir private chat enum
---
src/mjolnir/Mjolnir.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/mjolnir/Mjolnir.ts b/src/mjolnir/Mjolnir.ts
index 891438bbb9..71d63f650c 100644
--- a/src/mjolnir/Mjolnir.ts
+++ b/src/mjolnir/Mjolnir.ts
@@ -20,6 +20,7 @@ import SettingsStore from "../settings/SettingsStore";
import {_t} from "../languageHandler";
import dis from "../dispatcher/dispatcher";
import {SettingLevel} from "../settings/SettingLevel";
+import { Preset } from "../createRoom";
// TODO: Move this and related files to the js-sdk or something once finalized.
@@ -86,7 +87,7 @@ export class Mjolnir {
const resp = await MatrixClientPeg.get().createRoom({
name: _t("My Ban List"),
topic: _t("This is your list of users/servers you have blocked - don't leave the room!"),
- preset: "private_chat",
+ preset: Preset.PrivateChat,
});
personalRoomId = resp['room_id'];
await SettingsStore.setValue(
From 2e6dab0bcd93cfc6e8362423218372767572ae63 Mon Sep 17 00:00:00 2001
From: Germain Souquet
Date: Tue, 15 Jun 2021 00:01:05 +0100
Subject: [PATCH 33/61] change parameter to use preset enum
---
src/components/views/dialogs/CreateRoomDialog.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/views/dialogs/CreateRoomDialog.tsx b/src/components/views/dialogs/CreateRoomDialog.tsx
index cce6b6c34c..614ed4f645 100644
--- a/src/components/views/dialogs/CreateRoomDialog.tsx
+++ b/src/components/views/dialogs/CreateRoomDialog.tsx
@@ -72,7 +72,7 @@ export default class CreateRoomDialog extends React.Component {
canChangeEncryption: true,
};
- MatrixClientPeg.get().doesServerForceEncryptionForPreset("private")
+ MatrixClientPeg.get().doesServerForceEncryptionForPreset(Preset.PrivateChat)
.then(isForced => this.setState({ canChangeEncryption: !isForced }));
}
From 19cae421619021d2b1e453c43490e5ae0426a62b Mon Sep 17 00:00:00 2001
From: Germain Souquet
Date: Tue, 15 Jun 2021 15:06:00 +0100
Subject: [PATCH 34/61] Benchmark multiple common user scenario
---
src/performance/entry-names.ts | 10 +++++-----
.../end-to-end-tests/src/scenarios/e2e-encryption.js | 8 ++++++--
test/end-to-end-tests/src/usecases/create-room.js | 6 ++++++
test/end-to-end-tests/src/usecases/join.js | 4 ++++
test/end-to-end-tests/src/usecases/verify.js | 2 +-
test/end-to-end-tests/src/util.js | 12 ++++++++++++
test/end-to-end-tests/start.js | 4 ++++
7 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/src/performance/entry-names.ts b/src/performance/entry-names.ts
index effd9506f6..6cb193b1b1 100644
--- a/src/performance/entry-names.ts
+++ b/src/performance/entry-names.ts
@@ -37,17 +37,17 @@ export enum PerformanceEntryNames {
SWITCH_ROOM = "mx_SwithRoom",
JUMP_TO_ROOM = "mx_JumpToRoom",
- JOIN_ROOM = "mx_JoinRoom",
- CREATE_DM = "mx_CreateDM",
+ JOIN_ROOM = "mx_JoinRoom", // ✅
+ CREATE_DM = "mx_CreateDM", // ✅
PEEK_ROOM = "mx_PeekRoom",
/**
* User
*/
- VERIFY_E2EE_USER = "mx_VerifyE2EEUser",
- LOGIN = "mx_Login",
- REGISTER = "mx_Register",
+ VERIFY_E2EE_USER = "mx_VerifyE2EEUser", // ✅
+ LOGIN = "mx_Login", // ✅
+ REGISTER = "mx_Register", // ✅
/**
* VoIP
diff --git a/test/end-to-end-tests/src/scenarios/e2e-encryption.js b/test/end-to-end-tests/src/scenarios/e2e-encryption.js
index 20e8af2947..ed5c598032 100644
--- a/test/end-to-end-tests/src/scenarios/e2e-encryption.js
+++ b/test/end-to-end-tests/src/scenarios/e2e-encryption.js
@@ -20,9 +20,11 @@ const acceptInvite = require('../usecases/accept-invite');
const {receiveMessage} = require('../usecases/timeline');
const {createDm} = require('../usecases/create-room');
const {checkRoomSettings} = require('../usecases/room-settings');
-const {startSasVerifcation, acceptSasVerification} = require('../usecases/verify');
+const {startSasVerification, acceptSasVerification} = require('../usecases/verify');
const { setupSecureBackup } = require('../usecases/security');
const assert = require('assert');
+const { measureStart, measureStop } = require('../util');
+
module.exports = async function e2eEncryptionScenarios(alice, bob) {
console.log(" creating an e2e encrypted DM and join through invite:");
@@ -31,12 +33,14 @@ module.exports = async function e2eEncryptionScenarios(alice, bob) {
await acceptInvite(alice, 'bob');
// do sas verifcation
bob.log.step(`starts SAS verification with ${alice.username}`);
- const bobSasPromise = startSasVerifcation(bob, alice.username);
+ await measureStart(bob, "mx_VerifyE2EEUser");
+ const bobSasPromise = startSasVerification(bob, alice.username);
const aliceSasPromise = acceptSasVerification(alice, bob.username);
// wait in parallel, so they don't deadlock on each other
// the logs get a bit messy here, but that's fine enough for debugging (hopefully)
const [bobSas, aliceSas] = await Promise.all([bobSasPromise, aliceSasPromise]);
assert.deepEqual(bobSas, aliceSas);
+ await measureStop(bob, "mx_VerifyE2EEUser"); //
bob.log.done(`done (match for ${bobSas.join(", ")})`);
const aliceMessage = "Guess what I just heard?!";
await sendMessage(alice, aliceMessage);
diff --git a/test/end-to-end-tests/src/usecases/create-room.js b/test/end-to-end-tests/src/usecases/create-room.js
index 3830e3e0da..36b9ed21ec 100644
--- a/test/end-to-end-tests/src/usecases/create-room.js
+++ b/test/end-to-end-tests/src/usecases/create-room.js
@@ -15,6 +15,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
+const { measureStart, measureStop } = require('../util');
+
async function openRoomDirectory(session) {
const roomDirectoryButton = await session.query('.mx_LeftPanel_exploreButton');
await roomDirectoryButton.click();
@@ -52,6 +54,8 @@ async function createRoom(session, roomName, encrypted=false) {
async function createDm(session, invitees) {
session.log.step(`creates DM with ${JSON.stringify(invitees)}`);
+ await measureStart(session, "mx_CreateDM");
+
const dmsSublist = await findSublist(session, "people");
const startChatButton = await dmsSublist.$(".mx_RoomSublist_auxButton");
await startChatButton.click();
@@ -76,6 +80,8 @@ async function createDm(session, invitees) {
await session.query('.mx_MessageComposer');
session.log.done();
+
+ await measureStop(session, "mx_CreateDM");
}
module.exports = {openRoomDirectory, findSublist, createRoom, createDm};
diff --git a/test/end-to-end-tests/src/usecases/join.js b/test/end-to-end-tests/src/usecases/join.js
index 655c0be686..cf0f67be44 100644
--- a/test/end-to-end-tests/src/usecases/join.js
+++ b/test/end-to-end-tests/src/usecases/join.js
@@ -16,9 +16,12 @@ limitations under the License.
*/
const {openRoomDirectory} = require('./create-room');
+const { measureStart, measureStop } = require('../util');
+
module.exports = async function join(session, roomName) {
session.log.step(`joins room "${roomName}"`);
+ await measureStart(session, "mx_JoinRoom");
await openRoomDirectory(session);
const roomInput = await session.query('.mx_DirectorySearchBox input');
await session.replaceInputText(roomInput, roomName);
@@ -26,5 +29,6 @@ module.exports = async function join(session, roomName) {
const joinFirstLink = await session.query('.mx_RoomDirectory_table .mx_RoomDirectory_join .mx_AccessibleButton');
await joinFirstLink.click();
await session.query('.mx_MessageComposer');
+ await measureStop(session, "mx_JoinRoom");
session.log.done();
};
diff --git a/test/end-to-end-tests/src/usecases/verify.js b/test/end-to-end-tests/src/usecases/verify.js
index ea5b9961a4..a66c8c1b1c 100644
--- a/test/end-to-end-tests/src/usecases/verify.js
+++ b/test/end-to-end-tests/src/usecases/verify.js
@@ -74,7 +74,7 @@ async function doSasVerification(session) {
return sasCodes;
}
-module.exports.startSasVerifcation = async function(session, name) {
+module.exports.startSasVerification = async function(session, name) {
session.log.startGroup("starts verification");
await startVerification(session, name);
diff --git a/test/end-to-end-tests/src/util.js b/test/end-to-end-tests/src/util.js
index cc7391fa9f..854c1f7ad2 100644
--- a/test/end-to-end-tests/src/util.js
+++ b/test/end-to-end-tests/src/util.js
@@ -26,3 +26,15 @@ module.exports.range = function(start, amount, step = 1) {
module.exports.delay = function(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
};
+
+module.exports.measureStart = function(session, name) {
+ return session.page.evaluate(() => {
+ window.mxPerformanceMonitor.start(name);
+ });
+};
+
+module.exports.measureStop = function(session, name) {
+ return session.page.evaluate(() => {
+ window.mxPerformanceMonitor.stop(name);
+ });
+};
diff --git a/test/end-to-end-tests/start.js b/test/end-to-end-tests/start.js
index c1588e848e..04df0c51c0 100644
--- a/test/end-to-end-tests/start.js
+++ b/test/end-to-end-tests/start.js
@@ -88,6 +88,10 @@ async function runTests() {
window.mxPerformanceMonitor.addPerformanceDataCallback({
entryNames: [
window.mxPerformanceEntryNames.REGISTER,
+ window.mxPerformanceEntryNames.LOGIN,
+ window.mxPerformanceEntryNames.JOIN_ROOM,
+ window.mxPerformanceEntryNames.CREATE_DM,
+ window.mxPerformanceEntryNames.VERIFY_E2EE_USER,
],
callback: (events) => {
measurements = JSON.stringify(events);
From adc4bd14c0f360c1bae445e7b13375c2fdc26051 Mon Sep 17 00:00:00 2001
From: Germain Souquet
Date: Tue, 15 Jun 2021 15:19:47 +0100
Subject: [PATCH 35/61] Disable comment-on-alert
---
.github/workflows/develop.yml | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml
index b57a5de8c1..4e8cdff139 100644
--- a/.github/workflows/develop.yml
+++ b/.github/workflows/develop.yml
@@ -31,9 +31,7 @@ jobs:
tool: 'jsperformanceentry'
output-file-path: test/end-to-end-tests/performance-entries.json
fail-on-alert: false
- # Secrets are not passed to fork, the action won't be able to comment
- # for community PRs
- comment-on-alert: ${{ github.repository_owner == 'matrix-org' }}
+ comment-on-alert: false
# Only temporary to monitor where failures occur
alert-comment-cc-users: '@gsouquet'
github-token: ${{ secrets.DEPLOY_GH_PAGES }}
From f1cd086ae2e469071af26ee39af46f598f5c566b Mon Sep 17 00:00:00 2001
From: David Baker
Date: Tue, 15 Jun 2021 16:27:18 +0100
Subject: [PATCH 36/61] Cache virtual/native room mappings when they're created
Otherwise we look up the mapping immediately afterwards and the
remote echo of the account data hasn't come back yet, so we get
nothing.
Fixes "You're already in a call with this person" bug with virtual
rooms.
---
src/VoipUserMapper.ts | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/VoipUserMapper.ts b/src/VoipUserMapper.ts
index d576a5434c..dacb4262bd 100644
--- a/src/VoipUserMapper.ts
+++ b/src/VoipUserMapper.ts
@@ -24,7 +24,9 @@ import { Room } from 'matrix-js-sdk/src/models/room';
// is sip virtual: there could be others in the future.
export default class VoipUserMapper {
- private virtualRoomIdCache = new Set();
+ // We store mappings of virtual -> native room IDs here until the local echo for the
+ // account data arrives.
+ private virtualToNativeRoomIdCache = new Map();
public static sharedInstance(): VoipUserMapper {
if (window.mxVoipUserMapper === undefined) window.mxVoipUserMapper = new VoipUserMapper();
@@ -49,10 +51,20 @@ export default class VoipUserMapper {
native_room: roomId,
});
+ this.virtualToNativeRoomIdCache.set(virtualRoomId, roomId);
+
return virtualRoomId;
}
public nativeRoomForVirtualRoom(roomId: string): string {
+ const cachedNativeRoomId = this.virtualToNativeRoomIdCache.get(roomId);
+ if (cachedNativeRoomId) {
+ console.log(
+ "Returning native room ID " + cachedNativeRoomId + " for virtual room ID " + roomId + " from cache",
+ );
+ return cachedNativeRoomId;
+ }
+
const virtualRoom = MatrixClientPeg.get().getRoom(roomId);
if (!virtualRoom) return null;
const virtualRoomEvent = virtualRoom.getAccountData(VIRTUAL_ROOM_EVENT_TYPE);
@@ -67,7 +79,7 @@ export default class VoipUserMapper {
public isVirtualRoom(room: Room): boolean {
if (this.nativeRoomForVirtualRoom(room.roomId)) return true;
- if (this.virtualRoomIdCache.has(room.roomId)) return true;
+ if (this.virtualToNativeRoomIdCache.has(room.roomId)) return true;
// also look in the create event for the claimed native room ID, which is the only
// way we can recognise a virtual room we've created when it first arrives down
@@ -110,7 +122,7 @@ export default class VoipUserMapper {
// also put this room in the virtual room ID cache so isVirtualRoom return the right answer
// in however long it takes for the echo of setAccountData to come down the sync
- this.virtualRoomIdCache.add(invitedRoom.roomId);
+ this.virtualToNativeRoomIdCache.set(invitedRoom.roomId, nativeRoom.roomId);
}
}
}
From 6ee55bb03c28822bdca14aaaa2730d2bba6ffa9f Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 15 Jun 2021 16:08:33 +0000
Subject: [PATCH 37/61] Bump postcss from 7.0.35 to 7.0.36
Bumps [postcss](https://github.com/postcss/postcss) from 7.0.35 to 7.0.36.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/7.0.35...7.0.36)
---
updated-dependencies:
- dependency-name: postcss
dependency-type: indirect
...
Signed-off-by: dependabot[bot]
---
yarn.lock | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/yarn.lock b/yarn.lock
index 7c232d2aa1..cd4a8b0bd6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6583,9 +6583,9 @@ postcss-value-parser@^4.1.0:
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.35, postcss@^7.0.6:
- version "7.0.35"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24"
- integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==
+ version "7.0.36"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.36.tgz#056f8cffa939662a8f5905950c07d5285644dfcb"
+ integrity sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==
dependencies:
chalk "^2.4.2"
source-map "^0.6.1"
From d13611736a90d69092db8ae227864841ced56ac4 Mon Sep 17 00:00:00 2001
From: Travis Ralston
Date: Tue, 15 Jun 2021 17:24:56 -0600
Subject: [PATCH 38/61] Update MSC number references for voice messages
as per https://github.com/matrix-org/matrix-doc/pull/3245
---
src/components/views/messages/MVoiceOrAudioBody.tsx | 4 +++-
.../views/rooms/VoiceRecordComposerTile.tsx | 11 ++++-------
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/components/views/messages/MVoiceOrAudioBody.tsx b/src/components/views/messages/MVoiceOrAudioBody.tsx
index 0cebcf3440..6d26ef3dcb 100644
--- a/src/components/views/messages/MVoiceOrAudioBody.tsx
+++ b/src/components/views/messages/MVoiceOrAudioBody.tsx
@@ -28,7 +28,9 @@ interface IProps {
@replaceableComponent("views.messages.MVoiceOrAudioBody")
export default class MVoiceOrAudioBody extends React.PureComponent {
public render() {
- const isVoiceMessage = !!this.props.mxEvent.getContent()['org.matrix.msc2516.voice'];
+ // MSC2516 is a legacy identifier. See https://github.com/matrix-org/matrix-doc/pull/3245
+ const isVoiceMessage = !!this.props.mxEvent.getContent()['org.matrix.msc2516.voice']
+ || !!this.props.mxEvent.getContent()['org.matrix.msc3245.voice'];
const voiceMessagesEnabled = SettingsStore.getValue("feature_voice_messages");
if (isVoiceMessage && voiceMessagesEnabled) {
return ;
diff --git a/src/components/views/rooms/VoiceRecordComposerTile.tsx b/src/components/views/rooms/VoiceRecordComposerTile.tsx
index 2102071bf3..20d8c9c5d4 100644
--- a/src/components/views/rooms/VoiceRecordComposerTile.tsx
+++ b/src/components/views/rooms/VoiceRecordComposerTile.tsx
@@ -77,7 +77,8 @@ export default class VoiceRecordComposerTile extends React.PureComponent Math.round(v * 1024)),
},
- "org.matrix.msc2516.voice": {}, // No content, this is a rendering hint
+ "org.matrix.msc3245.voice": {}, // No content, this is a rendering hint
});
await this.disposeRecording();
}
From a5d608f2af12199223711d3e1a473c21c1498259 Mon Sep 17 00:00:00 2001
From: Germain Souquet
Date: Wed, 16 Jun 2021 10:01:23 +0100
Subject: [PATCH 39/61] Keep composer reply when scrolling away from a
highlighted event
---
src/components/structures/RoomView.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx
index fe90d2f873..c0ce6ba4c9 100644
--- a/src/components/structures/RoomView.tsx
+++ b/src/components/structures/RoomView.tsx
@@ -701,6 +701,7 @@ export default class RoomView extends React.Component {
room_id: this.state.room.roomId,
event_id: this.state.initialEventId,
highlighted: false,
+ replyingToEvent: this.state.replyToEvent,
});
}
}
From 069e2e13cf3cc73327027e16d7c2abe1aca106c8 Mon Sep 17 00:00:00 2001
From: Germain Souquet
Date: Wed, 16 Jun 2021 10:01:30 +0100
Subject: [PATCH 40/61] Migrate MessageTimestamp to TypeScript
---
...ssageTimestamp.js => MessageTimestamp.tsx} | 29 ++++++++++---------
1 file changed, 16 insertions(+), 13 deletions(-)
rename src/components/views/messages/{MessageTimestamp.js => MessageTimestamp.tsx} (67%)
diff --git a/src/components/views/messages/MessageTimestamp.js b/src/components/views/messages/MessageTimestamp.tsx
similarity index 67%
rename from src/components/views/messages/MessageTimestamp.js
rename to src/components/views/messages/MessageTimestamp.tsx
index a7f350adcd..8b02f6b38e 100644
--- a/src/components/views/messages/MessageTimestamp.js
+++ b/src/components/views/messages/MessageTimestamp.tsx
@@ -16,20 +16,19 @@ limitations under the License.
*/
import React from 'react';
-import PropTypes from 'prop-types';
-import {formatFullDate, formatTime, formatFullTime} from '../../../DateUtils';
-import {replaceableComponent} from "../../../utils/replaceableComponent";
+import { formatFullDate, formatTime, formatFullTime } from '../../../DateUtils';
+import { replaceableComponent } from "../../../utils/replaceableComponent";
+
+interface IProps {
+ ts: number;
+ showTwelveHour?: boolean;
+ showFullDate?: boolean;
+ showSeconds?: boolean;
+}
@replaceableComponent("views.messages.MessageTimestamp")
-export default class MessageTimestamp extends React.Component {
- static propTypes = {
- ts: PropTypes.number.isRequired,
- showTwelveHour: PropTypes.bool,
- showFullDate: PropTypes.bool,
- showSeconds: PropTypes.bool,
- };
-
- render() {
+export default class MessageTimestamp extends React.Component {
+ public render() {
const date = new Date(this.props.ts);
let timestamp;
if (this.props.showFullDate) {
@@ -41,7 +40,11 @@ export default class MessageTimestamp extends React.Component {
}
return (
-
+
{timestamp}
);
From 9f8d04ab9aa64463998f173bce65a4ec8469fbe7 Mon Sep 17 00:00:00 2001
From: Germain Souquet
Date: Wed, 16 Jun 2021 11:39:04 +0100
Subject: [PATCH 41/61] Fix passing variable down to evaluate context
---
test/end-to-end-tests/src/util.js | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/test/end-to-end-tests/src/util.js b/test/end-to-end-tests/src/util.js
index 854c1f7ad2..5abb110df4 100644
--- a/test/end-to-end-tests/src/util.js
+++ b/test/end-to-end-tests/src/util.js
@@ -28,13 +28,13 @@ module.exports.delay = function(ms) {
};
module.exports.measureStart = function(session, name) {
- return session.page.evaluate(() => {
- window.mxPerformanceMonitor.start(name);
- });
+ return session.page.evaluate(_name => {
+ window.mxPerformanceMonitor.start(_name);
+ }, name);
};
module.exports.measureStop = function(session, name) {
- return session.page.evaluate(() => {
- window.mxPerformanceMonitor.stop(name);
- });
+ return session.page.evaluate(_name => {
+ window.mxPerformanceMonitor.stop(_name);
+ }, name);
};
From deb2e8d679f56e833c2ef6147218fd5d85b005fb Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 16 Jun 2021 12:04:01 +0100
Subject: [PATCH 42/61] Remove unused methods
---
src/components/structures/RoomView.tsx | 6 ------
src/components/views/rooms/AuxPanel.tsx | 10 ----------
2 files changed, 16 deletions(-)
diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx
index fe90d2f873..b6fafbaaf2 100644
--- a/src/components/structures/RoomView.tsx
+++ b/src/components/structures/RoomView.tsx
@@ -705,12 +705,6 @@ export default class RoomView extends React.Component {
}
}
- private onLayoutChange = () => {
- this.setState({
- layout: SettingsStore.getValue("layout"),
- });
- };
-
private onRightPanelStoreUpdate = () => {
this.setState({
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
diff --git a/src/components/views/rooms/AuxPanel.tsx b/src/components/views/rooms/AuxPanel.tsx
index 6d2ae39059..0e3c58dfd4 100644
--- a/src/components/views/rooms/AuxPanel.tsx
+++ b/src/components/views/rooms/AuxPanel.tsx
@@ -96,16 +96,6 @@ export default class AuxPanel extends React.Component {
}
}
- onConferenceNotificationClick = (ev, type) => {
- dis.dispatch({
- action: 'place_call',
- type: type,
- room_id: this.props.room.roomId,
- });
- ev.stopPropagation();
- ev.preventDefault();
- };
-
_rateLimitedUpdate = new RateLimitedFunc(() => {
if (SettingsStore.getValue("feature_state_counters")) {
this.setState({counters: this._computeCounters()});
From e3a6ce13cd98aa5be02cbbe20bd7cb50f1ce259c Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 16 Jun 2021 12:04:37 +0100
Subject: [PATCH 43/61] Fix tight-loop update issue caused by a broken
shouldComponentUpdate
---
src/components/structures/RoomView.tsx | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx
index b6fafbaaf2..1224bdb5ae 100644
--- a/src/components/structures/RoomView.tsx
+++ b/src/components/structures/RoomView.tsx
@@ -80,7 +80,6 @@ import { objectHasDiff } from "../../utils/objects";
import SpaceRoomView from "./SpaceRoomView";
import { IOpts } from "../../createRoom";
import { replaceableComponent } from "../../utils/replaceableComponent";
-import { omit } from 'lodash';
import UIStore from "../../stores/UIStore";
const DEBUG = false;
@@ -572,16 +571,12 @@ export default class RoomView extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
const hasPropsDiff = objectHasDiff(this.props, nextProps);
- // React only shallow comparison and we only want to trigger
- // a component re-render if a room requires an upgrade
- const newUpgradeRecommendation = nextState.upgradeRecommendation || {}
-
- const state = omit(this.state, ['upgradeRecommendation']);
- const newState = omit(nextState, ['upgradeRecommendation'])
+ const { upgradeRecommendation, ...state } = this.state;
+ const { upgradeRecommendation: newUpgradeRecommendation, ...newState } = nextState;
const hasStateDiff =
- objectHasDiff(state, newState) ||
- (newUpgradeRecommendation.needsUpgrade === true)
+ newUpgradeRecommendation?.needsUpgrade !== upgradeRecommendation?.needsUpgrade ||
+ objectHasDiff(state, newState);
return hasPropsDiff || hasStateDiff;
}
From d87325ae6a665fbf9a8d7d6e44b99435cc032b99 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 16 Jun 2021 12:06:41 +0100
Subject: [PATCH 44/61] Small cleanup around the room status bar and auxpanel
to prevent redundant state updates
---
src/components/structures/RoomStatusBar.js | 2 +-
src/components/structures/RoomView.tsx | 14 +++++---------
src/components/views/rooms/AppsDrawer.js | 12 ++++--------
src/components/views/rooms/AuxPanel.tsx | 13 ++++++-------
.../views/rooms/RoomUpgradeWarningBar.js | 2 +-
5 files changed, 17 insertions(+), 26 deletions(-)
diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js
index b2f0c70bd7..7d74229421 100644
--- a/src/components/structures/RoomStatusBar.js
+++ b/src/components/structures/RoomStatusBar.js
@@ -41,7 +41,7 @@ export function getUnsentMessages(room) {
}
@replaceableComponent("structures.RoomStatusBar")
-export default class RoomStatusBar extends React.Component {
+export default class RoomStatusBar extends React.PureComponent {
static propTypes = {
// the room this statusbar is representing.
room: PropTypes.object.isRequired,
diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx
index 1224bdb5ae..d2f90cfa0e 100644
--- a/src/components/structures/RoomView.tsx
+++ b/src/components/structures/RoomView.tsx
@@ -1633,7 +1633,7 @@ export default class RoomView extends React.Component {
let auxPanelMaxHeight = UIStore.instance.windowHeight -
(54 + // height of RoomHeader
36 + // height of the status area
- 51 + // minimum height of the message compmoser
+ 51 + // minimum height of the message composer
120); // amount of desired scrollback
// XXX: this is a bit of a hack and might possibly cause the video to push out the page anyway
@@ -1644,18 +1644,14 @@ export default class RoomView extends React.Component {
};
private onStatusBarVisible = () => {
- if (this.unmounted) return;
- this.setState({
- statusBarVisible: true,
- });
+ if (this.unmounted || this.state.statusBarVisible) return;
+ this.setState({ statusBarVisible: true });
};
private onStatusBarHidden = () => {
// This is currently not desired as it is annoying if it keeps expanding and collapsing
- if (this.unmounted) return;
- this.setState({
- statusBarVisible: false,
- });
+ if (this.unmounted || !this.state.statusBarVisible) return;
+ this.setState({ statusBarVisible: false });
};
/**
diff --git a/src/components/views/rooms/AppsDrawer.js b/src/components/views/rooms/AppsDrawer.js
index 693ec8bc80..0b32d5d1bb 100644
--- a/src/components/views/rooms/AppsDrawer.js
+++ b/src/components/views/rooms/AppsDrawer.js
@@ -82,13 +82,6 @@ export default class AppsDrawer extends React.Component {
this.props.resizeNotifier.off("isResizing", this.onIsResizing);
}
- // TODO: [REACT-WARNING] Replace with appropriate lifecycle event
- // eslint-disable-next-line camelcase
- UNSAFE_componentWillReceiveProps(newProps) {
- // Room has changed probably, update apps
- this._updateApps();
- }
-
onIsResizing = (resizing) => {
// This one is the vertical, ie. change height of apps drawer
this.setState({ resizingVertical: resizing });
@@ -141,7 +134,10 @@ export default class AppsDrawer extends React.Component {
_getAppsHash = (apps) => apps.map(app => app.id).join("~");
componentDidUpdate(prevProps, prevState) {
- if (this._getAppsHash(this.state.apps) !== this._getAppsHash(prevState.apps)) {
+ if (prevProps.userId !== this.props.userId || prevProps.room !== this.props.room) {
+ // Room has changed, update apps
+ this._updateApps();
+ } else if (this._getAppsHash(this.state.apps) !== this._getAppsHash(prevState.apps)) {
this._loadResizerPreferences();
}
}
diff --git a/src/components/views/rooms/AuxPanel.tsx b/src/components/views/rooms/AuxPanel.tsx
index 0e3c58dfd4..f89390ea25 100644
--- a/src/components/views/rooms/AuxPanel.tsx
+++ b/src/components/views/rooms/AuxPanel.tsx
@@ -17,7 +17,6 @@ limitations under the License.
import React from 'react';
import {MatrixClientPeg} from "../../../MatrixClientPeg";
import { Room } from 'matrix-js-sdk/src/models/room'
-import dis from "../../../dispatcher/dispatcher";
import AppsDrawer from './AppsDrawer';
import classNames from 'classnames';
import RateLimitedFunc from '../../../ratelimitedfunc';
@@ -75,12 +74,14 @@ export default class AuxPanel extends React.Component {
componentDidMount() {
const cli = MatrixClientPeg.get();
- cli.on("RoomState.events", this._rateLimitedUpdate);
+ if (SettingsStore.getValue("feature_state_counters")) {
+ cli.on("RoomState.events", this._rateLimitedUpdate);
+ }
}
componentWillUnmount() {
const cli = MatrixClientPeg.get();
- if (cli) {
+ if (cli && SettingsStore.getValue("feature_state_counters")) {
cli.removeListener("RoomState.events", this._rateLimitedUpdate);
}
}
@@ -97,9 +98,7 @@ export default class AuxPanel extends React.Component {
}
_rateLimitedUpdate = new RateLimitedFunc(() => {
- if (SettingsStore.getValue("feature_state_counters")) {
- this.setState({counters: this._computeCounters()});
- }
+ this.setState({ counters: this._computeCounters() });
}, 500);
_computeCounters() {
@@ -215,7 +214,7 @@ export default class AuxPanel extends React.Component {
}
return (
-
+
{ stateViews }
{ appsDrawer }
{ callView }
diff --git a/src/components/views/rooms/RoomUpgradeWarningBar.js b/src/components/views/rooms/RoomUpgradeWarningBar.js
index a2d4f92d35..66e76903eb 100644
--- a/src/components/views/rooms/RoomUpgradeWarningBar.js
+++ b/src/components/views/rooms/RoomUpgradeWarningBar.js
@@ -24,7 +24,7 @@ import {MatrixClientPeg} from "../../../MatrixClientPeg";
import {replaceableComponent} from "../../../utils/replaceableComponent";
@replaceableComponent("views.rooms.RoomUpgradeWarningBar")
-export default class RoomUpgradeWarningBar extends React.Component {
+export default class RoomUpgradeWarningBar extends React.PureComponent {
static propTypes = {
room: PropTypes.object.isRequired,
recommendation: PropTypes.object.isRequired,
From 626d5758207bac8af6fdeeec83d4231a8374ff28 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 16 Jun 2021 12:07:58 +0100
Subject: [PATCH 45/61] tidy AuxPanel TS
---
src/components/views/rooms/AuxPanel.tsx | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/components/views/rooms/AuxPanel.tsx b/src/components/views/rooms/AuxPanel.tsx
index f89390ea25..74609cca13 100644
--- a/src/components/views/rooms/AuxPanel.tsx
+++ b/src/components/views/rooms/AuxPanel.tsx
@@ -15,18 +15,18 @@ limitations under the License.
*/
import React from 'react';
-import {MatrixClientPeg} from "../../../MatrixClientPeg";
+import { MatrixClientPeg } from "../../../MatrixClientPeg";
import { Room } from 'matrix-js-sdk/src/models/room'
import AppsDrawer from './AppsDrawer';
import classNames from 'classnames';
import RateLimitedFunc from '../../../ratelimitedfunc';
import SettingsStore from "../../../settings/SettingsStore";
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
-import {UIFeature} from "../../../settings/UIFeature";
+import { UIFeature } from "../../../settings/UIFeature";
import { ResizeNotifier } from "../../../utils/ResizeNotifier";
import CallViewForRoom from '../voip/CallViewForRoom';
-import {objectHasDiff} from "../../../utils/objects";
-import {replaceableComponent} from "../../../utils/replaceableComponent";
+import { objectHasDiff } from "../../../utils/objects";
+import { replaceableComponent } from "../../../utils/replaceableComponent";
interface IProps {
// js-sdk room object
@@ -68,21 +68,21 @@ export default class AuxPanel extends React.Component {
super(props);
this.state = {
- counters: this._computeCounters(),
+ counters: this.computeCounters(),
};
}
componentDidMount() {
const cli = MatrixClientPeg.get();
if (SettingsStore.getValue("feature_state_counters")) {
- cli.on("RoomState.events", this._rateLimitedUpdate);
+ cli.on("RoomState.events", this.rateLimitedUpdate);
}
}
componentWillUnmount() {
const cli = MatrixClientPeg.get();
if (cli && SettingsStore.getValue("feature_state_counters")) {
- cli.removeListener("RoomState.events", this._rateLimitedUpdate);
+ cli.removeListener("RoomState.events", this.rateLimitedUpdate);
}
}
@@ -97,11 +97,11 @@ export default class AuxPanel extends React.Component {
}
}
- _rateLimitedUpdate = new RateLimitedFunc(() => {
- this.setState({ counters: this._computeCounters() });
+ private rateLimitedUpdate = new RateLimitedFunc(() => {
+ this.setState({ counters: this.computeCounters() });
}, 500);
- _computeCounters() {
+ private computeCounters() {
const counters = [];
if (this.props.room && SettingsStore.getValue("feature_state_counters")) {
From ab964339d2b28af6d89315e65aba66cae20f1769 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 16 Jun 2021 12:11:17 +0100
Subject: [PATCH 46/61] Add another setState skip to prevent redundant state
updates
---
src/components/structures/RoomView.tsx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx
index d2f90cfa0e..2c081314de 100644
--- a/src/components/structures/RoomView.tsx
+++ b/src/components/structures/RoomView.tsx
@@ -1640,7 +1640,9 @@ export default class RoomView extends React.Component {
// but it's better than the video going missing entirely
if (auxPanelMaxHeight < 50) auxPanelMaxHeight = 50;
- this.setState({auxPanelMaxHeight: auxPanelMaxHeight});
+ if (this.state.auxPanelMaxHeight !== auxPanelMaxHeight) {
+ this.setState({ auxPanelMaxHeight });
+ }
};
private onStatusBarVisible = () => {
From 8f02ca8ce958f1df9537bd9d15efd270100a8188 Mon Sep 17 00:00:00 2001
From: "J. Ryan Stinnett"
Date: Wed, 16 Jun 2021 18:00:06 +0100
Subject: [PATCH 47/61] Stop requesting null next replies from the server
A recent change (47e007e08f9bedaf47cf59a63c9bd04219195d76) introduced a
regression where we failed to check whether a reply thread has a next reply.
This meant that we would end up sending `/context/undefined` requests to the
server for every reply thread on every room view.
Fixes https://github.com/vector-im/element-web/issues/17563
Regressed by https://github.com/matrix-org/matrix-react-sdk/pull/6079
---
src/components/views/elements/ReplyThread.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js
index 81ed360b17..a9b24a306b 100644
--- a/src/components/views/elements/ReplyThread.js
+++ b/src/components/views/elements/ReplyThread.js
@@ -297,6 +297,7 @@ export default class ReplyThread extends React.Component {
}
async getEvent(eventId) {
+ if (!eventId) return null;
const event = this.room.findEventById(eventId);
if (event) return event;
From ce57b66c91af59a0d43819e755be9bcfcab48a7c Mon Sep 17 00:00:00 2001
From: Robin Townsend
Date: Wed, 16 Jun 2021 18:17:25 -0400
Subject: [PATCH 48/61] Fix forward dialog message preview display names
Signed-off-by: Robin Townsend
---
src/components/views/dialogs/ForwardDialog.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/components/views/dialogs/ForwardDialog.tsx b/src/components/views/dialogs/ForwardDialog.tsx
index 1c90dca432..a83f3f177c 100644
--- a/src/components/views/dialogs/ForwardDialog.tsx
+++ b/src/components/views/dialogs/ForwardDialog.tsx
@@ -162,6 +162,7 @@ const ForwardDialog: React.FC = ({ matrixClient: cli, event, permalinkCr
});
mockEvent.sender = {
name: profileInfo.displayname || userId,
+ rawDisplayName: profileInfo.displayname,
userId,
getAvatarUrl: (..._) => {
return avatarUrlForUser(
From 1a08af8ccfda1a3cf2e97e0d3aa9d0ad5bcfb2d1 Mon Sep 17 00:00:00 2001
From: Germain Souquet
Date: Thu, 17 Jun 2021 08:45:09 +0100
Subject: [PATCH 49/61] remove stray bullet point in reply preview
---
src/components/views/elements/ReplyThread.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js
index a9b24a306b..ebf4a18aa9 100644
--- a/src/components/views/elements/ReplyThread.js
+++ b/src/components/views/elements/ReplyThread.js
@@ -393,6 +393,7 @@ export default class ReplyThread extends React.Component {
alwaysShowTimestamps={this.props.alwaysShowTimestamps}
enableFlair={SettingsStore.getValue(UIFeature.Flair)}
replacingEventId={ev.replacingEventId()}
+ as="div"
/>
;
});
From 48e090abccd3ffe3d65bbe8a3ab3c7b9a21594cb Mon Sep 17 00:00:00 2001
From: Germain
Date: Thu, 17 Jun 2021 10:20:43 +0100
Subject: [PATCH 50/61] Remove unnecessary comment
---
test/end-to-end-tests/src/scenarios/e2e-encryption.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/end-to-end-tests/src/scenarios/e2e-encryption.js b/test/end-to-end-tests/src/scenarios/e2e-encryption.js
index ed5c598032..b20874fdaf 100644
--- a/test/end-to-end-tests/src/scenarios/e2e-encryption.js
+++ b/test/end-to-end-tests/src/scenarios/e2e-encryption.js
@@ -40,7 +40,7 @@ module.exports = async function e2eEncryptionScenarios(alice, bob) {
// the logs get a bit messy here, but that's fine enough for debugging (hopefully)
const [bobSas, aliceSas] = await Promise.all([bobSasPromise, aliceSasPromise]);
assert.deepEqual(bobSas, aliceSas);
- await measureStop(bob, "mx_VerifyE2EEUser"); //
+ await measureStop(bob, "mx_VerifyE2EEUser");
bob.log.done(`done (match for ${bobSas.join(", ")})`);
const aliceMessage = "Guess what I just heard?!";
await sendMessage(alice, aliceMessage);
From cce4ccb15735a40994536c496ddba590306db44c Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Thu, 17 Jun 2021 11:37:06 +0100
Subject: [PATCH 51/61] Fix types in SlashCommands which assumed something was
a promise but it wasn't
---
src/SlashCommands.tsx | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx
index 4a7b37b5e5..9700c57d67 100644
--- a/src/SlashCommands.tsx
+++ b/src/SlashCommands.tsx
@@ -150,6 +150,10 @@ function success(promise?: Promise) {
return {promise};
}
+function successSync(value: any) {
+ return success(Promise.resolve(value));
+}
+
/* Disable the "unexpected this" error for these commands - all of the run
* functions are called with `this` bound to the Command instance.
*/
@@ -160,7 +164,7 @@ export const Commands = [
args: '',
description: _td('Sends the given message as a spoiler'),
runFn: function(roomId, message) {
- return success(ContentHelpers.makeHtmlMessage(
+ return successSync(ContentHelpers.makeHtmlMessage(
message,
`${message}`,
));
@@ -176,7 +180,7 @@ export const Commands = [
if (args) {
message = message + ' ' + args;
}
- return success(ContentHelpers.makeTextMessage(message));
+ return successSync(ContentHelpers.makeTextMessage(message));
},
category: CommandCategories.messages,
}),
@@ -189,7 +193,7 @@ export const Commands = [
if (args) {
message = message + ' ' + args;
}
- return success(ContentHelpers.makeTextMessage(message));
+ return successSync(ContentHelpers.makeTextMessage(message));
},
category: CommandCategories.messages,
}),
@@ -202,7 +206,7 @@ export const Commands = [
if (args) {
message = message + ' ' + args;
}
- return success(ContentHelpers.makeTextMessage(message));
+ return successSync(ContentHelpers.makeTextMessage(message));
},
category: CommandCategories.messages,
}),
@@ -215,7 +219,7 @@ export const Commands = [
if (args) {
message = message + ' ' + args;
}
- return success(ContentHelpers.makeTextMessage(message));
+ return successSync(ContentHelpers.makeTextMessage(message));
},
category: CommandCategories.messages,
}),
@@ -224,7 +228,7 @@ export const Commands = [
args: '',
description: _td('Sends a message as plain text, without interpreting it as markdown'),
runFn: function(roomId, messages) {
- return success(ContentHelpers.makeTextMessage(messages));
+ return successSync(ContentHelpers.makeTextMessage(messages));
},
category: CommandCategories.messages,
}),
@@ -233,7 +237,7 @@ export const Commands = [
args: '',
description: _td('Sends a message as html, without interpreting it as markdown'),
runFn: function(roomId, messages) {
- return success(ContentHelpers.makeHtmlMessage(messages, messages));
+ return successSync(ContentHelpers.makeHtmlMessage(messages, messages));
},
category: CommandCategories.messages,
}),
@@ -978,7 +982,7 @@ export const Commands = [
args: '',
runFn: function(roomId, args) {
if (!args) return reject(this.getUserId());
- return success(ContentHelpers.makeHtmlMessage(args, textToHtmlRainbow(args)));
+ return successSync(ContentHelpers.makeHtmlMessage(args, textToHtmlRainbow(args)));
},
category: CommandCategories.messages,
}),
@@ -988,7 +992,7 @@ export const Commands = [
args: '',
runFn: function(roomId, args) {
if (!args) return reject(this.getUserId());
- return success(ContentHelpers.makeHtmlEmote(args, textToHtmlRainbow(args)));
+ return successSync(ContentHelpers.makeHtmlEmote(args, textToHtmlRainbow(args)));
},
category: CommandCategories.messages,
}),
From f929d2ee5f59d158a644609bec18147580753f65 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Thu, 17 Jun 2021 14:06:03 +0100
Subject: [PATCH 52/61] Typescript fixes due to MatrixEvent being TSified
---
src/Avatar.ts | 22 ++++--
src/autocomplete/UserProvider.tsx | 2 +-
src/components/views/dialogs/InviteDialog.tsx | 16 ++--
.../views/right_panel/EncryptionInfo.tsx | 9 ++-
src/components/views/right_panel/UserInfo.tsx | 73 ++++++++++---------
.../views/right_panel/VerificationPanel.tsx | 13 ++--
.../payloads/SetRightPanelPhasePayload.ts | 3 +-
7 files changed, 78 insertions(+), 60 deletions(-)
diff --git a/src/Avatar.ts b/src/Avatar.ts
index a6499c688e..8ea0b0c9fa 100644
--- a/src/Avatar.ts
+++ b/src/Avatar.ts
@@ -14,18 +14,23 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import {RoomMember} from "matrix-js-sdk/src/models/room-member";
-import {User} from "matrix-js-sdk/src/models/user";
-import {Room} from "matrix-js-sdk/src/models/room";
+import { RoomMember } from "matrix-js-sdk/src/models/room-member";
+import { User } from "matrix-js-sdk/src/models/user";
+import { Room } from "matrix-js-sdk/src/models/room";
import DMRoomMap from './utils/DMRoomMap';
-import {mediaFromMxc} from "./customisations/Media";
+import { mediaFromMxc } from "./customisations/Media";
import SettingsStore from "./settings/SettingsStore";
export type ResizeMethod = "crop" | "scale";
// Not to be used for BaseAvatar urls as that has similar default avatar fallback already
-export function avatarUrlForMember(member: RoomMember, width: number, height: number, resizeMethod: ResizeMethod) {
+export function avatarUrlForMember(
+ member: RoomMember,
+ width: number,
+ height: number,
+ resizeMethod: ResizeMethod,
+): string {
let url: string;
if (member?.getMxcAvatarUrl()) {
url = mediaFromMxc(member.getMxcAvatarUrl()).getThumbnailOfSourceHttp(width, height, resizeMethod);
@@ -39,7 +44,12 @@ export function avatarUrlForMember(member: RoomMember, width: number, height: nu
return url;
}
-export function avatarUrlForUser(user: User, width: number, height: number, resizeMethod?: ResizeMethod) {
+export function avatarUrlForUser(
+ user: Pick,
+ width: number,
+ height: number,
+ resizeMethod?: ResizeMethod,
+): string | null {
if (!user.avatarUrl) return null;
return mediaFromMxc(user.avatarUrl).getThumbnailOfSourceHttp(width, height, resizeMethod);
}
diff --git a/src/autocomplete/UserProvider.tsx b/src/autocomplete/UserProvider.tsx
index 3cf43d0b84..f3f79cb33b 100644
--- a/src/autocomplete/UserProvider.tsx
+++ b/src/autocomplete/UserProvider.tsx
@@ -28,7 +28,7 @@ import {MatrixClientPeg} from '../MatrixClientPeg';
import MatrixEvent from "matrix-js-sdk/src/models/event";
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 RoomState from "matrix-js-sdk/src/models/room-state";
import EventTimeline from "matrix-js-sdk/src/models/event-timeline";
import {makeUserPermalink} from "../utils/permalinks/Permalinks";
diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx
index 778744b783..ffca9a88a7 100644
--- a/src/components/views/dialogs/InviteDialog.tsx
+++ b/src/components/views/dialogs/InviteDialog.tsx
@@ -153,8 +153,8 @@ class ThreepidMember extends Member {
}
interface IDMUserTileProps {
- member: RoomMember;
- onRemove(member: RoomMember): void;
+ member: Member;
+ onRemove(member: Member): void;
}
class DMUserTile extends React.PureComponent {
@@ -168,7 +168,7 @@ class DMUserTile extends React.PureComponent {
render() {
const avatarSize = 20;
- const avatar = this.props.member.isEmail
+ const avatar = (this.props.member as ThreepidMember).isEmail
? {
}
interface IDMRoomTileProps {
- member: RoomMember;
+ member: Member;
lastActiveTs: number;
- onToggle(member: RoomMember): void;
+ onToggle(member: Member): void;
highlightWord: string;
isSelected: boolean;
}
@@ -270,7 +270,7 @@ class DMRoomTile extends React.PureComponent {
}
const avatarSize = 36;
- const avatar = this.props.member.isEmail
+ const avatar = (this.props.member as ThreepidMember).isEmail
?
@@ -298,7 +298,7 @@ class DMRoomTile extends React.PureComponent {
);
- const caption = this.props.member.isEmail
+ const caption = (this.props.member as ThreepidMember).isEmail
? _t("Invite by email")
: this.highlightName(this.props.member.userId);
@@ -334,7 +334,7 @@ interface IInviteDialogProps {
}
interface IInviteDialogState {
- targets: RoomMember[]; // array of Member objects (see interface above)
+ targets: Member[]; // array of Member objects (see interface above)
filterText: string;
recents: { user: Member, userId: string }[];
numRecentsShown: number;
diff --git a/src/components/views/right_panel/EncryptionInfo.tsx b/src/components/views/right_panel/EncryptionInfo.tsx
index aa51965ac6..db59a88967 100644
--- a/src/components/views/right_panel/EncryptionInfo.tsx
+++ b/src/components/views/right_panel/EncryptionInfo.tsx
@@ -17,8 +17,9 @@ limitations under the License.
import React from "react";
import * as sdk from "../../../index";
-import {_t} from "../../../languageHandler";
-import {RoomMember} from "matrix-js-sdk/src/models/room-member";
+import { _t } from "../../../languageHandler";
+import { RoomMember } from "matrix-js-sdk/src/models/room-member";
+import { User } from "matrix-js-sdk/src/models/user";
export const PendingActionSpinner = ({text}) => {
const Spinner = sdk.getComponent('elements.Spinner');
@@ -31,7 +32,7 @@ export const PendingActionSpinner = ({text}) => {
interface IProps {
waitingForOtherParty: boolean;
waitingForNetwork: boolean;
- member: RoomMember;
+ member: RoomMember | User;
onStartVerification: () => Promise;
isRoomEncrypted: boolean;
inDialog: boolean;
@@ -55,7 +56,7 @@ const EncryptionInfo: React.FC = ({
text = _t("Accept on your other login…");
} else {
text = _t("Waiting for %(displayName)s to accept…", {
- displayName: member.displayName || member.name || member.userId,
+ displayName: (member as User).displayName || (member as RoomMember).name || member.userId,
});
}
} else {
diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx
index d6c97f9cf2..e280c209f5 100644
--- a/src/components/views/right_panel/UserInfo.tsx
+++ b/src/components/views/right_panel/UserInfo.tsx
@@ -146,7 +146,7 @@ async function openDMForUser(matrixClient: MatrixClient, userId: string) {
type SetUpdating = (updating: boolean) => void;
-function useHasCrossSigningKeys(cli: MatrixClient, member: RoomMember, canVerify: boolean, setUpdating: SetUpdating) {
+function useHasCrossSigningKeys(cli: MatrixClient, member: User, canVerify: boolean, setUpdating: SetUpdating) {
return useAsyncMemo(async () => {
if (!canVerify) {
return undefined;
@@ -971,7 +971,7 @@ interface IRoomPermissions {
canInvite: boolean;
}
-function useRoomPermissions(cli: MatrixClient, room: Room, user: User): IRoomPermissions {
+function useRoomPermissions(cli: MatrixClient, room: Room, user: RoomMember): IRoomPermissions {
const [roomPermissions, setRoomPermissions] = useState({
// modifyLevelMax is the max PL we can set this user to, typically min(their PL, our PL) && canSetPL
modifyLevelMax: -1,
@@ -1028,7 +1028,7 @@ function useRoomPermissions(cli: MatrixClient, room: Room, user: User): IRoomPer
}
const PowerLevelSection: React.FC<{
- user: User;
+ user: RoomMember;
room: Room;
roomPermissions: IRoomPermissions;
powerLevels: IPowerLevelsContent;
@@ -1037,7 +1037,7 @@ const PowerLevelSection: React.FC<{
return ();
} else {
const powerLevelUsersDefault = powerLevels.users_default || 0;
- const powerLevel = parseInt(user.powerLevel, 10);
+ const powerLevel = user.powerLevel;
const role = textualPowerLevel(powerLevel, powerLevelUsersDefault);
return (
@@ -1048,13 +1048,13 @@ const PowerLevelSection: React.FC<{
};
const PowerLevelEditor: React.FC<{
- user: User;
+ user: RoomMember;
room: Room;
roomPermissions: IRoomPermissions;
}> = ({user, room, roomPermissions}) => {
const cli = useContext(MatrixClientContext);
- const [selectedPowerLevel, setSelectedPowerLevel] = useState(parseInt(user.powerLevel, 10));
+ const [selectedPowerLevel, setSelectedPowerLevel] = useState(user.powerLevel);
const onPowerChange = useCallback(async (powerLevelStr: string) => {
const powerLevel = parseInt(powerLevelStr, 10);
setSelectedPowerLevel(powerLevel);
@@ -1231,7 +1231,7 @@ const BasicUserInfo: React.FC<{
setPendingUpdateCount(pendingUpdateCount - 1);
}, [pendingUpdateCount]);
- const roomPermissions = useRoomPermissions(cli, room, member);
+ const roomPermissions = useRoomPermissions(cli, room, member as RoomMember);
const onSynapseDeactivate = useCallback(async () => {
const {finished} = Modal.createTrackedDialog('Synapse User Deactivation', '', QuestionDialog, {
@@ -1275,12 +1275,26 @@ const BasicUserInfo: React.FC<{
);
}
+ let memberDetails;
let adminToolsContainer;
- if (room && member.roomId) {
+ if (room && (member as RoomMember).roomId) {
+ // hide the Roles section for DMs as it doesn't make sense there
+ if (!DMRoomMap.shared().getUserIdForRoomId((member as RoomMember).roomId)) {
+ memberDetails =
;
+ }
+
adminToolsContainer = (
@@ -1309,20 +1323,6 @@ const BasicUserInfo: React.FC<{
spinner = ;
}
- let memberDetails;
- // hide the Roles section for DMs as it doesn't make sense there
- if (room && member.roomId && !DMRoomMap.shared().getUserIdForRoomId(member.roomId)) {
- memberDetails = ;
- }
-
// only display the devices list if our client supports E2E
const cryptoEnabled = cli.isCryptoEnabled();
@@ -1349,8 +1349,7 @@ const BasicUserInfo: React.FC<{
const setUpdating = (updating) => {
setPendingUpdateCount(count => count + (updating ? 1 : -1));
};
- const hasCrossSigningKeys =
- useHasCrossSigningKeys(cli, member, canVerify, setUpdating );
+ const hasCrossSigningKeys = useHasCrossSigningKeys(cli, member as User, canVerify, setUpdating);
const showDeviceListSpinner = devices === undefined;
if (canVerify) {
@@ -1359,9 +1358,9 @@ const BasicUserInfo: React.FC<{
verifyButton = (
{
if (hasCrossSigningKeys) {
- verifyUser(member);
+ verifyUser(member as User);
} else {
- legacyVerifyUser(member);
+ legacyVerifyUser(member as User);
}
}}>
{_t("Verify")}
@@ -1409,7 +1408,7 @@ const BasicUserInfo: React.FC<{
@@ -1428,13 +1427,15 @@ const UserInfoHeader: React.FC<{
const cli = useContext(MatrixClientContext);
const onMemberAvatarClick = useCallback(() => {
- const avatarUrl = member.getMxcAvatarUrl ? member.getMxcAvatarUrl() : member.avatarUrl;
+ const avatarUrl = (member as RoomMember).getMxcAvatarUrl
+ ? (member as RoomMember).getMxcAvatarUrl()
+ : (member as User).avatarUrl;
if (!avatarUrl) return;
const httpUrl = mediaFromMxc(avatarUrl).srcHttp;
const params = {
src: httpUrl,
- name: member.name,
+ name: (member as RoomMember).name || (member as User).displayName,
};
Modal.createDialog(ImageView, params, "mx_Dialog_lightbox", null, true);
@@ -1446,13 +1447,13 @@ const UserInfoHeader: React.FC<{
+ urls={(member as User).avatarUrl ? [(member as User).avatarUrl] : undefined} />
@@ -1469,7 +1470,11 @@ const UserInfoHeader: React.FC<{
presenceCurrentlyActive = member.user.currentlyActive;
if (SettingsStore.getValue("feature_custom_status")) {
- statusMessage = member.user._unstable_statusMessage;
+ if ((member as RoomMember).user) {
+ statusMessage = member.user.unstable_statusMessage;
+ } else {
+ statusMessage = (member as unknown as User).unstable_statusMessage;
+ }
}
}
@@ -1500,7 +1505,7 @@ const UserInfoHeader: React.FC<{
e2eIcon = ;
}
- const displayName = member.rawDisplayName || member.displayname;
+ const displayName = (member as RoomMember).rawDisplayName || (member as GroupMember).displayname;
return
{ avatarElement }
diff --git a/src/components/views/right_panel/VerificationPanel.tsx b/src/components/views/right_panel/VerificationPanel.tsx
index ac01c953b9..edfe0e3483 100644
--- a/src/components/views/right_panel/VerificationPanel.tsx
+++ b/src/components/views/right_panel/VerificationPanel.tsx
@@ -22,6 +22,7 @@ import {verificationMethods} from 'matrix-js-sdk/src/crypto';
import {SCAN_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode";
import {VerificationRequest} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
import {RoomMember} from "matrix-js-sdk/src/models/room-member";
+import { User } from "matrix-js-sdk/src/models/user";
import {ReciprocateQRCode} from "matrix-js-sdk/src/crypto/verification/QRCode";
import {SAS} from "matrix-js-sdk/src/crypto/verification/SAS";
@@ -51,7 +52,7 @@ enum VerificationPhase {
interface IProps {
layout: string;
request: VerificationRequest;
- member: RoomMember;
+ member: RoomMember | User;
phase: VerificationPhase;
onClose: () => void;
isRoomEncrypted: boolean;
@@ -134,7 +135,7 @@ export default class VerificationPanel extends React.PureComponent
{_t("Verify by scanning")}
{_t("Ask %(displayName)s to scan your code:", {
- displayName: member.displayName || member.name || member.userId,
+ displayName: (member as User).displayName || (member as RoomMember).name || member.userId,
})}
@@ -205,7 +206,7 @@ export default class VerificationPanel extends React.PureComponent
Date: Thu, 17 Jun 2021 14:24:53 +0100
Subject: [PATCH 53/61] Fix more type definitions
---
src/autocomplete/UserProvider.tsx | 18 +++++++++---------
.../views/dialogs/DevtoolsDialog.tsx | 2 +-
.../views/elements/MemberEventListSummary.tsx | 6 +++---
.../views/messages/SenderProfile.tsx | 6 +++---
src/components/views/rooms/EventTile.tsx | 2 +-
.../settings/tabs/room/BridgeSettingsTab.tsx | 2 +-
src/indexing/EventIndex.ts | 2 +-
src/stores/WidgetEchoStore.ts | 4 ++--
src/stores/widgets/StopGapWidget.ts | 4 ++--
src/stores/widgets/StopGapWidgetDriver.ts | 6 ++----
src/utils/DMRoomMap.ts | 13 +++++++------
11 files changed, 32 insertions(+), 33 deletions(-)
diff --git a/src/autocomplete/UserProvider.tsx b/src/autocomplete/UserProvider.tsx
index f3f79cb33b..687b477133 100644
--- a/src/autocomplete/UserProvider.tsx
+++ b/src/autocomplete/UserProvider.tsx
@@ -20,19 +20,19 @@ limitations under the License.
import React from 'react';
import { _t } from '../languageHandler';
import AutocompleteProvider from './AutocompleteProvider';
-import {PillCompletion} from './Components';
+import { PillCompletion } from './Components';
import * as sdk from '../index';
import QueryMatcher from './QueryMatcher';
-import {sortBy} from 'lodash';
-import {MatrixClientPeg} from '../MatrixClientPeg';
+import { sortBy } from 'lodash';
+import { MatrixClientPeg } from '../MatrixClientPeg';
-import MatrixEvent from "matrix-js-sdk/src/models/event";
-import Room from "matrix-js-sdk/src/models/room";
+import { MatrixEvent } from "matrix-js-sdk/src/models/event";
+import { Room } from "matrix-js-sdk/src/models/room";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
-import RoomState from "matrix-js-sdk/src/models/room-state";
-import EventTimeline from "matrix-js-sdk/src/models/event-timeline";
-import {makeUserPermalink} from "../utils/permalinks/Permalinks";
-import {ICompletion, ISelectionRange} from "./Autocompleter";
+import { RoomState } from "matrix-js-sdk/src/models/room-state";
+import { EventTimeline } from "matrix-js-sdk/src/models/event-timeline";
+import { makeUserPermalink } from "../utils/permalinks/Permalinks";
+import { ICompletion, ISelectionRange } from "./Autocompleter";
const USER_REGEX = /\B@\S*/g;
diff --git a/src/components/views/dialogs/DevtoolsDialog.tsx b/src/components/views/dialogs/DevtoolsDialog.tsx
index fdbf6a36fc..2690eb67d7 100644
--- a/src/components/views/dialogs/DevtoolsDialog.tsx
+++ b/src/components/views/dialogs/DevtoolsDialog.tsx
@@ -525,11 +525,11 @@ class RoomStateExplorer extends React.PureComponent {
diff --git a/src/components/views/elements/MemberEventListSummary.tsx b/src/components/views/elements/MemberEventListSummary.tsx
index 0290ef6d83..f10884ce9d 100644
--- a/src/components/views/elements/MemberEventListSummary.tsx
+++ b/src/components/views/elements/MemberEventListSummary.tsx
@@ -24,7 +24,7 @@ import { _t } from '../../../languageHandler';
import { formatCommaSeparatedList } from '../../../utils/FormattingUtils';
import { isValid3pidInvite } from "../../../RoomInvite";
import EventListSummary from "./EventListSummary";
-import {replaceableComponent} from "../../../utils/replaceableComponent";
+import { replaceableComponent } from "../../../utils/replaceableComponent";
interface IProps {
// An array of member events to summarise
@@ -303,7 +303,7 @@ export default class MemberEventListSummary extends React.Component {
return res;
}
- private static getTransitionSequence(events: MatrixEvent[]) {
+ private static getTransitionSequence(events: IUserEvents[]) {
return events.map(MemberEventListSummary.getTransition);
}
@@ -315,7 +315,7 @@ export default class MemberEventListSummary extends React.Component {
* @returns {string?} the transition type given to this event. This defaults to `null`
* if a transition is not recognised.
*/
- private static getTransition(e: MatrixEvent): TransitionType {
+ private static getTransition(e: IUserEvents): TransitionType {
if (e.mxEvent.getType() === 'm.room.third_party_invite') {
// Handle 3pid invites the same as invites so they get bundled together
if (!isValid3pidInvite(e.mxEvent)) {
diff --git a/src/components/views/messages/SenderProfile.tsx b/src/components/views/messages/SenderProfile.tsx
index 805f842fbc..883b2bd8a7 100644
--- a/src/components/views/messages/SenderProfile.tsx
+++ b/src/components/views/messages/SenderProfile.tsx
@@ -17,10 +17,10 @@
import React from 'react';
import Flair from '../elements/Flair.js';
import FlairStore from '../../../stores/FlairStore';
-import {getUserNameColorClass} from '../../../utils/FormattingUtils';
+import { getUserNameColorClass } from '../../../utils/FormattingUtils';
import MatrixClientContext from "../../../contexts/MatrixClientContext";
-import {replaceableComponent} from "../../../utils/replaceableComponent";
-import MatrixEvent from "matrix-js-sdk/src/models/event";
+import { replaceableComponent } from "../../../utils/replaceableComponent";
+import { MatrixEvent } from "matrix-js-sdk/src/models/event";
interface IProps {
mxEvent: MatrixEvent;
diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx
index 85b9cac2c4..8add7ae3b5 100644
--- a/src/components/views/rooms/EventTile.tsx
+++ b/src/components/views/rooms/EventTile.tsx
@@ -376,7 +376,7 @@ export default class EventTile extends React.Component {
EventType.RoomMessage,
EventType.RoomMessageEncrypted,
];
- if (!simpleSendableEvents.includes(this.props.mxEvent.getType())) return false;
+ if (!simpleSendableEvents.includes(this.props.mxEvent.getType() as EventType)) return false;
// Default case
return true;
diff --git a/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx b/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx
index 8d886a191e..428c10b338 100644
--- a/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx
+++ b/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx
@@ -44,7 +44,7 @@ export default class BridgeSettingsTab extends React.Component {
return ;
}
- static getBridgeStateEvents(roomId: string) {
+ static getBridgeStateEvents(roomId: string): MatrixEvent[] {
const client = MatrixClientPeg.get();
const roomState = client.getRoom(roomId).currentState;
diff --git a/src/indexing/EventIndex.ts b/src/indexing/EventIndex.ts
index b6289969bd..c36f96f368 100644
--- a/src/indexing/EventIndex.ts
+++ b/src/indexing/EventIndex.ts
@@ -300,7 +300,7 @@ export default class EventIndex extends EventEmitter {
}
private eventToJson(ev: MatrixEvent) {
- const jsonEvent = ev.toJSON();
+ const jsonEvent: any = ev.toJSON();
const e = ev.isEncrypted() ? jsonEvent.decrypted : jsonEvent;
if (ev.isEncrypted()) {
diff --git a/src/stores/WidgetEchoStore.ts b/src/stores/WidgetEchoStore.ts
index 09120d6108..0b0be50541 100644
--- a/src/stores/WidgetEchoStore.ts
+++ b/src/stores/WidgetEchoStore.ts
@@ -16,8 +16,8 @@ limitations under the License.
import EventEmitter from 'events';
import { IWidget } from 'matrix-widget-api';
-import MatrixEvent from "matrix-js-sdk/src/models/event";
-import {WidgetType} from "../widgets/WidgetType";
+import { MatrixEvent } from "matrix-js-sdk/src/models/event";
+import { WidgetType } from "../widgets/WidgetType";
/**
* Acts as a place to get & set widget state, storing local echo state and
diff --git a/src/stores/widgets/StopGapWidget.ts b/src/stores/widgets/StopGapWidget.ts
index 397d637125..6dcaf7abd7 100644
--- a/src/stores/widgets/StopGapWidget.ts
+++ b/src/stores/widgets/StopGapWidget.ts
@@ -51,7 +51,7 @@ import ThemeWatcher from "../../settings/watchers/ThemeWatcher";
import {getCustomTheme} from "../../theme";
import CountlyAnalytics from "../../CountlyAnalytics";
import { ElementWidgetCapabilities } from "./ElementWidgetCapabilities";
-import { MatrixEvent } from "matrix-js-sdk/src/models/event";
+import { MatrixEvent, IEvent } from "matrix-js-sdk/src/models/event";
import { ELEMENT_CLIENT_ID } from "../../identifiers";
import { getUserLanguage } from "../../languageHandler";
@@ -415,7 +415,7 @@ export class StopGapWidget extends EventEmitter {
private feedEvent(ev: MatrixEvent) {
if (!this.messaging) return;
- const raw = ev.event;
+ const raw = ev.event as IEvent;
this.messaging.feedEvent(raw).catch(e => {
console.error("Error sending event to widget: ", e);
});
diff --git a/src/stores/widgets/StopGapWidgetDriver.ts b/src/stores/widgets/StopGapWidgetDriver.ts
index 25e81c47a2..9d477a38bf 100644
--- a/src/stores/widgets/StopGapWidgetDriver.ts
+++ b/src/stores/widgets/StopGapWidgetDriver.ts
@@ -145,7 +145,7 @@ export class StopGapWidgetDriver extends WidgetDriver {
return {roomId, eventId: r.event_id};
}
- public async readRoomEvents(eventType: string, msgtype: string | undefined, limit: number): Promise {
+ public async readRoomEvents(eventType: string, msgtype: string | undefined, limit: number): Promise