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

@ -30,24 +30,20 @@ import { UPDATE_EVENT } from "../../stores/AsyncStore";
import { useEventEmitter } from "../../hooks/useEventEmitter";
import MatrixClientContext from "../../contexts/MatrixClientContext";
import MiniAvatarUploader, { AVATAR_SIZE } from "../views/elements/MiniAvatarUploader";
import Analytics from "../../Analytics";
import PosthogTrackers from "../../PosthogTrackers";
import EmbeddedPage from "./EmbeddedPage";
const onClickSendDm = (ev: ButtonEvent) => {
Analytics.trackEvent('home_page', 'button', 'dm');
PosthogTrackers.trackInteraction("WebHomeCreateChatButton", ev);
dis.dispatch({ action: 'view_create_chat' });
};
const onClickExplore = (ev: ButtonEvent) => {
Analytics.trackEvent('home_page', 'button', 'room_directory');
PosthogTrackers.trackInteraction("WebHomeExploreRoomsButton", ev);
dis.fire(Action.ViewRoomDirectory);
};
const onClickNewRoom = (ev: ButtonEvent) => {
Analytics.trackEvent('home_page', 'button', 'create_room');
PosthogTrackers.trackInteraction("WebHomeCreateRoomButton", ev);
dis.dispatch({ action: 'view_create_room' });
};

View file

@ -39,7 +39,6 @@ import 'focus-visible';
import 'what-input';
import PosthogTrackers from '../../PosthogTrackers';
import Analytics from "../../Analytics";
import { DecryptionFailureTracker } from "../../DecryptionFailureTracker";
import { IMatrixClientCreds, MatrixClientPeg } from "../../MatrixClientPeg";
import PlatformPeg from "../../PlatformPeg";
@ -73,8 +72,7 @@ import LoggedInView from './LoggedInView';
import { Action } from "../../dispatcher/actions";
import {
hideToast as hideAnalyticsToast,
showAnonymousAnalyticsOptInToast,
showPseudonymousAnalyticsOptInToast,
showToast as showAnalyticsToast,
} from "../../toasts/AnalyticsToast";
import { showToast as showNotificationsToast } from "../../toasts/DesktopNotificationsToast";
import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
@ -344,10 +342,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
});
}
if (SettingsStore.getValue("pseudonymousAnalyticsOptIn")) {
Analytics.enable();
}
initSentry(SdkConfig.get("sentry"));
}
@ -406,7 +400,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
componentDidUpdate(prevProps, prevState) {
if (this.shouldTrackPageChange(prevState, this.state)) {
const durationMs = this.stopPageChangeTimer();
Analytics.trackPageChange(durationMs);
PosthogTrackers.instance.trackPageChange(this.state.view, this.state.page_type, durationMs);
}
if (this.focusComposer) {
@ -625,7 +618,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
this.copyRoom(payload.room_id);
break;
case 'reject_invite':
Modal.createTrackedDialog('Reject invitation', '', QuestionDialog, {
Modal.createDialog(QuestionDialog, {
title: _t('Reject invitation'),
description: _t('Are you sure you want to reject the invitation?'),
onFinished: (confirm) => {
@ -640,7 +633,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
}, (err) => {
modal.close();
Modal.createTrackedDialog('Failed to reject invitation', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Failed to reject invitation'),
description: err.toString(),
});
@ -684,7 +677,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
break;
case Action.ViewUserSettings: {
const tabPayload = payload as OpenToTabPayload;
Modal.createTrackedDialog('User settings', '', UserSettingsDialog,
Modal.createDialog(UserSettingsDialog,
{ initialTabId: tabPayload.initialTabId },
/*className=*/null, /*isPriority=*/false, /*isStatic=*/true);
@ -699,7 +692,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
this.viewSomethingBehindModal();
break;
case Action.ViewRoomDirectory: {
Modal.createTrackedDialog('Room directory', '', RoomDirectory, {
Modal.createDialog(RoomDirectory, {
initialText: payload.initialText,
}, 'mx_RoomDirectory_dialogWrapper', false, true);
@ -756,7 +749,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
});
break;
case Action.OpenDialPad:
Modal.createTrackedDialog('Dial pad', '', DialPadModal, {}, "mx_Dialog_dialPadWrapper");
Modal.createDialog(DialPadModal, {}, "mx_Dialog_dialPadWrapper");
break;
case Action.OnLoggedIn:
if (
@ -801,19 +794,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
hideToSRUsers: false,
});
break;
case Action.AnonymousAnalyticsAccept:
hideAnalyticsToast();
SettingsStore.setValue("analyticsOptIn", null, SettingLevel.DEVICE, true);
SettingsStore.setValue("showCookieBar", null, SettingLevel.DEVICE, false);
if (Analytics.canEnable()) {
Analytics.enable();
}
break;
case Action.AnonymousAnalyticsReject:
hideAnalyticsToast();
SettingsStore.setValue("analyticsOptIn", null, SettingLevel.DEVICE, false);
SettingsStore.setValue("showCookieBar", null, SettingLevel.DEVICE, false);
break;
case Action.PseudonymousAnalyticsAccept:
hideAnalyticsToast();
SettingsStore.setValue("pseudonymousAnalyticsOptIn", null, SettingLevel.ACCOUNT, true);
@ -1009,7 +989,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
private async createRoom(defaultPublic = false, defaultName?: string, type?: RoomType) {
const modal = Modal.createTrackedDialog('Create Room', '', CreateRoomDialog, {
const modal = Modal.createDialog(CreateRoomDialog, {
type,
defaultPublic,
defaultName,
@ -1112,7 +1092,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
const warnings = this.leaveRoomWarnings(roomId);
const isSpace = roomToLeave?.isSpaceRoom();
Modal.createTrackedDialog(isSpace ? "Leave space" : "Leave room", '', QuestionDialog, {
Modal.createDialog(QuestionDialog, {
title: isSpace ? _t("Leave space") : _t("Leave room"),
description: (
<span>
@ -1156,7 +1136,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
RoomListStore.instance.manualRoomUpdate(room, RoomUpdateCause.RoomRemoved);
}).catch((err) => {
const errCode = err.errcode || _td("unknown error code");
Modal.createTrackedDialog("Failed to forget room", '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Failed to forget room %(errCode)s", { errCode }),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});
@ -1167,7 +1147,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
const roomLink = makeRoomPermalink(roomId);
const success = await copyPlaintext(roomLink);
if (!success) {
Modal.createTrackedDialog("Unable to copy room link", "", ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Unable to copy room link"),
description: _t("Unable to copy a link to the room to the clipboard."),
});
@ -1271,8 +1251,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
if (PosthogAnalytics.instance.isEnabled() && SettingsStore.isLevelSupported(SettingLevel.ACCOUNT)) {
this.initPosthogAnalyticsToast();
} else if (Analytics.canEnable() && SettingsStore.getValue("showCookieBar")) {
showAnonymousAnalyticsOptInToast();
}
if (SdkConfig.get("mobile_guide_toast")) {
@ -1282,14 +1260,10 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
}
private showPosthogToast(analyticsOptIn: boolean) {
showPseudonymousAnalyticsOptInToast(analyticsOptIn);
}
private initPosthogAnalyticsToast() {
// Show the analytics toast if necessary
if (SettingsStore.getValue("pseudonymousAnalyticsOptIn") === null) {
this.showPosthogToast(SettingsStore.getValue("analyticsOptIn", null, true));
showAnalyticsToast();
}
// Listen to changes in settings and show the toast if appropriate - this is necessary because account
@ -1298,7 +1272,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
SettingsStore.watchSetting("pseudonymousAnalyticsOptIn", null,
(originalSettingName, changedInRoomId, atLevel, newValueAtLevel, newValue) => {
if (newValue === null) {
this.showPosthogToast(SettingsStore.getValue("analyticsOptIn", null, true));
showAnalyticsToast();
} else {
// It's possible for the value to change if a cached sync loads at page load, but then network
// sync contains a new value of the flag with it set to false (e.g. another device set it since last
@ -1478,7 +1452,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
return;
}
Modal.createTrackedDialog('Signed out', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Signed Out'),
description: _t('For security, this session has been signed out. Please sign in again.'),
});
@ -1488,7 +1462,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
});
});
cli.on(HttpApiEvent.NoConsent, function(message, consentUri) {
Modal.createTrackedDialog('No Consent Dialog', '', QuestionDialog, {
Modal.createDialog(QuestionDialog, {
title: _t('Terms and Conditions'),
description: <div>
<p> { _t(
@ -1535,7 +1509,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
cli.on(CryptoEvent.Warning, (type) => {
switch (type) {
case 'CRYPTO_WARNING_OLD_VERSION_DETECTED':
Modal.createTrackedDialog('Crypto migrated', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Old cryptography data detected'),
description: _t(
"Data from an older version of %(brand)s has been detected. " +
@ -1569,14 +1543,14 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
if (haveNewVersion) {
Modal.createTrackedDialogAsync('New Recovery Method', 'New Recovery Method',
Modal.createDialogAsync(
import(
'../../async-components/views/dialogs/security/NewRecoveryMethodDialog'
) as unknown as Promise<ComponentType<{}>>,
{ newVersionInfo },
);
} else {
Modal.createTrackedDialogAsync('Recovery Method Removed', 'Recovery Method Removed',
Modal.createDialogAsync(
import(
'../../async-components/views/dialogs/security/RecoveryMethodRemovedDialog'
) as unknown as Promise<ComponentType<{}>>,
@ -1585,16 +1559,14 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
});
cli.on(CryptoEvent.KeySignatureUploadFailure, (failures, source, continuation) => {
Modal.createTrackedDialog(
'Failed to upload key signatures',
'Failed to upload key signatures',
Modal.createDialog(
KeySignatureUploadFailedDialog,
{ failures, source, continuation });
});
cli.on(CryptoEvent.VerificationRequest, request => {
if (request.verifier) {
Modal.createTrackedDialog('Incoming Verification', '', IncomingSasDialog, {
Modal.createDialog(IncomingSasDialog, {
verifier: request.verifier,
}, null, /* priority = */ false, /* static = */ true);
} else if (request.pending) {

View file

@ -27,7 +27,6 @@ import Modal from "../../Modal";
import { _t } from '../../languageHandler';
import SdkConfig from '../../SdkConfig';
import { instanceForInstanceId, protocolNameForInstanceId, ALL_ROOMS, Protocols } from '../../utils/DirectoryUtils';
import Analytics from '../../Analytics';
import NetworkDropdown from "../views/directory/NetworkDropdown";
import SettingsStore from "../../settings/SettingsStore";
import { IDialogProps } from "../views/dialogs/IDialogProps";
@ -47,10 +46,6 @@ import { GenericError } from "../../utils/error";
const LAST_SERVER_KEY = "mx_last_room_directory_server";
const LAST_INSTANCE_KEY = "mx_last_room_directory_instance";
function track(action: string) {
Analytics.trackEvent('RoomDirectory', action);
}
interface IProps extends IDialogProps {
initialText?: string;
}
@ -121,7 +116,6 @@ export default class RoomDirectory extends React.Component<IProps, IState> {
// thing you see when loading the client!
return;
}
track('Failed to get protocol list from homeserver');
const brand = SdkConfig.get().brand;
this.setState({
error: _t(
@ -225,7 +219,6 @@ export default class RoomDirectory extends React.Component<IProps, IState> {
}
logger.error("Failed to get publicRooms: %s", JSON.stringify(err));
track('Failed to get public room list');
const brand = SdkConfig.get().brand;
this.setState({
loading: false,
@ -255,7 +248,7 @@ export default class RoomDirectory extends React.Component<IProps, IState> {
desc = _t('Remove %(name)s from the directory?', { name: name });
}
Modal.createTrackedDialog('Remove from Directory', '', QuestionDialog, {
Modal.createDialog(QuestionDialog, {
title: _t('Remove from Directory'),
description: desc,
onFinished: (shouldDelete: boolean) => {
@ -275,7 +268,7 @@ export default class RoomDirectory extends React.Component<IProps, IState> {
modal.close();
this.refreshRoomList();
logger.error("Failed to " + step + ": " + err);
Modal.createTrackedDialog('Remove from Directory Error', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Error'),
description: (err && err.message)
? err.message
@ -360,7 +353,7 @@ export default class RoomDirectory extends React.Component<IProps, IState> {
});
} catch (e) {
if (e instanceof GenericError) {
Modal.createTrackedDialog(e.message, '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: e.message,
description: e.description,
});

View file

@ -104,7 +104,7 @@ export default class RoomSearch extends React.PureComponent<IProps, IState> {
};
private openSpotlight() {
Modal.createTrackedDialog("Spotlight", "", SpotlightDialog, {}, "mx_SpotlightDialog_wrapper", false, true);
Modal.createDialog(SpotlightDialog, {}, "mx_SpotlightDialog_wrapper", false, true);
}
private onAction = (payload: ActionPayload) => {

View file

@ -1397,7 +1397,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
});
}, (error) => {
logger.error("Search failed", error);
Modal.createTrackedDialog('Search failed', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Search failed"),
description: ((error && error.message) ? error.message :
_t("Server may be unavailable, overloaded, or search timed out :(")),
@ -1522,7 +1522,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
logger.error("Failed to reject invite: %s", error);
const msg = error.message ? error.message : JSON.stringify(error);
Modal.createTrackedDialog('Failed to reject invite', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Failed to reject invite"),
description: msg,
});
@ -1555,7 +1555,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
logger.error("Failed to reject invite: %s", error);
const msg = error.message ? error.message : JSON.stringify(error);
Modal.createTrackedDialog('Failed to reject invite', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Failed to reject invite"),
description: msg,
});

View file

@ -234,7 +234,7 @@ const ThreadPanel: React.FC<IProps> = ({
}, [timelineSet, timelinePanel]);
const openFeedback = SdkConfig.get().bug_report_endpoint_url ? () => {
Modal.createTrackedDialog("Threads Feedback", "feature_thread", BetaFeedbackDialog, {
Modal.createDialog(BetaFeedbackDialog, {
featureId: "feature_thread",
});
} : null;

View file

@ -1353,7 +1353,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
);
}
Modal.createTrackedDialog('Failed to load timeline position', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t("Failed to load timeline position"),
description,
onFinished,

View file

@ -229,7 +229,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
ev.preventDefault();
ev.stopPropagation();
Modal.createTrackedDialog('Feedback Dialog', '', FeedbackDialog);
Modal.createDialog(FeedbackDialog);
this.setState({ contextMenuPosition: null }); // also close the menu
};
@ -242,7 +242,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
// log out without user prompt if they have no local megolm sessions
defaultDispatcher.dispatch({ action: 'logout' });
} else {
Modal.createTrackedDialog('Logout from LeftPanel', '', LogoutDialog);
Modal.createDialog(LogoutDialog);
}
this.setState({ contextMenuPosition: null }); // also close the menu

View file

@ -70,7 +70,7 @@ export default class UserView extends React.Component<IProps, IState> {
try {
profileInfo = await cli.getProfileInfo(this.props.userId);
} catch (err) {
Modal.createTrackedDialog(_t('Could not load user profile'), '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title: _t('Could not load user profile'),
description: ((err && err.message) ? err.message : _t("Operation failed")),
});

View file

@ -199,7 +199,7 @@ export default class ForgotPassword extends React.Component<IProps, IState> {
}
if (this.state.logoutDevices) {
const { finished } = Modal.createTrackedDialog<[boolean]>('Forgot Password Warning', '', QuestionDialog, {
const { finished } = Modal.createDialog<[boolean]>(QuestionDialog, {
title: _t('Warning!'),
description:
<div>
@ -271,7 +271,7 @@ export default class ForgotPassword extends React.Component<IProps, IState> {
};
public showErrorDialog(description: string, title?: string) {
Modal.createTrackedDialog('Forgot Password Error', '', ErrorDialog, {
Modal.createDialog(ErrorDialog, {
title,
description,
});

View file

@ -98,7 +98,7 @@ export default class SetupEncryptionBody extends React.Component<IProps, IState>
// We need to call onFinished now to close this dialog, and
// again later to signal that the verification is complete.
this.props.onFinished();
Modal.createTrackedDialog('New Session Verification', 'Starting dialog', VerificationRequestDialog, {
Modal.createDialog(VerificationRequestDialog, {
verificationRequestPromise: requestPromise,
member: cli.getUser(userId),
onFinished: async () => {

View file

@ -101,7 +101,7 @@ export default class SoftLogout extends React.Component<IProps, IState> {
}
private onClearAll = () => {
Modal.createTrackedDialog('Clear Data', 'Soft Logout', ConfirmWipeDeviceDialog, {
Modal.createDialog(ConfirmWipeDeviceDialog, {
onFinished: (wipeData) => {
if (!wipeData) return;