Auto-fix lint errors
This commit is contained in:
parent
4c5720a573
commit
ae0a8b8da4
625 changed files with 3170 additions and 3232 deletions
|
@ -14,13 +14,13 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, {useState} from "react";
|
||||
import React, { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import {_t} from "../../../languageHandler";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import classNames from "classnames";
|
||||
|
||||
const AvatarSetting = ({avatarUrl, avatarAltText, avatarName, uploadAvatar, removeAvatar}) => {
|
||||
const AvatarSetting = ({ avatarUrl, avatarAltText, avatarName, uploadAvatar, removeAvatar }) => {
|
||||
const [isHovering, setIsHovering] = useState(false);
|
||||
const hoveringProps = {
|
||||
onMouseEnter: () => setIsHovering(true),
|
||||
|
|
|
@ -16,16 +16,16 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {_t} from "../../../languageHandler";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import Pill from "../elements/Pill";
|
||||
import {makeUserPermalink} from "../../../utils/permalinks/Permalinks";
|
||||
import { makeUserPermalink } from "../../../utils/permalinks/Permalinks";
|
||||
import BaseAvatar from "../avatars/BaseAvatar";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import {MatrixEvent} from "matrix-js-sdk/src/models/event";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { isUrlPermitted } from '../../../HtmlUtils';
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import {mediaFromMxc} from "../../../customisations/Media";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import { mediaFromMxc } from "../../../customisations/Media";
|
||||
|
||||
interface IProps {
|
||||
ev: MatrixEvent;
|
||||
|
@ -69,7 +69,7 @@ export default class BridgeTile extends React.PureComponent<IProps> {
|
|||
static propTypes = {
|
||||
ev: PropTypes.object.isRequired,
|
||||
room: PropTypes.object.isRequired,
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const content: IBridgeStateEvent = this.props.ev.getContent();
|
||||
|
@ -131,7 +131,7 @@ export default class BridgeTile extends React.PureComponent<IProps> {
|
|||
const networkName = network.displayname || network.id;
|
||||
let networkLink = <span>{networkName}</span>;
|
||||
if (typeof network.external_url === "string" && isUrlPermitted(network.external_url)) {
|
||||
networkLink = <a href={network.external_url} target="_blank" rel="noreferrer noopener">{networkName}</a>
|
||||
networkLink = <a href={network.external_url} target="_blank" rel="noreferrer noopener">{networkName}</a>;
|
||||
}
|
||||
networkItem = _t("Workspace: <networkLink/>", {}, {
|
||||
networkLink: () => networkLink,
|
||||
|
@ -140,7 +140,7 @@ export default class BridgeTile extends React.PureComponent<IProps> {
|
|||
|
||||
let channelLink = <span>{channelName}</span>;
|
||||
if (typeof channel.external_url === "string" && isUrlPermitted(channel.external_url)) {
|
||||
channelLink = <a href={channel.external_url} target="_blank" rel="noreferrer noopener">{channelName}</a>
|
||||
channelLink = <a href={channel.external_url} target="_blank" rel="noreferrer noopener">{channelName}</a>;
|
||||
}
|
||||
|
||||
const id = this.props.ev.getId();
|
||||
|
|
|
@ -16,12 +16,12 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import * as sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import Spinner from '../elements/Spinner';
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import {mediaFromMxc} from "../../../customisations/Media";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import { mediaFromMxc } from "../../../customisations/Media";
|
||||
|
||||
@replaceableComponent("views.settings.ChangeAvatar")
|
||||
export default class ChangeAvatar extends React.Component {
|
||||
|
@ -107,7 +107,7 @@ export default class ChangeAvatar extends React.Component {
|
|||
return MatrixClientPeg.get().sendStateEvent(
|
||||
self.props.room.roomId,
|
||||
'm.room.avatar',
|
||||
{url: url},
|
||||
{ url: url },
|
||||
'',
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -18,9 +18,9 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import * as sdk from '../../../index';
|
||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.ChangeDisplayName")
|
||||
export default class ChangeDisplayName extends React.Component {
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
import Field from "../elements/Field";
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import Spinner from '../elements/Spinner';
|
||||
import withValidation from '../elements/Validation';
|
||||
|
@ -27,7 +27,7 @@ import * as sdk from "../../../index";
|
|||
import Modal from "../../../Modal";
|
||||
import PassphraseField from "../auth/PassphraseField";
|
||||
import CountlyAnalytics from "../../../CountlyAnalytics";
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import { PASSWORD_MIN_SCORE } from '../auth/RegistrationForm';
|
||||
|
||||
const FIELD_OLD_PASSWORD = 'field_old_password';
|
||||
|
|
|
@ -16,14 +16,14 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
|
||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import * as sdk from '../../../index';
|
||||
import Modal from '../../../Modal';
|
||||
import Spinner from '../elements/Spinner';
|
||||
import InteractiveAuthDialog from '../dialogs/InteractiveAuthDialog';
|
||||
import ConfirmDestroyCrossSigningDialog from '../dialogs/security/ConfirmDestroyCrossSigningDialog';
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.CrossSigningPanel")
|
||||
export default class CrossSigningPanel extends React.PureComponent {
|
||||
|
|
|
@ -20,11 +20,11 @@ import PropTypes from 'prop-types';
|
|||
import classNames from 'classnames';
|
||||
|
||||
import * as sdk from '../../../index';
|
||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import Modal from '../../../Modal';
|
||||
import {SSOAuthEntry} from "../auth/InteractiveAuthEntryComponents";
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { SSOAuthEntry } from "../auth/InteractiveAuthEntryComponents";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.DevicesPanel")
|
||||
export default class DevicesPanel extends React.Component {
|
||||
|
@ -58,7 +58,7 @@ export default class DevicesPanel extends React.Component {
|
|||
MatrixClientPeg.get().getDevices().then(
|
||||
(resp) => {
|
||||
if (this._unmounted) { return; }
|
||||
this.setState({devices: resp.devices || []});
|
||||
this.setState({ devices: resp.devices || [] });
|
||||
},
|
||||
(error) => {
|
||||
if (this._unmounted) { return; }
|
||||
|
@ -70,12 +70,11 @@ export default class DevicesPanel extends React.Component {
|
|||
console.error("Error loading sessions:", error);
|
||||
errtxt = _t("Unable to load session list");
|
||||
}
|
||||
this.setState({deviceLoadError: errtxt});
|
||||
this.setState({ deviceLoadError: errtxt });
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* compare two devices, sorting from most-recently-seen to least-recently-seen
|
||||
* (and then, for stability, by device id)
|
||||
|
@ -107,7 +106,7 @@ export default class DevicesPanel extends React.Component {
|
|||
selectedDevices.splice(i, 1);
|
||||
}
|
||||
|
||||
return {selectedDevices};
|
||||
return { selectedDevices };
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -141,7 +140,7 @@ export default class DevicesPanel extends React.Component {
|
|||
body: _t("Click the button below to confirm deleting these sessions.", {
|
||||
count: numDevices,
|
||||
}),
|
||||
continueText: _t("Delete sessions", {count: numDevices}),
|
||||
continueText: _t("Delete sessions", { count: numDevices }),
|
||||
continueKind: "danger",
|
||||
},
|
||||
};
|
||||
|
@ -214,7 +213,7 @@ export default class DevicesPanel extends React.Component {
|
|||
const deleteButton = this.state.deleting ?
|
||||
<Spinner w={22} h={22} /> :
|
||||
<AccessibleButton onClick={this._onDeleteClick} kind="danger_sm">
|
||||
{ _t("Delete %(count)s sessions", {count: this.state.selectedDevices.length})}
|
||||
{ _t("Delete %(count)s sessions", { count: this.state.selectedDevices.length })}
|
||||
</AccessibleButton>;
|
||||
|
||||
const classes = classNames(this.props.className, "mx_DevicesPanel");
|
||||
|
|
|
@ -19,10 +19,10 @@ import PropTypes from 'prop-types';
|
|||
|
||||
import * as sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||
import {formatDate} from '../../../DateUtils';
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import { formatDate } from '../../../DateUtils';
|
||||
import StyledCheckbox from '../elements/StyledCheckbox';
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.DevicesPanelEntry")
|
||||
export default class DevicesPanelEntry extends React.Component {
|
||||
|
|
|
@ -17,8 +17,8 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
|
||||
import * as sdk from '../../../index';
|
||||
import {_t} from "../../../languageHandler";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
|
||||
const SETTING_MANUALLY_VERIFY_ALL_SESSIONS = "e2ee.manuallyVerifyAllSessions";
|
||||
|
|
|
@ -22,10 +22,10 @@ import * as sdk from '../../../index';
|
|||
import Modal from '../../../Modal';
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import {formatBytes, formatCountLong} from "../../../utils/FormattingUtils";
|
||||
import { formatBytes, formatCountLong } from "../../../utils/FormattingUtils";
|
||||
import EventIndexPeg from "../../../indexing/EventIndexPeg";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import SeshatResetDialog from '../dialogs/SeshatResetDialog';
|
||||
|
||||
interface IState {
|
||||
|
@ -118,7 +118,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
|
|||
onFinished: () => {},
|
||||
}, null, /* priority = */ false, /* static = */ true,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
private onEnable = async () => {
|
||||
this.setState({
|
||||
|
@ -130,7 +130,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
|
|||
await EventIndexPeg.get().startCrawler();
|
||||
await SettingsStore.setValue('enableEventIndexing', null, SettingLevel.DEVICE, true);
|
||||
await this.updateState();
|
||||
}
|
||||
};
|
||||
|
||||
private confirmEventStoreReset = () => {
|
||||
const { close } = Modal.createDialog(SeshatResetDialog, {
|
||||
|
@ -143,7 +143,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
|
|||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
let eventIndexingSettings = null;
|
||||
|
|
|
@ -20,8 +20,8 @@ import PropTypes from 'prop-types';
|
|||
import * as sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import {Key} from "../../../Keyboard";
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { Key } from "../../../Keyboard";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.IntegrationManager")
|
||||
export default class IntegrationManager extends React.Component {
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import * as sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import SettingsStore from '../../../settings/SettingsStore';
|
||||
import Modal from '../../../Modal';
|
||||
import {
|
||||
|
@ -30,9 +30,9 @@ import {
|
|||
import SdkConfig from "../../../SdkConfig";
|
||||
import LabelledToggleSwitch from "../elements/LabelledToggleSwitch";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
import {UIFeature} from "../../../settings/UIFeature";
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||
import { UIFeature } from "../../../settings/UIFeature";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
// TODO: this "view" component still has far too much application logic in it,
|
||||
// which should be factored out to other files.
|
||||
|
@ -40,7 +40,6 @@ import {replaceableComponent} from "../../../utils/replaceableComponent";
|
|||
// TODO: this component also does a lot of direct poking into this.state, which
|
||||
// is VERY NAUGHTY.
|
||||
|
||||
|
||||
/**
|
||||
* Rules that Vector used to set in order to override the actions of default rules.
|
||||
* These are used to port peoples existing overrides to match the current API.
|
||||
|
@ -517,7 +516,7 @@ export default class Notifications extends React.Component {
|
|||
};
|
||||
|
||||
// HS default rules
|
||||
const defaultRules = {master: [], vector: {}, others: []};
|
||||
const defaultRules = { master: [], vector: {}, others: [] };
|
||||
|
||||
for (const kind in rulesets.global) {
|
||||
for (let i = 0; i < Object.keys(rulesets.global[kind]).length; ++i) {
|
||||
|
@ -632,7 +631,7 @@ export default class Notifications extends React.Component {
|
|||
});
|
||||
|
||||
const pushersPromise = MatrixClientPeg.get().getPushers().then(function(resp) {
|
||||
self.setState({pushers: resp.pushers});
|
||||
self.setState({ pushers: resp.pushers });
|
||||
});
|
||||
|
||||
Promise.all([pushRulesPromise, pushersPromise]).then(function() {
|
||||
|
@ -655,7 +654,7 @@ export default class Notifications extends React.Component {
|
|||
});
|
||||
});
|
||||
|
||||
MatrixClientPeg.get().getThreePids().then((r) => this.setState({threepids: r.threepids}));
|
||||
MatrixClientPeg.get().getThreePids().then((r) => this.setState({ threepids: r.threepids }));
|
||||
};
|
||||
|
||||
_onClearNotifications = () => {
|
||||
|
|
|
@ -14,17 +14,17 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, {createRef} from 'react';
|
||||
import {_t} from "../../../languageHandler";
|
||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||
import React, { createRef } from 'react';
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import Field from "../elements/Field";
|
||||
import { getHostingLink } from '../../../utils/HostingLink';
|
||||
import * as sdk from "../../../index";
|
||||
import {OwnProfileStore} from "../../../stores/OwnProfileStore";
|
||||
import { OwnProfileStore } from "../../../stores/OwnProfileStore";
|
||||
import Modal from "../../../Modal";
|
||||
import ErrorDialog from "../dialogs/ErrorDialog";
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import {mediaFromMxc} from "../../../customisations/Media";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import { mediaFromMxc } from "../../../customisations/Media";
|
||||
|
||||
@replaceableComponent("views.settings.ProfileSettings")
|
||||
export default class ProfileSettings extends React.Component {
|
||||
|
@ -79,7 +79,7 @@ export default class ProfileSettings extends React.Component {
|
|||
e.preventDefault();
|
||||
|
||||
if (!this.state.enableProfileSave) return;
|
||||
this.setState({enableProfileSave: false});
|
||||
this.setState({ enableProfileSave: false });
|
||||
|
||||
const client = MatrixClientPeg.get();
|
||||
const newState = {};
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
|
||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import Modal from '../../../Modal';
|
||||
import { isSecureBackupRequired } from '../../../utils/WellKnownUtils';
|
||||
|
@ -26,7 +26,7 @@ import AccessibleButton from '../elements/AccessibleButton';
|
|||
import QuestionDialog from '../dialogs/QuestionDialog';
|
||||
import RestoreKeyBackupDialog from '../dialogs/security/RestoreKeyBackupDialog';
|
||||
import { accessSecretStorage } from '../../../SecurityManager';
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.SecureBackupPanel")
|
||||
export default class SecureBackupPanel extends React.PureComponent {
|
||||
|
@ -85,7 +85,7 @@ export default class SecureBackupPanel extends React.PureComponent {
|
|||
async _checkKeyBackupStatus() {
|
||||
this._getUpdatedDiagnostics();
|
||||
try {
|
||||
const {backupInfo, trustInfo} = await MatrixClientPeg.get().checkKeyBackup();
|
||||
const { backupInfo, trustInfo } = await MatrixClientPeg.get().checkKeyBackup();
|
||||
this.setState({
|
||||
loading: false,
|
||||
error: null,
|
||||
|
@ -172,7 +172,7 @@ export default class SecureBackupPanel extends React.PureComponent {
|
|||
danger: true,
|
||||
onFinished: (proceed) => {
|
||||
if (!proceed) return;
|
||||
this.setState({loading: true});
|
||||
this.setState({ loading: true });
|
||||
MatrixClientPeg.get().deleteKeyBackupVersion(this.state.backupInfo.version).then(() => {
|
||||
this._loadBackupStatus();
|
||||
});
|
||||
|
@ -237,7 +237,7 @@ export default class SecureBackupPanel extends React.PureComponent {
|
|||
"This session is <b>not backing up your keys</b>, " +
|
||||
"but you do have an existing backup you can restore from " +
|
||||
"and add to going forward.", {},
|
||||
{b: sub => <b>{sub}</b>},
|
||||
{ b: sub => <b>{sub}</b> },
|
||||
)}</p>
|
||||
<p>{_t(
|
||||
"Connect this session to key backup before signing out to avoid " +
|
||||
|
@ -385,7 +385,7 @@ export default class SecureBackupPanel extends React.PureComponent {
|
|||
statusDescription = <>
|
||||
<p>{_t(
|
||||
"Your keys are <b>not being backed up from this session</b>.", {},
|
||||
{b: sub => <b>{sub}</b>},
|
||||
{ b: sub => <b>{sub}</b> },
|
||||
)}</p>
|
||||
<p>{_t("Back up your keys before signing out to avoid losing them.")}</p>
|
||||
</>;
|
||||
|
|
|
@ -16,17 +16,17 @@ limitations under the License.
|
|||
|
||||
import url from 'url';
|
||||
import React from 'react';
|
||||
import {_t} from "../../../languageHandler";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import * as sdk from '../../../index';
|
||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import Modal from '../../../Modal';
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import { getThreepidsWithBindStatus } from '../../../boundThreepids';
|
||||
import IdentityAuthClient from "../../../IdentityAuthClient";
|
||||
import {abbreviateUrl, unabbreviateUrl} from "../../../utils/UrlUtils";
|
||||
import { abbreviateUrl, unabbreviateUrl } from "../../../utils/UrlUtils";
|
||||
import { getDefaultIdentityServerUrl, doesIdentityServerHaveTerms } from '../../../utils/IdentityServerUtils';
|
||||
import {timeout} from "../../../utils/promise";
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { timeout } from "../../../utils/promise";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import { ActionPayload } from '../../../dispatcher/payloads';
|
||||
|
||||
// We'll wait up to this long when checking for 3PID bindings on the IS.
|
||||
|
@ -50,7 +50,7 @@ async function checkIdentityServerUrl(u) {
|
|||
if (response.ok) {
|
||||
return null;
|
||||
} else if (response.status < 200 || response.status >= 300) {
|
||||
return _t("Not a valid Identity Server (status code %(code)s)", {code: response.status});
|
||||
return _t("Not a valid Identity Server (status code %(code)s)", { code: response.status });
|
||||
} else {
|
||||
return _t("Could not connect to Identity Server");
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
|
|||
private onIdentityServerChanged = (ev) => {
|
||||
const u = ev.target.value;
|
||||
|
||||
this.setState({idServer: u});
|
||||
this.setState({ idServer: u });
|
||||
};
|
||||
|
||||
private getTooltip = () => {
|
||||
|
@ -159,14 +159,14 @@ export default class SetIdServer extends React.Component<IProps, IState> {
|
|||
e.preventDefault();
|
||||
const { idServer, currentClientIdServer } = this.state;
|
||||
|
||||
this.setState({busy: true, checking: true, error: null});
|
||||
this.setState({ busy: true, checking: true, error: null });
|
||||
|
||||
const fullUrl = unabbreviateUrl(idServer);
|
||||
|
||||
let errStr = await checkIdentityServerUrl(fullUrl);
|
||||
if (!errStr) {
|
||||
try {
|
||||
this.setState({checking: false}); // clear tooltip
|
||||
this.setState({ checking: false }); // clear tooltip
|
||||
|
||||
// Test the identity server by trying to register with it. This
|
||||
// may result in a terms of service prompt.
|
||||
|
@ -236,13 +236,13 @@ export default class SetIdServer extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
private onDisconnectClicked = async () => {
|
||||
this.setState({disconnectBusy: true});
|
||||
this.setState({ disconnectBusy: true });
|
||||
try {
|
||||
const [confirmed] = await this.showServerChangeWarning({
|
||||
title: _t("Disconnect identity server"),
|
||||
unboundMessage: _t(
|
||||
"Disconnect from the identity server <idserver />?", {},
|
||||
{idserver: sub => <b>{abbreviateUrl(this.state.currentClientIdServer)}</b>},
|
||||
{ idserver: sub => <b>{abbreviateUrl(this.state.currentClientIdServer)}</b> },
|
||||
),
|
||||
button: _t("Disconnect"),
|
||||
});
|
||||
|
@ -250,7 +250,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
|
|||
this.disconnectIdServer();
|
||||
}
|
||||
} finally {
|
||||
this.setState({disconnectBusy: false});
|
||||
this.setState({ disconnectBusy: false });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -369,7 +369,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
|
|||
bodyText = _t(
|
||||
"If you don't want to use <server /> to discover and be discoverable by existing " +
|
||||
"contacts you know, enter another identity server below.",
|
||||
{}, {server: sub => <b>{abbreviateUrl(idServerUrl)}</b>},
|
||||
{}, { server: sub => <b>{abbreviateUrl(idServerUrl)}</b> },
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -15,12 +15,12 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {_t} from "../../../languageHandler";
|
||||
import {IntegrationManagers} from "../../../integrations/IntegrationManagers";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { IntegrationManagers } from "../../../integrations/IntegrationManagers";
|
||||
import * as sdk from '../../../index';
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.SetIntegrationManager")
|
||||
export default class SetIntegrationManager extends React.Component {
|
||||
|
@ -41,9 +41,9 @@ export default class SetIntegrationManager extends React.Component {
|
|||
console.error("Error changing integration manager provisioning");
|
||||
console.error(err);
|
||||
|
||||
this.setState({provisioningEnabled: current});
|
||||
this.setState({ provisioningEnabled: current });
|
||||
});
|
||||
this.setState({provisioningEnabled: !current});
|
||||
this.setState({ provisioningEnabled: !current });
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -57,7 +57,7 @@ export default class SetIntegrationManager extends React.Component {
|
|||
bodyText = _t(
|
||||
"Use an Integration Manager <b>(%(serverName)s)</b> to manage bots, widgets, " +
|
||||
"and sticker packs.",
|
||||
{serverName: currentManager.name},
|
||||
{ serverName: currentManager.name },
|
||||
{ b: sub => <b>{sub}</b> },
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -17,8 +17,8 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import SpellCheckLanguagesDropdown from "../../../components/views/elements/SpellCheckLanguagesDropdown";
|
||||
import AccessibleButton from "../../../components/views/elements/AccessibleButton";
|
||||
import {_t} from "../../../languageHandler";
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
interface ExistingSpellCheckLanguageIProps {
|
||||
language: string,
|
||||
|
@ -60,7 +60,7 @@ export default class SpellCheckLanguages extends React.Component<SpellCheckLangu
|
|||
super(props);
|
||||
this.state = {
|
||||
newLanguage: "",
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
_onRemoved = (language) => {
|
||||
|
@ -77,13 +77,13 @@ export default class SpellCheckLanguages extends React.Component<SpellCheckLangu
|
|||
if (!language) return;
|
||||
if (this.props.languages.includes(language)) return;
|
||||
|
||||
this.props.languages.push(language)
|
||||
this.props.languages.push(language);
|
||||
this.props.onLanguagesChange(this.props.languages);
|
||||
};
|
||||
|
||||
_onNewLanguageChange = (language: string) => {
|
||||
if (this.state.newLanguage === language) return;
|
||||
this.setState({newLanguage: language});
|
||||
this.setState({ newLanguage: language });
|
||||
};
|
||||
|
||||
render() {
|
||||
|
|
|
@ -14,17 +14,17 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, {useState} from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import {UpdateCheckStatus} from "../../../BasePlatform";
|
||||
import { UpdateCheckStatus } from "../../../BasePlatform";
|
||||
import PlatformPeg from "../../../PlatformPeg";
|
||||
import {useDispatcher} from "../../../hooks/useDispatcher";
|
||||
import { useDispatcher } from "../../../hooks/useDispatcher";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import {Action} from "../../../dispatcher/actions";
|
||||
import {_t} from "../../../languageHandler";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import InlineSpinner from "../../../components/views/elements/InlineSpinner";
|
||||
import AccessibleButton from "../../../components/views/elements/AccessibleButton";
|
||||
import {CheckUpdatesPayload} from "../../../dispatcher/payloads/CheckUpdatesPayload";
|
||||
import { CheckUpdatesPayload } from "../../../dispatcher/payloads/CheckUpdatesPayload";
|
||||
|
||||
function installUpdate() {
|
||||
PlatformPeg.get().installUpdate();
|
||||
|
@ -61,7 +61,7 @@ const UpdateCheckButton = () => {
|
|||
PlatformPeg.get().startUpdateCheck();
|
||||
};
|
||||
|
||||
useDispatcher(dis, ({action, ...params}) => {
|
||||
useDispatcher(dis, ({ action, ...params }) => {
|
||||
if (action === Action.CheckUpdates) {
|
||||
setState(params as CheckUpdatesPayload);
|
||||
}
|
||||
|
|
|
@ -17,15 +17,15 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {_t} from "../../../../languageHandler";
|
||||
import {MatrixClientPeg} from "../../../../MatrixClientPeg";
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../../../MatrixClientPeg";
|
||||
import Field from "../../elements/Field";
|
||||
import AccessibleButton from "../../elements/AccessibleButton";
|
||||
import * as Email from "../../../../email";
|
||||
import AddThreepid from "../../../../AddThreepid";
|
||||
import * as sdk from '../../../../index';
|
||||
import Modal from '../../../../Modal';
|
||||
import {replaceableComponent} from "../../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../../utils/replaceableComponent";
|
||||
|
||||
/*
|
||||
TODO: Improve the UX for everything in here.
|
||||
|
@ -57,14 +57,14 @@ export class ExistingEmailAddress extends React.Component {
|
|||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
this.setState({verifyRemove: true});
|
||||
this.setState({ verifyRemove: true });
|
||||
};
|
||||
|
||||
_onDontRemove = (e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
this.setState({verifyRemove: false});
|
||||
this.setState({ verifyRemove: false });
|
||||
};
|
||||
|
||||
_onActuallyRemove = (e) => {
|
||||
|
@ -88,7 +88,7 @@ export class ExistingEmailAddress extends React.Component {
|
|||
return (
|
||||
<div className="mx_ExistingEmailAddress">
|
||||
<span className="mx_ExistingEmailAddress_promptText">
|
||||
{_t("Remove %(email)s?", {email: this.props.email.address} )}
|
||||
{_t("Remove %(email)s?", { email: this.props.email.address } )}
|
||||
</span>
|
||||
<AccessibleButton
|
||||
onClick={this._onActuallyRemove}
|
||||
|
@ -167,13 +167,13 @@ export default class EmailAddresses extends React.Component {
|
|||
}
|
||||
|
||||
const task = new AddThreepid();
|
||||
this.setState({verifying: true, continueDisabled: true, addTask: task});
|
||||
this.setState({ verifying: true, continueDisabled: true, addTask: task });
|
||||
|
||||
task.addEmailAddress(email).then(() => {
|
||||
this.setState({continueDisabled: false});
|
||||
this.setState({ continueDisabled: false });
|
||||
}).catch((err) => {
|
||||
console.error("Unable to add email address " + email + " " + err);
|
||||
this.setState({verifying: false, continueDisabled: false, addTask: null});
|
||||
this.setState({ verifying: false, continueDisabled: false, addTask: null });
|
||||
Modal.createTrackedDialog('Unable to add email address', '', ErrorDialog, {
|
||||
title: _t("Unable to add email address"),
|
||||
description: ((err && err.message) ? err.message : _t("Operation failed")),
|
||||
|
@ -185,7 +185,7 @@ export default class EmailAddresses extends React.Component {
|
|||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
this.setState({continueDisabled: true});
|
||||
this.setState({ continueDisabled: true });
|
||||
this.state.addTask.checkEmailLinkClicked().then(([finished]) => {
|
||||
let newEmailAddress = this.state.newEmailAddress;
|
||||
if (finished) {
|
||||
|
@ -204,7 +204,7 @@ export default class EmailAddresses extends React.Component {
|
|||
newEmailAddress,
|
||||
});
|
||||
}).catch((err) => {
|
||||
this.setState({continueDisabled: false});
|
||||
this.setState({ continueDisabled: false });
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
if (err.errcode === 'M_THREEPID_AUTH_FAILED') {
|
||||
Modal.createTrackedDialog("Email hasn't been verified yet", "", ErrorDialog, {
|
||||
|
|
|
@ -17,15 +17,15 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {_t} from "../../../../languageHandler";
|
||||
import {MatrixClientPeg} from "../../../../MatrixClientPeg";
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../../../MatrixClientPeg";
|
||||
import Field from "../../elements/Field";
|
||||
import AccessibleButton from "../../elements/AccessibleButton";
|
||||
import AddThreepid from "../../../../AddThreepid";
|
||||
import CountryDropdown from "../../auth/CountryDropdown";
|
||||
import * as sdk from '../../../../index';
|
||||
import Modal from '../../../../Modal';
|
||||
import {replaceableComponent} from "../../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../../utils/replaceableComponent";
|
||||
|
||||
/*
|
||||
TODO: Improve the UX for everything in here.
|
||||
|
@ -52,14 +52,14 @@ export class ExistingPhoneNumber extends React.Component {
|
|||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
this.setState({verifyRemove: true});
|
||||
this.setState({ verifyRemove: true });
|
||||
};
|
||||
|
||||
_onDontRemove = (e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
this.setState({verifyRemove: false});
|
||||
this.setState({ verifyRemove: false });
|
||||
};
|
||||
|
||||
_onActuallyRemove = (e) => {
|
||||
|
@ -83,7 +83,7 @@ export class ExistingPhoneNumber extends React.Component {
|
|||
return (
|
||||
<div className="mx_ExistingPhoneNumber">
|
||||
<span className="mx_ExistingPhoneNumber_promptText">
|
||||
{_t("Remove %(phone)s?", {phone: this.props.msisdn.address})}
|
||||
{_t("Remove %(phone)s?", { phone: this.props.msisdn.address })}
|
||||
</span>
|
||||
<AccessibleButton
|
||||
onClick={this._onActuallyRemove}
|
||||
|
@ -164,13 +164,13 @@ export default class PhoneNumbers extends React.Component {
|
|||
const phoneCountry = this.state.phoneCountry;
|
||||
|
||||
const task = new AddThreepid();
|
||||
this.setState({verifying: true, continueDisabled: true, addTask: task});
|
||||
this.setState({ verifying: true, continueDisabled: true, addTask: task });
|
||||
|
||||
task.addMsisdn(phoneCountry, phoneNumber).then((response) => {
|
||||
this.setState({continueDisabled: false, verifyMsisdn: response.msisdn});
|
||||
this.setState({ continueDisabled: false, verifyMsisdn: response.msisdn });
|
||||
}).catch((err) => {
|
||||
console.error("Unable to add phone number " + phoneNumber + " " + err);
|
||||
this.setState({verifying: false, continueDisabled: false, addTask: null});
|
||||
this.setState({ verifying: false, continueDisabled: false, addTask: null });
|
||||
Modal.createTrackedDialog('Add Phone Number Error', '', ErrorDialog, {
|
||||
title: _t("Error"),
|
||||
description: ((err && err.message) ? err.message : _t("Operation failed")),
|
||||
|
@ -182,7 +182,7 @@ export default class PhoneNumbers extends React.Component {
|
|||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
this.setState({continueDisabled: true});
|
||||
this.setState({ continueDisabled: true });
|
||||
const token = this.state.newPhoneNumberCode;
|
||||
const address = this.state.verifyMsisdn;
|
||||
this.state.addTask.haveMsisdnToken(token).then(([finished]) => {
|
||||
|
@ -205,7 +205,7 @@ export default class PhoneNumbers extends React.Component {
|
|||
newPhoneNumberCode: "",
|
||||
});
|
||||
}).catch((err) => {
|
||||
this.setState({continueDisabled: false});
|
||||
this.setState({ continueDisabled: false });
|
||||
if (err.errcode !== 'M_THREEPID_AUTH_FAILED') {
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
console.error("Unable to verify phone number: " + err);
|
||||
|
@ -214,13 +214,13 @@ export default class PhoneNumbers extends React.Component {
|
|||
description: ((err && err.message) ? err.message : _t("Operation failed")),
|
||||
});
|
||||
} else {
|
||||
this.setState({verifyError: _t("Incorrect verification code")});
|
||||
this.setState({ verifyError: _t("Incorrect verification code") });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
_onCountryChanged = (e) => {
|
||||
this.setState({phoneCountry: e.iso2});
|
||||
this.setState({ phoneCountry: e.iso2 });
|
||||
};
|
||||
|
||||
render() {
|
||||
|
|
|
@ -19,11 +19,11 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import {MatrixClientPeg} from "../../../../MatrixClientPeg";
|
||||
import { MatrixClientPeg } from "../../../../MatrixClientPeg";
|
||||
import * as sdk from '../../../../index';
|
||||
import Modal from '../../../../Modal';
|
||||
import AddThreepid from '../../../../AddThreepid';
|
||||
import {replaceableComponent} from "../../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../../utils/replaceableComponent";
|
||||
|
||||
/*
|
||||
TODO: Improve the UX for everything in here.
|
||||
|
|
|
@ -19,11 +19,11 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import {MatrixClientPeg} from "../../../../MatrixClientPeg";
|
||||
import { MatrixClientPeg } from "../../../../MatrixClientPeg";
|
||||
import * as sdk from '../../../../index';
|
||||
import Modal from '../../../../Modal';
|
||||
import AddThreepid from '../../../../AddThreepid';
|
||||
import {replaceableComponent} from "../../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../../utils/replaceableComponent";
|
||||
|
||||
/*
|
||||
TODO: Improve the UX for everything in here.
|
||||
|
@ -190,7 +190,7 @@ export class PhoneNumber extends React.Component {
|
|||
description: ((err && err.message) ? err.message : _t("Operation failed")),
|
||||
});
|
||||
} else {
|
||||
this.setState({verifyError: _t("Incorrect verification code")});
|
||||
this.setState({ verifyError: _t("Incorrect verification code") });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ export default class AdvancedRoomSettingsTab extends React.Component<IProps, ISt
|
|||
};
|
||||
|
||||
private openDevtools = (e) => {
|
||||
Modal.createDialog(DevtoolsDialog, {roomId: this.props.roomId});
|
||||
Modal.createDialog(DevtoolsDialog, { roomId: this.props.roomId });
|
||||
};
|
||||
|
||||
private onOldRoomClicked = (e) => {
|
||||
|
|
|
@ -15,13 +15,13 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import {Room} from "matrix-js-sdk/src/models/room";
|
||||
import {MatrixEvent} from "matrix-js-sdk/src/models/event";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||
import BridgeTile from "../../BridgeTile";
|
||||
import {replaceableComponent} from "../../../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
|
||||
const BRIDGE_EVENT_TYPES = [
|
||||
"uk.half-shot.bridge",
|
||||
|
|
|
@ -16,15 +16,15 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import RoomProfileSettings from "../../../room_settings/RoomProfileSettings";
|
||||
import * as sdk from "../../../../..";
|
||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
import dis from "../../../../../dispatcher/dispatcher";
|
||||
import MatrixClientContext from "../../../../../contexts/MatrixClientContext";
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
import {UIFeature} from "../../../../../settings/UIFeature";
|
||||
import {replaceableComponent} from "../../../../../utils/replaceableComponent";
|
||||
import { UIFeature } from "../../../../../settings/UIFeature";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.tabs.room.GeneralRoomSettingsTab")
|
||||
export default class GeneralRoomSettingsTab extends React.Component {
|
||||
|
|
|
@ -14,15 +14,15 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, {createRef} from 'react';
|
||||
import React, { createRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
import Notifier from "../../../../../Notifier";
|
||||
import SettingsStore from '../../../../../settings/SettingsStore';
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
import {replaceableComponent} from "../../../../../utils/replaceableComponent";
|
||||
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.tabs.room.NotificationsSettingsTab")
|
||||
export default class NotificationsSettingsTab extends React.Component {
|
||||
|
@ -47,7 +47,7 @@ export default class NotificationsSettingsTab extends React.Component {
|
|||
if (!soundData) {
|
||||
return;
|
||||
}
|
||||
this.setState({currentSound: soundData.name || soundData.url});
|
||||
this.setState({ currentSound: soundData.name || soundData.url });
|
||||
}
|
||||
|
||||
async _triggerUploader(e) {
|
||||
|
|
|
@ -15,13 +15,13 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {_t, _td} from "../../../../../languageHandler";
|
||||
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
||||
import { _t, _td } from "../../../../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||
import * as sdk from "../../../../..";
|
||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
import Modal from "../../../../../Modal";
|
||||
import {replaceableComponent} from "../../../../../utils/replaceableComponent";
|
||||
import {EventType} from "matrix-js-sdk/src/@types/event";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
import { RoomState } from "matrix-js-sdk/src/models/room-state";
|
||||
|
@ -45,18 +45,18 @@ const plEventsToLabels = {
|
|||
|
||||
const plEventsToShow = {
|
||||
// If an event is listed here, it will be shown in the PL settings. Defaults will be calculated.
|
||||
[EventType.RoomAvatar]: {isState: true},
|
||||
[EventType.RoomName]: {isState: true},
|
||||
[EventType.RoomCanonicalAlias]: {isState: true},
|
||||
[EventType.RoomHistoryVisibility]: {isState: true},
|
||||
[EventType.RoomPowerLevels]: {isState: true},
|
||||
[EventType.RoomTopic]: {isState: true},
|
||||
[EventType.RoomTombstone]: {isState: true},
|
||||
[EventType.RoomEncryption]: {isState: true},
|
||||
[EventType.RoomServerAcl]: {isState: true},
|
||||
[EventType.RoomAvatar]: { isState: true },
|
||||
[EventType.RoomName]: { isState: true },
|
||||
[EventType.RoomCanonicalAlias]: { isState: true },
|
||||
[EventType.RoomHistoryVisibility]: { isState: true },
|
||||
[EventType.RoomPowerLevels]: { isState: true },
|
||||
[EventType.RoomTopic]: { isState: true },
|
||||
[EventType.RoomTombstone]: { isState: true },
|
||||
[EventType.RoomEncryption]: { isState: true },
|
||||
[EventType.RoomServerAcl]: { isState: true },
|
||||
|
||||
// TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
|
||||
"im.vector.modular.widgets": {isState: true},
|
||||
"im.vector.modular.widgets": { isState: true },
|
||||
};
|
||||
|
||||
// parse a string as an integer; if the input is undefined, or cannot be parsed
|
||||
|
@ -103,7 +103,7 @@ export class BannedUser extends React.Component<IBannedUserProps> {
|
|||
return (
|
||||
<li>
|
||||
{unbanButton}
|
||||
<span title={_t("Banned by %(displayName)s", {displayName: this.props.by})}>
|
||||
<span title={_t("Banned by %(displayName)s", { displayName: this.props.by })}>
|
||||
<strong>{ this.props.member.name }</strong> {userId}
|
||||
{this.props.reason ? " " + _t('Reason') + ": " + this.props.reason : ""}
|
||||
</span>
|
||||
|
@ -394,7 +394,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
|
|||
if (label) {
|
||||
label = _t(label);
|
||||
} else {
|
||||
label = _t("Send %(eventType)s events", {eventType});
|
||||
label = _t("Send %(eventType)s events", { eventType });
|
||||
}
|
||||
return (
|
||||
<div className="" key={eventType}>
|
||||
|
|
|
@ -16,16 +16,16 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||
import * as sdk from "../../../../..";
|
||||
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
|
||||
import Modal from "../../../../../Modal";
|
||||
import QuestionDialog from "../../../dialogs/QuestionDialog";
|
||||
import StyledRadioGroup from '../../../elements/StyledRadioGroup';
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
import {UIFeature} from "../../../../../settings/UIFeature";
|
||||
import { UIFeature } from "../../../../../settings/UIFeature";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
|
||||
// Knock and private are reserved keywords which are not yet implemented.
|
||||
|
@ -100,9 +100,9 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
|||
HistoryVisibility.Shared,
|
||||
);
|
||||
const encrypted = MatrixClientPeg.get().isRoomEncrypted(this.props.roomId);
|
||||
this.setState({joinRule, guestAccess, history, encrypted});
|
||||
this.setState({ joinRule, guestAccess, history, encrypted });
|
||||
const hasAliases = await this.hasAliases();
|
||||
this.setState({hasAliases});
|
||||
this.setState({ hasAliases });
|
||||
}
|
||||
|
||||
private pullContentPropertyFromEvent<T>(event: MatrixEvent, key: string, defaultValue: T): T {
|
||||
|
@ -140,18 +140,18 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
|||
),
|
||||
onFinished: (confirm) => {
|
||||
if (!confirm) {
|
||||
this.setState({encrypted: false});
|
||||
this.setState({ encrypted: false });
|
||||
return;
|
||||
}
|
||||
|
||||
const beforeEncrypted = this.state.encrypted;
|
||||
this.setState({encrypted: true});
|
||||
this.setState({ encrypted: true });
|
||||
MatrixClientPeg.get().sendStateEvent(
|
||||
this.props.roomId, "m.room.encryption",
|
||||
{ algorithm: "m.megolm.v1.aes-sha2" },
|
||||
).catch((e) => {
|
||||
console.error(e);
|
||||
this.setState({encrypted: beforeEncrypted});
|
||||
this.setState({ encrypted: beforeEncrypted });
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -166,16 +166,16 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
|||
|
||||
const beforeJoinRule = this.state.joinRule;
|
||||
const beforeGuestAccess = this.state.guestAccess;
|
||||
this.setState({joinRule, guestAccess});
|
||||
this.setState({ joinRule, guestAccess });
|
||||
|
||||
const client = MatrixClientPeg.get();
|
||||
client.sendStateEvent(this.props.roomId, "m.room.join_rules", {join_rule: joinRule}, "").catch((e) => {
|
||||
client.sendStateEvent(this.props.roomId, "m.room.join_rules", { join_rule: joinRule }, "").catch((e) => {
|
||||
console.error(e);
|
||||
this.setState({joinRule: beforeJoinRule});
|
||||
this.setState({ joinRule: beforeJoinRule });
|
||||
});
|
||||
client.sendStateEvent(this.props.roomId, "m.room.guest_access", {guest_access: guestAccess}, "").catch((e) => {
|
||||
client.sendStateEvent(this.props.roomId, "m.room.guest_access", { guest_access: guestAccess }, "").catch((e) => {
|
||||
console.error(e);
|
||||
this.setState({guestAccess: beforeGuestAccess});
|
||||
this.setState({ guestAccess: beforeGuestAccess });
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -212,27 +212,27 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
|||
|
||||
const beforeJoinRule = this.state.joinRule;
|
||||
const beforeGuestAccess = this.state.guestAccess;
|
||||
this.setState({joinRule, guestAccess});
|
||||
this.setState({ joinRule, guestAccess });
|
||||
|
||||
const client = MatrixClientPeg.get();
|
||||
client.sendStateEvent(this.props.roomId, "m.room.join_rules", {join_rule: joinRule}, "").catch((e) => {
|
||||
client.sendStateEvent(this.props.roomId, "m.room.join_rules", { join_rule: joinRule }, "").catch((e) => {
|
||||
console.error(e);
|
||||
this.setState({joinRule: beforeJoinRule});
|
||||
this.setState({ joinRule: beforeJoinRule });
|
||||
});
|
||||
client.sendStateEvent(this.props.roomId, "m.room.guest_access", {guest_access: guestAccess}, "").catch((e) => {
|
||||
client.sendStateEvent(this.props.roomId, "m.room.guest_access", { guest_access: guestAccess }, "").catch((e) => {
|
||||
console.error(e);
|
||||
this.setState({guestAccess: beforeGuestAccess});
|
||||
this.setState({ guestAccess: beforeGuestAccess });
|
||||
});
|
||||
};
|
||||
|
||||
private onHistoryRadioToggle = (history: HistoryVisibility) => {
|
||||
const beforeHistory = this.state.history;
|
||||
this.setState({history: history});
|
||||
this.setState({ history: history });
|
||||
MatrixClientPeg.get().sendStateEvent(this.props.roomId, "m.room.history_visibility", {
|
||||
history_visibility: history,
|
||||
}, "").catch((e) => {
|
||||
console.error(e);
|
||||
this.setState({history: beforeHistory});
|
||||
this.setState({ history: beforeHistory });
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import SdkConfig from "../../../../../SdkConfig";
|
||||
import { MatrixClientPeg } from '../../../../../MatrixClientPeg';
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
|
@ -84,7 +84,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
|||
fontSize: (SettingsStore.getValue("baseFontSize", null) + FontWatcher.SIZE_DIFF).toString(),
|
||||
...this.calculateThemeState(),
|
||||
customThemeUrl: "",
|
||||
customThemeMessage: {isError: false, text: ""},
|
||||
customThemeMessage: { isError: false, text: "" },
|
||||
useCustomFontSize: SettingsStore.getValue("useCustomFontSize"),
|
||||
useSystemFont: SettingsStore.getValue("useSystemFont"),
|
||||
systemFont: SettingsStore.getValue("systemFont"),
|
||||
|
@ -149,43 +149,43 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
|||
// so remember what the value was before we tried to set it so we can revert
|
||||
const oldTheme: string = SettingsStore.getValue('theme');
|
||||
SettingsStore.setValue("theme", null, SettingLevel.DEVICE, newTheme).catch(() => {
|
||||
dis.dispatch<RecheckThemePayload>({action: Action.RecheckTheme});
|
||||
this.setState({theme: oldTheme});
|
||||
dis.dispatch<RecheckThemePayload>({ action: Action.RecheckTheme });
|
||||
this.setState({ theme: oldTheme });
|
||||
});
|
||||
this.setState({theme: newTheme});
|
||||
this.setState({ theme: newTheme });
|
||||
// The settings watcher doesn't fire until the echo comes back from the
|
||||
// server, so to make the theme change immediately we need to manually
|
||||
// do the dispatch now
|
||||
// XXX: The local echoed value appears to be unreliable, in particular
|
||||
// when settings custom themes(!) so adding forceTheme to override
|
||||
// the value from settings.
|
||||
dis.dispatch<RecheckThemePayload>({action: Action.RecheckTheme, forceTheme: newTheme});
|
||||
dis.dispatch<RecheckThemePayload>({ action: Action.RecheckTheme, forceTheme: newTheme });
|
||||
};
|
||||
|
||||
private onUseSystemThemeChanged = (checked: boolean): void => {
|
||||
this.setState({useSystemTheme: checked});
|
||||
this.setState({ useSystemTheme: checked });
|
||||
SettingsStore.setValue("use_system_theme", null, SettingLevel.DEVICE, checked);
|
||||
dis.dispatch<RecheckThemePayload>({action: Action.RecheckTheme});
|
||||
dis.dispatch<RecheckThemePayload>({ action: Action.RecheckTheme });
|
||||
};
|
||||
|
||||
private onFontSizeChanged = (size: number): void => {
|
||||
this.setState({fontSize: size.toString()});
|
||||
this.setState({ fontSize: size.toString() });
|
||||
SettingsStore.setValue("baseFontSize", null, SettingLevel.DEVICE, size - FontWatcher.SIZE_DIFF);
|
||||
};
|
||||
|
||||
private onValidateFontSize = async ({value}: Pick<IFieldState, "value">): Promise<IValidationResult> => {
|
||||
private onValidateFontSize = async ({ value }: Pick<IFieldState, "value">): Promise<IValidationResult> => {
|
||||
const parsedSize = parseFloat(value);
|
||||
const min = FontWatcher.MIN_SIZE + FontWatcher.SIZE_DIFF;
|
||||
const max = FontWatcher.MAX_SIZE + FontWatcher.SIZE_DIFF;
|
||||
|
||||
if (isNaN(parsedSize)) {
|
||||
return {valid: false, feedback: _t("Size must be a number")};
|
||||
return { valid: false, feedback: _t("Size must be a number") };
|
||||
}
|
||||
|
||||
if (!(min <= parsedSize && parsedSize <= max)) {
|
||||
return {
|
||||
valid: false,
|
||||
feedback: _t('Custom font size can only be between %(min)s pt and %(max)s pt', {min, max}),
|
||||
feedback: _t('Custom font size can only be between %(min)s pt and %(max)s pt', { min, max }),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -196,7 +196,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
|||
parseInt(value, 10) - FontWatcher.SIZE_DIFF,
|
||||
);
|
||||
|
||||
return {valid: true, feedback: _t('Use between %(min)s pt and %(max)s pt', {min, max})};
|
||||
return { valid: true, feedback: _t('Use between %(min)s pt and %(max)s pt', { min, max }) };
|
||||
};
|
||||
|
||||
private onAddCustomTheme = async (): Promise<void> => {
|
||||
|
@ -213,37 +213,37 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
|||
// XXX: need some schema for this
|
||||
const themeInfo = await r.json();
|
||||
if (!themeInfo || typeof(themeInfo['name']) !== 'string' || typeof(themeInfo['colors']) !== 'object') {
|
||||
this.setState({customThemeMessage: {text: _t("Invalid theme schema."), isError: true}});
|
||||
this.setState({ customThemeMessage: { text: _t("Invalid theme schema."), isError: true } });
|
||||
return;
|
||||
}
|
||||
currentThemes.push(themeInfo);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
this.setState({customThemeMessage: {text: _t("Error downloading theme information."), isError: true}});
|
||||
this.setState({ customThemeMessage: { text: _t("Error downloading theme information."), isError: true } });
|
||||
return; // Don't continue on error
|
||||
}
|
||||
|
||||
await SettingsStore.setValue("custom_themes", null, SettingLevel.ACCOUNT, currentThemes);
|
||||
this.setState({customThemeUrl: "", customThemeMessage: {text: _t("Theme added!"), isError: false}});
|
||||
this.setState({ customThemeUrl: "", customThemeMessage: { text: _t("Theme added!"), isError: false } });
|
||||
|
||||
this.themeTimer = setTimeout(() => {
|
||||
this.setState({customThemeMessage: {text: "", isError: false}});
|
||||
this.setState({ customThemeMessage: { text: "", isError: false } });
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
private onCustomThemeChange = (e: React.ChangeEvent<HTMLSelectElement | HTMLInputElement>): void => {
|
||||
this.setState({customThemeUrl: e.target.value});
|
||||
this.setState({ customThemeUrl: e.target.value });
|
||||
};
|
||||
|
||||
private onIRCLayoutChange = (enabled: boolean) => {
|
||||
if (enabled) {
|
||||
this.setState({layout: Layout.IRC});
|
||||
this.setState({ layout: Layout.IRC });
|
||||
SettingsStore.setValue("layout", null, SettingLevel.DEVICE, Layout.IRC);
|
||||
} else {
|
||||
this.setState({layout: Layout.Group});
|
||||
this.setState({ layout: Layout.Group });
|
||||
SettingsStore.setValue("layout", null, SettingLevel.DEVICE, Layout.Group);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private renderThemeSection() {
|
||||
const themeWatcher = new ThemeWatcher();
|
||||
|
@ -293,7 +293,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
|||
|
||||
// XXX: replace any type here
|
||||
const themes = Object.entries<any>(enumerateThemes())
|
||||
.map(p => ({id: p[0], name: p[1]})); // convert pairs to objects for code readability
|
||||
.map(p => ({ id: p[0], name: p[1] })); // convert pairs to objects for code readability
|
||||
const builtInThemes = themes.filter(p => !p.id.startsWith("custom-"));
|
||||
const customThemes = themes.filter(p => !builtInThemes.includes(p))
|
||||
.sort((a, b) => compare(a.name, b.name));
|
||||
|
@ -348,7 +348,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
|||
<SettingsFlag
|
||||
name="useCustomFontSize"
|
||||
level={SettingLevel.ACCOUNT}
|
||||
onChange={(checked) => this.setState({useCustomFontSize: checked})}
|
||||
onChange={(checked) => this.setState({ useCustomFontSize: checked })}
|
||||
useCheckbox={true}
|
||||
/>
|
||||
|
||||
|
@ -360,7 +360,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
|||
value={this.state.fontSize.toString()}
|
||||
id="font_size_field"
|
||||
onValidate={this.onValidateFontSize}
|
||||
onChange={(value) => this.setState({fontSize: value.target.value})}
|
||||
onChange={(value) => this.setState({ fontSize: value.target.value })}
|
||||
disabled={!this.state.useCustomFontSize}
|
||||
className="mx_SettingsTab_customFontSizeField"
|
||||
/>
|
||||
|
@ -373,7 +373,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
|||
const brand = SdkConfig.get().brand;
|
||||
const toggle = <div
|
||||
className="mx_AppearanceUserSettingsTab_AdvancedToggle"
|
||||
onClick={() => this.setState({showAdvanced: !this.state.showAdvanced})}
|
||||
onClick={() => this.setState({ showAdvanced: !this.state.showAdvanced })}
|
||||
>
|
||||
{this.state.showAdvanced ? _t("Hide advanced") : _t("Show advanced")}
|
||||
</div>;
|
||||
|
@ -403,7 +403,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
|||
name="useSystemFont"
|
||||
level={SettingLevel.DEVICE}
|
||||
useCheckbox={true}
|
||||
onChange={(checked) => this.setState({useSystemFont: checked})}
|
||||
onChange={(checked) => this.setState({ useSystemFont: checked })}
|
||||
/>
|
||||
<Field
|
||||
className="mx_AppearanceUserSettingsTab_systemFont"
|
||||
|
|
|
@ -15,9 +15,9 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import GroupUserSettings from "../../../groups/GroupUserSettings";
|
||||
import {replaceableComponent} from "../../../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.tabs.user.FlairUserSettingsTab")
|
||||
export default class FlairUserSettingsTab extends React.Component {
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import ProfileSettings from "../../ProfileSettings";
|
||||
import * as languageHandler from "../../../../../languageHandler";
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
|
@ -27,19 +27,19 @@ import AccessibleButton from "../../../elements/AccessibleButton";
|
|||
import DeactivateAccountDialog from "../../../dialogs/DeactivateAccountDialog";
|
||||
import PropTypes from "prop-types";
|
||||
import PlatformPeg from "../../../../../PlatformPeg";
|
||||
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||
import * as sdk from "../../../../..";
|
||||
import Modal from "../../../../../Modal";
|
||||
import dis from "../../../../../dispatcher/dispatcher";
|
||||
import {Service, startTermsFlow} from "../../../../../Terms";
|
||||
import {SERVICE_TYPES} from "matrix-js-sdk/src/service-types";
|
||||
import { Service, startTermsFlow } from "../../../../../Terms";
|
||||
import { SERVICE_TYPES } from "matrix-js-sdk/src/service-types";
|
||||
import IdentityAuthClient from "../../../../../IdentityAuthClient";
|
||||
import {abbreviateUrl} from "../../../../../utils/UrlUtils";
|
||||
import { abbreviateUrl } from "../../../../../utils/UrlUtils";
|
||||
import { getThreepidsWithBindStatus } from '../../../../../boundThreepids';
|
||||
import Spinner from "../../../elements/Spinner";
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
import {UIFeature} from "../../../../../settings/UIFeature";
|
||||
import {replaceableComponent} from "../../../../../utils/replaceableComponent";
|
||||
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||
import { UIFeature } from "../../../../../settings/UIFeature";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.tabs.user.GeneralUserSettingsTab")
|
||||
export default class GeneralUserSettingsTab extends React.Component {
|
||||
|
@ -84,7 +84,7 @@ export default class GeneralUserSettingsTab extends React.Component {
|
|||
// the enabled flag value.
|
||||
const canChangePassword = !changePasswordCap || changePasswordCap['enabled'] !== false;
|
||||
|
||||
this.setState({serverSupportsSeparateAddAndBind, canChangePassword});
|
||||
this.setState({ serverSupportsSeparateAddAndBind, canChangePassword });
|
||||
|
||||
this._getThreepidState();
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ export default class GeneralUserSettingsTab extends React.Component {
|
|||
|
||||
_onAction = (payload) => {
|
||||
if (payload.action === 'id_server_changed') {
|
||||
this.setState({haveIdServer: Boolean(MatrixClientPeg.get().getIdentityServerUrl())});
|
||||
this.setState({ haveIdServer: Boolean(MatrixClientPeg.get().getIdentityServerUrl()) });
|
||||
this._getThreepidState();
|
||||
}
|
||||
};
|
||||
|
@ -145,7 +145,7 @@ export default class GeneralUserSettingsTab extends React.Component {
|
|||
|
||||
async _checkTerms() {
|
||||
if (!this.state.haveIdServer) {
|
||||
this.setState({idServerHasUnsignedTerms: false});
|
||||
this.setState({ idServerHasUnsignedTerms: false });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,7 @@ export default class GeneralUserSettingsTab extends React.Component {
|
|||
if (this.state.language === newLanguage) return;
|
||||
|
||||
SettingsStore.setValue("language", null, SettingLevel.DEVICE, newLanguage);
|
||||
this.setState({language: newLanguage});
|
||||
this.setState({ language: newLanguage });
|
||||
const platform = PlatformPeg.get();
|
||||
if (platform) {
|
||||
platform.setLanguage(newLanguage);
|
||||
|
@ -200,7 +200,7 @@ export default class GeneralUserSettingsTab extends React.Component {
|
|||
};
|
||||
|
||||
_onSpellCheckLanguagesChange = (languages) => {
|
||||
this.setState({spellCheckLanguages: languages});
|
||||
this.setState({ spellCheckLanguages: languages });
|
||||
|
||||
const plaf = PlatformPeg.get();
|
||||
if (plaf) {
|
||||
|
@ -353,7 +353,7 @@ export default class GeneralUserSettingsTab extends React.Component {
|
|||
{_t(
|
||||
"Agree to the identity server (%(serverName)s) Terms of Service to " +
|
||||
"allow yourself to be discoverable by email address or phone number.",
|
||||
{serverName: this.state.idServerName},
|
||||
{ serverName: this.state.idServerName },
|
||||
)}
|
||||
</span>;
|
||||
return (
|
||||
|
|
|
@ -15,8 +15,8 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {_t, getCurrentLanguage} from "../../../../../languageHandler";
|
||||
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
||||
import { _t, getCurrentLanguage } from "../../../../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
import AccessibleTooltipButton from '../../../elements/AccessibleTooltipButton';
|
||||
import SdkConfig from "../../../../../SdkConfig";
|
||||
|
@ -54,10 +54,10 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
|
|||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
PlatformPeg.get().getAppVersion().then((ver) => this.setState({appVersion: ver})).catch((e) => {
|
||||
PlatformPeg.get().getAppVersion().then((ver) => this.setState({ appVersion: ver })).catch((e) => {
|
||||
console.error("Error getting vector version: ", e);
|
||||
});
|
||||
PlatformPeg.get().canSelfUpdate().then((v) => this.setState({canUpdate: v})).catch((e) => {
|
||||
PlatformPeg.get().canSelfUpdate().then((v) => this.setState({ canUpdate: v })).catch((e) => {
|
||||
console.error("Error getting self updatability: ", e);
|
||||
});
|
||||
}
|
||||
|
@ -172,12 +172,12 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
|
|||
const successful = await copyPlaintext(MatrixClientPeg.get().getAccessToken());
|
||||
const buttonRect = target.getBoundingClientRect();
|
||||
const GenericTextContextMenu = sdk.getComponent('context_menus.GenericTextContextMenu');
|
||||
const {close} = ContextMenu.createMenu(GenericTextContextMenu, {
|
||||
const { close } = ContextMenu.createMenu(GenericTextContextMenu, {
|
||||
...toRightOf(buttonRect, 2),
|
||||
message: successful ? _t('Copied!') : _t('Failed to copy'),
|
||||
});
|
||||
this.closeCopiedTooltip = target.onmouseleave = close;
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const brand = SdkConfig.get().brand;
|
||||
|
|
|
@ -15,13 +15,13 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import PropTypes from "prop-types";
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
|
||||
import * as sdk from "../../../../../index";
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
import {replaceableComponent} from "../../../../../utils/replaceableComponent";
|
||||
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
import SdkConfig from "../../../../../SdkConfig";
|
||||
import BetaCard from "../../../beta/BetaCard";
|
||||
|
||||
|
|
|
@ -15,15 +15,15 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import SdkConfig from "../../../../../SdkConfig";
|
||||
import {Mjolnir} from "../../../../../mjolnir/Mjolnir";
|
||||
import {ListRule} from "../../../../../mjolnir/ListRule";
|
||||
import {BanList, RULE_SERVER, RULE_USER} from "../../../../../mjolnir/BanList";
|
||||
import { Mjolnir } from "../../../../../mjolnir/Mjolnir";
|
||||
import { ListRule } from "../../../../../mjolnir/ListRule";
|
||||
import { BanList, RULE_SERVER, RULE_USER } from "../../../../../mjolnir/BanList";
|
||||
import Modal from "../../../../../Modal";
|
||||
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||
import * as sdk from "../../../../../index";
|
||||
import {replaceableComponent} from "../../../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
|
||||
interface IState {
|
||||
busy: boolean;
|
||||
|
@ -44,11 +44,11 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
|||
}
|
||||
|
||||
private onPersonalRuleChanged = (e) => {
|
||||
this.setState({newPersonalRule: e.target.value});
|
||||
this.setState({ newPersonalRule: e.target.value });
|
||||
};
|
||||
|
||||
private onNewListChanged = (e) => {
|
||||
this.setState({newList: e.target.value});
|
||||
this.setState({ newList: e.target.value });
|
||||
};
|
||||
|
||||
private onAddPersonalRule = async (e) => {
|
||||
|
@ -60,11 +60,11 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
|||
kind = RULE_USER;
|
||||
}
|
||||
|
||||
this.setState({busy: true});
|
||||
this.setState({ busy: true });
|
||||
try {
|
||||
const list = await Mjolnir.sharedInstance().getOrCreatePersonalList();
|
||||
await list.banEntity(kind, this.state.newPersonalRule, _t("Ignored/Blocked"));
|
||||
this.setState({newPersonalRule: ""}); // this will also cause the new rule to be rendered
|
||||
this.setState({ newPersonalRule: "" }); // this will also cause the new rule to be rendered
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
||||
|
@ -74,7 +74,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
|||
description: _t('Something went wrong. Please try again or view your console for hints.'),
|
||||
});
|
||||
} finally {
|
||||
this.setState({busy: false});
|
||||
this.setState({ busy: false });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -82,11 +82,11 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
|||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
this.setState({busy: true});
|
||||
this.setState({ busy: true });
|
||||
try {
|
||||
const room = await MatrixClientPeg.get().joinRoom(this.state.newList);
|
||||
await Mjolnir.sharedInstance().subscribeToList(room.roomId);
|
||||
this.setState({newList: ""}); // this will also cause the new rule to be rendered
|
||||
this.setState({ newList: "" }); // this will also cause the new rule to be rendered
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
||||
|
@ -96,12 +96,12 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
|||
description: _t('Please verify the room ID or address and try again.'),
|
||||
});
|
||||
} finally {
|
||||
this.setState({busy: false});
|
||||
this.setState({ busy: false });
|
||||
}
|
||||
};
|
||||
|
||||
private async removePersonalRule(rule: ListRule) {
|
||||
this.setState({busy: true});
|
||||
this.setState({ busy: true });
|
||||
try {
|
||||
const list = Mjolnir.sharedInstance().getPersonalList();
|
||||
await list.unbanEntity(rule.kind, rule.entity);
|
||||
|
@ -114,12 +114,12 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
|||
description: _t('Something went wrong. Please try again or view your console for hints.'),
|
||||
});
|
||||
} finally {
|
||||
this.setState({busy: false});
|
||||
this.setState({ busy: false });
|
||||
}
|
||||
}
|
||||
|
||||
private async unsubscribeFromList(list: BanList) {
|
||||
this.setState({busy: true});
|
||||
this.setState({ busy: true });
|
||||
try {
|
||||
await Mjolnir.sharedInstance().unsubscribeFromList(list.roomId);
|
||||
await MatrixClientPeg.get().leave(list.roomId);
|
||||
|
@ -132,7 +132,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
|||
description: _t('Please try again or view your console for hints.'),
|
||||
});
|
||||
} finally {
|
||||
this.setState({busy: false});
|
||||
this.setState({ busy: false });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
|||
};
|
||||
|
||||
Modal.createTrackedDialog('View Mjolnir list rules', '', QuestionDialog, {
|
||||
title: _t("Ban list rules - %(roomName)s", {roomName: name}),
|
||||
title: _t("Ban list rules - %(roomName)s", { roomName: name }),
|
||||
description: (
|
||||
<div>
|
||||
<h3>{_t("Server rules")}</h3>
|
||||
|
@ -256,7 +256,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
|||
"Add users and servers you want to ignore here. Use asterisks " +
|
||||
"to have %(brand)s match any characters. For example, <code>@bot:*</code> " +
|
||||
"would ignore all users that have the name 'bot' on any server.",
|
||||
{ brand }, {code: (s) => <code>{s}</code>},
|
||||
{ brand }, { code: (s) => <code>{s}</code> },
|
||||
)}<br />
|
||||
<br />
|
||||
{_t(
|
||||
|
|
|
@ -15,9 +15,9 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import * as sdk from "../../../../../index";
|
||||
import {replaceableComponent} from "../../../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.tabs.user.NotificationUserSettingsTab")
|
||||
export default class NotificationUserSettingsTab extends React.Component {
|
||||
|
|
|
@ -16,13 +16,13 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
import Field from "../../../elements/Field";
|
||||
import * as sdk from "../../../../..";
|
||||
import PlatformPeg from "../../../../../PlatformPeg";
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
|
||||
interface IState {
|
||||
|
@ -143,33 +143,33 @@ export default class PreferencesUserSettingsTab extends React.Component<{}, ISta
|
|||
}
|
||||
|
||||
private onAutoLaunchChange = (checked: boolean) => {
|
||||
PlatformPeg.get().setAutoLaunchEnabled(checked).then(() => this.setState({autoLaunch: checked}));
|
||||
PlatformPeg.get().setAutoLaunchEnabled(checked).then(() => this.setState({ autoLaunch: checked }));
|
||||
};
|
||||
|
||||
private onWarnBeforeExitChange = (checked: boolean) => {
|
||||
PlatformPeg.get().setWarnBeforeExit(checked).then(() => this.setState({warnBeforeExit: checked}));
|
||||
}
|
||||
PlatformPeg.get().setWarnBeforeExit(checked).then(() => this.setState({ warnBeforeExit: checked }));
|
||||
};
|
||||
|
||||
private onAlwaysShowMenuBarChange = (checked: boolean) => {
|
||||
PlatformPeg.get().setAutoHideMenuBarEnabled(!checked).then(() => this.setState({alwaysShowMenuBar: checked}));
|
||||
PlatformPeg.get().setAutoHideMenuBarEnabled(!checked).then(() => this.setState({ alwaysShowMenuBar: checked }));
|
||||
};
|
||||
|
||||
private onMinimizeToTrayChange = (checked: boolean) => {
|
||||
PlatformPeg.get().setMinimizeToTrayEnabled(checked).then(() => this.setState({minimizeToTray: checked}));
|
||||
PlatformPeg.get().setMinimizeToTrayEnabled(checked).then(() => this.setState({ minimizeToTray: checked }));
|
||||
};
|
||||
|
||||
private onAutocompleteDelayChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({autocompleteDelay: e.target.value});
|
||||
this.setState({ autocompleteDelay: e.target.value });
|
||||
SettingsStore.setValue("autocompleteDelay", null, SettingLevel.DEVICE, e.target.value);
|
||||
};
|
||||
|
||||
private onReadMarkerInViewThresholdMs = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({readMarkerInViewThresholdMs: e.target.value});
|
||||
this.setState({ readMarkerInViewThresholdMs: e.target.value });
|
||||
SettingsStore.setValue("readMarkerInViewThresholdMs", null, SettingLevel.DEVICE, e.target.value);
|
||||
};
|
||||
|
||||
private onReadMarkerOutOfViewThresholdMs = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({readMarkerOutOfViewThresholdMs: e.target.value});
|
||||
this.setState({ readMarkerOutOfViewThresholdMs: e.target.value });
|
||||
SettingsStore.setValue("readMarkerOutOfViewThresholdMs", null, SettingLevel.DEVICE, e.target.value);
|
||||
};
|
||||
|
||||
|
|
|
@ -17,24 +17,24 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import SdkConfig from "../../../../../SdkConfig";
|
||||
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||
import * as FormattingUtils from "../../../../../utils/FormattingUtils";
|
||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
import Analytics from "../../../../../Analytics";
|
||||
import Modal from "../../../../../Modal";
|
||||
import * as sdk from "../../../../..";
|
||||
import {sleep} from "../../../../../utils/promise";
|
||||
import { sleep } from "../../../../../utils/promise";
|
||||
import dis from "../../../../../dispatcher/dispatcher";
|
||||
import {privateShouldBeEncrypted} from "../../../../../createRoom";
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
import { privateShouldBeEncrypted } from "../../../../../createRoom";
|
||||
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||
import SecureBackupPanel from "../../SecureBackupPanel";
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
import {UIFeature} from "../../../../../settings/UIFeature";
|
||||
import {isE2eAdvancedPanelPossible} from "../../E2eAdvancedPanel";
|
||||
import { UIFeature } from "../../../../../settings/UIFeature";
|
||||
import { isE2eAdvancedPanelPossible } from "../../E2eAdvancedPanel";
|
||||
import CountlyAnalytics from "../../../../../CountlyAnalytics";
|
||||
import {replaceableComponent} from "../../../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
|
||||
export class IgnoredUser extends React.Component {
|
||||
static propTypes = {
|
||||
|
@ -82,12 +82,11 @@ export default class SecurityUserSettingsTab extends React.Component {
|
|||
this._onAction = this._onAction.bind(this);
|
||||
}
|
||||
|
||||
|
||||
_onAction({action}) {
|
||||
_onAction({ action }) {
|
||||
if (action === "ignore_state_changed") {
|
||||
const ignoredUserIds = MatrixClientPeg.get().getIgnoredUsers();
|
||||
const newWaitingUnignored = this.state.waitingUnignored.filter(e=> ignoredUserIds.includes(e));
|
||||
this.setState({ignoredUserIds, waitingUnignored: newWaitingUnignored});
|
||||
this.setState({ ignoredUserIds, waitingUnignored: newWaitingUnignored });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,14 +110,14 @@ export default class SecurityUserSettingsTab extends React.Component {
|
|||
_onExportE2eKeysClicked = () => {
|
||||
Modal.createTrackedDialogAsync('Export E2E Keys', '',
|
||||
import('../../../../../async-components/views/dialogs/security/ExportE2eKeysDialog'),
|
||||
{matrixClient: MatrixClientPeg.get()},
|
||||
{ matrixClient: MatrixClientPeg.get() },
|
||||
);
|
||||
};
|
||||
|
||||
_onImportE2eKeysClicked = () => {
|
||||
Modal.createTrackedDialogAsync('Import E2E Keys', '',
|
||||
import('../../../../../async-components/views/dialogs/security/ImportE2eKeysDialog'),
|
||||
{matrixClient: MatrixClientPeg.get()},
|
||||
{ matrixClient: MatrixClientPeg.get() },
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -131,13 +130,13 @@ export default class SecurityUserSettingsTab extends React.Component {
|
|||
}
|
||||
|
||||
_onUserUnignored = async (userId) => {
|
||||
const {ignoredUserIds, waitingUnignored} = this.state;
|
||||
const { ignoredUserIds, waitingUnignored } = this.state;
|
||||
const currentlyIgnoredUserIds = ignoredUserIds.filter(e => !waitingUnignored.includes(e));
|
||||
|
||||
const index = currentlyIgnoredUserIds.indexOf(userId);
|
||||
if (index !== -1) {
|
||||
currentlyIgnoredUserIds.splice(index, 1);
|
||||
this.setState(({waitingUnignored}) => ({waitingUnignored: [...waitingUnignored, userId]}));
|
||||
this.setState(({ waitingUnignored }) => ({ waitingUnignored: [...waitingUnignored, userId] }));
|
||||
MatrixClientPeg.get().setIgnoredUsers(currentlyIgnoredUserIds);
|
||||
}
|
||||
};
|
||||
|
@ -168,7 +167,7 @@ export default class SecurityUserSettingsTab extends React.Component {
|
|||
// Accept/reject invite
|
||||
await action(roomId).then(() => {
|
||||
// No error, update invited rooms button
|
||||
this.setState({invitedRoomAmt: self.state.invitedRoomAmt - 1});
|
||||
this.setState({ invitedRoomAmt: self.state.invitedRoomAmt - 1 });
|
||||
}, async (e) => {
|
||||
// Action failure
|
||||
if (e.errcode === "M_LIMIT_EXCEEDED") {
|
||||
|
@ -253,7 +252,7 @@ export default class SecurityUserSettingsTab extends React.Component {
|
|||
}
|
||||
|
||||
_renderIgnoredUsers() {
|
||||
const {waitingUnignored, ignoredUserIds} = this.state;
|
||||
const { waitingUnignored, ignoredUserIds } = this.state;
|
||||
|
||||
const userIds = !ignoredUserIds?.length
|
||||
? _t('You have no ignored users.')
|
||||
|
@ -291,10 +290,10 @@ export default class SecurityUserSettingsTab extends React.Component {
|
|||
<div className='mx_SettingsTab_section mx_SecurityUserSettingsTab_bulkOptions'>
|
||||
<span className='mx_SettingsTab_subheading'>{_t('Bulk options')}</span>
|
||||
<AccessibleButton onClick={onClickAccept} kind='primary' disabled={this.state.managingInvites}>
|
||||
{_t("Accept all %(invitedRooms)s invites", {invitedRooms: this.state.invitedRoomAmt})}
|
||||
{_t("Accept all %(invitedRooms)s invites", { invitedRooms: this.state.invitedRoomAmt })}
|
||||
</AccessibleButton>
|
||||
<AccessibleButton onClick={onClickReject} kind='danger' disabled={this.state.managingInvites}>
|
||||
{_t("Reject all %(invitedRooms)s invites", {invitedRooms: this.state.invitedRoomAmt})}
|
||||
{_t("Reject all %(invitedRooms)s invites", { invitedRooms: this.state.invitedRoomAmt })}
|
||||
</AccessibleButton>
|
||||
{this.state.managingInvites ? <InlineSpinner /> : <div />}
|
||||
</div>
|
||||
|
|
|
@ -16,16 +16,16 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {_t} from "../../../../../languageHandler";
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import SdkConfig from "../../../../../SdkConfig";
|
||||
import MediaDeviceHandler from "../../../../../MediaDeviceHandler";
|
||||
import Field from "../../../elements/Field";
|
||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
|
||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||
import * as sdk from "../../../../../index";
|
||||
import Modal from "../../../../../Modal";
|
||||
import {SettingLevel} from "../../../../../settings/SettingLevel";
|
||||
import {replaceableComponent} from "../../../../../utils/replaceableComponent";
|
||||
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||
|
||||
@replaceableComponent("views.settings.tabs.user.VoiceUserSettingsTab")
|
||||
export default class VoiceUserSettingsTab extends React.Component {
|
||||
|
@ -67,7 +67,7 @@ export default class VoiceUserSettingsTab extends React.Component {
|
|||
let stream;
|
||||
let error;
|
||||
try {
|
||||
constraints = {video: true, audio: true};
|
||||
constraints = { video: true, audio: true };
|
||||
stream = await navigator.mediaDevices.getUserMedia(constraints);
|
||||
} catch (err) {
|
||||
// user likely doesn't have a webcam,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue