diff --git a/src/Analytics.js b/src/Analytics.js index 92691da1ea..5831eb7f8d 100644 --- a/src/Analytics.js +++ b/src/Analytics.js @@ -15,7 +15,6 @@ */ import { getCurrentLanguage } from './languageHandler'; -import MatrixClientPeg from './MatrixClientPeg'; import PlatformPeg from './PlatformPeg'; import SdkConfig from './SdkConfig'; @@ -31,8 +30,17 @@ const customVariables = { 'User Type': 3, 'Chosen Language': 4, 'Instance': 5, + 'Homeserver URL': 6, + 'Identity Server URL': 7, }; +function whitelistRedact(whitelist, str) { + if (whitelist.includes(str)) return str; + return ''; +} + +const whitelistedHSUrls = ["https://matrix.org"]; +const whitelistedISUrls = ["https://vector.im"]; class Analytics { constructor() { @@ -76,7 +84,7 @@ class Analytics { this._paq.push(['trackAllContentImpressions']); this._paq.push(['discardHashTag', false]); this._paq.push(['enableHeartBeatTimer']); - this._paq.push(['enableLinkTracking', true]); + // this._paq.push(['enableLinkTracking', true]); const platform = PlatformPeg.get(); this._setVisitVariable('App Platform', platform.getHumanReadableName()); @@ -130,20 +138,15 @@ class Analytics { this._paq.push(['deleteCookies']); } - login() { // not used currently - const cli = MatrixClientPeg.get(); - if (this.disabled || !cli) return; - - this._paq.push(['setUserId', `@${cli.getUserIdLocalpart()}:${cli.getDomain()}`]); - } - _setVisitVariable(key, value) { this._paq.push(['setCustomVariable', customVariables[key], key, value, 'visit']); } - setGuest(guest) { + setLoggedIn(isGuest, homeserverUrl, identityServerUrl) { if (this.disabled) return; - this._setVisitVariable('User Type', guest ? 'Guest' : 'Logged In'); + this._setVisitVariable('User Type', isGuest ? 'Guest' : 'Logged In'); + this._setVisitVariable('Homeserver URL', whitelistRedact(whitelistedHSUrls, homeserverUrl)); + this._setVisitVariable('Identity Server URL', whitelistRedact(whitelistedISUrls, identityServerUrl)); } } diff --git a/src/CallHandler.js b/src/CallHandler.js index e3fbe9e5e3..8331d579df 100644 --- a/src/CallHandler.js +++ b/src/CallHandler.js @@ -143,7 +143,7 @@ function _setCallListeners(call) { pause("ringbackAudio"); play("busyAudio"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Call Timeout', ErrorDialog, { title: _t('Call Timeout'), description: _t('The remote side failed to pick up') + '.', }); @@ -205,7 +205,7 @@ function _onAction(payload) { _setCallState(undefined, newCall.roomId, "ended"); console.log("Can't capture screen: " + screenCapErrorString); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Unable to capture screen', ErrorDialog, { title: _t('Unable to capture screen'), description: screenCapErrorString, }); @@ -225,7 +225,7 @@ function _onAction(payload) { case 'place_call': if (module.exports.getAnyActiveCall()) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Existing Call', ErrorDialog, { title: _t('Existing Call'), description: _t('You are already in a call.'), }); @@ -235,7 +235,7 @@ function _onAction(payload) { // if the runtime env doesn't do VoIP, whine. if (!MatrixClientPeg.get().supportsVoip()) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'VoIP is unsupported', ErrorDialog, { title: _t('VoIP is unsupported'), description: _t('You cannot place VoIP calls in this browser.'), }); @@ -251,7 +251,7 @@ function _onAction(payload) { var members = room.getJoinedMembers(); if (members.length <= 1) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Cannot place call with self', ErrorDialog, { description: _t('You cannot place a call with yourself.'), }); return; @@ -277,13 +277,13 @@ function _onAction(payload) { console.log("Place conference call in %s", payload.room_id); if (!ConferenceHandler) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Conference call unsupported client', ErrorDialog, { description: _t('Conference calls are not supported in this client'), }); } else if (!MatrixClientPeg.get().supportsVoip()) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'VoIP is unsupported', ErrorDialog, { title: _t('VoIP is unsupported'), description: _t('You cannot place VoIP calls in this browser.'), }); @@ -296,13 +296,13 @@ function _onAction(payload) { // participant. // Therefore we disable conference calling in E2E rooms. const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Conference calls unsupported e2e', ErrorDialog, { description: _t('Conference calls are not supported in encrypted rooms'), }); } else { var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Call Handler', 'Conference calling in development', QuestionDialog, { title: _t('Warning!'), description: _t('Conference calling is in development and may not be reliable.'), onFinished: confirm=>{ @@ -314,7 +314,7 @@ function _onAction(payload) { }, function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Conference call failed: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Call Handler', 'Failed to set up conference call', ErrorDialog, { title: _t('Failed to set up conference call'), description: _t('Conference call failed.') + ' ' + ((err && err.message) ? err.message : ''), }); diff --git a/src/ContentMessages.js b/src/ContentMessages.js index 9239de9d8f..1bd1332ab3 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -360,7 +360,7 @@ class ContentMessages { desc = _t('The file \'%(fileName)s\' exceeds this home server\'s size limit for uploads', {fileName: upload.fileName}); } var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Upload failed', err.message, ErrorDialog, { title: _t('Upload Failed'), description: desc, }); diff --git a/src/KeyRequestHandler.js b/src/KeyRequestHandler.js index 1da4922153..0b54d88e5f 100644 --- a/src/KeyRequestHandler.js +++ b/src/KeyRequestHandler.js @@ -125,7 +125,7 @@ export default class KeyRequestHandler { }; const KeyShareDialog = sdk.getComponent("dialogs.KeyShareDialog"); - Modal.createDialog(KeyShareDialog, { + Modal.createTrackedDialog('Key Share', 'Process Next Request', KeyShareDialog, { matrixClient: this._matrixClient, userId: userId, deviceId: deviceId, diff --git a/src/Lifecycle.js b/src/Lifecycle.js index eb2156e780..f4d1eeef08 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -240,7 +240,7 @@ function _handleRestoreFailure(e) { const SessionRestoreErrorDialog = sdk.getComponent('views.dialogs.SessionRestoreErrorDialog'); - Modal.createDialog(SessionRestoreErrorDialog, { + Modal.createTrackedDialog('Session Restore Error', e.message, SessionRestoreErrorDialog, { error: e.message, onFinished: (success) => { def.resolve(success); @@ -318,7 +318,7 @@ async function _doSetLoggedIn(credentials, clearStorage) { await _clearStorage(); } - Analytics.setGuest(credentials.guest); + Analytics.setLoggedIn(credentials.guest, credentials.homeserverUrl, credentials.identityServerUrl); // Resolves by default let teamPromise = Promise.resolve(null); diff --git a/src/Modal.js b/src/Modal.js index e100105a88..79fcaaefd1 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -103,13 +103,20 @@ class ModalManager { return container; } + createTrackedDialog(analyticsAction, analyticsInfo, Element, props, className) { + Analytics.trackEvent('Modal', analyticsAction, analyticsInfo); + return this.createDialog(Element, props, className); + } + createDialog(Element, props, className) { - if (props && props.title) { - Analytics.trackEvent('Modal', props.title, 'createDialog'); - } return this.createDialogAsync((cb) => {cb(Element);}, props, className); } + createTrackedDialogAsync(analyticsId, loader, props, className) { + Analytics.trackEvent('Modal', analyticsId); + return this.createDialogAsync(loader, props, className); + } + /** * Open a modal view. * diff --git a/src/Notifier.js b/src/Notifier.js index 40a65d4106..1bb435307d 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -142,7 +142,7 @@ const Notifier = { ? _t('Riot does not have permission to send you notifications - please check your browser settings') : _t('Riot was not given permission to send notifications - please try again'); const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Unable to enable Notifications', result, ErrorDialog, { title: _t('Unable to enable Notifications'), description, }); diff --git a/src/SlashCommands.js b/src/SlashCommands.js index dea3d27751..e5378d4347 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -68,7 +68,7 @@ const commands = { ddg: new Command("ddg", "", function(roomId, args) { const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); // TODO Don't explain this away, actually show a search UI here. - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Slash Commands', '/ddg is not a command', ErrorDialog, { title: _t('/ddg is not a command'), description: _t('To use it, just wait for autocomplete results to load and tab through them.'), }); @@ -326,13 +326,11 @@ const commands = { {deviceId: deviceId, fprint: fprint, userId: userId, fingerprint: fingerprint})); } - return MatrixClientPeg.get().setDeviceVerified( - userId, deviceId, true, - ); + return MatrixClientPeg.get().setDeviceVerified(userId, deviceId, true); }).then(() => { // Tell the user we verified everything const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Slash Commands', 'Verified key', QuestionDialog, { title: _t("Verified key"), description: (
diff --git a/src/UnknownDeviceErrorHandler.js b/src/UnknownDeviceErrorHandler.js index 2b1cf23380..e7d77b3b66 100644 --- a/src/UnknownDeviceErrorHandler.js +++ b/src/UnknownDeviceErrorHandler.js @@ -24,7 +24,7 @@ const onAction = function(payload) { if (payload.action === 'unknown_device_error' && !isDialogOpen) { const UnknownDeviceDialog = sdk.getComponent('dialogs.UnknownDeviceDialog'); isDialogOpen = true; - Modal.createDialog(UnknownDeviceDialog, { + Modal.createTrackedDialog('Unknown Device Error', '', UnknownDeviceDialog, { devices: payload.err.devices, room: payload.room, onFinished: (r) => { diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 5f7866773d..fff61b1c24 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -266,7 +266,7 @@ export default React.createClass({ this.setState({uploadingAvatar: false}); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to upload avatar image", e); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to upload image', e.toString(), ErrorDialog, { title: _t('Error'), description: _t('Failed to upload image'), }); @@ -288,7 +288,7 @@ export default React.createClass({ }); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to save group profile", e); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to update group', e.toString(), ErrorDialog, { title: _t('Error'), description: _t('Failed to update group'), }); diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index b90cb53435..f042b41991 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -410,7 +410,7 @@ module.exports = React.createClass({ this._leaveRoom(payload.room_id); break; case 'reject_invite': - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Reject invitation', '', QuestionDialog, { title: _t('Reject invitation'), description: _t('Are you sure you want to reject the invitation?'), onFinished: (confirm) => { @@ -426,7 +426,7 @@ module.exports = React.createClass({ } }, (err) => { modal.close(); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to reject invitation', err.toString(), ErrorDialog, { title: _t('Failed to reject invitation'), description: err.toString(), }); @@ -728,7 +728,7 @@ module.exports = React.createClass({ _setMxId: function(payload) { const SetMxIdDialog = sdk.getComponent('views.dialogs.SetMxIdDialog'); - const close = Modal.createDialog(SetMxIdDialog, { + const close = Modal.createTrackedDialog('Set MXID', '', SetMxIdDialog, { homeserverUrl: MatrixClientPeg.get().getHomeserverUrl(), onFinished: (submitted, credentials) => { if (!submitted) { @@ -767,7 +767,7 @@ module.exports = React.createClass({ return; } const ChatInviteDialog = sdk.getComponent("dialogs.ChatInviteDialog"); - Modal.createDialog(ChatInviteDialog, { + Modal.createTrackedDialog('Start a chat', '', ChatInviteDialog, { title: _t('Start a chat'), description: _t("Who would you like to communicate with?"), placeholder: _t("Email, name or matrix ID"), @@ -787,7 +787,7 @@ module.exports = React.createClass({ return; } const TextInputDialog = sdk.getComponent("dialogs.TextInputDialog"); - Modal.createDialog(TextInputDialog, { + Modal.createTrackedDialog('Create Room', '', TextInputDialog, { title: _t('Create Room'), description: _t('Room name (optional)'), button: _t('Create Room'), @@ -831,7 +831,7 @@ module.exports = React.createClass({ return; } - const close = Modal.createDialog(ChatCreateOrReuseDialog, { + const close = Modal.createTrackedDialog('Chat create or reuse', '', ChatCreateOrReuseDialog, { userId: userId, onFinished: (success) => { if (!success && goHomeOnCancel) { @@ -859,7 +859,7 @@ module.exports = React.createClass({ _invite: function(roomId) { const ChatInviteDialog = sdk.getComponent("dialogs.ChatInviteDialog"); - Modal.createDialog(ChatInviteDialog, { + Modal.createTrackedDialog('Chat Invite', '', ChatInviteDialog, { title: _t('Invite new room members'), description: _t('Who would you like to add to this room?'), button: _t('Send Invites'), @@ -873,7 +873,7 @@ module.exports = React.createClass({ const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); const roomToLeave = MatrixClientPeg.get().getRoom(roomId); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Leave room', '', QuestionDialog, { title: _t("Leave room"), description: ( @@ -896,7 +896,7 @@ module.exports = React.createClass({ }, (err) => { modal.close(); console.error("Failed to leave room " + roomId + " " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to leave room', err.toString(), ErrorDialog, { title: _t("Failed to leave room"), description: (err && err.message ? err.message : _t("Server may be unavailable, overloaded, or you hit a bug.")), @@ -1092,7 +1092,7 @@ module.exports = React.createClass({ }); cli.on('Session.logged_out', function(call) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Signed out', '', ErrorDialog, { title: _t('Signed Out'), description: _t('For security, this session has been signed out. Please sign in again.'), }); diff --git a/src/components/structures/MyGroups.js b/src/components/structures/MyGroups.js index 3eb694acce..0b8055beda 100644 --- a/src/components/structures/MyGroups.js +++ b/src/components/structures/MyGroups.js @@ -63,7 +63,7 @@ export default withMatrixClient(React.createClass({ _onCreateGroupClick: function() { const CreateGroupDialog = sdk.getComponent("dialogs.CreateGroupDialog"); - Modal.createDialog(CreateGroupDialog); + Modal.createTrackedDialog('Create Group', '', CreateGroupDialog); }, _fetch: function() { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 094251f4c1..40dbc93071 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -544,7 +544,7 @@ module.exports = React.createClass({ } if (!userHasUsedEncryption) { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('E2E Warning', '', QuestionDialog, { title: _t("Warning!"), hasCancelButton: false, description: ( @@ -820,7 +820,7 @@ module.exports = React.createClass({ }); const SetMxIdDialog = sdk.getComponent('views.dialogs.SetMxIdDialog'); - const close = Modal.createDialog(SetMxIdDialog, { + const close = Modal.createTrackedDialog('Set MXID', '', SetMxIdDialog, { homeserverUrl: cli.getHomeserverUrl(), onFinished: (submitted, credentials) => { if (submitted) { @@ -934,7 +934,7 @@ module.exports = React.createClass({ } const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to upload file " + file + " " + error); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to upload file', error.toString(), ErrorDialog, { title: _t('Failed to upload file'), description: ((error && error.message) ? error.message : _t("Server may be unavailable, overloaded, or the file too big")), }); @@ -1021,7 +1021,7 @@ module.exports = React.createClass({ }, function(error) { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Search failed: " + error); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Search failed', error.toString(), ErrorDialog, { title: _t("Search failed"), description: ((error && error.message) ? error.message : _t("Server may be unavailable, overloaded, or search timed out :(")), }); @@ -1148,7 +1148,7 @@ module.exports = React.createClass({ console.error(result.reason); }); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to save room settings', '', ErrorDialog, { title: _t("Failed to save settings"), description: fails.map(function(result) { return result.reason; }).join("\n"), }); @@ -1195,7 +1195,7 @@ module.exports = React.createClass({ }, function(err) { var errCode = err.errcode || _t("unknown error code"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to forget room', err.toString(), ErrorDialog, { title: _t("Error"), description: _t("Failed to forget room %(errCode)s", { errCode: errCode }), }); @@ -1217,7 +1217,7 @@ module.exports = React.createClass({ var msg = error.message ? error.message : JSON.stringify(error); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to reject invite', error.toString(), ErrorDialog, { title: _t("Failed to reject invite"), description: msg, }); diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 0aee19545c..7cd67f3da8 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -923,7 +923,7 @@ var TimelinePanel = React.createClass({ var message = (error.errcode == 'M_FORBIDDEN') ? _t("Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.") : _t("Tried to load a specific point in this room's timeline, but was unable to find it."); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to load timeline position', error.toString(), ErrorDialog, { title: _t("Failed to load timeline position"), description: message, onFinished: onFinished, diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 1e0fcff445..9a0567ec30 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -331,7 +331,7 @@ module.exports = React.createClass({ }, function(error) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to load user settings: " + error); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Can\'t load user settings', error.toString(), ErrorDialog, { title: _t("Can't load user settings"), description: ((error && error.message) ? error.message : _t("Server may be unavailable or overloaded")), }); @@ -364,7 +364,7 @@ module.exports = React.createClass({ // const errMsg = (typeof err === "string") ? err : (err.error || ""); console.error("Failed to set avatar: " + err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to set avatar', err.toString(), ErrorDialog, { title: _t("Failed to set avatar."), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -373,7 +373,7 @@ module.exports = React.createClass({ onLogoutClicked: function(ev) { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Logout E2E Export', '', QuestionDialog, { title: _t("Sign out"), description:
@@ -409,7 +409,7 @@ module.exports = React.createClass({ } const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to change password: " + errMsg); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to change password', err.toString(), ErrorDialog, { title: _t("Error"), description: errMsg, }); @@ -417,7 +417,7 @@ module.exports = React.createClass({ onPasswordChanged: function() { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Password changed', '', ErrorDialog, { title: _t("Success"), description: _t( "Your password was successfully changed. You will not receive " + @@ -442,7 +442,7 @@ module.exports = React.createClass({ const emailAddress = this.refs.add_email_input.value; if (!Email.looksValid(emailAddress)) { - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Invalid email address', '', ErrorDialog, { title: _t("Invalid Email Address"), description: _t("This doesn't appear to be a valid email address"), }); @@ -452,7 +452,7 @@ module.exports = React.createClass({ // we always bind emails when registering, so let's do the // same here. this._addThreepid.addEmailAddress(emailAddress, true).done(() => { - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Verification Pending', '', QuestionDialog, { title: _t("Verification Pending"), description: _t( "Please check your email and click on the link it contains. Once this " + @@ -464,7 +464,7 @@ module.exports = React.createClass({ }, (err) => { this.setState({email_add_pending: false}); console.error("Unable to add email address " + emailAddress + " " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Unable to add email address', err.toString(), ErrorDialog, { title: _t("Unable to add email address"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -475,7 +475,7 @@ module.exports = React.createClass({ onRemoveThreepidClicked: function(threepid) { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Remove 3pid', '', QuestionDialog, { title: _t("Remove Contact Information?"), description: _t("Remove %(threePid)s?", { threePid: threepid.address }), button: _t('Remove'), @@ -489,7 +489,7 @@ module.exports = React.createClass({ }).catch((err) => { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Unable to remove contact information: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Remove 3pid failed', err.toString(), ErrorDialog, { title: _t("Unable to remove contact information"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -521,7 +521,7 @@ module.exports = React.createClass({ const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const message = _t("Unable to verify email address.") + " " + _t("Please check your email and click on the link it contains. Once this is done, click continue."); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Verification Pending', '', QuestionDialog, { title: _t("Verification Pending"), description: message, button: _t('Continue'), @@ -530,7 +530,7 @@ module.exports = React.createClass({ } else { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Unable to verify email address: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Unable to verify email address', err.toString(), ErrorDialog, { title: _t("Unable to verify email address."), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -540,7 +540,7 @@ module.exports = React.createClass({ _onDeactivateAccountClicked: function() { const DeactivateAccountDialog = sdk.getComponent("dialogs.DeactivateAccountDialog"); - Modal.createDialog(DeactivateAccountDialog, {}); + Modal.createTrackedDialog('Deactivate Account', '', DeactivateAccountDialog, {}); }, _onBugReportClicked: function() { @@ -548,7 +548,7 @@ module.exports = React.createClass({ if (!BugReportDialog) { return; } - Modal.createDialog(BugReportDialog, {}); + Modal.createTrackedDialog('Bug Report Dialog', '', BugReportDialog, {}); }, _onClearCacheClicked: function() { @@ -585,27 +585,23 @@ module.exports = React.createClass({ }, _onExportE2eKeysClicked: function() { - Modal.createDialogAsync( - (cb) => { - require.ensure(['../../async-components/views/dialogs/ExportE2eKeysDialog'], () => { - cb(require('../../async-components/views/dialogs/ExportE2eKeysDialog')); - }, "e2e-export"); - }, { - matrixClient: MatrixClientPeg.get(), - }, - ); + Modal.createTrackedDialogAsync('Export E2E Keys', '', (cb) => { + require.ensure(['../../async-components/views/dialogs/ExportE2eKeysDialog'], () => { + cb(require('../../async-components/views/dialogs/ExportE2eKeysDialog')); + }, "e2e-export"); + }, { + matrixClient: MatrixClientPeg.get(), + }); }, _onImportE2eKeysClicked: function() { - Modal.createDialogAsync( - (cb) => { - require.ensure(['../../async-components/views/dialogs/ImportE2eKeysDialog'], () => { - cb(require('../../async-components/views/dialogs/ImportE2eKeysDialog')); - }, "e2e-export"); - }, { - matrixClient: MatrixClientPeg.get(), - }, - ); + Modal.createTrackedDialogAsync('Import E2E Keys', '', (cb) => { + require.ensure(['../../async-components/views/dialogs/ImportE2eKeysDialog'], () => { + cb(require('../../async-components/views/dialogs/ImportE2eKeysDialog')); + }, "e2e-export"); + }, { + matrixClient: MatrixClientPeg.get(), + }); }, _renderReferral: function() { @@ -1004,7 +1000,7 @@ module.exports = React.createClass({ this._refreshMediaDevices, function() { const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('No media permissions', '', ErrorDialog, { title: _t('No media permissions'), description: _t('You may need to manually permit Riot to access your microphone/webcam'), }); diff --git a/src/components/structures/login/ForgotPassword.js b/src/components/structures/login/ForgotPassword.js index 18a9dca5dd..2a6d5042dd 100644 --- a/src/components/structures/login/ForgotPassword.js +++ b/src/components/structures/login/ForgotPassword.js @@ -89,14 +89,14 @@ module.exports = React.createClass({ } else { var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Forgot Password Warning', '', QuestionDialog, { title: _t('Warning!'), description:
{ _t( 'Resetting password will currently reset any ' + 'end-to-end encryption keys on all devices, ' + - 'making encrypted chat history unreadable, ' + + 'making encrypted chat history unreadable, ' + 'unless you first export your room keys and re-import ' + 'them afterwards. In future this will be improved.' ) } @@ -121,15 +121,13 @@ module.exports = React.createClass({ }, _onExportE2eKeysClicked: function() { - Modal.createDialogAsync( - (cb) => { - require.ensure(['../../../async-components/views/dialogs/ExportE2eKeysDialog'], () => { - cb(require('../../../async-components/views/dialogs/ExportE2eKeysDialog')); - }, "e2e-export"); - }, { - matrixClient: MatrixClientPeg.get(), - } - ); + Modal.createTrackedDialogAsync('Export E2E Keys', 'Forgot Password', (cb) => { + require.ensure(['../../../async-components/views/dialogs/ExportE2eKeysDialog'], () => { + cb(require('../../../async-components/views/dialogs/ExportE2eKeysDialog')); + }, "e2e-export"); + }, { + matrixClient: MatrixClientPeg.get(), + }); }, onInputChanged: function(stateKey, ev) { @@ -152,7 +150,8 @@ module.exports = React.createClass({ showErrorDialog: function(body, title) { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + // TODO this will still lead to i18n in Analytics. + Modal.createTrackedDialog('Forgot Password Error', body, ErrorDialog, { title: title, description: body, }); diff --git a/src/components/views/dialogs/ChatInviteDialog.js b/src/components/views/dialogs/ChatInviteDialog.js index d3a208a785..156d493fee 100644 --- a/src/components/views/dialogs/ChatInviteDialog.js +++ b/src/components/views/dialogs/ChatInviteDialog.js @@ -103,7 +103,7 @@ module.exports = React.createClass({ const ChatCreateOrReuseDialog = sdk.getComponent( "views.dialogs.ChatCreateOrReuseDialog", ); - const close = Modal.createDialog(ChatCreateOrReuseDialog, { + const close = Modal.createTrackedDialog('Create or Reuse', '', ChatCreateOrReuseDialog, { userId: userId, onFinished: (success) => { this.props.onFinished(success); @@ -367,7 +367,7 @@ module.exports = React.createClass({ .catch(function(err) { console.error(err.stack); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to invite', err.toString(), ErrorDialog, { title: _t("Failed to invite"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -380,7 +380,7 @@ module.exports = React.createClass({ .catch(function(err) { console.error(err.stack); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to invite user', err.toString(), ErrorDialog, { title: _t("Failed to invite user"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -401,7 +401,7 @@ module.exports = React.createClass({ .catch(function(err) { console.error(err.stack); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to invite', err.toString(), ErrorDialog, { title: _t("Failed to invite"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -448,7 +448,7 @@ module.exports = React.createClass({ if (errorList.length > 0) { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to invite the following users to the room', '', ErrorDialog, { title: _t("Failed to invite the following users to the %(roomName)s room:", {roomName: room.name}), description: errorList.join(", "), }); diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index e3b7cca078..0ee264b69b 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import sdk from '../../../index'; +import Analytics from '../../../Analytics'; import MatrixClientPeg from '../../../MatrixClientPeg'; import * as Lifecycle from '../../../Lifecycle'; import Velocity from 'velocity-vector'; @@ -54,6 +55,7 @@ export default class DeactivateAccountDialog extends React.Component { user: MatrixClientPeg.get().credentials.userId, password: this._passwordField.value, }).done(() => { + Analytics.trackEvent('Account', 'Deactivate Account'); Lifecycle.onLoggedOut(); this.props.onFinished(false); }, (err) => { diff --git a/src/components/views/dialogs/ErrorDialog.js b/src/components/views/dialogs/ErrorDialog.js index bf48d1757b..889549369d 100644 --- a/src/components/views/dialogs/ErrorDialog.js +++ b/src/components/views/dialogs/ErrorDialog.js @@ -16,7 +16,7 @@ limitations under the License. /* * Usage: - * Modal.createDialog(ErrorDialog, { + * Modal.createTrackedDialog('An Identifier', err.toString(), ErrorDialog, { * title: "some text", (default: "Error") * description: "some more text", * button: "Button Text", diff --git a/src/components/views/dialogs/KeyShareDialog.js b/src/components/views/dialogs/KeyShareDialog.js index 61391d281c..aed8e6a5af 100644 --- a/src/components/views/dialogs/KeyShareDialog.js +++ b/src/components/views/dialogs/KeyShareDialog.js @@ -88,7 +88,7 @@ export default React.createClass({ const DeviceVerifyDialog = sdk.getComponent('views.dialogs.DeviceVerifyDialog'); console.log("KeyShareDialog: Starting verify dialog"); - Modal.createDialog(DeviceVerifyDialog, { + Modal.createTrackedDialog('Key Share', 'Starting dialog', DeviceVerifyDialog, { userId: this.props.userId, device: this.state.deviceInfo, onFinished: (verified) => { diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index a3eb7c6962..010072e8c6 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -31,7 +31,7 @@ export default React.createClass({ _sendBugReport: function() { const BugReportDialog = sdk.getComponent("dialogs.BugReportDialog"); - Modal.createDialog(BugReportDialog, {}); + Modal.createTrackedDialog('Session Restore Error', 'Send Bug Report Dialog', BugReportDialog, {}); }, _continueClicked: function() { diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index 3c38064ee1..b5efbab8b7 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -55,7 +55,7 @@ export default React.createClass({ const emailAddress = this.state.emailAddress; if (!Email.looksValid(emailAddress)) { - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Invalid Email Address', '', ErrorDialog, { title: _t("Invalid Email Address"), description: _t("This doesn't appear to be a valid email address"), }); @@ -65,7 +65,7 @@ export default React.createClass({ // we always bind emails when registering, so let's do the // same here. this._addThreepid.addEmailAddress(emailAddress, true).done(() => { - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Verification Pending', '', QuestionDialog, { title: _t("Verification Pending"), description: _t( "Please check your email and click on the link it contains. Once this " + @@ -77,7 +77,7 @@ export default React.createClass({ }, (err) => { this.setState({emailBusy: false}); console.error("Unable to add email address " + emailAddress + " " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Unable to add email address', err.toString(), ErrorDialog, { title: _t("Unable to add email address"), description: ((err && err.message) ? err.message : _t("Operation failed")), }); @@ -106,7 +106,7 @@ export default React.createClass({ const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const message = _t("Unable to verify email address.") + " " + _t("Please check your email and click on the link it contains. Once this is done, click continue."); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Verification Pending', 'M_THREEPID_AUTH_FAILED', QuestionDialog, { title: _t("Verification Pending"), description: message, button: _t('Continue'), @@ -115,7 +115,7 @@ export default React.createClass({ } else { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Unable to verify email address: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Unable to verify email address', err.toString(), ErrorDialog, { title: _t("Unable to verify email address."), description: ((err && err.message) ? err.message : _t("Operation failed")), }); diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 9573b9fd9f..76ab5ed989 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -95,7 +95,7 @@ export default React.createClass({ console.log("Edit widget ID ", this.props.id); const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); const src = this._scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId, 'type_' + this.props.type); - Modal.createDialog(IntegrationsManager, { + Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, }, "mx_IntegrationsManager"); }, diff --git a/src/components/views/elements/DeviceVerifyButtons.js b/src/components/views/elements/DeviceVerifyButtons.js index dfca7e2600..bfe45905a1 100644 --- a/src/components/views/elements/DeviceVerifyButtons.js +++ b/src/components/views/elements/DeviceVerifyButtons.js @@ -52,7 +52,7 @@ export default React.createClass({ onVerifyClick: function() { const DeviceVerifyDialog = sdk.getComponent('views.dialogs.DeviceVerifyDialog'); - Modal.createDialog(DeviceVerifyDialog, { + Modal.createTrackedDialog('Device Verify Dialog', '', DeviceVerifyDialog, { userId: this.props.userId, device: this.state.device, }); diff --git a/src/components/views/login/RegistrationForm.js b/src/components/views/login/RegistrationForm.js index ff07cd36e5..d5b7bcf46a 100644 --- a/src/components/views/login/RegistrationForm.js +++ b/src/components/views/login/RegistrationForm.js @@ -95,7 +95,7 @@ module.exports = React.createClass({ if (this.allFieldsValid()) { if (this.refs.email.value == '') { var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, { title: _t("Warning!"), description:
diff --git a/src/components/views/login/ServerConfig.js b/src/components/views/login/ServerConfig.js index a63d02416c..0042ab5e9f 100644 --- a/src/components/views/login/ServerConfig.js +++ b/src/components/views/login/ServerConfig.js @@ -122,7 +122,7 @@ module.exports = React.createClass({ showHelpPopup: function() { var CustomServerDialog = sdk.getComponent('login.CustomServerDialog'); - Modal.createDialog(CustomServerDialog); + Modal.createTrackedDialog('Custom Server Dialog', '', CustomServerDialog); }, render: function() { diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index bccae923eb..b300e41e50 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -282,8 +282,8 @@ module.exports = React.createClass({ }); }).catch((err) => { console.warn("Unable to decrypt attachment: ", err); - Modal.createDialog(ErrorDialog, { - title: _t("Error"), + Modal.createTrackedDialog('Error decrypting attachment', err.toString(), ErrorDialog, { + title: _t("Error"), description: _t("Error decrypting attachment"), }); }).finally(() => { diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 6d4d01a196..740b0c10ca 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -299,7 +299,7 @@ module.exports = React.createClass({ let completeUrl = scalarClient.getStarterLink(starterLink); let QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); let integrationsUrl = SdkConfig.get().integrations_ui_url; - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Add an integration', '', QuestionDialog, { title: _t("Add an Integration"), description:
diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index ba0663153e..f37bd4271a 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -154,7 +154,7 @@ module.exports = React.createClass({ } else { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Invalid alias format', '', ErrorDialog, { title: _t('Invalid alias format'), description: _t('\'%(alias)s\' is not a valid format for an alias', { alias: alias }), }); @@ -170,7 +170,7 @@ module.exports = React.createClass({ } else { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Invalid address format', '', ErrorDialog, { title: _t('Invalid address format'), description: _t('\'%(alias)s\' is not a valid format for an address', { alias: alias }), }); diff --git a/src/components/views/rooms/AppsDrawer.js b/src/components/views/rooms/AppsDrawer.js index 3b8acc3f40..285d43ad6e 100644 --- a/src/components/views/rooms/AppsDrawer.js +++ b/src/components/views/rooms/AppsDrawer.js @@ -156,7 +156,7 @@ module.exports = React.createClass({ const src = (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId, 'add_integ') : null; - Modal.createDialog(IntegrationsManager, { + Modal.createTrackedDialog('Integrations Manager', '', IntegrationsManager, { src: src, }, "mx_IntegrationsManager"); }, diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index b3831a7d0d..a2841e907f 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -367,7 +367,7 @@ module.exports = withMatrixClient(React.createClass({ onCryptoClicked: function(e) { var event = this.props.mxEvent; - Modal.createDialogAsync((cb) => { + Modal.createTrackedDialogAsync('Encrypted Event Dialog', '', (cb) => { require(['../../../async-components/views/dialogs/EncryptedEventDialog'], cb); }, { event: event, diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 290bd35483..23c5de2eaa 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -229,7 +229,7 @@ module.exports = withMatrixClient(React.createClass({ const membership = this.props.member.membership; const kickLabel = membership === "invite" ? _t("Disinvite") : _t("Kick"); const ConfirmUserActionDialog = sdk.getComponent("dialogs.ConfirmUserActionDialog"); - Modal.createDialog(ConfirmUserActionDialog, { + Modal.createTrackedDialog('Confirm User Action Dialog', 'onKick', ConfirmUserActionDialog, { member: this.props.member, action: kickLabel, askReason: membership == "join", @@ -248,7 +248,7 @@ module.exports = withMatrixClient(React.createClass({ }, function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Kick error: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to kick', err.message, ErrorDialog, { title: _t("Failed to kick"), description: ((err && err.message) ? err.message : "Operation failed"), }); @@ -262,7 +262,7 @@ module.exports = withMatrixClient(React.createClass({ onBanOrUnban: function() { const ConfirmUserActionDialog = sdk.getComponent("dialogs.ConfirmUserActionDialog"); - Modal.createDialog(ConfirmUserActionDialog, { + Modal.createTrackedDialog('Confirm User Action Dialog', 'onBanOrUnban', ConfirmUserActionDialog, { member: this.props.member, action: this.props.member.membership == 'ban' ? _t("Unban") : _t("Ban"), askReason: this.props.member.membership != 'ban', @@ -290,7 +290,7 @@ module.exports = withMatrixClient(React.createClass({ }, function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Ban error: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to ban user', err.message, ErrorDialog, { title: _t("Error"), description: _t("Failed to ban user"), }); @@ -340,7 +340,7 @@ module.exports = withMatrixClient(React.createClass({ console.log("Mute toggle success"); }, function(err) { console.error("Mute error: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to mute user', err.message, ErrorDialog, { title: _t("Error"), description: _t("Failed to mute user"), }); @@ -385,7 +385,7 @@ module.exports = withMatrixClient(React.createClass({ dis.dispatch({action: 'view_set_mxid'}); } else { console.error("Toggle moderator error:" + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to toggle moderator status', err.message, ErrorDialog, { title: _t("Error"), description: _t("Failed to toggle moderator status"), }); @@ -406,7 +406,7 @@ module.exports = withMatrixClient(React.createClass({ }, function(err) { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to change power level " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to change power level', err.message, ErrorDialog, { title: _t("Error"), description: _t("Failed to change power level"), }); @@ -435,7 +435,7 @@ module.exports = withMatrixClient(React.createClass({ var myPower = powerLevelEvent.getContent().users[this.props.matrixClient.credentials.userId]; if (parseInt(myPower) === parseInt(powerLevel)) { var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Promote to PL100 Warning', '', QuestionDialog, { title: _t("Warning!"), description:
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 14f52706ec..51b595eab0 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -99,7 +99,7 @@ export default class MessageComposer extends React.Component { ); } - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Upload Files confirmation', '', QuestionDialog, { title: _t('Upload Files'), description: (
diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index ba1673a9df..34e9e4a1e6 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -667,7 +667,7 @@ export default class MessageComposerInput extends React.Component { }, function(err) { console.error("Command failure: %s", err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Server error', err.toString(), ErrorDialog, { title: _t("Server error"), description: ((err && err.message) ? err.message : _t("Server unavailable, overloaded, or something else went wrong.")), }); @@ -675,7 +675,7 @@ export default class MessageComposerInput extends React.Component { } else if (cmd.error) { console.error(cmd.error); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Command error', cmd.error, ErrorDialog, { title: _t("Command error"), description: cmd.error, }); diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index 85aedadf64..741d7085e6 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -119,7 +119,7 @@ module.exports = React.createClass({ const errMsg = (typeof err === "string") ? err : (err.error || ""); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to set avatar: " + errMsg); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to set avatar', err.toString(), ErrorDialog, { title: _t("Error"), description: _t("Failed to set avatar."), }); diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index d6a973f648..b59ad1510c 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -46,7 +46,7 @@ const BannedUser = React.createClass({ _onUnbanClick: function() { const ConfirmUserActionDialog = sdk.getComponent("dialogs.ConfirmUserActionDialog"); - Modal.createDialog(ConfirmUserActionDialog, { + Modal.createTrackedDialog('Confirm User Action Dialog', 'onUnbanClick', ConfirmUserActionDialog, { member: this.props.member, action: _t('Unban'), danger: false, @@ -58,7 +58,7 @@ const BannedUser = React.createClass({ ).catch((err) => { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to unban: " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to unban', err.toString(), ErrorDialog, { title: _t('Error'), description: _t('Failed to unban'), }); @@ -423,7 +423,7 @@ module.exports = React.createClass({ ev.preventDefault(); var value = ev.target.value; - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Privacy warning', '', QuestionDialog, { title: _t('Privacy warning'), description:
@@ -516,7 +516,7 @@ module.exports = React.createClass({ onManageIntegrations(ev) { ev.preventDefault(); var IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager"); - Modal.createDialog(IntegrationsManager, { + Modal.createTrackedDialog('Integrations Manager', 'onManageIntegrations', IntegrationsManager, { src: (this.scalarClient !== null && this.scalarClient.hasCredentials()) ? this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId) : null, @@ -549,7 +549,7 @@ module.exports = React.createClass({ }, function(err) { var errCode = err.errcode || _t('unknown error code'); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to forget room', err.toString(), ErrorDialog, { title: _t('Error'), description: _t("Failed to forget room %(errCode)s", { errCode: errCode }), }); @@ -560,7 +560,7 @@ module.exports = React.createClass({ if (!this.refs.encrypt.checked) return; var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('E2E Enable Warning', '', QuestionDialog, { title: _t('Warning!'), description: (
diff --git a/src/components/views/settings/AddPhoneNumber.js b/src/components/views/settings/AddPhoneNumber.js index 7bc551477e..bda488a412 100644 --- a/src/components/views/settings/AddPhoneNumber.js +++ b/src/components/views/settings/AddPhoneNumber.js @@ -82,7 +82,7 @@ export default withMatrixClient(React.createClass({ }).catch((err) => { console.error("Unable to add phone number: " + err); let msg = err.message; - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Add Phone Number Error', err.toString(), ErrorDialog, { title: _t("Error"), description: msg, }); @@ -107,7 +107,7 @@ export default withMatrixClient(React.createClass({ } msgElements.push(
{msg}
); } - Modal.createDialog(TextInputDialog, { + Modal.createTrackedDialog('Prompt for MSISDN Verification Code', '', TextInputDialog, { title: _t("Enter Code"), description:
{msgElements}
, button: _t("Submit"), diff --git a/src/components/views/settings/ChangePassword.js b/src/components/views/settings/ChangePassword.js index 14ec9806b4..f3c0d9033c 100644 --- a/src/components/views/settings/ChangePassword.js +++ b/src/components/views/settings/ChangePassword.js @@ -104,7 +104,7 @@ module.exports = React.createClass({ } const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createDialog(QuestionDialog, { + Modal.createTrackedDialog('Change Password', '', QuestionDialog, { title: _t("Warning!"), description:
@@ -164,7 +164,7 @@ module.exports = React.createClass({ const deferred = Promise.defer(); // Ask for an email otherwise the user has no way to reset their password const SetEmailDialog = sdk.getComponent("dialogs.SetEmailDialog"); - Modal.createDialog(SetEmailDialog, { + Modal.createTrackedDialog('Do you want to set an email address?', '', SetEmailDialog, { title: _t('Do you want to set an email address?'), onFinished: (confirmed) => { // ignore confirmed, setting an email is optional @@ -175,15 +175,13 @@ module.exports = React.createClass({ }, _onExportE2eKeysClicked: function() { - Modal.createDialogAsync( - (cb) => { - require.ensure(['../../../async-components/views/dialogs/ExportE2eKeysDialog'], () => { - cb(require('../../../async-components/views/dialogs/ExportE2eKeysDialog')); - }, "e2e-export"); - }, { - matrixClient: MatrixClientPeg.get(), - } - ); + Modal.createTrackedDialogAsync('Export E2E Keys', 'Change Password', (cb) => { + require.ensure(['../../../async-components/views/dialogs/ExportE2eKeysDialog'], () => { + cb(require('../../../async-components/views/dialogs/ExportE2eKeysDialog')); + }, "e2e-export"); + }, { + matrixClient: MatrixClientPeg.get(), + }); }, onClickChange: function() { diff --git a/src/components/views/settings/DevicesPanelEntry.js b/src/components/views/settings/DevicesPanelEntry.js index f295a7c2d5..69534f09b1 100644 --- a/src/components/views/settings/DevicesPanelEntry.js +++ b/src/components/views/settings/DevicesPanelEntry.js @@ -71,8 +71,8 @@ export default class DevicesPanelEntry extends React.Component { // pop up an interactive auth dialog var InteractiveAuthDialog = sdk.getComponent("dialogs.InteractiveAuthDialog"); - Modal.createDialog(InteractiveAuthDialog, { - title: _t("Authentication"), + Modal.createTrackedDialog('Delete Device Dialog', InteractiveAuthDialog, { + title: _t("Authentication"), matrixClient: MatrixClientPeg.get(), authData: error.data, makeRequest: this._makeDeleteRequest, diff --git a/src/createRoom.js b/src/createRoom.js index 74e4b3c2fc..2ba3bd06ef 100644 --- a/src/createRoom.js +++ b/src/createRoom.js @@ -115,7 +115,7 @@ function createRoom(opts) { action: 'join_room_error', }); console.error("Failed to create room " + roomId + " " + err); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failure to create room', err.message, ErrorDialog, { title: _t("Failure to create room"), description: _t("Server may be unavailable, overloaded, or you hit a bug."), }); diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 865caa8997..e4fe1068b7 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -221,7 +221,7 @@ class RoomViewStore extends Store { }); const msg = err.message ? err.message : JSON.stringify(err); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { + Modal.createTrackedDialog('Failed to join room', err.toString(), ErrorDialog, { title: _t("Failed to join room"), description: msg, });