diff --git a/app/src/constants.js b/app/src/constants.js
index 62c6c06..a48197e 100644
--- a/app/src/constants.js
+++ b/app/src/constants.js
@@ -16,6 +16,7 @@ const Constants = {
KEY_FIRST_RUN_EMAIL: "firstRunEmail",
KEY_FIRST_RUN_PASSWORD: "firstRunPassword",
+ KEY_FIRST_USER_AUTH: "firstUserAuth",
KEY_SHOULD_VERIFY_EMAIL: "shouldVerifyEmail",
KEY_EMAIL_VERIFY_PENDING: "emailVerifyPending",
diff --git a/app/src/page/firstRun/internal/email-collect-page.js b/app/src/page/firstRun/internal/email-collect-page.js
index 93ea2cf..0d37045 100644
--- a/app/src/page/firstRun/internal/email-collect-page.js
+++ b/app/src/page/firstRun/internal/email-collect-page.js
@@ -1,8 +1,6 @@
import React from 'react';
import { Lbry } from 'lbry-redux';
import {
- ActivityIndicator,
- Linking,
NativeModules,
Platform,
Text,
@@ -15,25 +13,16 @@ import Constants from 'constants';
import firstRunStyle from 'styles/firstRun';
class EmailCollectPage extends React.PureComponent {
- static MAX_STATUS_TRIES = 30;
-
state = {
email: null,
- authenticationStarted: false,
- authenticationFailed: false,
placeholder: 'you@example.com',
- statusTries: 0,
verifying: true
};
componentWillReceiveProps(nextProps) {
- const { authenticating, authToken, showNextPage } = this.props;
+ const { showNextPage } = this.props;
const { user } = nextProps;
- if (this.state.authenticationStarted && !authenticating && authToken === null) {
- this.setState({ authenticationFailed: true, authenticationStarted: false });
- }
-
if (this.state.verifying) {
if (user && user.primary_email && user.has_verified_email) {
if (showNextPage) {
@@ -45,33 +34,6 @@ class EmailCollectPage extends React.PureComponent {
}
}
- componentDidMount() {
- // call user/new
- const { generateAuthToken, authenticating, authToken } = this.props;
- if (!authenticating) {
- this.startAuthenticating();
- }
- }
-
- startAuthenticating = () => {
- const { authenticate } = this.props;
- this.setState({ authenticationStarted: true, authenticationFailed: false });
- NativeModules.VersionInfo.getAppVersion().then(appVersion => {
- Lbry.status().then(info => {
- authenticate(appVersion, Platform.OS);
- }).catch(error => {
- if (this.state.statusTries >= EmailCollectPage.MAX_STATUS_TRIES) {
- this.setState({ authenticationFailed: true });
- } else {
- setTimeout(() => {
- this.startAuthenticating();
- this.setState({ statusTries: this.state.statusTries + 1 });
- }, 1000); // Retry every second for a maximum of MAX_STATUS_TRIES tries (30 seconds)
- }
- });
- });
- }
-
handleChangeText = (text) => {
// save the value to the state email
const { onEmailChanged } = this.props;
@@ -84,49 +46,32 @@ class EmailCollectPage extends React.PureComponent {
}
render() {
- const { authenticating, authToken, onEmailChanged, onEmailViewLayout, emailToVerify } = this.props;
+ const { onEmailViewLayout } = this.props;
- let content;
- if (this.state.authenticationFailed) {
- // Ask the user to try again
- content = (
-
- The LBRY servers were unreachable at this time. Please check your Internet connection and then restart the app to try again.
-
- );
- } else if (!authToken || authenticating || this.state.verifying) {
- content = (
-
-
- Please wait while we get some things ready...
-
- );
- } else {
- content = (
-
- Setup account
- this.handleChangeText(text)}
- onFocus={() => {
- if (!this.state.email || this.state.email.length === 0) {
- this.setState({ placeholder: '' });
- }
- }}
- onBlur={() => {
- if (!this.state.email || this.state.email.length === 0) {
- this.setState({ placeholder: 'you@example.com' });
- }
- }}
- />
- An account will allow you to earn rewards and keep your account and settings synced.
- This information is disclosed only to LBRY, Inc. and not to the LBRY network.
-
- );
- }
+ const content = (
+
+ Setup account
+ this.handleChangeText(text)}
+ onFocus={() => {
+ if (!this.state.email || this.state.email.length === 0) {
+ this.setState({ placeholder: '' });
+ }
+ }}
+ onBlur={() => {
+ if (!this.state.email || this.state.email.length === 0) {
+ this.setState({ placeholder: 'you@example.com' });
+ }
+ }}
+ />
+ An account will allow you to earn rewards and keep your account and settings synced.
+ This information is disclosed only to LBRY, Inc. and not to the LBRY network.
+
+ );
return (
diff --git a/app/src/page/firstRun/internal/welcome-page.js b/app/src/page/firstRun/internal/welcome-page.js
index 30698a2..0451959 100644
--- a/app/src/page/firstRun/internal/welcome-page.js
+++ b/app/src/page/firstRun/internal/welcome-page.js
@@ -1,15 +1,108 @@
import React from 'react';
import { Lbry } from 'lbry-redux';
-import { View, Text, Linking } from 'react-native';
+import {
+ ActivityIndicator,
+ NativeModules,
+ Platform,
+ Text,
+ View
+} from 'react-native';
+import AsyncStorage from '@react-native-community/async-storage';
import Colors from 'styles/colors';
+import Constants from 'constants';
import firstRunStyle from 'styles/firstRun';
class WelcomePage extends React.PureComponent {
+ static MAX_STATUS_TRIES = 60;
+
+ state = {
+ authenticationStarted: false,
+ authenticationFailed: false,
+ sdkStarted: false,
+ statusTries: 0,
+ };
+
+ componentWillReceiveProps(nextProps) {
+ const { authenticating, authToken } = this.props;
+
+ if (this.state.authenticationStarted && !authenticating) {
+ if (authToken === null) {
+ this.setState({ authenticationFailed: true, authenticationStarted: false });
+ } else {
+ // first_user_auth because it's the first time
+ AsyncStorage.getItem(Constants.KEY_FIRST_USER_AUTH).then(firstUserAuth => {
+ if ('true' !== firstUserAuth) {
+ // first_user_auth
+ NativeModules.Firebase.track('first_user_auth', null);
+ AsyncStorage.setItem(Constants.KEY_FIRST_USER_AUTH, 'true');
+ }
+ });
+ }
+ }
+ }
+
+ componentDidMount() {
+ // call user/new
+ const { generateAuthToken, authenticating, authToken } = this.props;
+ if (!authenticating) {
+ this.startAuthenticating();
+ }
+ }
+
+ startAuthenticating = () => {
+ const { authenticate } = this.props;
+ this.setState({ authenticationStarted: true, authenticationFailed: false });
+ NativeModules.VersionInfo.getAppVersion().then(appVersion => {
+ Lbry.status().then(info => {
+ this.setState({ sdkStarted: true });
+
+ authenticate(appVersion, Platform.OS);
+ }).catch(error => {
+ if (this.state.statusTries >= WelcomePage.MAX_STATUS_TRIES) {
+ this.setState({ authenticationFailed: true });
+
+ // sdk_start_failed
+ NativeModules.Firebase.track('sdk_start_failed', null);
+ } else {
+ setTimeout(() => {
+ this.startAuthenticating();
+ this.setState({ statusTries: this.state.statusTries + 1 });
+ }, 1000); // Retry every second for a maximum of MAX_STATUS_TRIES tries (60 seconds)
+ }
+ });
+ });
+ }
+
render() {
+ const { authenticating, authToken, onWelcomePageLayout } = this.props;
+
+ let content;
+ if (this.state.authenticationFailed) {
+ // Ask the user to try again
+ content = (
+
+ The LBRY servers were unreachable at this time. Please check your Internet connection and then restart the app to try again.
+
+ );
+ } else if (!authToken || authenticating) {
+ content = (
+
+
+ Please wait while we get some things ready...
+
+ );
+ } else {
+ content = (
+
+ Welcome to LBRY.
+ LBRY is a community-controlled content platform where you can find and publish videos, music, books, and more.
+
+ );
+ }
+
return (
- Welcome to LBRY.
- LBRY is a community-controlled content platform where you can find and publish videos, music, books, and more.
+ {content}
);
}
diff --git a/app/src/page/firstRun/view.js b/app/src/page/firstRun/view.js
index 58313f3..be70f04 100644
--- a/app/src/page/firstRun/view.js
+++ b/app/src/page/firstRun/view.js
@@ -37,7 +37,7 @@ class FirstRunScreen extends React.PureComponent {
showSkip: false,
isEmailVerified: false,
skipAccountConfirmed: false,
- showBottomContainer: true,
+ showBottomContainer: false,
walletPassword: null,
syncApplyStarted: false
};
@@ -252,6 +252,10 @@ class FirstRunScreen extends React.PureComponent {
this.setState({ showBottomContainer: true });
}
+ onWelcomePageLayout = () => {
+ this.setState({ showBottomContainer: true });
+ }
+
onSkipSwitchChanged = (checked) => {
this.setState({ skipAccountConfirmed: checked });
}
@@ -291,16 +295,17 @@ class FirstRunScreen extends React.PureComponent {
let page = null;
switch (this.state.currentPage) {
case Constants.FIRST_RUN_PAGE_WELCOME:
- page = ();
+ page = ();
break;
case Constants.FIRST_RUN_PAGE_EMAIL_COLLECT:
page = ();
break;
diff --git a/app/src/page/splash/view.js b/app/src/page/splash/view.js
index 1588c4f..0daa2c2 100644
--- a/app/src/page/splash/view.js
+++ b/app/src/page/splash/view.js
@@ -241,9 +241,10 @@ class SplashScreen extends React.PureComponent {
}
});
- // Start measuring the first launch time from the splash screen (time from daemon start to user interaction)
+ // Start measuring the first launch time from the splash screen
+ // (time to first user interaction - after first run completed)
AsyncStorage.getItem('hasLaunched').then(value => {
- if (value == null || value !== 'true') {
+ if ('true' !== value) {
AsyncStorage.setItem('hasLaunched', 'true');
// only set firstLaunchTime since we've determined that this is the first app launch ever
AsyncStorage.setItem('firstLaunchTime', String(moment().unix()));
diff --git a/app/src/page/verification/view.js b/app/src/page/verification/view.js
index 89fe42a..d1bedf7 100644
--- a/app/src/page/verification/view.js
+++ b/app/src/page/verification/view.js
@@ -22,7 +22,6 @@ class VerificationScreen extends React.PureComponent {
state = {
currentPage: null,
emailSubmitted: false,
- isFirstRun: false,
launchUrl: null,
showSkip: false,
skipAccountConfirmed: false,
diff --git a/src/main/java/io/lbry/browser/reactmodules/FirstRunModule.java b/src/main/java/io/lbry/browser/reactmodules/FirstRunModule.java
index 6e8b2b8..7321201 100644
--- a/src/main/java/io/lbry/browser/reactmodules/FirstRunModule.java
+++ b/src/main/java/io/lbry/browser/reactmodules/FirstRunModule.java
@@ -4,12 +4,15 @@ import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.SharedPreferences;
+import android.os.Bundle;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
+import com.google.firebase.analytics.FirebaseAnalytics;
+
import io.lbry.browser.MainActivity;
public class FirstRunModule extends ReactContextBaseJavaModule {
@@ -40,5 +43,11 @@ public class FirstRunModule extends ReactContextBaseJavaModule {
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("firstRun", false);
editor.commit();
+
+ FirebaseAnalytics firebase = FirebaseAnalytics.getInstance(context);
+ if (firebase != null) {
+ Bundle bundle = new Bundle();
+ firebase.logEvent("first_run_completed", bundle);
+ }
}
}