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:
parent
7a36ba0fde
commit
030b7e90bf
683 changed files with 3459 additions and 3013 deletions
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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 />;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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} />;
|
||||
});
|
||||
|
|
|
@ -268,7 +268,7 @@ export default class ThemeChoicePanel extends React.Component<IProps, IState> {
|
|||
);
|
||||
}
|
||||
|
||||
public apparentSelectedThemeId() {
|
||||
public apparentSelectedThemeId(): string {
|
||||
if (this.state.useSystemTheme) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -33,7 +33,7 @@ export const deleteDevicesWithInteractiveAuth = async (
|
|||
matrixClient: MatrixClient,
|
||||
deviceIds: string[],
|
||||
onFinished?: InteractiveAuthCallback,
|
||||
) => {
|
||||
): Promise<void> => {
|
||||
if (!deviceIds.length) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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, 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(
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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([]);
|
||||
};
|
||||
|
|
|
@ -41,7 +41,7 @@ export const onMetaSpaceChangeFactory =
|
|||
);
|
||||
};
|
||||
|
||||
const SidebarUserSettingsTab = () => {
|
||||
const SidebarUserSettingsTab: React.FC = () => {
|
||||
const {
|
||||
[MetaSpace.Home]: homeEnabled,
|
||||
[MetaSpace.Favourites]: favouritesEnabled,
|
||||
|
|
|
@ -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() });
|
||||
}}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue