Enable @typescript-eslint/explicit-function-return-type in /src (#9788)

* Enable `@typescript-eslint/explicit-member-accessibility` on /src

* Prettier

* Enable `@typescript-eslint/explicit-function-return-type` in /src

* Fix types

* tsc strict fixes

* Delint

* Fix test

* Fix bad merge
This commit is contained in:
Michael Telatynski 2023-01-12 13:25:14 +00:00 committed by GitHub
parent 7a36ba0fde
commit 030b7e90bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
683 changed files with 3459 additions and 3013 deletions

View file

@ -45,7 +45,7 @@ export const AddPrivilegedUsers: React.FC<AddPrivilegedUsersProps> = ({ room, de
[room, defaultUserLevel],
);
const onSubmit = async (event: FormEvent) => {
const onSubmit = async (event: FormEvent): Promise<void> => {
event.preventDefault();
setIsLoading(true);
@ -106,7 +106,11 @@ export const AddPrivilegedUsers: React.FC<AddPrivilegedUsersProps> = ({ room, de
);
};
export const hasLowerOrEqualLevelThanDefaultLevel = (room: Room, user: ICompletion, defaultUserLevel: number) => {
export const hasLowerOrEqualLevelThanDefaultLevel = (
room: Room,
user: ICompletion,
defaultUserLevel: number,
): boolean => {
if (user.completionId === undefined) {
return false;
}
@ -120,7 +124,7 @@ export const hasLowerOrEqualLevelThanDefaultLevel = (room: Room, user: ICompleti
return member.powerLevel <= defaultUserLevel;
};
export const getUserIdsFromCompletions = (completions: ICompletion[]) => {
export const getUserIdsFromCompletions = (completions: ICompletion[]): string[] => {
const completionsWithId = completions.filter((completion) => completion.completionId !== undefined);
// undefined completionId's are filtered out above but TypeScript does not seem to understand.

View file

@ -65,7 +65,7 @@ interface IBridgeStateEvent {
}
export default class BridgeTile extends React.PureComponent<IProps> {
public render() {
public render(): JSX.Element {
const content: IBridgeStateEvent = this.props.ev.getContent();
// Validate
if (!content.channel?.id || !content.protocol?.id) {

View file

@ -49,7 +49,7 @@ export default class CrossSigningPanel extends React.PureComponent<{}, IState> {
this.state = {};
}
public componentDidMount() {
public componentDidMount(): void {
const cli = MatrixClientPeg.get();
cli.on(ClientEvent.AccountData, this.onAccountData);
cli.on(CryptoEvent.UserTrustStatusChanged, this.onStatusChanged);
@ -57,7 +57,7 @@ export default class CrossSigningPanel extends React.PureComponent<{}, IState> {
this.getUpdatedStatus();
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this.unmounted = true;
const cli = MatrixClientPeg.get();
if (!cli) return;
@ -73,7 +73,7 @@ export default class CrossSigningPanel extends React.PureComponent<{}, IState> {
}
};
private onBootstrapClick = () => {
private onBootstrapClick = (): void => {
if (this.state.crossSigningPrivateKeysInStorage) {
Modal.createDialog(SetupEncryptionDialog, {}, null, /* priority = */ false, /* static = */ true);
} else {
@ -83,7 +83,7 @@ export default class CrossSigningPanel extends React.PureComponent<{}, IState> {
}
};
private onStatusChanged = () => {
private onStatusChanged = (): void => {
this.getUpdatedStatus();
};
@ -127,7 +127,7 @@ export default class CrossSigningPanel extends React.PureComponent<{}, IState> {
try {
const cli = MatrixClientPeg.get();
await cli.bootstrapCrossSigning({
authUploadDeviceSigningKeys: async (makeRequest) => {
authUploadDeviceSigningKeys: async (makeRequest): Promise<void> => {
const { finished } = Modal.createDialog(InteractiveAuthDialog, {
title: _t("Setting up keys"),
matrixClient: cli,
@ -157,7 +157,7 @@ export default class CrossSigningPanel extends React.PureComponent<{}, IState> {
});
};
public render() {
public render(): JSX.Element {
const {
error,
crossSigningPublicKeysOnDevice,

View file

@ -64,7 +64,7 @@ export default class DevicesPanel extends React.Component<IProps, IState> {
this.unmounted = true;
}
private onDevicesUpdated = (users: string[]) => {
private onDevicesUpdated = (users: string[]): void => {
if (!users.includes(this.context.getUserId())) return;
this.loadDevices();
};

View file

@ -69,7 +69,7 @@ export default class DevicesPanelEntry extends React.Component<IProps, IState> {
});
};
private onRenameSubmit = async () => {
private onRenameSubmit = async (): Promise<void> => {
this.setState({ renaming: false });
await MatrixClientPeg.get()
.setDeviceDetails(this.props.device.device_id, {
@ -96,7 +96,7 @@ export default class DevicesPanelEntry extends React.Component<IProps, IState> {
);
};
private verify = async () => {
private verify = async (): Promise<void> => {
if (this.props.isOwnDevice) {
Modal.createDialog(SetupEncryptionDialog, {
onFinished: this.props.onDeviceChange,
@ -108,7 +108,7 @@ export default class DevicesPanelEntry extends React.Component<IProps, IState> {
Modal.createDialog(VerificationRequestDialog, {
verificationRequestPromise,
member: cli.getUser(userId),
onFinished: async () => {
onFinished: async (): Promise<void> => {
const request = await verificationRequestPromise;
request.cancel();
this.props.onDeviceChange();

View file

@ -23,7 +23,7 @@ import SettingsFlag from "../elements/SettingsFlag";
const SETTING_MANUALLY_VERIFY_ALL_SESSIONS = "e2ee.manuallyVerifyAllSessions";
const E2eAdvancedPanel = (props) => {
const E2eAdvancedPanel: React.FC = () => {
return (
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Encryption")}</span>

View file

@ -46,7 +46,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
};
}
public updateCurrentRoom = async () => {
public updateCurrentRoom = async (): Promise<void> => {
const eventIndex = EventIndexPeg.get();
let stats;
@ -76,7 +76,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
this.updateState();
}
public async updateState() {
public async updateState(): Promise<void> {
const eventIndex = EventIndexPeg.get();
const eventIndexingEnabled = SettingsStore.getValueAt(SettingLevel.DEVICE, "enableEventIndexing");
const enabling = false;
@ -106,7 +106,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
});
}
private onManage = async () => {
private onManage = async (): Promise<void> => {
Modal.createDialogAsync(
// @ts-ignore: TS doesn't seem to like the type of this now that it
// has also been converted to TS as well, but I can't figure out why...
@ -120,7 +120,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
);
};
private onEnable = async () => {
private onEnable = async (): Promise<void> => {
this.setState({
enabling: true,
});
@ -132,9 +132,9 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
await this.updateState();
};
private confirmEventStoreReset = () => {
private confirmEventStoreReset = (): void => {
const { close } = Modal.createDialog(SeshatResetDialog, {
onFinished: async (success) => {
onFinished: async (success): Promise<void> => {
if (success) {
await SettingsStore.setValue("enableEventIndexing", null, SettingLevel.DEVICE, false);
await EventIndexPeg.deleteEventIndex();
@ -145,7 +145,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
});
};
public render() {
public render(): JSX.Element {
let eventIndexingSettings = null;
const brand = SdkConfig.get().brand;

View file

@ -61,7 +61,7 @@ export default class FontScalingPanel extends React.Component<IProps, IState> {
};
}
public async componentDidMount() {
public async componentDidMount(): Promise<void> {
// Fetch the current user profile for the message preview
const client = MatrixClientPeg.get();
const userId = client.getUserId();
@ -75,7 +75,7 @@ export default class FontScalingPanel extends React.Component<IProps, IState> {
});
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this.unmounted = true;
}
@ -105,7 +105,7 @@ export default class FontScalingPanel extends React.Component<IProps, IState> {
return { valid: true, feedback: _t("Use between %(min)s pt and %(max)s pt", { min, max }) };
};
public render() {
public render(): JSX.Element {
return (
<div className="mx_SettingsTab_section mx_FontScalingPanel">
<span className="mx_SettingsTab_subheading">{_t("Font size")}</span>

View file

@ -46,7 +46,14 @@ interface IProps {
aliasWarning?: ReactNode;
}
const JoinRuleSettings = ({ room, promptUpgrade, aliasWarning, onError, beforeChange, closeSettingsFn }: IProps) => {
const JoinRuleSettings: React.FC<IProps> = ({
room,
promptUpgrade,
aliasWarning,
onError,
beforeChange,
closeSettingsFn,
}) => {
const cli = room.client;
const roomSupportsRestricted = doesRoomVersionSupport(room.getVersion(), PreferredRoomVersions.RestrictedRooms);
@ -135,7 +142,7 @@ const JoinRuleSettings = ({ room, promptUpgrade, aliasWarning, onError, beforeCh
}
}
const onRestrictedRoomIdsChange = (newAllowRoomIds: string[]) => {
const onRestrictedRoomIdsChange = (newAllowRoomIds: string[]): void => {
if (!arrayHasDiff(restrictedAllowRoomIds || [], newAllowRoomIds)) return;
if (!newAllowRoomIds.length) {
@ -154,7 +161,7 @@ const JoinRuleSettings = ({ room, promptUpgrade, aliasWarning, onError, beforeCh
});
};
const onEditRestrictedClick = async () => {
const onEditRestrictedClick = async (): Promise<void> => {
const restrictedAllowRoomIds = await editRestrictedRoomIds();
if (!Array.isArray(restrictedAllowRoomIds)) return;
if (restrictedAllowRoomIds.length > 0) {
@ -224,7 +231,7 @@ const JoinRuleSettings = ({ room, promptUpgrade, aliasWarning, onError, beforeCh
});
}
const onChange = async (joinRule: JoinRule) => {
const onChange = async (joinRule: JoinRule): Promise<void> => {
const beforeJoinRule = content.join_rule;
let restrictedAllowRoomIds: string[];

View file

@ -155,13 +155,13 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
return this.state.masterPushRule?.enabled;
}
public componentDidMount() {
public componentDidMount(): void {
// noinspection JSIgnoredPromiseFromCall
this.refreshFromServer();
this.refreshFromAccountData();
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this.settingWatchers.forEach((watcher) => SettingsStore.unwatchSetting(watcher));
}
@ -171,7 +171,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
}
}
private async refreshFromServer() {
private async refreshFromServer(): Promise<void> {
try {
const newState = (
await Promise.all([this.refreshRules(), this.refreshPushers(), this.refreshThreepids()])
@ -196,7 +196,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
}
}
private async refreshFromAccountData() {
private async refreshFromAccountData(): Promise<void> {
const cli = MatrixClientPeg.get();
const settingsEvent = cli.getAccountData(getLocalNotificationAccountDataEventType(cli.deviceId));
if (settingsEvent) {
@ -317,14 +317,14 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
return MatrixClientPeg.get().getThreePids();
}
private showSaveError() {
private showSaveError(): void {
Modal.createDialog(ErrorDialog, {
title: _t("Error saving notification preferences"),
description: _t("An error occurred whilst saving your notification preferences."),
});
}
private onMasterRuleChanged = async (checked: boolean) => {
private onMasterRuleChanged = async (checked: boolean): Promise<void> => {
this.setState({ phase: Phase.Persisting });
try {
@ -338,11 +338,11 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
}
};
private updateDeviceNotifications = async (checked: boolean) => {
private updateDeviceNotifications = async (checked: boolean): Promise<void> => {
await SettingsStore.setValue("deviceNotificationsEnabled", null, SettingLevel.DEVICE, checked);
};
private onEmailNotificationsChanged = async (email: string, checked: boolean) => {
private onEmailNotificationsChanged = async (email: string, checked: boolean): Promise<void> => {
this.setState({ phase: Phase.Persisting });
try {
@ -376,19 +376,19 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
}
};
private onDesktopNotificationsChanged = async (checked: boolean) => {
private onDesktopNotificationsChanged = async (checked: boolean): Promise<void> => {
await SettingsStore.setValue("notificationsEnabled", null, SettingLevel.DEVICE, checked);
};
private onDesktopShowBodyChanged = async (checked: boolean) => {
private onDesktopShowBodyChanged = async (checked: boolean): Promise<void> => {
await SettingsStore.setValue("notificationBodyEnabled", null, SettingLevel.DEVICE, checked);
};
private onAudioNotificationsChanged = async (checked: boolean) => {
private onAudioNotificationsChanged = async (checked: boolean): Promise<void> => {
await SettingsStore.setValue("audioNotificationsEnabled", null, SettingLevel.DEVICE, checked);
};
private onRadioChecked = async (rule: IVectorPushRule, checkedState: VectorState) => {
private onRadioChecked = async (rule: IVectorPushRule, checkedState: VectorState): Promise<void> => {
this.setState({ phase: Phase.Persisting });
try {
@ -454,7 +454,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
}
};
private async setKeywords(keywords: string[], originalRules: IAnnotatedPushRule[]) {
private async setKeywords(keywords: string[], originalRules: IAnnotatedPushRule[]): Promise<void> {
try {
// De-duplicate and remove empties
keywords = Array.from(new Set(keywords)).filter((k) => !!k);
@ -502,7 +502,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
}
}
private onKeywordAdd = (keyword: string) => {
private onKeywordAdd = (keyword: string): void => {
const originalRules = objectClone(this.state.vectorKeywordRuleInfo.rules);
// We add the keyword immediately as a sort of local echo effect
@ -519,7 +519,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
],
},
},
async () => {
async (): Promise<void> => {
await this.setKeywords(
this.state.vectorKeywordRuleInfo.rules.map((r) => r.pattern),
originalRules,
@ -528,7 +528,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
);
};
private onKeywordRemove = (keyword: string) => {
private onKeywordRemove = (keyword: string): void => {
const originalRules = objectClone(this.state.vectorKeywordRuleInfo.rules);
// We remove the keyword immediately as a sort of local echo effect
@ -540,7 +540,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
rules: this.state.vectorKeywordRuleInfo.rules.filter((r) => r.pattern !== keyword),
},
},
async () => {
async (): Promise<void> => {
await this.setKeywords(
this.state.vectorKeywordRuleInfo.rules.map((r) => r.pattern),
originalRules,
@ -549,7 +549,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
);
};
private renderTopSection() {
private renderTopSection(): JSX.Element {
const masterSwitch = (
<LabelledToggleSwitch
data-testid="notif-master-switch"
@ -622,7 +622,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
);
}
private renderCategory(category: RuleClass) {
private renderCategory(category: RuleClass): JSX.Element {
if (category !== RuleClass.VectorOther && this.isInhibited) {
return null; // nothing to show for the section
}
@ -680,7 +680,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
[VectorState.Loud]: _t("Noisy"),
};
const makeRadio = (r: IVectorPushRule, s: VectorState) => (
const makeRadio = (r: IVectorPushRule, s: VectorState): JSX.Element => (
<StyledRadioButton
key={r.ruleId + s}
name={r.ruleId}
@ -736,7 +736,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
);
}
private renderTargets() {
private renderTargets(): JSX.Element {
if (this.isInhibited) return null; // no targets if there's no notifications
const rows = this.state.pushers.map((p) => (
@ -758,7 +758,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
);
}
public render() {
public render(): JSX.Element {
if (this.state.phase === Phase.Loading) {
// Ends up default centered
return <Spinner />;

View file

@ -206,7 +206,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
private resetSecretStorage = async (): Promise<void> => {
this.setState({ error: null });
try {
await accessSecretStorage(async () => {}, /* forceReset = */ true);
await accessSecretStorage(async (): Promise<void> => {}, /* forceReset = */ true);
} catch (e) {
logger.error("Error resetting secret storage", e);
if (this.unmounted) return;
@ -286,12 +286,12 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
let backupSigStatuses: React.ReactNode = backupSigStatus.sigs.map((sig, i) => {
const deviceName = sig.device ? sig.device.getDisplayName() || sig.device.deviceId : null;
const validity = (sub) => (
const validity = (sub: string): JSX.Element => (
<span className={sig.valid ? "mx_SecureBackupPanel_sigValid" : "mx_SecureBackupPanel_sigInvalid"}>
{sub}
</span>
);
const verify = (sub) => (
const verify = (sub: string): JSX.Element => (
<span
className={
sig.device && sig.deviceTrust.isVerified()
@ -302,7 +302,9 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
{sub}
</span>
);
const device = (sub) => <span className="mx_SecureBackupPanel_deviceName">{deviceName}</span>;
const device = (sub: string): JSX.Element => (
<span className="mx_SecureBackupPanel_deviceName">{deviceName}</span>
);
const fromThisDevice =
sig.device && sig.device.getFingerprint() === MatrixClientPeg.get().getDeviceEd25519Key();
const fromThisUser = sig.crossSigningId && sig.deviceId === MatrixClientPeg.get().getCrossSigningId();

View file

@ -15,8 +15,9 @@ limitations under the License.
*/
import url from "url";
import React from "react";
import React, { ReactNode } from "react";
import { logger } from "matrix-js-sdk/src/logger";
import { IThreepid } from "matrix-js-sdk/src/@types/threepids";
import { _t } from "../../../languageHandler";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
@ -42,7 +43,7 @@ const REACHABILITY_TIMEOUT = 10000; // ms
* @param {string} u The url to check
* @returns {string} null if url passes all checks, otherwise i18ned error string
*/
async function checkIdentityServerUrl(u) {
async function checkIdentityServerUrl(u: string): Promise<string | null> {
const parsedUrl = url.parse(u);
if (parsedUrl.protocol !== "https:") return _t("Identity server URL must be HTTPS");
@ -111,7 +112,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
dis.unregister(this.dispatcherRef);
}
private onAction = (payload: ActionPayload) => {
private onAction = (payload: ActionPayload): void => {
// We react to changes in the identity server in the event the user is staring at this form
// when changing their identity server on another device.
if (payload.action !== "id_server_changed") return;
@ -121,13 +122,13 @@ export default class SetIdServer extends React.Component<IProps, IState> {
});
};
private onIdentityServerChanged = (ev) => {
private onIdentityServerChanged = (ev: React.ChangeEvent<HTMLInputElement>): void => {
const u = ev.target.value;
this.setState({ idServer: u });
};
private getTooltip = () => {
private getTooltip = (): JSX.Element => {
if (this.state.checking) {
return (
<div>
@ -142,11 +143,11 @@ export default class SetIdServer extends React.Component<IProps, IState> {
}
};
private idServerChangeEnabled = () => {
private idServerChangeEnabled = (): boolean => {
return !!this.state.idServer && !this.state.busy;
};
private saveIdServer = (fullUrl) => {
private saveIdServer = (fullUrl: string): void => {
// Account data change will update localstorage, client, etc through dispatcher
MatrixClientPeg.get().setAccountData("m.identity_server", {
base_url: fullUrl,
@ -159,7 +160,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
});
};
private checkIdServer = async (e) => {
private checkIdServer = async (e: React.SyntheticEvent): Promise<void> => {
e.preventDefault();
const { idServer, currentClientIdServer } = this.state;
@ -220,8 +221,8 @@ export default class SetIdServer extends React.Component<IProps, IState> {
});
};
private showNoTermsWarning(fullUrl) {
const { finished } = Modal.createDialog(QuestionDialog, {
private showNoTermsWarning(fullUrl: string): Promise<[boolean]> {
const { finished } = Modal.createDialog<[boolean]>(QuestionDialog, {
title: _t("Identity server has no terms of service"),
description: (
<div>
@ -236,7 +237,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
return finished;
}
private onDisconnectClicked = async () => {
private onDisconnectClicked = async (): Promise<void> => {
this.setState({ disconnectBusy: true });
try {
const [confirmed] = await this.showServerChangeWarning({
@ -256,10 +257,18 @@ export default class SetIdServer extends React.Component<IProps, IState> {
}
};
private async showServerChangeWarning({ title, unboundMessage, button }) {
private async showServerChangeWarning({
title,
unboundMessage,
button,
}: {
title: string;
unboundMessage: ReactNode;
button: string;
}): Promise<[boolean]> {
const { currentClientIdServer } = this.state;
let threepids = [];
let threepids: IThreepid[] = [];
let currentServerReachable = true;
try {
threepids = await timeout(
@ -341,7 +350,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
message = unboundMessage;
}
const { finished } = Modal.createDialog(QuestionDialog, {
const { finished } = Modal.createDialog<[boolean]>(QuestionDialog, {
title,
description: message,
button,
@ -351,7 +360,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
return finished;
}
private disconnectIdServer = () => {
private disconnectIdServer = (): void => {
// Account data change will update localstorage, client, etc through dispatcher
MatrixClientPeg.get().setAccountData("m.identity_server", {
base_url: null, // clear
@ -372,7 +381,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
});
};
public render() {
public render(): JSX.Element {
const idServerUrl = this.state.currentClientIdServer;
let sectionTitle;
let bodyText;

View file

@ -35,14 +35,14 @@ interface SpellCheckLanguagesIState {
}
export class ExistingSpellCheckLanguage extends React.Component<ExistingSpellCheckLanguageIProps> {
private onRemove = (e) => {
private onRemove = (e): void => {
e.stopPropagation();
e.preventDefault();
return this.props.onRemoved(this.props.language);
};
public render() {
public render(): JSX.Element {
return (
<div className="mx_ExistingSpellCheckLanguage">
<span className="mx_ExistingSpellCheckLanguage_language">{this.props.language}</span>
@ -62,12 +62,12 @@ export default class SpellCheckLanguages extends React.Component<SpellCheckLangu
};
}
private onRemoved = (language: string) => {
private onRemoved = (language: string): void => {
const languages = this.props.languages.filter((e) => e !== language);
this.props.onLanguagesChange(languages);
};
private onAddClick = (e) => {
private onAddClick = (e): void => {
e.stopPropagation();
e.preventDefault();
@ -81,12 +81,12 @@ export default class SpellCheckLanguages extends React.Component<SpellCheckLangu
this.props.onLanguagesChange(this.props.languages);
};
private onNewLanguageChange = (language: string) => {
private onNewLanguageChange = (language: string): void => {
if (this.state.newLanguage === language) return;
this.setState({ newLanguage: language });
};
public render() {
public render(): JSX.Element {
const existingSpellCheckLanguages = this.props.languages.map((e) => {
return <ExistingSpellCheckLanguage language={e} onRemoved={this.onRemoved} key={e} />;
});

View file

@ -268,7 +268,7 @@ export default class ThemeChoicePanel extends React.Component<IProps, IState> {
);
}
public apparentSelectedThemeId() {
public apparentSelectedThemeId(): string {
if (this.state.useSystemTheme) {
return undefined;
}

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { useState } from "react";
import React, { ReactNode, useState } from "react";
import { UpdateCheckStatus } from "../../../BasePlatform";
import PlatformPeg from "../../../PlatformPeg";
@ -26,11 +26,11 @@ import InlineSpinner from "../../../components/views/elements/InlineSpinner";
import AccessibleButton from "../../../components/views/elements/AccessibleButton";
import { CheckUpdatesPayload } from "../../../dispatcher/payloads/CheckUpdatesPayload";
function installUpdate() {
function installUpdate(): void {
PlatformPeg.get().installUpdate();
}
function getStatusText(status: UpdateCheckStatus, errorDetail?: string) {
function getStatusText(status: UpdateCheckStatus, errorDetail?: string): ReactNode {
switch (status) {
case UpdateCheckStatus.Error:
return _t("Error encountered (%(errorDetail)s).", { errorDetail });
@ -57,10 +57,10 @@ function getStatusText(status: UpdateCheckStatus, errorDetail?: string) {
const doneStatuses = [UpdateCheckStatus.Ready, UpdateCheckStatus.Error, UpdateCheckStatus.NotAvailable];
const UpdateCheckButton = () => {
const UpdateCheckButton: React.FC = () => {
const [state, setState] = useState<CheckUpdatesPayload>(null);
const onCheckForUpdateClick = () => {
const onCheckForUpdateClick = (): void => {
setState(null);
PlatformPeg.get().startUpdateCheck();
};

View file

@ -41,7 +41,7 @@ const DeviceNameEditor: React.FC<Props & { stopEditing: () => void }> = ({ devic
const onInputChange = (event: React.ChangeEvent<HTMLInputElement>): void => setDeviceName(event.target.value);
const onSubmit = async (event: FormEvent<HTMLFormElement>) => {
const onSubmit = async (event: FormEvent<HTMLFormElement>): Promise<void> => {
setIsLoading(true);
setError(null);
event.preventDefault();

View file

@ -51,15 +51,17 @@ interface Props {
supportsMSC3881?: boolean | undefined;
}
const isDeviceSelected = (deviceId: ExtendedDevice["device_id"], selectedDeviceIds: ExtendedDevice["device_id"][]) =>
selectedDeviceIds.includes(deviceId);
const isDeviceSelected = (
deviceId: ExtendedDevice["device_id"],
selectedDeviceIds: ExtendedDevice["device_id"][],
): boolean => selectedDeviceIds.includes(deviceId);
// devices without timestamp metadata should be sorted last
const sortDevicesByLatestActivityThenDisplayName = (left: ExtendedDevice, right: ExtendedDevice) =>
const sortDevicesByLatestActivityThenDisplayName = (left: ExtendedDevice, right: ExtendedDevice): number =>
(right.last_seen_ts || 0) - (left.last_seen_ts || 0) ||
(left.display_name || left.device_id).localeCompare(right.display_name || right.device_id);
const getFilteredSortedDevices = (devices: DevicesDictionary, filter?: FilterVariation) =>
const getFilteredSortedDevices = (devices: DevicesDictionary, filter?: FilterVariation): ExtendedDevice[] =>
filterDevicesBySecurityRecommendation(Object.values(devices), filter ? [filter] : []).sort(
sortDevicesByLatestActivityThenDisplayName,
);
@ -280,12 +282,12 @@ export const FilteredDeviceList = forwardRef(
},
];
const onFilterOptionChange = (filterId: DeviceFilterKey) => {
const onFilterOptionChange = (filterId: DeviceFilterKey): void => {
onFilterChange(filterId === ALL_FILTER_ID ? undefined : (filterId as FilterVariation));
};
const isAllSelected = selectedDeviceIds.length >= sortedDevices.length;
const toggleSelectAll = () => {
const toggleSelectAll = (): void => {
if (isAllSelected) {
setSelectedDeviceIds([]);
} else {

View file

@ -33,7 +33,7 @@ export const deleteDevicesWithInteractiveAuth = async (
matrixClient: MatrixClient,
deviceIds: string[],
onFinished?: InteractiveAuthCallback,
) => {
): Promise<void> => {
if (!deviceIds.length) {
return;
}

View file

@ -39,7 +39,7 @@ const filters: Record<FilterVariation, DeviceFilterCondition> = {
export const filterDevicesBySecurityRecommendation = (
devices: ExtendedDevice[],
securityVariations: FilterVariation[],
) => {
): ExtendedDevice[] => {
const activeFilters = securityVariations.map((variation) => filters[variation]);
if (!activeFilters.length) {
return devices;

View file

@ -135,7 +135,7 @@ export const useOwnDevices = (): DevicesState => {
});
}, [matrixClient]);
const refreshDevices = useCallback(async () => {
const refreshDevices = useCallback(async (): Promise<void> => {
setIsLoadingDeviceList(true);
try {
const devices = await fetchDevicesWithVerification(matrixClient, userId);
@ -200,7 +200,7 @@ export const useOwnDevices = (): DevicesState => {
const requestDeviceVerification =
isCurrentDeviceVerified && userId
? async (deviceId: ExtendedDevice["device_id"]) => {
? async (deviceId: ExtendedDevice["device_id"]): Promise<VerificationRequest> => {
return await matrixClient.requestVerification(userId, [deviceId]);
}
: undefined;

View file

@ -67,7 +67,7 @@ export class EmailAddress extends React.Component<IEmailAddressProps, IEmailAddr
};
}
public componentDidUpdate(prevProps: Readonly<IEmailAddressProps>) {
public componentDidUpdate(prevProps: Readonly<IEmailAddressProps>): void {
if (this.props.email !== prevProps.email) {
const { bound } = this.props.email;
this.setState({ bound });

View file

@ -63,7 +63,7 @@ export class PhoneNumber extends React.Component<IPhoneNumberProps, IPhoneNumber
};
}
public componentDidUpdate(prevProps: Readonly<IPhoneNumberProps>) {
public componentDidUpdate(prevProps: Readonly<IPhoneNumberProps>): void {
if (this.props.msisdn !== prevProps.msisdn) {
const { bound } = this.props.msisdn;
this.setState({ bound });

View file

@ -75,12 +75,12 @@ export default class AdvancedRoomSettingsTab extends React.Component<IProps, ISt
});
}
private upgradeRoom = (e) => {
private upgradeRoom = (e): void => {
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
Modal.createDialog(RoomUpgradeDialog, { room });
};
private onOldRoomClicked = (e) => {
private onOldRoomClicked = (e): void => {
e.preventDefault();
e.stopPropagation();
@ -94,7 +94,7 @@ export default class AdvancedRoomSettingsTab extends React.Component<IProps, ISt
this.props.closeSettingsFn();
};
public render() {
public render(): JSX.Element {
const client = MatrixClientPeg.get();
const room = client.getRoom(this.props.roomId);
const isSpace = room.isSpaceRoom();

View file

@ -34,7 +34,7 @@ interface IProps {
}
export default class BridgeSettingsTab extends React.Component<IProps> {
private renderBridgeCard(event: MatrixEvent, room: Room) {
private renderBridgeCard(event: MatrixEvent, room: Room): JSX.Element {
const content = event.getContent();
if (!content || !content.channel || !content.protocol) {
return null;
@ -49,7 +49,7 @@ export default class BridgeSettingsTab extends React.Component<IProps> {
return BRIDGE_EVENT_TYPES.map((typeName) => roomState.getStateEvents(typeName)).flat(1);
}
public render() {
public render(): JSX.Element {
// This settings tab will only be invoked if the following function returns more
// than 0 events, so no validation is needed at this stage.
const bridgeEvents = BridgeSettingsTab.getBridgeStateEvents(this.props.roomId);

View file

@ -140,12 +140,12 @@ export default class NotificationsSettingsTab extends React.Component<IProps, IS
});
};
private onRoomNotificationChange = (value: RoomNotifState) => {
private onRoomNotificationChange = (value: RoomNotifState): void => {
this.roomProps.notificationVolume = value;
this.forceUpdate();
};
private onOpenSettingsClick = (event: ButtonEvent) => {
private onOpenSettingsClick = (event: ButtonEvent): void => {
// avoid selecting the radio button
event.preventDefault();
this.props.closeSettingsFn();

View file

@ -19,7 +19,7 @@ import { EventType } from "matrix-js-sdk/src/@types/event";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { RoomState, RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
import { logger } from "matrix-js-sdk/src/logger";
import { throttle } from "lodash";
import { throttle, get } from "lodash";
import { compare } from "matrix-js-sdk/src/utils";
import { _t, _td } from "../../../../../languageHandler";
@ -74,7 +74,7 @@ const plEventsToShow: Record<string, IEventShowOpts> = {
// parse a string as an integer; if the input is undefined, or cannot be parsed
// as an integer, return a default.
function parseIntWithDefault(val, def) {
function parseIntWithDefault(val: string, def: number): number {
const res = parseInt(val);
return isNaN(res) ? def : res;
}
@ -87,7 +87,7 @@ interface IBannedUserProps {
}
export class BannedUser extends React.Component<IBannedUserProps> {
private onUnbanClick = (e) => {
private onUnbanClick = (): void => {
MatrixClientPeg.get()
.unban(this.props.member.roomId, this.props.member.userId)
.catch((err) => {
@ -99,7 +99,7 @@ export class BannedUser extends React.Component<IBannedUserProps> {
});
};
public render() {
public render(): JSX.Element {
let unbanButton;
if (this.props.canUnban) {
@ -132,18 +132,18 @@ interface IProps {
}
export default class RolesRoomSettingsTab extends React.Component<IProps> {
public componentDidMount() {
public componentDidMount(): void {
MatrixClientPeg.get().on(RoomStateEvent.Update, this.onRoomStateUpdate);
}
public componentWillUnmount() {
public componentWillUnmount(): void {
const client = MatrixClientPeg.get();
if (client) {
client.removeListener(RoomStateEvent.Update, this.onRoomStateUpdate);
}
}
private onRoomStateUpdate = (state: RoomState) => {
private onRoomStateUpdate = (state: RoomState): void => {
if (state.roomId !== this.props.roomId) return;
this.onThisRoomMembership();
};
@ -156,7 +156,11 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
{ leading: true, trailing: true },
);
private populateDefaultPlEvents(eventsSection: Record<string, number>, stateLevel: number, eventsLevel: number) {
private populateDefaultPlEvents(
eventsSection: Record<string, number>,
stateLevel: number,
eventsLevel: number,
): void {
for (const desiredEvent of Object.keys(plEventsToShow)) {
if (!(desiredEvent in eventsSection)) {
eventsSection[desiredEvent] = plEventsToShow[desiredEvent].isState ? stateLevel : eventsLevel;
@ -164,7 +168,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
}
}
private onPowerLevelsChanged = (value: number, powerLevelKey: string) => {
private onPowerLevelsChanged = (value: number, powerLevelKey: string): void => {
const client = MatrixClientPeg.get();
const room = client.getRoom(this.props.roomId);
const plEvent = room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
@ -206,7 +210,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
});
};
private onUserPowerLevelChanged = (value: number, powerLevelKey: string) => {
private onUserPowerLevelChanged = (value: number, powerLevelKey: string): void => {
const client = MatrixClientPeg.get();
const room = client.getRoom(this.props.roomId);
const plEvent = room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
@ -232,7 +236,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
});
};
public render() {
public render(): JSX.Element {
const client = MatrixClientPeg.get();
const room = client.getRoom(this.props.roomId);
const isSpaceRoom = room.isSpaceRoom();
@ -367,9 +371,11 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
});
// comparator for sorting PL users lexicographically on PL descending, MXID ascending. (case-insensitive)
const comparator = (a, b) => {
const plDiff = userLevels[b.key] - userLevels[a.key];
return plDiff !== 0 ? plDiff : compare(a.key.toLocaleLowerCase(), b.key.toLocaleLowerCase());
const comparator = (a: JSX.Element, b: JSX.Element): number => {
const aKey = a.key as string;
const bKey = b.key as string;
const plDiff = userLevels[bKey] - userLevels[aKey];
return plDiff !== 0 ? plDiff : compare(aKey.toLocaleLowerCase(), bKey.toLocaleLowerCase());
};
privilegedUsers.sort(comparator);
@ -419,16 +425,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
return null;
}
const keyPath = key.split(".");
let currentObj = plContent;
for (const prop of keyPath) {
if (currentObj === undefined) {
break;
}
currentObj = currentObj[prop];
}
const value = parseIntWithDefault(currentObj, descriptor.defaultValue);
const value = parseIntWithDefault(get(plContent, key), descriptor.defaultValue);
return (
<div key={index} className="">
<PowerSelector

View file

@ -80,7 +80,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
};
}
public componentDidMount() {
public componentDidMount(): void {
this.context.on(RoomStateEvent.Events, this.onStateEvent);
this.hasAliases().then((hasAliases) => this.setState({ hasAliases }));
}
@ -89,11 +89,11 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
return event?.getContent()[key] || defaultValue;
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this.context.removeListener(RoomStateEvent.Events, this.onStateEvent);
}
private onStateEvent = (e: MatrixEvent) => {
private onStateEvent = (e: MatrixEvent): void => {
const refreshWhenTypes: EventType[] = [
EventType.RoomJoinRules,
EventType.RoomGuestAccess,
@ -103,7 +103,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
if (refreshWhenTypes.includes(e.getType() as EventType)) this.forceUpdate();
};
private onEncryptionChange = async () => {
private onEncryptionChange = async (): Promise<void> => {
if (this.context.getRoom(this.props.roomId)?.getJoinRule() === JoinRule.Public) {
const dialog = Modal.createDialog(QuestionDialog, {
title: _t("Are you sure you want to add encryption to this public room?"),
@ -181,7 +181,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
});
};
private onGuestAccessChange = (allowed: boolean) => {
private onGuestAccessChange = (allowed: boolean): void => {
const guestAccess = allowed ? GuestAccess.CanJoin : GuestAccess.Forbidden;
const beforeGuestAccess = this.state.guestAccess;
if (beforeGuestAccess === guestAccess) return;
@ -203,7 +203,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
});
};
private createNewRoom = async (defaultPublic: boolean, defaultEncrypted: boolean) => {
private createNewRoom = async (defaultPublic: boolean, defaultEncrypted: boolean): Promise<boolean> => {
const modal = Modal.createDialog<[boolean, IOpts]>(CreateRoomDialog, { defaultPublic, defaultEncrypted });
PosthogTrackers.trackInteraction("WebRoomSettingsSecurityTabCreateNewRoomButton");
@ -215,7 +215,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
return shouldCreate;
};
private onHistoryRadioToggle = (history: HistoryVisibility) => {
private onHistoryRadioToggle = (history: HistoryVisibility): void => {
const beforeHistory = this.state.history;
if (beforeHistory === history) return;
@ -235,7 +235,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
});
};
private updateBlacklistDevicesFlag = (checked: boolean) => {
private updateBlacklistDevicesFlag = (checked: boolean): void => {
this.context.getRoom(this.props.roomId).setBlacklistUnverifiedDevices(checked);
};
@ -246,7 +246,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
return Array.isArray(localAliases) && localAliases.length !== 0;
}
private renderJoinRule() {
private renderJoinRule(): JSX.Element {
const client = this.context;
const room = client.getRoom(this.props.roomId);
@ -277,7 +277,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
);
}
private onJoinRuleChangeError = (error: Error) => {
private onJoinRuleChangeError = (error: Error): void => {
Modal.createDialog(ErrorDialog, {
title: _t("Failed to update the join rules"),
description: error.message ?? _t("Unknown failure"),
@ -311,7 +311,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
a: (sub) => (
<AccessibleButton
kind="link_inline"
onClick={() => {
onClick={(): void => {
dialog.close();
this.createNewRoom(true, false);
}}
@ -335,7 +335,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
return true;
};
private renderHistory() {
private renderHistory(): JSX.Element {
if (!SettingsStore.getValue(UIFeature.RoomHistorySettings)) {
return null;
}
@ -386,11 +386,11 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
);
}
private toggleAdvancedSection = () => {
private toggleAdvancedSection = (): void => {
this.setState({ showAdvancedSection: !this.state.showAdvancedSection });
};
private renderAdvanced() {
private renderAdvanced(): JSX.Element {
const client = this.context;
const guestAccess = this.state.guestAccess;
const state = client.getRoom(this.props.roomId).currentState;
@ -414,7 +414,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
);
}
public render() {
public render(): JSX.Element {
const client = this.context;
const room = client.getRoom(this.props.roomId);
const isEncrypted = this.state.encrypted;

View file

@ -64,7 +64,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
};
}
public async componentDidMount() {
public async componentDidMount(): Promise<void> {
// Fetch the current user profile for the message preview
const client = MatrixClientPeg.get();
const userId = client.getUserId();
@ -78,7 +78,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
});
}
public componentWillUnmount() {
public componentWillUnmount(): void {
this.unmounted = true;
}
@ -86,7 +86,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
this.setState({ layout: layout });
};
private renderAdvancedSection() {
private renderAdvancedSection(): JSX.Element {
if (!SettingsStore.getValue(UIFeature.AdvancedSettings)) return null;
const brand = SdkConfig.get().brand;
@ -139,7 +139,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
);
}
public render() {
public render(): JSX.Element {
const brand = SdkConfig.get().brand;
return (

View file

@ -80,7 +80,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
};
}
private onClearCacheAndReload = (e) => {
private onClearCacheAndReload = (e): void => {
if (!PlatformPeg.get()) return;
// Dev note: please keep this log line, it's useful when troubleshooting a MatrixClient suddenly
@ -94,11 +94,11 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
});
};
private onBugReport = (e) => {
private onBugReport = (e): void => {
Modal.createDialog(BugReportDialog, {});
};
private onStartBotChat = (e) => {
private onStartBotChat = (e): void => {
this.props.closeSettingsFn();
createRoom({
dmUserId: SdkConfig.get("welcome_user_id"),
@ -106,7 +106,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
});
};
private renderLegal() {
private renderLegal(): JSX.Element {
const tocLinks = SdkConfig.get().terms_and_conditions_links;
if (!tocLinks) return null;
@ -129,7 +129,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
);
}
private renderCredits() {
private renderCredits(): JSX.Element {
// Note: This is not translated because it is legal text.
// Also, &nbsp; is ugly but necessary.
return (
@ -206,7 +206,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
});
};
public render() {
public render(): JSX.Element {
const brand = SdkConfig.get().brand;
let faqText = _t(

View file

@ -46,15 +46,15 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
};
}
private onPersonalRuleChanged = (e) => {
private onPersonalRuleChanged = (e): void => {
this.setState({ newPersonalRule: e.target.value });
};
private onNewListChanged = (e) => {
private onNewListChanged = (e): void => {
this.setState({ newList: e.target.value });
};
private onAddPersonalRule = async (e) => {
private onAddPersonalRule = async (e): Promise<void> => {
e.preventDefault();
e.stopPropagation();
@ -80,7 +80,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
}
};
private onSubscribeList = async (e) => {
private onSubscribeList = async (e): Promise<void> => {
e.preventDefault();
e.stopPropagation();
@ -101,7 +101,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
}
};
private async removePersonalRule(rule: ListRule) {
private async removePersonalRule(rule: ListRule): Promise<void> {
this.setState({ busy: true });
try {
const list = Mjolnir.sharedInstance().getPersonalList();
@ -118,7 +118,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
}
}
private async unsubscribeFromList(list: BanList) {
private async unsubscribeFromList(list: BanList): Promise<void> {
this.setState({ busy: true });
try {
await Mjolnir.sharedInstance().unsubscribeFromList(list.roomId);
@ -135,11 +135,11 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
}
}
private viewListRules(list: BanList) {
private viewListRules(list: BanList): void {
const room = MatrixClientPeg.get().getRoom(list.roomId);
const name = room ? room.name : list.roomId;
const renderRules = (rules: ListRule[]) => {
const renderRules = (rules: ListRule[]): JSX.Element => {
if (rules.length === 0) return <i>{_t("None")}</i>;
const tiles = [];
@ -168,7 +168,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
});
}
private renderPersonalBanListRules() {
private renderPersonalBanListRules(): JSX.Element {
const list = Mjolnir.sharedInstance().getPersonalList();
const rules = list ? [...list.userRules, ...list.serverRules] : [];
if (!list || rules.length <= 0) return <i>{_t("You have not ignored anyone.")}</i>;
@ -198,7 +198,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
);
}
private renderSubscribedBanLists() {
private renderSubscribedBanLists(): JSX.Element {
const personalList = Mjolnir.sharedInstance().getPersonalList();
const lists = Mjolnir.sharedInstance().lists.filter((b) => {
return personalList ? personalList.roomId !== b.roomId : true;
@ -246,7 +246,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
);
}
public render() {
public render(): JSX.Element {
const brand = SdkConfig.get().brand;
return (

View file

@ -20,7 +20,7 @@ import { _t } from "../../../../../languageHandler";
import Notifications from "../../Notifications";
export default class NotificationUserSettingsTab extends React.Component {
public render() {
public render(): JSX.Element {
return (
<div className="mx_SettingsTab">
<div className="mx_SettingsTab_heading">{_t("Notifications")}</div>

View file

@ -122,17 +122,17 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
});
}
private onAutocompleteDelayChange = (e: React.ChangeEvent<HTMLInputElement>) => {
private onAutocompleteDelayChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
this.setState({ autocompleteDelay: e.target.value });
SettingsStore.setValue("autocompleteDelay", null, SettingLevel.DEVICE, e.target.value);
};
private onReadMarkerInViewThresholdMs = (e: React.ChangeEvent<HTMLInputElement>) => {
private onReadMarkerInViewThresholdMs = (e: React.ChangeEvent<HTMLInputElement>): void => {
this.setState({ readMarkerInViewThresholdMs: e.target.value });
SettingsStore.setValue("readMarkerInViewThresholdMs", null, SettingLevel.DEVICE, e.target.value);
};
private onReadMarkerOutOfViewThresholdMs = (e: React.ChangeEvent<HTMLInputElement>) => {
private onReadMarkerOutOfViewThresholdMs = (e: React.ChangeEvent<HTMLInputElement>): void => {
this.setState({ readMarkerOutOfViewThresholdMs: e.target.value });
SettingsStore.setValue("readMarkerOutOfViewThresholdMs", null, SettingLevel.DEVICE, e.target.value);
};
@ -151,7 +151,7 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
});
};
public render() {
public render(): JSX.Element {
const useCase = SettingsStore.getValue<UseCase | null>("FTUE.useCaseSelection");
const roomListSettings = PreferencesUserSettingsTab.ROOM_LIST_SETTINGS
// Only show the breadcrumbs setting if breadcrumbs v2 is disabled

View file

@ -102,7 +102,7 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
};
}
private onAction = ({ action }: ActionPayload) => {
private onAction = ({ action }: ActionPayload): void => {
if (action === "ignore_state_changed") {
const ignoredUserIds = MatrixClientPeg.get().getIgnoredUsers();
const newWaitingUnignored = this.state.waitingUnignored.filter((e) => ignoredUserIds.includes(e));
@ -193,7 +193,7 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
// No error, update invited rooms button
this.removeInvitedRoom(roomId);
},
async (e) => {
async (e): Promise<void> => {
// Action failure
if (e.errcode === "M_LIMIT_EXCEEDED") {
// Add a delay between each invite change in order to avoid rate
@ -328,7 +328,7 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
let privacySection;
if (PosthogAnalytics.instance.isEnabled()) {
const onClickAnalyticsLearnMore = () => {
const onClickAnalyticsLearnMore = (): void => {
showAnalyticsLearnMoreDialog({
primaryButton: _t("Okay"),
hasCancel: false,

View file

@ -70,7 +70,7 @@ const useSignOut = (
} => {
const [signingOutDeviceIds, setSigningOutDeviceIds] = useState<ExtendedDevice["device_id"][]>([]);
const onSignOutCurrentDevice = () => {
const onSignOutCurrentDevice = (): void => {
Modal.createDialog(
LogoutDialog,
{}, // props,
@ -80,7 +80,7 @@ const useSignOut = (
);
};
const onSignOutOtherDevices = async (deviceIds: ExtendedDevice["device_id"][]) => {
const onSignOutOtherDevices = async (deviceIds: ExtendedDevice["device_id"][]): Promise<void> => {
if (!deviceIds.length) {
return;
}
@ -91,7 +91,7 @@ const useSignOut = (
try {
setSigningOutDeviceIds([...signingOutDeviceIds, ...deviceIds]);
await deleteDevicesWithInteractiveAuth(matrixClient, deviceIds, async (success) => {
await deleteDevicesWithInteractiveAuth(matrixClient, deviceIds, async (success): Promise<void> => {
if (success) {
await onSignoutResolvedCallback();
}
@ -142,7 +142,7 @@ const SessionManagerTab: React.FC = () => {
}
};
const onGoToFilteredList = (filter: FilterVariation) => {
const onGoToFilteredList = (filter: FilterVariation): void => {
setFilter(filter);
clearTimeout(scrollIntoViewTimeoutRef.current);
// wait a tick for the filtered section to rerender with different height
@ -160,7 +160,7 @@ const SessionManagerTab: React.FC = () => {
const otherSessionsCount = Object.keys(otherDevices).length;
const shouldShowOtherSessions = otherSessionsCount > 0;
const onVerifyCurrentDevice = () => {
const onVerifyCurrentDevice = (): void => {
Modal.createDialog(SetupEncryptionDialog as unknown as React.ComponentType, { onFinished: refreshDevices });
};
@ -173,7 +173,7 @@ const SessionManagerTab: React.FC = () => {
Modal.createDialog(VerificationRequestDialog, {
verificationRequestPromise,
member: currentUserMember,
onFinished: async () => {
onFinished: async (): Promise<void> => {
const request = await verificationRequestPromise;
request.cancel();
await refreshDevices();
@ -183,7 +183,7 @@ const SessionManagerTab: React.FC = () => {
[requestDeviceVerification, refreshDevices, currentUserMember],
);
const onSignoutResolvedCallback = async () => {
const onSignoutResolvedCallback = async (): Promise<void> => {
await refreshDevices();
setSelectedDeviceIds([]);
};

View file

@ -41,7 +41,7 @@ export const onMetaSpaceChangeFactory =
);
};
const SidebarUserSettingsTab = () => {
const SidebarUserSettingsTab: React.FC = () => {
const {
[MetaSpace.Home]: homeEnabled,
[MetaSpace.Favourites]: favouritesEnabled,

View file

@ -52,7 +52,7 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
};
}
public async componentDidMount() {
public async componentDidMount(): Promise<void> {
const canSeeDeviceLabels = await MediaDeviceHandler.hasAnyLabeledDevices();
if (canSeeDeviceLabels) {
this.refreshMediaDevices();
@ -121,7 +121,7 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
);
}
public render() {
public render(): JSX.Element {
let requestButton = null;
let speakerDropdown = null;
let microphoneDropdown = null;
@ -157,7 +157,7 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
{microphoneDropdown}
<LabelledToggleSwitch
value={this.state.audioAutoGainControl}
onChange={async (v) => {
onChange={async (v): Promise<void> => {
await MediaDeviceHandler.setAudioAutoGainControl(v);
this.setState({ audioAutoGainControl: MediaDeviceHandler.getAudioAutoGainControl() });
}}
@ -177,7 +177,7 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
<div className="mx_SettingsTab_section">
<LabelledToggleSwitch
value={this.state.audioNoiseSuppression}
onChange={async (v) => {
onChange={async (v): Promise<void> => {
await MediaDeviceHandler.setAudioNoiseSuppression(v);
this.setState({ audioNoiseSuppression: MediaDeviceHandler.getAudioNoiseSuppression() });
}}
@ -186,7 +186,7 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
/>
<LabelledToggleSwitch
value={this.state.audioEchoCancellation}
onChange={async (v) => {
onChange={async (v): Promise<void> => {
await MediaDeviceHandler.setAudioEchoCancellation(v);
this.setState({ audioEchoCancellation: MediaDeviceHandler.getAudioEchoCancellation() });
}}