Merge pull request #6408 from matrix-org/t3chguy/eslint

This commit is contained in:
Michael Telatynski 2021-07-20 11:23:36 +01:00 committed by GitHub
commit 770de8f6b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
268 changed files with 1993 additions and 2008 deletions

View file

@ -46,6 +46,7 @@
"start:build": "babel src -w -s -d lib --verbose --extensions \".ts,.js\"",
"lint": "yarn lint:types && yarn lint:js && yarn lint:style",
"lint:js": "eslint --max-warnings 0 src test",
"lint:js-fix": "eslint --fix src test",
"lint:types": "tsc --noEmit --jsx react",
"lint:style": "stylelint 'res/css/**/*.scss'",
"test": "jest",

View file

@ -50,6 +50,8 @@ import UIStore from "../stores/UIStore";
import { SetupEncryptionStore } from "../stores/SetupEncryptionStore";
import { RoomScrollStateStore } from "../stores/RoomScrollStateStore";
/* eslint-disable @typescript-eslint/naming-convention */
declare global {
interface Window {
matrixChat: ReturnType<Renderer>;
@ -186,3 +188,5 @@ declare global {
}
);
}
/* eslint-enable @typescript-eslint/naming-convention */

View file

@ -270,7 +270,7 @@ export class Analytics {
localStorage.removeItem(LAST_VISIT_TS_KEY);
}
private async _track(data: IData) {
private async track(data: IData) {
if (this.disabled) return;
const now = new Date();
@ -304,7 +304,7 @@ export class Analytics {
}
public ping() {
this._track({
this.track({
ping: "1",
});
localStorage.setItem(LAST_VISIT_TS_KEY, String(new Date().getTime())); // update last visit ts
@ -324,14 +324,14 @@ export class Analytics {
// But continue anyway because we still want to track the change
}
this._track({
this.track({
gt_ms: String(generationTimeMs),
});
}
public trackEvent(category: string, action: string, name?: string, value?: string) {
if (this.disabled) return;
this._track({
this.track({
e_c: category,
e_a: action,
e_n: name,

View file

@ -33,6 +33,7 @@ import { isSecretStorageBeingAccessed, accessSecretStorage } from "./SecurityMan
import { isSecureBackupRequired } from './utils/WellKnownUtils';
import { isLoggedIn } from './components/structures/MatrixChat';
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { ActionPayload } from "./dispatcher/payloads";
const KEY_BACKUP_POLL_INTERVAL = 5 * 60 * 1000;
@ -58,28 +59,28 @@ export default class DeviceListener {
}
start() {
MatrixClientPeg.get().on('crypto.willUpdateDevices', this._onWillUpdateDevices);
MatrixClientPeg.get().on('crypto.devicesUpdated', this._onDevicesUpdated);
MatrixClientPeg.get().on('deviceVerificationChanged', this._onDeviceVerificationChanged);
MatrixClientPeg.get().on('userTrustStatusChanged', this._onUserTrustStatusChanged);
MatrixClientPeg.get().on('crossSigning.keysChanged', this._onCrossSingingKeysChanged);
MatrixClientPeg.get().on('accountData', this._onAccountData);
MatrixClientPeg.get().on('sync', this._onSync);
MatrixClientPeg.get().on('RoomState.events', this._onRoomStateEvents);
this.dispatcherRef = dis.register(this._onAction);
this._recheck();
MatrixClientPeg.get().on('crypto.willUpdateDevices', this.onWillUpdateDevices);
MatrixClientPeg.get().on('crypto.devicesUpdated', this.onDevicesUpdated);
MatrixClientPeg.get().on('deviceVerificationChanged', this.onDeviceVerificationChanged);
MatrixClientPeg.get().on('userTrustStatusChanged', this.onUserTrustStatusChanged);
MatrixClientPeg.get().on('crossSigning.keysChanged', this.onCrossSingingKeysChanged);
MatrixClientPeg.get().on('accountData', this.onAccountData);
MatrixClientPeg.get().on('sync', this.onSync);
MatrixClientPeg.get().on('RoomState.events', this.onRoomStateEvents);
this.dispatcherRef = dis.register(this.onAction);
this.recheck();
}
stop() {
if (MatrixClientPeg.get()) {
MatrixClientPeg.get().removeListener('crypto.willUpdateDevices', this._onWillUpdateDevices);
MatrixClientPeg.get().removeListener('crypto.devicesUpdated', this._onDevicesUpdated);
MatrixClientPeg.get().removeListener('deviceVerificationChanged', this._onDeviceVerificationChanged);
MatrixClientPeg.get().removeListener('userTrustStatusChanged', this._onUserTrustStatusChanged);
MatrixClientPeg.get().removeListener('crossSigning.keysChanged', this._onCrossSingingKeysChanged);
MatrixClientPeg.get().removeListener('accountData', this._onAccountData);
MatrixClientPeg.get().removeListener('sync', this._onSync);
MatrixClientPeg.get().removeListener('RoomState.events', this._onRoomStateEvents);
MatrixClientPeg.get().removeListener('crypto.willUpdateDevices', this.onWillUpdateDevices);
MatrixClientPeg.get().removeListener('crypto.devicesUpdated', this.onDevicesUpdated);
MatrixClientPeg.get().removeListener('deviceVerificationChanged', this.onDeviceVerificationChanged);
MatrixClientPeg.get().removeListener('userTrustStatusChanged', this.onUserTrustStatusChanged);
MatrixClientPeg.get().removeListener('crossSigning.keysChanged', this.onCrossSingingKeysChanged);
MatrixClientPeg.get().removeListener('accountData', this.onAccountData);
MatrixClientPeg.get().removeListener('sync', this.onSync);
MatrixClientPeg.get().removeListener('RoomState.events', this.onRoomStateEvents);
}
if (this.dispatcherRef) {
dis.unregister(this.dispatcherRef);
@ -103,15 +104,15 @@ export default class DeviceListener {
this.dismissed.add(d);
}
this._recheck();
this.recheck();
}
dismissEncryptionSetup() {
this.dismissedThisDeviceToast = true;
this._recheck();
this.recheck();
}
_ensureDeviceIdsAtStartPopulated() {
private ensureDeviceIdsAtStartPopulated() {
if (this.ourDeviceIdsAtStart === null) {
const cli = MatrixClientPeg.get();
this.ourDeviceIdsAtStart = new Set(
@ -120,39 +121,39 @@ export default class DeviceListener {
}
}
_onWillUpdateDevices = async (users: string[], initialFetch?: boolean) => {
private onWillUpdateDevices = async (users: string[], initialFetch?: boolean) => {
// If we didn't know about *any* devices before (ie. it's fresh login),
// then they are all pre-existing devices, so ignore this and set the
// devicesAtStart list to the devices that we see after the fetch.
if (initialFetch) return;
const myUserId = MatrixClientPeg.get().getUserId();
if (users.includes(myUserId)) this._ensureDeviceIdsAtStartPopulated();
if (users.includes(myUserId)) this.ensureDeviceIdsAtStartPopulated();
// No need to do a recheck here: we just need to get a snapshot of our devices
// before we download any new ones.
};
_onDevicesUpdated = (users: string[]) => {
private onDevicesUpdated = (users: string[]) => {
if (!users.includes(MatrixClientPeg.get().getUserId())) return;
this._recheck();
this.recheck();
};
_onDeviceVerificationChanged = (userId: string) => {
private onDeviceVerificationChanged = (userId: string) => {
if (userId !== MatrixClientPeg.get().getUserId()) return;
this._recheck();
this.recheck();
};
_onUserTrustStatusChanged = (userId: string) => {
private onUserTrustStatusChanged = (userId: string) => {
if (userId !== MatrixClientPeg.get().getUserId()) return;
this._recheck();
this.recheck();
};
_onCrossSingingKeysChanged = () => {
this._recheck();
private onCrossSingingKeysChanged = () => {
this.recheck();
};
_onAccountData = (ev) => {
private onAccountData = (ev: MatrixEvent) => {
// User may have:
// * migrated SSSS to symmetric
// * uploaded keys to secret storage
@ -163,32 +164,32 @@ export default class DeviceListener {
ev.getType().startsWith('m.cross_signing.') ||
ev.getType() === 'm.megolm_backup.v1'
) {
this._recheck();
this.recheck();
}
};
_onSync = (state, prevState) => {
if (state === 'PREPARED' && prevState === null) this._recheck();
private onSync = (state, prevState) => {
if (state === 'PREPARED' && prevState === null) this.recheck();
};
_onRoomStateEvents = (ev: MatrixEvent) => {
private onRoomStateEvents = (ev: MatrixEvent) => {
if (ev.getType() !== "m.room.encryption") {
return;
}
// If a room changes to encrypted, re-check as it may be our first
// encrypted room. This also catches encrypted room creation as well.
this._recheck();
this.recheck();
};
_onAction = ({ action }) => {
private onAction = ({ action }: ActionPayload) => {
if (action !== "on_logged_in") return;
this._recheck();
this.recheck();
};
// The server doesn't tell us when key backup is set up, so we poll
// & cache the result
async _getKeyBackupInfo() {
private async getKeyBackupInfo() {
const now = (new Date()).getTime();
if (!this.keyBackupInfo || this.keyBackupFetchedAt < now - KEY_BACKUP_POLL_INTERVAL) {
this.keyBackupInfo = await MatrixClientPeg.get().getKeyBackupVersion();
@ -206,7 +207,7 @@ export default class DeviceListener {
return cli && cli.getRooms().some(r => cli.isRoomEncrypted(r.roomId));
}
async _recheck() {
private async recheck() {
const cli = MatrixClientPeg.get();
if (!await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")) return;
@ -235,7 +236,7 @@ export default class DeviceListener {
// Cross-signing on account but this device doesn't trust the master key (verify this session)
showSetupEncryptionToast(SetupKind.VERIFY_THIS_SESSION);
} else {
const backupInfo = await this._getKeyBackupInfo();
const backupInfo = await this.getKeyBackupInfo();
if (backupInfo) {
// No cross-signing on account but key backup available (upgrade encryption)
showSetupEncryptionToast(SetupKind.UPGRADE_ENCRYPTION);
@ -256,7 +257,7 @@ export default class DeviceListener {
// This needs to be done after awaiting on downloadKeys() above, so
// we make sure we get the devices after the fetch is done.
this._ensureDeviceIdsAtStartPopulated();
this.ensureDeviceIdsAtStartPopulated();
// Unverified devices that were there last time the app ran
// (technically could just be a boolean: we don't actually

View file

@ -105,7 +105,7 @@ export interface IMatrixClientPeg {
* This module provides a singleton instance of this class so the 'current'
* Matrix Client object is available easily.
*/
class _MatrixClientPeg implements IMatrixClientPeg {
class MatrixClientPegClass implements IMatrixClientPeg {
// These are the default options used when when the
// client is started in 'start'. These can be altered
// at any time up to after the 'will_start_client'
@ -300,7 +300,7 @@ class _MatrixClientPeg implements IMatrixClientPeg {
}
if (!window.mxMatrixClientPeg) {
window.mxMatrixClientPeg = new _MatrixClientPeg();
window.mxMatrixClientPeg = new MatrixClientPegClass();
}
export const MatrixClientPeg = window.mxMatrixClientPeg;

View file

@ -522,7 +522,7 @@ export const Commands = [
aliases: ['j', 'goto'],
args: '<room-address>',
description: _td('Joins room with given address'),
runFn: function(_, args) {
runFn: function(roomId, args) {
if (args) {
// Note: we support 2 versions of this command. The first is
// the public-facing one for most users and the other is a
@ -1069,7 +1069,7 @@ export const Commands = [
command: "msg",
description: _td("Sends a message to the given user"),
args: "<user-id> <message>",
runFn: function(_, args) {
runFn: function(roomId, args) {
if (args) {
// matches the first whitespace delimited group and then the rest of the string
const matches = args.match(/^(\S+?)(?: +(.*))?$/s);

View file

@ -109,7 +109,7 @@ export default class UserProvider extends AutocompleteProvider {
limit = -1,
): Promise<ICompletion[]> {
// lazy-load user list into matcher
if (!this.users) this._makeUsers();
if (!this.users) this.makeUsers();
let completions = [];
const { command, range } = this.getCurrentCommand(rawQuery, selection, force);
@ -147,7 +147,7 @@ export default class UserProvider extends AutocompleteProvider {
return _t('Users');
}
_makeUsers() {
private makeUsers() {
const events = this.room.getLiveTimeline().getEvents();
const lastSpoken = {};

View file

@ -17,8 +17,8 @@ limitations under the License.
*/
import * as React from 'react';
import * as PropTypes from 'prop-types';
import { MatrixClient } from 'matrix-js-sdk/src/client';
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
import { Key } from '../../Keyboard';
import PageTypes from '../../PageTypes';
@ -79,6 +79,8 @@ function canElementReceiveInput(el) {
interface IProps {
matrixClient: MatrixClient;
// Called with the credentials of a registered user (if they were a ROU that
// transitioned to PWLU)
onRegistered: (credentials: IMatrixClientCreds) => Promise<MatrixClient>;
hideToSRUsers: boolean;
resizeNotifier: ResizeNotifier;
@ -140,18 +142,6 @@ interface IState {
class LoggedInView extends React.Component<IProps, IState> {
static displayName = 'LoggedInView';
static propTypes = {
matrixClient: PropTypes.instanceOf(MatrixClient).isRequired,
page_type: PropTypes.string.isRequired,
onRoomCreated: PropTypes.func,
// Called with the credentials of a registered user (if they were a ROU that
// transitioned to PWLU)
onRegistered: PropTypes.func,
// and lots and lots of other stuff.
};
protected readonly _matrixClient: MatrixClient;
protected readonly _roomView: React.RefObject<any>;
protected readonly _resizeContainer: React.RefObject<ResizeHandle>;
@ -181,10 +171,10 @@ class LoggedInView extends React.Component<IProps, IState> {
}
componentDidMount() {
document.addEventListener('keydown', this._onNativeKeyDown, false);
document.addEventListener('keydown', this.onNativeKeyDown, false);
CallHandler.sharedInstance().addListener(CallHandlerEvent.CallsChanged, this.onCallsChanged);
this._updateServerNoticeEvents();
this.updateServerNoticeEvents();
this._matrixClient.on("accountData", this.onAccountData);
this._matrixClient.on("sync", this.onSync);
@ -200,13 +190,13 @@ class LoggedInView extends React.Component<IProps, IState> {
"useCompactLayout", null, this.onCompactLayoutChanged,
);
this.resizer = this._createResizer();
this.resizer = this.createResizer();
this.resizer.attach();
this._loadResizerPreferences();
this.loadResizerPreferences();
}
componentWillUnmount() {
document.removeEventListener('keydown', this._onNativeKeyDown, false);
document.removeEventListener('keydown', this.onNativeKeyDown, false);
CallHandler.sharedInstance().removeListener(CallHandlerEvent.CallsChanged, this.onCallsChanged);
this._matrixClient.removeListener("accountData", this.onAccountData);
this._matrixClient.removeListener("sync", this.onSync);
@ -221,37 +211,37 @@ class LoggedInView extends React.Component<IProps, IState> {
});
};
canResetTimelineInRoom = (roomId) => {
public canResetTimelineInRoom = (roomId: string) => {
if (!this._roomView.current) {
return true;
}
return this._roomView.current.canResetTimeline();
};
_createResizer() {
let size;
let collapsed;
private createResizer() {
let panelSize;
let panelCollapsed;
const collapseConfig: ICollapseConfig = {
// 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) {
onCollapsed: (collapsed) => {
panelCollapsed = collapsed;
if (collapsed) {
dis.dispatch({ action: "hide_left_panel" });
window.localStorage.setItem("mx_lhs_size", '0');
} else {
dis.dispatch({ action: "show_left_panel" });
}
},
onResized: (_size) => {
size = _size;
onResized: (size) => {
panelSize = size;
this.props.resizeNotifier.notifyLeftHandleResized();
},
onResizeStart: () => {
this.props.resizeNotifier.startResizing();
},
onResizeStop: () => {
if (!collapsed) window.localStorage.setItem("mx_lhs_size", '' + size);
if (!panelCollapsed) window.localStorage.setItem("mx_lhs_size", '' + panelSize);
this.props.resizeNotifier.stopResizing();
},
isItemCollapsed: domNode => {
@ -267,7 +257,7 @@ class LoggedInView extends React.Component<IProps, IState> {
return resizer;
}
_loadResizerPreferences() {
private loadResizerPreferences() {
let lhsSize = parseInt(window.localStorage.getItem("mx_lhs_size"), 10);
if (isNaN(lhsSize)) {
lhsSize = 350;
@ -275,7 +265,7 @@ class LoggedInView extends React.Component<IProps, IState> {
this.resizer.forHandleAt(0).resize(lhsSize);
}
onAccountData = (event) => {
private onAccountData = (event: MatrixEvent) => {
if (event.getType() === "m.ignored_user_list") {
dis.dispatch({ action: "ignore_state_changed" });
}
@ -307,16 +297,16 @@ class LoggedInView extends React.Component<IProps, IState> {
}
if (oldSyncState === 'PREPARED' && syncState === 'SYNCING') {
this._updateServerNoticeEvents();
this.updateServerNoticeEvents();
} else {
this._calculateServerLimitToast(this.state.syncErrorData, this.state.usageLimitEventContent);
this.calculateServerLimitToast(this.state.syncErrorData, this.state.usageLimitEventContent);
}
};
onRoomStateEvents = (ev, state) => {
const serverNoticeList = RoomListStore.instance.orderedLists[DefaultTagID.ServerNotice];
if (serverNoticeList && serverNoticeList.some(r => r.roomId === ev.getRoomId())) {
this._updateServerNoticeEvents();
this.updateServerNoticeEvents();
}
};
@ -326,7 +316,7 @@ class LoggedInView extends React.Component<IProps, IState> {
});
};
_calculateServerLimitToast(syncError: IState["syncErrorData"], usageLimitEventContent?: IUsageLimit) {
private calculateServerLimitToast(syncError: IState["syncErrorData"], usageLimitEventContent?: IUsageLimit) {
const error = syncError && syncError.error && syncError.error.errcode === "M_RESOURCE_LIMIT_EXCEEDED";
if (error) {
usageLimitEventContent = syncError.error.data;
@ -346,7 +336,7 @@ class LoggedInView extends React.Component<IProps, IState> {
}
}
_updateServerNoticeEvents = async () => {
private updateServerNoticeEvents = async () => {
const serverNoticeList = RoomListStore.instance.orderedLists[DefaultTagID.ServerNotice];
if (!serverNoticeList) return [];
@ -378,7 +368,7 @@ class LoggedInView extends React.Component<IProps, IState> {
);
});
const usageLimitEventContent = usageLimitEvent && usageLimitEvent.getContent();
this._calculateServerLimitToast(this.state.syncErrorData, usageLimitEventContent);
this.calculateServerLimitToast(this.state.syncErrorData, usageLimitEventContent);
this.setState({
usageLimitEventContent,
usageLimitEventTs: pinnedEventTs,
@ -387,7 +377,7 @@ class LoggedInView extends React.Component<IProps, IState> {
});
};
_onPaste = (ev) => {
private onPaste = (ev) => {
let canReceiveInput = false;
let element = ev.target;
// test for all parents because the target can be a child of a contenteditable element
@ -425,22 +415,22 @@ class LoggedInView extends React.Component<IProps, IState> {
We also listen with a native listener on the document to get keydown events when no element is focused.
Bubbling is irrelevant here as the target is the body element.
*/
_onReactKeyDown = (ev) => {
private onReactKeyDown = (ev) => {
// events caught while bubbling up on the root element
// of this component, so something must be focused.
this._onKeyDown(ev);
this.onKeyDown(ev);
};
_onNativeKeyDown = (ev) => {
private onNativeKeyDown = (ev) => {
// only pass this if there is no focused element.
// if there is, _onKeyDown will be called by the
// if there is, onKeyDown will be called by the
// react keydown handler that respects the react bubbling order.
if (ev.target === document.body) {
this._onKeyDown(ev);
this.onKeyDown(ev);
}
};
_onKeyDown = (ev) => {
private onKeyDown = (ev) => {
let handled = false;
const roomAction = getKeyBindingsManager().getRoomAction(ev);
@ -450,7 +440,7 @@ class LoggedInView extends React.Component<IProps, IState> {
case RoomAction.JumpToFirstMessage:
case RoomAction.JumpToLatestMessage:
// pass the event down to the scroll panel
this._onScrollKeyPressed(ev);
this.onScrollKeyPressed(ev);
handled = true;
break;
case RoomAction.FocusSearch:
@ -565,7 +555,7 @@ class LoggedInView extends React.Component<IProps, IState> {
* dispatch a page-up/page-down/etc to the appropriate component
* @param {Object} ev The key event
*/
_onScrollKeyPressed = (ev) => {
private onScrollKeyPressed = (ev) => {
if (this._roomView.current) {
this._roomView.current.handleScrollKey(ev);
}
@ -625,8 +615,8 @@ class LoggedInView extends React.Component<IProps, IState> {
return (
<MatrixClientContext.Provider value={this._matrixClient}>
<div
onPaste={this._onPaste}
onKeyDown={this._onReactKeyDown}
onPaste={this.onPaste}
onKeyDown={this.onReactKeyDown}
className='mx_MatrixChat_wrapper'
aria-hidden={this.props.hideToSRUsers}
>

View file

@ -431,7 +431,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
// TODO: [REACT-WARNING] Replace with appropriate lifecycle stage
// eslint-disable-next-line camelcase
// eslint-disable-next-line
UNSAFE_componentWillUpdate(props, state) {
if (this.shouldTrackPageChange(this.state, state)) {
this.startPageChangeTimer();
@ -1864,13 +1864,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
dis.dispatch({ action: 'timeline_resize' });
}
onRoomCreated(roomId: string) {
dis.dispatch({
action: "view_room",
room_id: roomId,
});
}
onRegisterClick = () => {
this.showScreen("register");
};
@ -2043,7 +2036,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
{...this.state}
ref={this.loggedInView}
matrixClient={MatrixClientPeg.get()}
onRoomCreated={this.onRoomCreated}
onRegistered={this.onRegistered}
currentRoomId={this.state.currentRoomId}
/>

View file

@ -17,6 +17,7 @@ limitations under the License.
import React from 'react';
import { Room } from "matrix-js-sdk/src/models/room";
import { RoomState } from "matrix-js-sdk/src/models/room-state";
import { User } from "matrix-js-sdk/src/models/user";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
@ -152,7 +153,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
}
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
UNSAFE_componentWillReceiveProps(newProps) { // eslint-disable-line camelcase
UNSAFE_componentWillReceiveProps(newProps) { // eslint-disable-line
if (newProps.groupId !== this.props.groupId) {
this.unregisterGroupStore();
this.initGroupStore(newProps.groupId);
@ -174,7 +175,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
});
};
private onRoomStateMember = (ev: MatrixEvent, _, member: RoomMember) => {
private onRoomStateMember = (ev: MatrixEvent, state: RoomState, member: RoomMember) => {
if (!this.props.room || member.roomId !== this.props.room.roomId) {
return;
}

View file

@ -814,7 +814,7 @@ export default class RoomDirectory extends React.Component<IProps, IState> {
}) : _t("Explore rooms");
return (
<BaseDialog
className={'mx_RoomDirectory_dialog'}
className="mx_RoomDirectory_dialog"
hasCancel={true}
onFinished={this.onFinished}
title={title}

View file

@ -458,7 +458,7 @@ const SpaceSetupFirstRooms = ({ space, title, description, onFinished }) => {
const numFields = 3;
const placeholders = [_t("General"), _t("Random"), _t("Support")];
const [roomNames, setRoomName] = useStateArray(numFields, [_t("General"), _t("Random"), ""]);
const fields = new Array(numFields).fill(0).map((_, i) => {
const fields = new Array(numFields).fill(0).map((x, i) => {
const name = "roomName" + i;
return <Field
key={name}
@ -625,7 +625,7 @@ const SpaceSetupPrivateInvite = ({ space, onFinished }) => {
const numFields = 3;
const fieldRefs: RefObject<Field>[] = [useRef(), useRef(), useRef()];
const [emailAddresses, setEmailAddress] = useStateArray(numFields, "");
const fields = new Array(numFields).fill(0).map((_, i) => {
const fields = new Array(numFields).fill(0).map((x, i) => {
const name = "emailAddress" + i;
return <Field
key={name}

View file

@ -74,7 +74,7 @@ export default class TabbedView extends React.Component<IProps, IState> {
tabLocation: TabLocation.LEFT,
};
private _getActiveTabIndex() {
private getActiveTabIndex() {
if (!this.state || !this.state.activeTabIndex) return 0;
return this.state.activeTabIndex;
}
@ -84,7 +84,7 @@ export default class TabbedView extends React.Component<IProps, IState> {
* @param {Tab} tab the tab to show
* @private
*/
private _setActiveTab(tab: Tab) {
private setActiveTab(tab: Tab) {
const idx = this.props.tabs.indexOf(tab);
if (idx !== -1) {
if (this.props.onChange) this.props.onChange(tab.id);
@ -94,18 +94,18 @@ export default class TabbedView extends React.Component<IProps, IState> {
}
}
private _renderTabLabel(tab: Tab) {
private renderTabLabel(tab: Tab) {
let classes = "mx_TabbedView_tabLabel ";
const idx = this.props.tabs.indexOf(tab);
if (idx === this._getActiveTabIndex()) classes += "mx_TabbedView_tabLabel_active";
if (idx === this.getActiveTabIndex()) classes += "mx_TabbedView_tabLabel_active";
let tabIcon = null;
if (tab.icon) {
tabIcon = <span className={`mx_TabbedView_maskedIcon ${tab.icon}`} />;
}
const onClickHandler = () => this._setActiveTab(tab);
const onClickHandler = () => this.setActiveTab(tab);
const label = _t(tab.label);
return (
@ -118,7 +118,7 @@ export default class TabbedView extends React.Component<IProps, IState> {
);
}
private _renderTabPanel(tab: Tab): React.ReactNode {
private renderTabPanel(tab: Tab): React.ReactNode {
return (
<div className="mx_TabbedView_tabPanel" key={"mx_tabpanel_" + tab.label}>
<AutoHideScrollbar className='mx_TabbedView_tabPanelContent'>
@ -129,8 +129,8 @@ export default class TabbedView extends React.Component<IProps, IState> {
}
public render(): React.ReactNode {
const labels = this.props.tabs.map(tab => this._renderTabLabel(tab));
const panel = this._renderTabPanel(this.props.tabs[this._getActiveTabIndex()]);
const labels = this.props.tabs.map(tab => this.renderTabLabel(tab));
const panel = this.renderTabPanel(this.props.tabs[this.getActiveTabIndex()]);
const tabbedViewClasses = classNames({
'mx_TabbedView': true,

View file

@ -277,7 +277,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
}
// TODO: [REACT-WARNING] Move into constructor
// eslint-disable-next-line camelcase
// eslint-disable-next-line
UNSAFE_componentWillMount() {
if (this.props.manageReadReceipts) {
this.updateReadReceiptOnUserActivity();
@ -290,7 +290,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
}
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
// eslint-disable-next-line camelcase
// eslint-disable-next-line
UNSAFE_componentWillReceiveProps(newProps) {
if (newProps.timelineSet !== this.props.timelineSet) {
// throw new Error("changing timelineSet on a TimelinePanel is not supported");

View file

@ -37,14 +37,14 @@ export default class ToastContainer extends React.Component<{}, IState> {
// toasts may dismiss themselves in their didMount if they find
// they're already irrelevant by the time they're mounted, and
// our own componentDidMount is too late.
ToastStore.sharedInstance().on('update', this._onToastStoreUpdate);
ToastStore.sharedInstance().on('update', this.onToastStoreUpdate);
}
componentWillUnmount() {
ToastStore.sharedInstance().removeListener('update', this._onToastStoreUpdate);
ToastStore.sharedInstance().removeListener('update', this.onToastStoreUpdate);
}
_onToastStoreUpdate = () => {
private onToastStoreUpdate = () => {
this.setState({
toasts: ToastStore.sharedInstance().getToasts(),
countSeen: ToastStore.sharedInstance().getCountSeen(),

View file

@ -101,7 +101,7 @@ export default class ForgotPassword extends React.Component<IProps, IState> {
}
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
// eslint-disable-next-line camelcase
// eslint-disable-next-line
public UNSAFE_componentWillReceiveProps(newProps: IProps): void {
if (newProps.serverConfig.hsUrl === this.props.serverConfig.hsUrl &&
newProps.serverConfig.isUrl === this.props.serverConfig.isUrl) return;

View file

@ -144,7 +144,7 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
}
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
// eslint-disable-next-line camelcase
// eslint-disable-next-line
UNSAFE_componentWillMount() {
this.initLoginLogic(this.props.serverConfig);
}
@ -154,7 +154,7 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
}
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
// eslint-disable-next-line camelcase
// eslint-disable-next-line
UNSAFE_componentWillReceiveProps(newProps) {
if (newProps.serverConfig.hsUrl === this.props.serverConfig.hsUrl &&
newProps.serverConfig.isUrl === this.props.serverConfig.isUrl) return;

View file

@ -141,7 +141,7 @@ export default class Registration extends React.Component<IProps, IState> {
}
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
// eslint-disable-next-line camelcase
// eslint-disable-next-line
UNSAFE_componentWillReceiveProps(newProps) {
if (newProps.serverConfig.hsUrl === this.props.serverConfig.hsUrl &&
newProps.serverConfig.isUrl === this.props.serverConfig.isUrl) return;

View file

@ -60,8 +60,8 @@ export default class AskInviteAnywayDialog extends React.Component<IProps> {
contentId='mx_Dialog_content'
>
<div id='mx_Dialog_content'>
{/* eslint-disable-next-line */}
<p>{_t("Unable to find profiles for the Matrix IDs listed below - would you like to invite them anyway?")}</p>
<p>{ _t("Unable to find profiles for the Matrix IDs listed below - " +
"would you like to invite them anyway?") }</p>
<ul>
{ errorList }
</ul>

View file

@ -187,7 +187,7 @@ export default class CommunityPrototypeInviteDialog extends React.PureComponent<
emailAddresses.push((
<Field
key={emailAddresses.length}
value={""}
value=""
onChange={(e) => this.onAddressChange(e, emailAddresses.length)}
label={emailAddresses.length > 0 ? _t("Add another email") : _t("Email address")}
placeholder={emailAddresses.length > 0 ? _t("Add another email") : _t("Email address")}

View file

@ -102,7 +102,7 @@ export default class CreateGroupDialog extends React.Component<IProps, IState> {
});
};
_onCancel = () => {
private onCancel = () => {
this.props.onFinished(false);
};
@ -167,7 +167,7 @@ export default class CreateGroupDialog extends React.Component<IProps, IState> {
</div>
<div className="mx_Dialog_buttons">
<input type="submit" value={_t('Create')} className="mx_Dialog_primary" />
<button onClick={this._onCancel}>
<button onClick={this.onCancel}>
{ _t("Cancel") }
</button>
</div>

View file

@ -337,7 +337,7 @@ class FilteredList extends React.PureComponent<IFilteredListProps, IFilteredList
}
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line
if (this.props.children === nextProps.children && this.props.query === nextProps.query) return;
this.setState({
filteredChildren: FilteredList.filterChildren(nextProps.children, nextProps.query),

View file

@ -40,7 +40,7 @@ interface IState {
busy: boolean;
err?: string;
// If we know it, the nature of the abuse, as specified by MSC3215.
nature?: EXTENDED_NATURE;
nature?: ExtendedNature;
}
const MODERATED_BY_STATE_EVENT_TYPE = [
@ -55,22 +55,22 @@ const MODERATED_BY_STATE_EVENT_TYPE = [
const ABUSE_EVENT_TYPE = "org.matrix.msc3215.abuse.report";
// Standard abuse natures.
enum NATURE {
DISAGREEMENT = "org.matrix.msc3215.abuse.nature.disagreement",
TOXIC = "org.matrix.msc3215.abuse.nature.toxic",
ILLEGAL = "org.matrix.msc3215.abuse.nature.illegal",
SPAM = "org.matrix.msc3215.abuse.nature.spam",
OTHER = "org.matrix.msc3215.abuse.nature.other",
enum Nature {
Disagreement = "org.matrix.msc3215.abuse.nature.disagreement",
Toxic = "org.matrix.msc3215.abuse.nature.toxic",
Illegal = "org.matrix.msc3215.abuse.nature.illegal",
Spam = "org.matrix.msc3215.abuse.nature.spam",
Other = "org.matrix.msc3215.abuse.nature.other",
}
enum NON_STANDARD_NATURE {
enum NonStandardValue {
// Non-standard abuse nature.
// It should never leave the client - we use it to fallback to
// server-wide abuse reporting.
ADMIN = "non-standard.abuse.nature.admin"
Admin = "non-standard.abuse.nature.admin"
}
type EXTENDED_NATURE = NATURE | NON_STANDARD_NATURE;
type ExtendedNature = Nature | NonStandardValue;
type Moderation = {
// The id of the moderation room.
@ -170,7 +170,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
// The user has clicked on a nature.
private onNatureChosen = (e: React.FormEvent<HTMLInputElement>): void => {
this.setState({ nature: e.currentTarget.value as EXTENDED_NATURE });
this.setState({ nature: e.currentTarget.value as ExtendedNature });
};
// The user has clicked "cancel".
@ -187,7 +187,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
// We need a nature.
// If the nature is `NATURE.OTHER` or `NON_STANDARD_NATURE.ADMIN`, we also need a `reason`.
if (!this.state.nature ||
((this.state.nature == NATURE.OTHER || this.state.nature == NON_STANDARD_NATURE.ADMIN)
((this.state.nature == Nature.Other || this.state.nature == NonStandardValue.Admin)
&& !reason)
) {
this.setState({
@ -214,8 +214,8 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
try {
const client = MatrixClientPeg.get();
const ev = this.props.mxEvent;
if (this.moderation && this.state.nature != NON_STANDARD_NATURE.ADMIN) {
const nature: NATURE = this.state.nature;
if (this.moderation && this.state.nature != NonStandardValue.Admin) {
const nature: Nature = this.state.nature;
// Report to moderators through to the dedicated bot,
// as configured in the room's state events.
@ -274,27 +274,27 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
const homeServerName = SdkConfig.get()["validated_server_config"].hsName;
let subtitle;
switch (this.state.nature) {
case NATURE.DISAGREEMENT:
case Nature.Disagreement:
subtitle = _t("What this user is writing is wrong.\n" +
"This will be reported to the room moderators.");
break;
case NATURE.TOXIC:
case Nature.Toxic:
subtitle = _t("This user is displaying toxic behaviour, " +
"for instance by insulting other users or sharing " +
" adult-only content in a family-friendly room " +
" or otherwise violating the rules of this room.\n" +
"This will be reported to the room moderators.");
break;
case NATURE.ILLEGAL:
case Nature.Illegal:
subtitle = _t("This user is displaying illegal behaviour, " +
"for instance by doxing people or threatening violence.\n" +
"This will be reported to the room moderators who may escalate this to legal authorities.");
break;
case NATURE.SPAM:
case Nature.Spam:
subtitle = _t("This user is spamming the room with ads, links to ads or to propaganda.\n" +
"This will be reported to the room moderators.");
break;
case NON_STANDARD_NATURE.ADMIN:
case NonStandardValue.Admin:
if (client.isRoomEncrypted(this.props.mxEvent.getRoomId())) {
subtitle = _t("This room is dedicated to illegal or toxic content " +
"or the moderators fail to moderate illegal or toxic content.\n" +
@ -308,7 +308,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
{ homeserver: homeServerName });
}
break;
case NATURE.OTHER:
case Nature.Other:
subtitle = _t("Any other reason. Please describe the problem.\n" +
"This will be reported to the room moderators.");
break;
@ -327,48 +327,48 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
<div>
<StyledRadioButton
name="nature"
value = { NATURE.DISAGREEMENT }
checked = { this.state.nature == NATURE.DISAGREEMENT }
value={Nature.Disagreement}
checked={this.state.nature == Nature.Disagreement}
onChange={this.onNatureChosen}
>
{ _t('Disagree') }
</StyledRadioButton>
<StyledRadioButton
name="nature"
value = { NATURE.TOXIC }
checked = { this.state.nature == NATURE.TOXIC }
value={Nature.Toxic}
checked={this.state.nature == Nature.Toxic}
onChange={this.onNatureChosen}
>
{ _t('Toxic Behaviour') }
</StyledRadioButton>
<StyledRadioButton
name="nature"
value = { NATURE.ILLEGAL }
checked = { this.state.nature == NATURE.ILLEGAL }
value={Nature.Illegal}
checked={this.state.nature == Nature.Illegal}
onChange={this.onNatureChosen}
>
{ _t('Illegal Content') }
</StyledRadioButton>
<StyledRadioButton
name="nature"
value = { NATURE.SPAM }
checked = { this.state.nature == NATURE.SPAM }
value={Nature.Spam}
checked={this.state.nature == Nature.Spam}
onChange={this.onNatureChosen}
>
{ _t('Spam or propaganda') }
</StyledRadioButton>
<StyledRadioButton
name="nature"
value = { NON_STANDARD_NATURE.ADMIN }
checked = { this.state.nature == NON_STANDARD_NATURE.ADMIN }
value={NonStandardValue.Admin}
checked={this.state.nature == NonStandardValue.Admin}
onChange={this.onNatureChosen}
>
{ _t('Report the entire room') }
</StyledRadioButton>
<StyledRadioButton
name="nature"
value = { NATURE.OTHER }
checked = { this.state.nature == NATURE.OTHER }
value={Nature.Other}
checked={this.state.nature == Nature.Other}
onChange={this.onNatureChosen}
>
{ _t('Other') }

View file

@ -81,7 +81,7 @@ export default class UserSettingsDialog extends React.Component<IProps, IState>
this.setState({ mjolnirEnabled: newValue });
};
_getTabs() {
private getTabs() {
const tabs = [];
tabs.push(new Tab(
@ -170,7 +170,7 @@ export default class UserSettingsDialog extends React.Component<IProps, IState>
title={_t("Settings")}
>
<div className='mx_SettingsDialog_content'>
<TabbedView tabs={this._getTabs()} initialTabId={this.props.initialTabId} />
<TabbedView tabs={this.getTabs()} initialTabId={this.props.initialTabId} />
</div>
</BaseDialog>
);

View file

@ -453,13 +453,13 @@ export default class AppTile extends React.Component {
title={_t('Popout widget')}
onClick={this._onPopoutWidgetClick}
/> }
{ <ContextMenuButton
<ContextMenuButton
className="mx_AppTileMenuBar_iconButton mx_AppTileMenuBar_iconButton_menu"
label={_t("Options")}
isExpanded={this.state.menuDisplayed}
inputRef={this._contextMenuButton}
onClick={this._onContextMenuClick}
/> }
/>
</span>
</div> }
{ appTileBody }

View file

@ -83,7 +83,7 @@ export default class PersistedElement extends React.Component {
// for this, so we bodge it by listening for document resize and
// the timeline_resize action.
window.addEventListener('resize', this._repositionChild);
this._dispatcherRef = dis.register(this._onAction);
this.dispatcherRef = dis.register(this._onAction);
}
/**

View file

@ -45,7 +45,7 @@ export default class SpellCheckLanguagesDropdown extends React.Component<SpellCh
SpellCheckLanguagesDropdownIState> {
constructor(props) {
super(props);
this._onSearchChange = this._onSearchChange.bind(this);
this.onSearchChange = this.onSearchChange.bind(this);
this.state = {
searchQuery: '',
@ -76,10 +76,8 @@ export default class SpellCheckLanguagesDropdown extends React.Component<SpellCh
}
}
_onSearchChange(search) {
this.setState({
searchQuery: search,
});
private onSearchChange(searchQuery: string) {
this.setState({ searchQuery });
}
render() {
@ -117,7 +115,7 @@ export default class SpellCheckLanguagesDropdown extends React.Component<SpellCh
id="mx_LanguageDropdown"
className={this.props.className}
onOptionChange={this.props.onOptionChange}
onSearchChange={this._onSearchChange}
onSearchChange={this.onSearchChange}
searchEnabled={true}
value={value}
label={_t("Language Dropdown")}>

View file

@ -56,7 +56,7 @@ export default class TextWithTooltip extends React.Component {
{...tooltipProps}
label={tooltip}
tooltipClassName={tooltipClass}
className={"mx_TextWithTooltip_tooltip"}
className="mx_TextWithTooltip_tooltip"
/> }
</span>
);

View file

@ -304,13 +304,6 @@ export default class MImageBody extends React.Component<IProps, IState> {
this.downloadImage();
this.setState({ showImage: true });
}
this._afterComponentDidMount();
}
// To be overridden by subclasses (e.g. MStickerBody) for further
// initialisation after componentDidMount
_afterComponentDidMount() {
}
componentWillUnmount() {

View file

@ -385,7 +385,7 @@ const UserOptionsSection: React.FC<{
}
insertPillButton = (
<AccessibleButton onClick={onInsertPillButton} className={"mx_UserInfo_field"}>
<AccessibleButton onClick={onInsertPillButton} className="mx_UserInfo_field">
{ _t('Mention') }
</AccessibleButton>
);

View file

@ -106,7 +106,7 @@ export default class RelatedGroupSettings extends React.Component {
<EditableItemList
id="relatedGroups"
items={this.state.newGroupsList}
className={"mx_RelatedGroupSettings"}
className="mx_RelatedGroupSettings"
newItem={this.state.newGroupId}
canRemove={this.props.canSetRelatedGroups}
canEdit={this.props.canSetRelatedGroups}

View file

@ -431,7 +431,7 @@ export default class EventTile extends React.Component<IProps, IState> {
}
// TODO: [REACT-WARNING] Move into constructor
// eslint-disable-next-line camelcase
// eslint-disable-next-line
UNSAFE_componentWillMount() {
this.verifyEvent(this.props.mxEvent);
}
@ -453,7 +453,7 @@ export default class EventTile extends React.Component<IProps, IState> {
}
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
// eslint-disable-next-line camelcase
// eslint-disable-next-line
UNSAFE_componentWillReceiveProps(nextProps) {
// re-check the sender verification as outgoing events progress through
// the send process.

View file

@ -93,7 +93,7 @@ export default class MemberList extends React.Component<IProps, IState> {
this.showPresence = enablePresenceByHsUrl?.[hsUrl] ?? true;
}
// eslint-disable-next-line camelcase
// eslint-disable-next-line
UNSAFE_componentWillMount() {
const cli = MatrixClientPeg.get();
this.mounted = true;

View file

@ -441,7 +441,7 @@ export default class SendMessageComposer extends React.Component<IProps> {
}
// TODO: [REACT-WARNING] Move this to constructor
UNSAFE_componentWillMount() { // eslint-disable-line camelcase
UNSAFE_componentWillMount() { // eslint-disable-line
const partCreator = new CommandPartCreator(this.props.room, this.context);
const parts = this.restoreStoredEditorState(partCreator) || [];
this.model = new EditorModel(parts, partCreator);

View file

@ -64,8 +64,8 @@ export default class WhoIsTypingTile extends React.Component<IProps, IState> {
}
componentDidUpdate(_, prevState) {
const wasVisible = this._isVisible(prevState);
const isVisible = this._isVisible(this.state);
const wasVisible = WhoIsTypingTile.isVisible(prevState);
const isVisible = WhoIsTypingTile.isVisible(this.state);
if (this.props.onShown && !wasVisible && isVisible) {
this.props.onShown();
} else if (this.props.onHidden && wasVisible && !isVisible) {
@ -83,12 +83,12 @@ export default class WhoIsTypingTile extends React.Component<IProps, IState> {
Object.values(this.state.delayedStopTypingTimers).forEach((t) => (t as Timer).abort());
}
private _isVisible(state: IState): boolean {
private static isVisible(state: IState): boolean {
return state.usersTyping.length !== 0 || Object.keys(state.delayedStopTypingTimers).length !== 0;
}
public isVisible = (): boolean => {
return this._isVisible(this.state);
return WhoIsTypingTile.isVisible(this.state);
};
private onRoomTimeline = (event: MatrixEvent, room: Room): void => {

View file

@ -35,7 +35,7 @@ interface SpellCheckLanguagesIState {
}
export class ExistingSpellCheckLanguage extends React.Component<ExistingSpellCheckLanguageIProps> {
_onRemove = (e) => {
private onRemove = (e) => {
e.stopPropagation();
e.preventDefault();
@ -46,7 +46,7 @@ export class ExistingSpellCheckLanguage extends React.Component<ExistingSpellChe
return (
<div className="mx_ExistingSpellCheckLanguage">
<span className="mx_ExistingSpellCheckLanguage_language">{ this.props.language }</span>
<AccessibleButton onClick={this._onRemove} kind="danger_sm">
<AccessibleButton onClick={this.onRemove} kind="danger_sm">
{ _t("Remove") }
</AccessibleButton>
</div>
@ -63,12 +63,12 @@ export default class SpellCheckLanguages extends React.Component<SpellCheckLangu
};
}
_onRemoved = (language) => {
private onRemoved = (language: string) => {
const languages = this.props.languages.filter((e) => e !== language);
this.props.onLanguagesChange(languages);
};
_onAddClick = (e) => {
private onAddClick = (e) => {
e.stopPropagation();
e.preventDefault();
@ -81,18 +81,18 @@ export default class SpellCheckLanguages extends React.Component<SpellCheckLangu
this.props.onLanguagesChange(this.props.languages);
};
_onNewLanguageChange = (language: string) => {
private onNewLanguageChange = (language: string) => {
if (this.state.newLanguage === language) return;
this.setState({ newLanguage: language });
};
render() {
const existingSpellCheckLanguages = this.props.languages.map((e) => {
return <ExistingSpellCheckLanguage language={e} onRemoved={this._onRemoved} key={e} />;
return <ExistingSpellCheckLanguage language={e} onRemoved={this.onRemoved} key={e} />;
});
const addButton = (
<AccessibleButton onClick={this._onAddClick} kind="primary">
<AccessibleButton onClick={this.onAddClick} kind="primary">
{ _t("Add") }
</AccessibleButton>
);
@ -100,11 +100,11 @@ export default class SpellCheckLanguages extends React.Component<SpellCheckLangu
return (
<div className="mx_SpellCheckLanguages">
{ existingSpellCheckLanguages }
<form onSubmit={this._onAddClick} noValidate={true}>
<form onSubmit={this.onAddClick} noValidate={true}>
<SpellCheckLanguagesDropdown
className="mx_GeneralUserSettingsTab_spellCheckLanguageInput"
value={this.state.newLanguage}
onOptionChange={this._onNewLanguageChange} />
onOptionChange={this.onNewLanguageChange} />
{ addButton }
</form>
</div>

View file

@ -78,7 +78,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
}
// TODO: [REACT-WARNING] Move this to constructor
async UNSAFE_componentWillMount() { // eslint-disable-line camelcase
async UNSAFE_componentWillMount() { // eslint-disable-line
MatrixClientPeg.get().on("RoomState.events", this.onStateEvent);
const room = MatrixClientPeg.get().getRoom(this.props.roomId);

View file

@ -407,10 +407,10 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
<StyledRadioButton
name="layout"
value="irc"
checked={this.state.layout == Layout.IRC}
checked={this.state.layout === Layout.IRC}
onChange={this.onLayoutChange}
>
{ "IRC" }
{ _t("IRC") }
</StyledRadioButton>
</div>
<div className="mx_AppearanceUserSettingsTab_spacer" />
@ -436,7 +436,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
</div>
<div className="mx_AppearanceUserSettingsTab_spacer" />
<div className={classNames("mx_AppearanceUserSettingsTab_Layout_RadioButton", {
mx_AppearanceUserSettingsTab_Layout_RadioButton_selected: this.state.layout == Layout.Bubble,
mx_AppearanceUserSettingsTab_Layout_RadioButton_selected: this.state.layout === Layout.Bubble,
})}>
<EventTilePreview
className="mx_AppearanceUserSettingsTab_Layout_RadioButton_preview"

View file

@ -60,14 +60,14 @@ export default class VerificationRequestToast extends React.PureComponent<IProps
this.setState({ counter });
}, 1000);
}
request.on("change", this._checkRequestIsPending);
request.on("change", this.checkRequestIsPending);
// We should probably have a separate class managing the active verification toasts,
// rather than monitoring this in the toast component itself, since we'll get problems
// like the toasdt not going away when the verification is cancelled unless it's the
// one on the top (ie. the one that's mounted).
// As a quick & dirty fix, check the toast is still relevant when it mounts (this prevents
// a toast hanging around after logging in if you did a verification as part of login).
this._checkRequestIsPending();
this.checkRequestIsPending();
if (request.isSelfVerification) {
const cli = MatrixClientPeg.get();
@ -83,10 +83,10 @@ export default class VerificationRequestToast extends React.PureComponent<IProps
componentWillUnmount() {
clearInterval(this.intervalHandle);
const { request } = this.props;
request.off("change", this._checkRequestIsPending);
request.off("change", this.checkRequestIsPending);
}
_checkRequestIsPending = () => {
private checkRequestIsPending = () => {
const { request } = this.props;
if (!request.canAccept) {
ToastStore.sharedInstance().dismissToast(this.props.toastKey);

View file

@ -513,7 +513,9 @@ export default class CallView extends React.Component<IProps, IState> {
transferee: transfereeName,
},
{
a: sub => <AccessibleButton kind="link" onClick={this.onTransferClick}>{sub}</AccessibleButton>,
a: sub => <AccessibleButton kind="link" onClick={this.onTransferClick}>
{ sub }
</AccessibleButton>,
},
) }
</div>;

View file

@ -144,7 +144,7 @@ export default class IncomingCallBox extends React.Component<IProps, IState> {
</div>
<div className="mx_IncomingCallBox_buttons">
<AccessibleButton
className={"mx_IncomingCallBox_decline"}
className="mx_IncomingCallBox_decline"
onClick={this.onRejectClick}
kind="danger"
>
@ -152,7 +152,7 @@ export default class IncomingCallBox extends React.Component<IProps, IState> {
</AccessibleButton>
<div className="mx_IncomingCallBox_spacer" />
<AccessibleButton
className={"mx_IncomingCallBox_accept"}
className="mx_IncomingCallBox_accept"
onClick={this.onAnswerClick}
kind="primary"
>

View file

@ -17,6 +17,7 @@ limitations under the License.
import { MatrixClient } from "matrix-js-sdk/src/client";
import { Room } from "matrix-js-sdk/src/models/room";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { MatrixClientPeg } from './MatrixClientPeg';
@ -247,11 +248,11 @@ export function findDMForUser(client: MatrixClient, userId: string): Room {
* NOTE: this assumes you've just created the room and there's not been an opportunity
* for other code to run, so we shouldn't miss RoomState.newMember when it comes by.
*/
export async function _waitForMember(client: MatrixClient, roomId: string, userId: string, opts = { timeout: 1500 }) {
export async function waitForMember(client: MatrixClient, roomId: string, userId: string, opts = { timeout: 1500 }) {
const { timeout } = opts;
let handler;
return new Promise((resolve) => {
handler = function(_event, _roomstate, member) {
handler = function(_, __, member: RoomMember) { // eslint-disable-line @typescript-eslint/naming-convention
if (member.userId !== userId) return;
if (member.roomId !== roomId) return;
resolve(true);
@ -324,7 +325,7 @@ export async function ensureDMExists(client: MatrixClient, userId: string): Prom
}
roomId = await createRoom({ encryption, dmUserId: userId, spinner: false, andView: false });
await _waitForMember(client, roomId, userId);
await waitForMember(client, roomId, userId);
}
return roomId;
}

View file

@ -274,7 +274,7 @@ abstract class PillPart extends BasePart implements IPillPart {
}
// helper method for subclasses
_setAvatarVars(node: HTMLElement, avatarUrl: string, initialLetter: string) {
protected setAvatarVars(node: HTMLElement, avatarUrl: string, initialLetter: string) {
const avatarBackground = `url('${avatarUrl}')`;
const avatarLetter = `'${initialLetter}'`;
// check if the value is changing,
@ -354,7 +354,7 @@ class RoomPillPart extends PillPart {
initialLetter = Avatar.getInitialLetter(this.room ? this.room.name : this.resourceId);
avatarUrl = Avatar.defaultAvatarUrlForString(this.room ? this.room.roomId : this.resourceId);
}
this._setAvatarVars(node, avatarUrl, initialLetter);
this.setAvatarVars(node, avatarUrl, initialLetter);
}
get type(): IPillPart["type"] {
@ -399,7 +399,7 @@ class UserPillPart extends PillPart {
if (avatarUrl === defaultAvatarUrl) {
initialLetter = Avatar.getInitialLetter(name);
}
this._setAvatarVars(node, avatarUrl, initialLetter);
this.setAvatarVars(node, avatarUrl, initialLetter);
}
get type(): IPillPart["type"] {

View file

@ -1247,6 +1247,7 @@
"Add theme": "Add theme",
"Theme": "Theme",
"Message layout": "Message layout",
"IRC": "IRC",
"Modern": "Modern",
"Message bubbles": "Message bubbles",
"Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Set the name of a font installed on your system & %(brand)s will attempt to use it.",

View file

@ -67,7 +67,7 @@ export function getUserLanguage(): string {
// Function which only purpose is to mark that a string is translatable
// Does not actually do anything. It's helpful for automatic extraction of translatable strings
export function _td(s: string): string {
export function _td(s: string): string { // eslint-disable-line @typescript-eslint/naming-convention
return s;
}
@ -132,6 +132,8 @@ export type TranslatedString = string | React.ReactNode;
*
* @return a React <span> component if any non-strings were used in substitutions, otherwise a string
*/
// eslint-next-line @typescript-eslint/naming-convention
// eslint-nexline @typescript-eslint/naming-convention
export function _t(text: string, variables?: IVariables): string;
export function _t(text: string, variables: IVariables, tags: Tags): React.ReactNode;
export function _t(text: string, variables?: IVariables, tags?: Tags): TranslatedString {

View file

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { ALL_RULE_TYPES, BanList } from "./BanList";
import SettingsStore from "../settings/SettingsStore";
@ -21,19 +22,17 @@ import { _t } from "../languageHandler";
import dis from "../dispatcher/dispatcher";
import { SettingLevel } from "../settings/SettingLevel";
import { Preset } from "matrix-js-sdk/src/@types/partials";
import { ActionPayload } from "../dispatcher/payloads";
// TODO: Move this and related files to the js-sdk or something once finalized.
export class Mjolnir {
static _instance: Mjolnir = null;
private static instance: Mjolnir = null;
_lists: BanList[] = [];
_roomIds: string[] = [];
_mjolnirWatchRef = null;
_dispatcherRef = null;
constructor() {
}
private _lists: BanList[] = []; // eslint-disable-line @typescript-eslint/naming-convention
private _roomIds: string[] = []; // eslint-disable-line @typescript-eslint/naming-convention
private mjolnirWatchRef: string = null;
private dispatcherRef: string = null;
get roomIds(): string[] {
return this._roomIds;
@ -44,16 +43,16 @@ export class Mjolnir {
}
start() {
this._mjolnirWatchRef = SettingsStore.watchSetting("mjolnirRooms", null, this._onListsChanged.bind(this));
this.mjolnirWatchRef = SettingsStore.watchSetting("mjolnirRooms", null, this.onListsChanged.bind(this));
this._dispatcherRef = dis.register(this._onAction);
this.dispatcherRef = dis.register(this.onAction);
dis.dispatch({
action: 'do_after_sync_prepared',
deferred_action: { action: 'setup_mjolnir' },
});
}
_onAction = (payload) => {
private onAction = (payload: ActionPayload) => {
if (payload['action'] === 'setup_mjolnir') {
console.log("Setting up Mjolnir: after sync");
this.setup();
@ -62,23 +61,23 @@ export class Mjolnir {
setup() {
if (!MatrixClientPeg.get()) return;
this._updateLists(SettingsStore.getValue("mjolnirRooms"));
MatrixClientPeg.get().on("RoomState.events", this._onEvent);
this.updateLists(SettingsStore.getValue("mjolnirRooms"));
MatrixClientPeg.get().on("RoomState.events", this.onEvent);
}
stop() {
if (this._mjolnirWatchRef) {
SettingsStore.unwatchSetting(this._mjolnirWatchRef);
this._mjolnirWatchRef = null;
if (this.mjolnirWatchRef) {
SettingsStore.unwatchSetting(this.mjolnirWatchRef);
this.mjolnirWatchRef = null;
}
if (this._dispatcherRef) {
dis.unregister(this._dispatcherRef);
this._dispatcherRef = null;
if (this.dispatcherRef) {
dis.unregister(this.dispatcherRef);
this.dispatcherRef = null;
}
if (!MatrixClientPeg.get()) return;
MatrixClientPeg.get().removeListener("RoomState.events", this._onEvent);
MatrixClientPeg.get().removeListener("RoomState.events", this.onEvent);
}
async getOrCreatePersonalList(): Promise<BanList> {
@ -132,20 +131,20 @@ export class Mjolnir {
this._lists = this._lists.filter(b => b.roomId !== roomId);
}
_onEvent = (event) => {
private onEvent = (event: MatrixEvent) => {
if (!MatrixClientPeg.get()) return;
if (!this._roomIds.includes(event.getRoomId())) return;
if (!ALL_RULE_TYPES.includes(event.getType())) return;
this._updateLists(this._roomIds);
this.updateLists(this._roomIds);
};
_onListsChanged(settingName, roomId, atLevel, newValue) {
private onListsChanged(settingName: string, roomId: string, atLevel: SettingLevel, newValue: string[]) {
// We know that ban lists are only recorded at one level so we don't need to re-eval them
this._updateLists(newValue);
this.updateLists(newValue);
}
_updateLists(listRoomIds: string[]) {
private updateLists(listRoomIds: string[]) {
if (!MatrixClientPeg.get()) return;
console.log("Updating Mjolnir ban lists to: " + listRoomIds);
@ -182,10 +181,10 @@ export class Mjolnir {
}
static sharedInstance(): Mjolnir {
if (!Mjolnir._instance) {
Mjolnir._instance = new Mjolnir();
if (!Mjolnir.instance) {
Mjolnir.instance = new Mjolnir();
}
return Mjolnir._instance;
return Mjolnir.instance;
}
}

View file

@ -203,7 +203,7 @@ export default async function sendBugReport(bugReportEndpoint: string, opts: IOp
const body = await collectBugReport(opts);
progressCallback(_t("Uploading logs"));
await _submitReport(bugReportEndpoint, body, progressCallback);
await submitReport(bugReportEndpoint, body, progressCallback);
}
/**
@ -289,10 +289,10 @@ export async function submitFeedback(
body.append(k, extraData[k]);
}
await _submitReport(SdkConfig.get().bug_report_endpoint_url, body, () => {});
await submitReport(SdkConfig.get().bug_report_endpoint_url, body, () => {});
}
function _submitReport(endpoint: string, body: FormData, progressCallback: (string) => void) {
function submitReport(endpoint: string, body: FormData, progressCallback: (str: string) => void) {
return new Promise<void>((resolve, reject) => {
const req = new XMLHttpRequest();
req.open("POST", endpoint);

View file

@ -49,7 +49,7 @@ class GroupFilterOrderStore extends Store {
this.__emitChange();
}
__onDispatch(payload) {
__onDispatch(payload) { // eslint-disable-line @typescript-eslint/naming-convention
switch (payload.action) {
// Initialise state after initial sync
case 'view_room': {

View file

@ -44,7 +44,7 @@ class LifecycleStore extends Store<ActionPayload> {
this.__emitChange();
}
protected __onDispatch(payload: ActionPayload) {
protected __onDispatch(payload: ActionPayload) { // eslint-disable-line @typescript-eslint/naming-convention
switch (payload.action) {
case 'do_after_sync_prepared':
this.setState({

View file

@ -144,7 +144,7 @@ export default class RightPanelStore extends Store<ActionPayload> {
this.__emitChange();
}
__onDispatch(payload: ActionPayload) {
__onDispatch(payload: ActionPayload) { // eslint-disable-line @typescript-eslint/naming-convention
switch (payload.action) {
case 'view_room':
if (payload.room_id === this.lastRoomId) break; // skip this transition, probably a permalink

View file

@ -96,7 +96,7 @@ class RoomViewStore extends Store<ActionPayload> {
this.__emitChange();
}
__onDispatch(payload) {
__onDispatch(payload) { // eslint-disable-line @typescript-eslint/naming-convention
switch (payload.action) {
// view_room:
// - room_alias: '#somealias:matrix.org'

View file

@ -63,7 +63,7 @@ const PREVIEWS = {
const MAX_EVENTS_BACKWARDS = 50;
// type merging ftw
type TAG_ANY = "im.vector.any";
type TAG_ANY = "im.vector.any"; // eslint-disable-line @typescript-eslint/naming-convention
const TAG_ANY: TAG_ANY = "im.vector.any";
interface IState {

View file

@ -20,7 +20,7 @@ import { EventType, MsgType } from "matrix-js-sdk/src/@types/event";
import { ElementWidgetCapabilities } from "../stores/widgets/ElementWidgetCapabilities";
import React from "react";
type GENERIC_WIDGET_KIND = "generic";
type GENERIC_WIDGET_KIND = "generic"; // eslint-disable-line @typescript-eslint/naming-convention
const GENERIC_WIDGET_KIND: GENERIC_WIDGET_KIND = "generic";
interface ISendRecvStaticCapText {

View file

@ -1,5 +1,5 @@
import './skinned-sdk'; // Must be first for skinning to work
import { _waitForMember, canEncryptToAllUsers } from '../src/createRoom';
import { waitForMember, canEncryptToAllUsers } from '../src/createRoom';
import { EventEmitter } from 'events';
/* Shorter timeout, we've got tests to run */
@ -13,7 +13,7 @@ describe("waitForMember", () => {
});
it("resolves with false if the timeout is reached", (done) => {
_waitForMember(client, "", "", { timeout: 0 }).then((r) => {
waitForMember(client, "", "", { timeout: 0 }).then((r) => {
expect(r).toBe(false);
done();
});
@ -22,7 +22,7 @@ describe("waitForMember", () => {
it("resolves with false if the timeout is reached, even if other RoomState.newMember events fire", (done) => {
const roomId = "!roomId:domain";
const userId = "@clientId:domain";
_waitForMember(client, roomId, userId, { timeout }).then((r) => {
waitForMember(client, roomId, userId, { timeout }).then((r) => {
expect(r).toBe(false);
done();
});
@ -32,7 +32,7 @@ describe("waitForMember", () => {
it("resolves with true if RoomState.newMember fires", (done) => {
const roomId = "!roomId:domain";
const userId = "@clientId:domain";
_waitForMember(client, roomId, userId, { timeout }).then((r) => {
waitForMember(client, roomId, userId, { timeout }).then((r) => {
expect(r).toBe(true);
expect(client.listeners("RoomState.newMember").length).toBe(0);
done();

View file

@ -3242,7 +3242,7 @@ eslint-config-google@^0.14.0:
"eslint-plugin-matrix-org@github:matrix-org/eslint-plugin-matrix-org#main":
version "0.3.2"
resolved "https://codeload.github.com/matrix-org/eslint-plugin-matrix-org/tar.gz/383a1e4a9ef7944c921efda0de2ac9635d45cb5c"
resolved "https://codeload.github.com/matrix-org/eslint-plugin-matrix-org/tar.gz/8529f1d77863db6327cf1a1a4fa65d06cc26f91b"
eslint-plugin-react-hooks@^4.2.0:
version "4.2.0"