Initial Countly work

This commit is contained in:
Michael Telatynski 2020-10-29 15:53:14 +00:00
parent 557d9ad90c
commit c3a355097d
33 changed files with 1416 additions and 72 deletions

View file

@ -17,6 +17,7 @@ limitations under the License.
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler';
import CountlyAnalytics from "../../../CountlyAnalytics";
const DIV_ID = 'mx_recaptcha';
@ -45,6 +46,8 @@ export default class CaptchaForm extends React.Component {
this._captchaWidgetId = null;
this._recaptchaContainer = createRef();
CountlyAnalytics.instance.track("onboarding_grecaptcha_begin");
}
componentDidMount() {
@ -99,10 +102,12 @@ export default class CaptchaForm extends React.Component {
console.log("Loaded recaptcha script.");
try {
this._renderRecaptcha(DIV_ID);
CountlyAnalytics.instance.track("onboarding_grecaptcha_loaded");
} catch (e) {
this.setState({
errorText: e.toString(),
});
CountlyAnalytics.instance.track("onboarding_grecaptcha_error", { error: e.toString() });
}
}

View file

@ -26,6 +26,7 @@ import { _t } from '../../../languageHandler';
import SettingsStore from "../../../settings/SettingsStore";
import AccessibleButton from "../elements/AccessibleButton";
import Spinner from "../elements/Spinner";
import CountlyAnalytics from "../../../CountlyAnalytics";
/* This file contains a collection of components which are used by the
* InteractiveAuth to prompt the user to enter the information needed
@ -189,6 +190,7 @@ export class RecaptchaAuthEntry extends React.Component {
}
_onCaptchaResponse = response => {
CountlyAnalytics.instance.track("onboarding_grecaptcha_submit");
this.props.submitAuthDict({
type: RecaptchaAuthEntry.LOGIN_TYPE,
response: response,
@ -297,6 +299,8 @@ export class TermsAuthEntry extends React.Component {
toggledPolicies: initToggles,
policies: pickedPolicies,
};
CountlyAnalytics.instance.track("onboarding_terms_begin");
}
@ -326,8 +330,12 @@ export class TermsAuthEntry extends React.Component {
allChecked = allChecked && checked;
}
if (allChecked) this.props.submitAuthDict({type: TermsAuthEntry.LOGIN_TYPE});
else this.setState({errorText: _t("Please review and accept all of the homeserver's policies")});
if (allChecked) {
this.props.submitAuthDict({type: TermsAuthEntry.LOGIN_TYPE});
CountlyAnalytics.instance.track("onboarding_terms_complete");
} else {
this.setState({errorText: _t("Please review and accept all of the homeserver's policies")});
}
};
render() {

View file

@ -24,6 +24,7 @@ import { _t } from '../../../languageHandler';
import SdkConfig from '../../../SdkConfig';
import {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
import AccessibleButton from "../elements/AccessibleButton";
import CountlyAnalytics from "../../../CountlyAnalytics";
/**
* A pure UI component which displays a username/password form.
@ -150,7 +151,20 @@ export default class PasswordLogin extends React.Component {
this.props.onUsernameChanged(ev.target.value);
}
onUsernameFocus() {
if (this.state.loginType === PasswordLogin.LOGIN_FIELD_MXID) {
CountlyAnalytics.instance.track("onboarding_login_mxid_focus");
} else {
CountlyAnalytics.instance.track("onboarding_login_email_focus");
}
}
onUsernameBlur(ev) {
if (this.state.loginType === PasswordLogin.LOGIN_FIELD_MXID) {
CountlyAnalytics.instance.track("onboarding_login_mxid_blur");
} else {
CountlyAnalytics.instance.track("onboarding_login_email_blur");
}
this.props.onUsernameBlur(ev.target.value);
}
@ -161,6 +175,7 @@ export default class PasswordLogin extends React.Component {
loginType: loginType,
username: "", // Reset because email and username use the same state
});
CountlyAnalytics.instance.track("onboarding_login_type_changed", { loginType });
}
onPhoneCountryChanged(country) {
@ -176,8 +191,13 @@ export default class PasswordLogin extends React.Component {
this.props.onPhoneNumberChanged(ev.target.value);
}
onPhoneNumberFocus() {
CountlyAnalytics.instance.track("onboarding_login_phone_number_focus");
}
onPhoneNumberBlur(ev) {
this.props.onPhoneNumberBlur(ev.target.value);
CountlyAnalytics.instance.track("onboarding_login_phone_number_blur");
}
onPasswordChanged(ev) {
@ -202,6 +222,7 @@ export default class PasswordLogin extends React.Component {
placeholder="joe@example.com"
value={this.state.username}
onChange={this.onUsernameChanged}
onFocus={this.onUsernameFocus}
onBlur={this.onUsernameBlur}
disabled={this.props.disableSubmit}
autoFocus={autoFocus}
@ -216,6 +237,7 @@ export default class PasswordLogin extends React.Component {
label={_t("Username")}
value={this.state.username}
onChange={this.onUsernameChanged}
onFocus={this.onUsernameFocus}
onBlur={this.onUsernameBlur}
disabled={this.props.disableSubmit}
autoFocus={autoFocus}
@ -240,6 +262,7 @@ export default class PasswordLogin extends React.Component {
value={this.state.phoneNumber}
prefixComponent={phoneCountry}
onChange={this.onPhoneNumberChanged}
onFocus={this.onPhoneNumberFocus}
onBlur={this.onPhoneNumberBlur}
disabled={this.props.disableSubmit}
autoFocus={autoFocus}

View file

@ -29,6 +29,7 @@ import { SAFE_LOCALPART_REGEX } from '../../../Registration';
import withValidation from '../elements/Validation';
import {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
import PassphraseField from "./PassphraseField";
import CountlyAnalytics from "../../../CountlyAnalytics";
const FIELD_EMAIL = 'field_email';
const FIELD_PHONE_NUMBER = 'field_phone_number';
@ -77,6 +78,8 @@ export default class RegistrationForm extends React.Component {
passwordConfirm: this.props.defaultPassword || "",
passwordComplexity: null,
};
CountlyAnalytics.instance.track("onboarding_registration_begin");
}
onSubmit = async ev => {
@ -86,6 +89,7 @@ export default class RegistrationForm extends React.Component {
const allFieldsValid = await this.verifyFieldsBeforeSubmit();
if (!allFieldsValid) {
CountlyAnalytics.instance.track("onboarding_registration_submit_failed");
return;
}
@ -110,6 +114,8 @@ export default class RegistrationForm extends React.Component {
return;
}
CountlyAnalytics.instance.track("onboarding_registration_submit_warn");
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, {
title: _t("Warning!"),
@ -128,6 +134,11 @@ export default class RegistrationForm extends React.Component {
_doSubmit(ev) {
const email = this.state.email.trim();
CountlyAnalytics.instance.track("onboarding_registration_submit_ok", {
email: !!email,
});
const promise = this.props.onRegisterClick({
username: this.state.username.trim(),
password: this.state.password.trim(),
@ -422,6 +433,8 @@ export default class RegistrationForm extends React.Component {
value={this.state.email}
onChange={this.onEmailChange}
onValidate={this.onEmailValidate}
onFocus={() => CountlyAnalytics.instance.track("onboarding_registration_email_focus")}
onBlur={() => CountlyAnalytics.instance.track("onboarding_registration_email_blur")}
/>;
}
@ -433,6 +446,8 @@ export default class RegistrationForm extends React.Component {
value={this.state.password}
onChange={this.onPasswordChange}
onValidate={this.onPasswordValidate}
onFocus={() => CountlyAnalytics.instance.track("onboarding_registration_password_focus")}
onBlur={() => CountlyAnalytics.instance.track("onboarding_registration_password_blur")}
/>;
}
@ -447,6 +462,8 @@ export default class RegistrationForm extends React.Component {
value={this.state.passwordConfirm}
onChange={this.onPasswordConfirmChange}
onValidate={this.onPasswordConfirmValidate}
onFocus={() => CountlyAnalytics.instance.track("onboarding_registration_passwordConfirm_focus")}
onBlur={() => CountlyAnalytics.instance.track("onboarding_registration_passwordConfirm_blur")}
/>;
}
@ -487,6 +504,8 @@ export default class RegistrationForm extends React.Component {
value={this.state.username}
onChange={this.onUsernameChange}
onValidate={this.onUsernameValidate}
onFocus={() => CountlyAnalytics.instance.track("onboarding_registration_username_focus")}
onBlur={() => CountlyAnalytics.instance.track("onboarding_registration_username_blur")}
/>;
}

View file

@ -26,6 +26,7 @@ import AutoDiscoveryUtils from "../../../utils/AutoDiscoveryUtils";
import SdkConfig from "../../../SdkConfig";
import { createClient } from 'matrix-js-sdk/src/matrix';
import classNames from 'classnames';
import CountlyAnalytics from "../../../CountlyAnalytics";
/*
* A pure UI component which displays the HS and IS to use.
@ -70,6 +71,8 @@ export default class ServerConfig extends React.PureComponent {
isUrl: props.serverConfig.isUrl,
showIdentityServer: false,
};
CountlyAnalytics.instance.track("onboarding_custom_server");
}
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event

View file

@ -23,11 +23,18 @@ import AuthPage from "./AuthPage";
import {_td} from "../../../languageHandler";
import SettingsStore from "../../../settings/SettingsStore";
import {UIFeature} from "../../../settings/UIFeature";
import CountlyAnalytics from "../../../CountlyAnalytics";
// translatable strings for Welcome pages
_td("Sign in with SSO");
export default class Welcome extends React.PureComponent {
constructor(props) {
super(props);
CountlyAnalytics.instance.track("onboarding_welcome");
}
render() {
const EmbeddedPage = sdk.getComponent('structures.EmbeddedPage');
const LanguageSelector = sdk.getComponent('auth.LanguageSelector');