Remove Piwik support (#8835)

* Remove all mentions of Piwik

* Kill off all consumer of the old Piwik Analytics module

* Simplify ModalManager interface

* i18n

* Attempt to fix old e2e tests

* Remove unused component

* Iterate PR
This commit is contained in:
Michael Telatynski 2022-06-14 17:51:51 +01:00 committed by GitHub
parent 7d14d15ba6
commit 3c5c2bef6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
142 changed files with 446 additions and 1412 deletions

View file

@ -95,7 +95,7 @@ export default class ChangePassword extends React.Component<IProps, IState> {
if (userHasOtherDevices && !serverSupportsControlOfDevicesLogout && this.props.confirm) {
// warn about logging out all devices
const { finished } = Modal.createTrackedDialog<[boolean]>('Change Password', '', QuestionDialog, {
const { finished } = Modal.createDialog<[boolean]>(QuestionDialog, {
title: _t("Warning!"),
description:
<div>
@ -196,14 +196,14 @@ export default class ChangePassword extends React.Component<IProps, IState> {
private optionallySetEmail(): Promise<boolean> {
// Ask for an email otherwise the user has no way to reset their password
const modal = Modal.createTrackedDialog('Do you want to set an email address?', '', SetEmailDialog, {
const modal = Modal.createDialog(SetEmailDialog, {
title: _t('Do you want to set an email address?'),
});
return modal.finished.then(([confirmed]) => confirmed);
}
private onExportE2eKeysClicked = (): void => {
Modal.createTrackedDialogAsync('Export E2E Keys', 'Change Password',
Modal.createDialogAsync(
import(
'../../../async-components/views/dialogs/security/ExportE2eKeysDialog'
) as unknown as Promise<ComponentType<{}>>,

View file

@ -75,10 +75,7 @@ export default class CrossSigningPanel extends React.PureComponent<{}, IState> {
private onBootstrapClick = () => {
if (this.state.crossSigningPrivateKeysInStorage) {
Modal.createTrackedDialog(
"Verify session", "Verify session", SetupEncryptionDialog,
{}, null, /* priority = */ false, /* static = */ true,
);
Modal.createDialog(SetupEncryptionDialog, {}, null, /* priority = */ false, /* static = */ true);
} else {
// Trigger the flow to set up secure backup, which is what this will do when in
// the appropriate state.
@ -130,14 +127,11 @@ export default class CrossSigningPanel extends React.PureComponent<{}, IState> {
const cli = MatrixClientPeg.get();
await cli.bootstrapCrossSigning({
authUploadDeviceSigningKeys: async (makeRequest) => {
const { finished } = Modal.createTrackedDialog(
'Cross-signing keys dialog', '', InteractiveAuthDialog,
{
title: _t("Setting up keys"),
matrixClient: cli,
makeRequest,
},
);
const { finished } = Modal.createDialog(InteractiveAuthDialog, {
title: _t("Setting up keys"),
matrixClient: cli,
makeRequest,
});
const [confirmed] = await finished;
if (!confirmed) {
throw new Error("Cross-signing key upload auth canceled");

View file

@ -91,7 +91,7 @@ export default class CryptographyPanel extends React.Component<IProps, IState> {
}
private onExportE2eKeysClicked = (): void => {
Modal.createTrackedDialogAsync('Export E2E Keys', '',
Modal.createDialogAsync(
import(
'../../../async-components/views/dialogs/security/ExportE2eKeysDialog'
) as unknown as Promise<ComponentType<{}>>,
@ -100,7 +100,7 @@ export default class CryptographyPanel extends React.Component<IProps, IState> {
};
private onImportE2eKeysClicked = (): void => {
Modal.createTrackedDialogAsync('Import E2E Keys', '',
Modal.createDialogAsync(
import(
'../../../async-components/views/dialogs/security/ImportE2eKeysDialog'
) as unknown as Promise<ComponentType<{}>>,

View file

@ -215,7 +215,7 @@ export default class DevicesPanel extends React.Component<IProps, IState> {
continueKind: "danger",
},
};
Modal.createTrackedDialog('Delete Device Dialog', '', InteractiveAuthDialog, {
Modal.createDialog(InteractiveAuthDialog, {
title: _t("Authentication"),
matrixClient: MatrixClientPeg.get(),
authData: error.data,

View file

@ -84,14 +84,14 @@ export default class DevicesPanelEntry extends React.Component<IProps, IState> {
};
private onOwnDeviceSignOut = (): void => {
Modal.createTrackedDialog('Logout from device list', '', LogoutDialog,
Modal.createDialog(LogoutDialog,
/* props= */{}, /* className= */null,
/* isPriority= */false, /* isStatic= */true);
};
private verify = async () => {
if (this.props.isOwnDevice) {
Modal.createTrackedDialog("Verify session", "Verify session", SetupEncryptionDialog, {
Modal.createDialog(SetupEncryptionDialog, {
onFinished: this.props.onDeviceChange,
});
} else {
@ -101,7 +101,7 @@ export default class DevicesPanelEntry extends React.Component<IProps, IState> {
userId,
[this.props.device.device_id],
);
Modal.createTrackedDialog('New Session Verification', 'Starting dialog', VerificationRequestDialog, {
Modal.createDialog(VerificationRequestDialog, {
verificationRequestPromise,
member: cli.getUser(userId),
onFinished: async () => {

View file

@ -108,7 +108,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
}
private onManage = async () => {
Modal.createTrackedDialogAsync('Message search', 'Message search',
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...
import('../../../async-components/views/dialogs/eventindex/ManageEventIndexDialog'),

View file

@ -75,7 +75,7 @@ const JoinRuleSettings = ({ room, promptUpgrade, aliasWarning, onError, beforeCh
}
const matrixClient = MatrixClientPeg.get();
const { finished } = Modal.createTrackedDialog('Edit restricted', '', ManageRestrictedJoinRuleDialog, {
const { finished } = Modal.createDialog(ManageRestrictedJoinRuleDialog, {
matrixClient,
room,
selected,
@ -227,7 +227,7 @@ const JoinRuleSettings = ({ room, promptUpgrade, aliasWarning, onError, beforeCh
</b>;
}
Modal.createTrackedDialog('Restricted join rule upgrade', '', RoomUpgradeWarningDialog, {
Modal.createDialog(RoomUpgradeWarningDialog, {
roomId: room.roomId,
targetVersion,
description: <>

View file

@ -277,7 +277,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
}
private showSaveError() {
Modal.createTrackedDialog('Error saving notification preferences', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Error saving notification preferences'),
description: _t('An error occurred whilst saving your notification preferences.'),
});

View file

@ -120,7 +120,7 @@ export default class ProfileSettings extends React.Component<{}, IState> {
}
} catch (err) {
logger.log("Failed to save profile", err);
Modal.createTrackedDialog('Failed to save profile', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Failed to save your profile"),
description: ((err && err.message) ? err.message : _t("The operation could not be completed")),
});

View file

@ -167,7 +167,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
}
private startNewBackup = (): void => {
Modal.createTrackedDialogAsync('Key Backup', 'Key Backup',
Modal.createDialogAsync(
import(
'../../../async-components/views/dialogs/security/CreateKeyBackupDialog'
) as unknown as Promise<ComponentType<{}>>,
@ -180,7 +180,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
};
private deleteBackup = (): void => {
Modal.createTrackedDialog('Delete Backup', '', QuestionDialog, {
Modal.createDialog(QuestionDialog, {
title: _t('Delete Backup'),
description: _t(
"Are you sure? You will lose your encrypted messages if your " +
@ -199,10 +199,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
};
private restoreBackup = async (): Promise<void> => {
Modal.createTrackedDialog(
'Restore Backup', '', RestoreKeyBackupDialog, null, null,
/* priority = */ false, /* static = */ true,
);
Modal.createDialog(RestoreKeyBackupDialog, null, null, /* priority = */ false, /* static = */ true);
};
private resetSecretStorage = async (): Promise<void> => {

View file

@ -219,7 +219,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
};
private showNoTermsWarning(fullUrl) {
const { finished } = Modal.createTrackedDialog('No Terms Warning', '', QuestionDialog, {
const { finished } = Modal.createDialog(QuestionDialog, {
title: _t("Identity server has no terms of service"),
description: (
<div>
@ -320,7 +320,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
message = unboundMessage;
}
const { finished } = Modal.createTrackedDialog('Identity Server Bound Warning', '', QuestionDialog, {
const { finished } = Modal.createDialog(QuestionDialog, {
title,
description: message,
button,

View file

@ -80,7 +80,7 @@ export class ExistingEmailAddress extends React.Component<IExistingEmailAddressP
return this.props.onRemoved(this.props.email);
}).catch((err) => {
logger.error("Unable to remove contact information: " + err);
Modal.createTrackedDialog('Remove 3pid failed', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Unable to remove contact information"),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
@ -168,7 +168,7 @@ export default class EmailAddresses extends React.Component<IProps, IState> {
// TODO: Inline field validation
if (!Email.looksValid(email)) {
Modal.createTrackedDialog('Invalid email address', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Invalid Email Address"),
description: _t("This doesn't appear to be a valid email address"),
});
@ -183,7 +183,7 @@ export default class EmailAddresses extends React.Component<IProps, IState> {
}).catch((err) => {
logger.error("Unable to add email address " + email + " " + err);
this.setState({ verifying: false, continueDisabled: false, addTask: null });
Modal.createTrackedDialog('Unable to add email address', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Unable to add email address"),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
@ -215,14 +215,14 @@ export default class EmailAddresses extends React.Component<IProps, IState> {
}).catch((err) => {
this.setState({ continueDisabled: false });
if (err.errcode === 'M_THREEPID_AUTH_FAILED') {
Modal.createTrackedDialog("Email hasn't been verified yet", "", ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Your email address hasn't been verified yet"),
description: _t("Click the link in the email you received to verify " +
"and then click continue again."),
});
} else {
logger.error("Unable to verify email address: ", err);
Modal.createTrackedDialog('Unable to verify email address', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Unable to verify email address."),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});

View file

@ -76,7 +76,7 @@ export class ExistingPhoneNumber extends React.Component<IExistingPhoneNumberPro
return this.props.onRemoved(this.props.msisdn);
}).catch((err) => {
logger.error("Unable to remove contact information: " + err);
Modal.createTrackedDialog('Remove 3pid failed', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Unable to remove contact information"),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
@ -185,7 +185,7 @@ export default class PhoneNumbers extends React.Component<IProps, IState> {
}).catch((err) => {
logger.error("Unable to add phone number " + phoneNumber + " " + err);
this.setState({ verifying: false, continueDisabled: false, addTask: null });
Modal.createTrackedDialog('Add Phone Number Error', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Error"),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
@ -222,7 +222,7 @@ export default class PhoneNumbers extends React.Component<IProps, IState> {
this.setState({ continueDisabled: false });
if (err.errcode !== 'M_THREEPID_AUTH_FAILED') {
logger.error("Unable to verify phone number: " + err);
Modal.createTrackedDialog('Unable to verify phone number', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Unable to verify phone number."),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});

View file

@ -104,7 +104,7 @@ export class EmailAddress extends React.Component<IEmailAddressProps, IEmailAddr
continueDisabled: false,
addTask: null,
});
Modal.createTrackedDialog(`Unable to ${label} email address`, '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: errorTitle,
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
@ -139,7 +139,7 @@ export class EmailAddress extends React.Component<IEmailAddressProps, IEmailAddr
continueDisabled: false,
addTask: null,
});
Modal.createTrackedDialog(`Unable to ${label} email address`, '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: errorTitle,
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
@ -181,14 +181,14 @@ export class EmailAddress extends React.Component<IEmailAddressProps, IEmailAddr
} catch (err) {
this.setState({ continueDisabled: false });
if (err.errcode === 'M_THREEPID_AUTH_FAILED') {
Modal.createTrackedDialog("E-mail hasn't been verified yet", "", ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Your email address hasn't been verified yet"),
description: _t("Click the link in the email you received to verify " +
"and then click continue again."),
});
} else {
logger.error("Unable to verify email address: " + err);
Modal.createTrackedDialog('Unable to verify email address', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Unable to verify email address."),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});

View file

@ -104,7 +104,7 @@ export class PhoneNumber extends React.Component<IPhoneNumberProps, IPhoneNumber
continueDisabled: false,
addTask: null,
});
Modal.createTrackedDialog(`Unable to ${label} phone number`, '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: errorTitle,
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
@ -143,7 +143,7 @@ export class PhoneNumber extends React.Component<IPhoneNumberProps, IPhoneNumber
continueDisabled: false,
addTask: null,
});
Modal.createTrackedDialog(`Unable to ${label} phone number`, '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: errorTitle,
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
@ -195,7 +195,7 @@ export class PhoneNumber extends React.Component<IPhoneNumberProps, IPhoneNumber
this.setState({ continueDisabled: false });
if (err.errcode !== 'M_THREEPID_AUTH_FAILED') {
logger.error("Unable to verify phone number: " + err);
Modal.createTrackedDialog('Unable to verify phone number', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Unable to verify phone number."),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});

View file

@ -77,7 +77,7 @@ export default class AdvancedRoomSettingsTab extends React.Component<IProps, ISt
private upgradeRoom = (e) => {
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
Modal.createTrackedDialog('Upgrade Room Version', '', RoomUpgradeDialog, { room });
Modal.createDialog(RoomUpgradeDialog, { room });
};
private onOldRoomClicked = (e) => {

View file

@ -81,7 +81,7 @@ export class BannedUser extends React.Component<IBannedUserProps> {
private onUnbanClick = (e) => {
MatrixClientPeg.get().unban(this.props.member.roomId, this.props.member.userId).catch((err) => {
logger.error("Failed to unban: " + err);
Modal.createTrackedDialog('Failed to unban', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Error'),
description: _t('Failed to unban'),
});
@ -180,7 +180,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
client.sendStateEvent(this.props.roomId, EventType.RoomPowerLevels, plContent).catch(e => {
logger.error(e);
Modal.createTrackedDialog('Power level requirement change failed', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Error changing power level requirement'),
description: _t(
"An error occurred changing the room's power level requirements. Ensure you have sufficient " +
@ -206,7 +206,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
client.sendStateEvent(this.props.roomId, EventType.RoomPowerLevels, plContent).catch(e => {
logger.error(e);
Modal.createTrackedDialog('Power level change failed', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Error changing power level'),
description: _t(
"An error occurred changing the user's power level. Ensure you have sufficient " +

View file

@ -104,7 +104,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
private onEncryptionChange = async () => {
if (this.context.getRoom(this.props.roomId)?.getJoinRule() === JoinRule.Public) {
const dialog = Modal.createTrackedDialog('Confirm Public Encrypted Room', '', QuestionDialog, {
const dialog = Modal.createDialog(QuestionDialog, {
title: _t('Are you sure you want to add encryption to this public room?'),
description: <div>
<p> { _t(
@ -137,7 +137,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
if (!confirm) return;
}
Modal.createTrackedDialog('Enable encryption', '', QuestionDialog, {
Modal.createDialog(QuestionDialog, {
title: _t('Enable encryption?'),
description: _t(
"Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted " +
@ -185,9 +185,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
};
private createNewRoom = async (defaultPublic: boolean, defaultEncrypted: boolean) => {
const modal = Modal.createTrackedDialog<[boolean, IOpts]>(
"Create Room",
"Create room after trying to make an E2EE room public",
const modal = Modal.createDialog<[boolean, IOpts]>(
CreateRoomDialog,
{ defaultPublic, defaultEncrypted },
);
@ -257,7 +255,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
}
private onJoinRuleChangeError = (error: Error) => {
Modal.createTrackedDialog('Room not found', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Failed to update the join rules"),
description: error.message ?? _t("Unknown failure"),
});
@ -265,7 +263,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
private onBeforeJoinRuleChange = async (joinRule: JoinRule): Promise<boolean> => {
if (this.state.encrypted && joinRule === JoinRule.Public) {
const dialog = Modal.createTrackedDialog('Confirm Public Encrypted Room', '', QuestionDialog, {
const dialog = Modal.createDialog(QuestionDialog, {
title: _t("Are you sure you want to make this encrypted room public?"),
description: <div>
<p> { _t(

View file

@ -254,7 +254,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
errMsg += ` (HTTP status ${err.httpStatus})`;
}
logger.error("Failed to change password: " + errMsg);
Modal.createTrackedDialog('Failed to change password', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Error"),
description: errMsg,
});
@ -268,14 +268,14 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
);
}
// TODO: Figure out a design that doesn't involve replacing the current dialog
Modal.createTrackedDialog('Password changed', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Success"),
description,
});
};
private onDeactivateClicked = (): void => {
Modal.createTrackedDialog('Deactivate Account', '', DeactivateAccountDialog, {
Modal.createDialog(DeactivateAccountDialog, {
onFinished: (success) => {
if (success) this.props.closeSettingsFn();
},

View file

@ -87,7 +87,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
};
private onBugReport = (e) => {
Modal.createTrackedDialog('Bug Report Dialog', '', BugReportDialog, {});
Modal.createDialog(BugReportDialog, {});
};
private onStartBotChat = (e) => {

View file

@ -71,7 +71,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
} catch (e) {
logger.error(e);
Modal.createTrackedDialog('Failed to add Mjolnir rule', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Error adding ignored user/server'),
description: _t('Something went wrong. Please try again or view your console for hints.'),
});
@ -92,7 +92,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
} catch (e) {
logger.error(e);
Modal.createTrackedDialog('Failed to subscribe to Mjolnir list', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Error subscribing to list'),
description: _t('Please verify the room ID or address and try again.'),
});
@ -109,7 +109,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
} catch (e) {
logger.error(e);
Modal.createTrackedDialog('Failed to remove Mjolnir rule', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Error removing ignored user/server'),
description: _t('Something went wrong. Please try again or view your console for hints.'),
});
@ -126,7 +126,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
} catch (e) {
logger.error(e);
Modal.createTrackedDialog('Failed to unsubscribe from Mjolnir list', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Error unsubscribing from list'),
description: _t('Please try again or view your console for hints.'),
});
@ -149,7 +149,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
return <ul>{ tiles }</ul>;
};
Modal.createTrackedDialog('View Mjolnir list rules', '', QuestionDialog, {
Modal.createDialog(QuestionDialog, {
title: _t("Ban list rules - %(roomName)s", { roomName: name }),
description: (
<div>

View file

@ -22,7 +22,6 @@ import { logger } from "matrix-js-sdk/src/logger";
import { _t } from "../../../../../languageHandler";
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
import AccessibleButton from "../../../elements/AccessibleButton";
import Analytics from "../../../../../Analytics";
import dis from "../../../../../dispatcher/dispatcher";
import { SettingLevel } from "../../../../../settings/SettingLevel";
import SecureBackupPanel from "../../SecureBackupPanel";
@ -110,10 +109,6 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
MatrixClientPeg.get().removeListener(RoomEvent.MyMembership, this.onMyMembership);
}
private updateAnalytics = (checked: boolean): void => {
checked ? Analytics.enable() : Analytics.disable();
};
private onMyMembership = (room: Room, membership: string): void => {
if (room.isSpaceRoom()) {
return;
@ -295,16 +290,12 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
}
let privacySection;
if (Analytics.canEnable() || PosthogAnalytics.instance.isEnabled()) {
if (PosthogAnalytics.instance.isEnabled()) {
const onClickAnalyticsLearnMore = () => {
if (PosthogAnalytics.instance.isEnabled()) {
showAnalyticsLearnMoreDialog({
primaryButton: _t("Okay"),
hasCancel: false,
});
} else {
Analytics.showDetailsModal();
}
showAnalyticsLearnMoreDialog({
primaryButton: _t("Okay"),
hasCancel: false,
});
};
privacySection = <React.Fragment>
<div className="mx_SettingsTab_heading">{ _t("Privacy") }</div>
@ -321,15 +312,11 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
</AccessibleButton>
</p>
</div>
{
PosthogAnalytics.instance.isEnabled() ?
<SettingsFlag name="pseudonymousAnalyticsOptIn"
level={SettingLevel.ACCOUNT}
onChange={this.updateAnalytics} /> :
<SettingsFlag name="analyticsOptIn"
level={SettingLevel.DEVICE}
onChange={this.updateAnalytics} />
}
{ PosthogAnalytics.instance.isEnabled() && (
<SettingsFlag
name="pseudonymousAnalyticsOptIn"
level={SettingLevel.ACCOUNT} />
) }
</div>
</React.Fragment>;
}

View file

@ -103,7 +103,7 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
if (error) {
logger.log("Failed to list userMedia devices", error);
const brand = SdkConfig.get().brand;
Modal.createTrackedDialog('No media permissions', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('No media permissions'),
description: _t(
'You may need to manually permit %(brand)s to access your microphone/webcam',