mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Establish onboarding-flow wrapper/router base and feature flag env variable (#12247)
* establish onboarding-flow wrapper/router base and feature flag env variable * small cleanup * addressing feedback
This commit is contained in:
parent
730605353a
commit
9355fb21c7
@ -27,6 +27,7 @@ const bifyModuleGroups = require('bify-module-groups');
|
||||
|
||||
const metamaskrc = require('rc')('metamask', {
|
||||
INFURA_PROJECT_ID: process.env.INFURA_PROJECT_ID,
|
||||
ONBOARDING_V2: process.env.ONBOARDING_V2,
|
||||
SEGMENT_HOST: process.env.SEGMENT_HOST,
|
||||
SEGMENT_WRITE_KEY: process.env.SEGMENT_WRITE_KEY,
|
||||
SEGMENT_LEGACY_WRITE_KEY: process.env.SEGMENT_LEGACY_WRITE_KEY,
|
||||
@ -612,6 +613,7 @@ function getEnvironmentVariables({ buildType, devMode, testing }) {
|
||||
? process.env.SEGMENT_PROD_LEGACY_WRITE_KEY
|
||||
: metamaskrc.SEGMENT_LEGACY_WRITE_KEY,
|
||||
SWAPS_USE_DEV_APIS: process.env.SWAPS_USE_DEV_APIS === '1',
|
||||
ONBOARDING_V2: metamaskrc.ONBOARDING_V2 === '1',
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -325,3 +325,18 @@ export function getIsGasEstimatesLoading(state) {
|
||||
|
||||
return isGasEstimatesLoading;
|
||||
}
|
||||
|
||||
export function getCompletedOnboarding(state) {
|
||||
return state.metamask.completedOnboarding;
|
||||
}
|
||||
export function getIsInitialized(state) {
|
||||
return state.metamask.isInitialized;
|
||||
}
|
||||
|
||||
export function getIsUnlocked(state) {
|
||||
return state.metamask.isUnlocked;
|
||||
}
|
||||
|
||||
export function getSeedPhraseBackedUp(state) {
|
||||
return state.metamask.seedPhraseBackedUp;
|
||||
}
|
||||
|
@ -52,6 +52,21 @@ const INITIALIZE_END_OF_FLOW_ROUTE = '/initialize/end-of-flow';
|
||||
const INITIALIZE_CONFIRM_SEED_PHRASE_ROUTE = '/initialize/seed-phrase/confirm';
|
||||
const INITIALIZE_METAMETRICS_OPT_IN_ROUTE = '/initialize/metametrics-opt-in';
|
||||
|
||||
const ONBOARDING_ROUTE = '/onboarding';
|
||||
const ONBOARDING_REVIEW_SRP_ROUTE = '/onboarding/review-srp';
|
||||
const ONBOARDING_CONFIRM_SRP_ROUTE = '/onboarding/confirm-srp';
|
||||
const ONBOARDING_CREATE_PASSWORD_ROUTE = '/onboarding/create-password';
|
||||
const ONBOARDING_COMPLETION_ROUTE = '/onboarding/completion';
|
||||
const ONBOARDING_UNLOCK_ROUTE = '/onboarding/unlock';
|
||||
const ONBOARDING_GET_STARTED_ROUTE = '/onboarding/get-started';
|
||||
const ONBOARDING_HELP_US_IMPROVE_ROUTE = '/onboarding/help-us-improve';
|
||||
const ONBOARDING_IMPORT_WITH_SRP_ROUTE =
|
||||
'/onboarding/create-password/import-with-sre';
|
||||
const ONBOARDING_IMPORT_MOBILE_ROUTE = '/onboarding/create-password';
|
||||
const ONBOARDING_SECURE_YOUR_WALLET_ROUTE = '/onboarding/secure-your-wallet';
|
||||
const ONBOARDING_PRIVACY_SETTINGS_ROUTE = '/onboarding/privacy-settings';
|
||||
const ONBOARDING_PIN_EXTENSION_ROUTE = '/onboarding/pin-extension';
|
||||
|
||||
const CONFIRM_TRANSACTION_ROUTE = '/confirm-transaction';
|
||||
const CONFIRM_SEND_ETHER_PATH = '/send-ether';
|
||||
const CONFIRM_SEND_TOKEN_PATH = '/send-token';
|
||||
@ -199,4 +214,17 @@ export {
|
||||
AWAITING_SIGNATURES_ROUTE,
|
||||
SWAPS_ERROR_ROUTE,
|
||||
SWAPS_MAINTENANCE_ROUTE,
|
||||
ONBOARDING_ROUTE,
|
||||
ONBOARDING_GET_STARTED_ROUTE,
|
||||
ONBOARDING_HELP_US_IMPROVE_ROUTE,
|
||||
ONBOARDING_CREATE_PASSWORD_ROUTE,
|
||||
ONBOARDING_IMPORT_WITH_SRP_ROUTE,
|
||||
ONBOARDING_IMPORT_MOBILE_ROUTE,
|
||||
ONBOARDING_SECURE_YOUR_WALLET_ROUTE,
|
||||
ONBOARDING_REVIEW_SRP_ROUTE,
|
||||
ONBOARDING_CONFIRM_SRP_ROUTE,
|
||||
ONBOARDING_PRIVACY_SETTINGS_ROUTE,
|
||||
ONBOARDING_COMPLETION_ROUTE,
|
||||
ONBOARDING_UNLOCK_ROUTE,
|
||||
ONBOARDING_PIN_EXTENSION_ROUTE,
|
||||
};
|
||||
|
@ -1,16 +1,32 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Redirect, Route } from 'react-router-dom';
|
||||
import { UNLOCK_ROUTE, INITIALIZE_ROUTE } from '../../constants/routes';
|
||||
import {
|
||||
UNLOCK_ROUTE,
|
||||
INITIALIZE_ROUTE,
|
||||
ONBOARDING_ROUTE,
|
||||
} from '../../constants/routes';
|
||||
|
||||
export default function Authenticated(props) {
|
||||
const { isUnlocked, completedOnboarding } = props;
|
||||
|
||||
switch (true) {
|
||||
// For ONBOARDING_V2 dev purposes,
|
||||
// Remove when ONBOARDING_V2 dev complete
|
||||
case process.env.ONBOARDING_V2 === true:
|
||||
return <Redirect to={{ pathname: ONBOARDING_ROUTE }} />;
|
||||
|
||||
case isUnlocked && completedOnboarding:
|
||||
return <Route {...props} />;
|
||||
case !completedOnboarding:
|
||||
return <Redirect to={{ pathname: INITIALIZE_ROUTE }} />;
|
||||
return (
|
||||
<Redirect
|
||||
to={{
|
||||
pathname: process.env.ONBOARDING_V2
|
||||
? ONBOARDING_ROUTE
|
||||
: INITIALIZE_ROUTE,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return <Redirect to={{ pathname: UNLOCK_ROUTE }} />;
|
||||
}
|
||||
|
@ -1,13 +1,19 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Redirect, Route } from 'react-router-dom';
|
||||
import { INITIALIZE_ROUTE } from '../../constants/routes';
|
||||
import { INITIALIZE_ROUTE, ONBOARDING_ROUTE } from '../../constants/routes';
|
||||
|
||||
export default function Initialized(props) {
|
||||
return props.completedOnboarding ? (
|
||||
<Route {...props} />
|
||||
) : (
|
||||
<Redirect to={{ pathname: INITIALIZE_ROUTE }} />
|
||||
<Redirect
|
||||
to={{
|
||||
pathname: process.env.ONBOARDING_V2
|
||||
? ONBOARDING_ROUTE
|
||||
: INITIALIZE_ROUTE,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
18
ui/pages/onboarding-flow/index.scss
Normal file
18
ui/pages/onboarding-flow/index.scss
Normal file
@ -0,0 +1,18 @@
|
||||
@import 'recovery-phrase/index';
|
||||
@import 'new-account/index';
|
||||
|
||||
.onboarding-flow {
|
||||
width: 100%;
|
||||
background-color: $white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&__wrapper {
|
||||
margin-top: 40px;
|
||||
padding: 32px;
|
||||
border: 1px solid $Grey-100;
|
||||
border-radius: 20px;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import {
|
||||
DEFAULT_ROUTE,
|
||||
ONBOARDING_COMPLETION_ROUTE,
|
||||
ONBOARDING_GET_STARTED_ROUTE,
|
||||
ONBOARDING_UNLOCK_ROUTE,
|
||||
LOCK_ROUTE,
|
||||
} from '../../../helpers/constants/routes';
|
||||
import {
|
||||
getCompletedOnboarding,
|
||||
getIsInitialized,
|
||||
getIsUnlocked,
|
||||
getSeedPhraseBackedUp,
|
||||
} from '../../../ducks/metamask/metamask';
|
||||
|
||||
export default function OnboardingFlowSwitch() {
|
||||
const completedOnboarding = useSelector(getCompletedOnboarding);
|
||||
const isInitialized = useSelector(getIsInitialized);
|
||||
const seedPhraseBackedUp = useSelector(getSeedPhraseBackedUp);
|
||||
const isUnlocked = useSelector(getIsUnlocked);
|
||||
|
||||
if (completedOnboarding) {
|
||||
return <Redirect to={{ pathname: DEFAULT_ROUTE }} />;
|
||||
}
|
||||
|
||||
if (seedPhraseBackedUp !== null) {
|
||||
return <Redirect to={{ pathname: ONBOARDING_COMPLETION_ROUTE }} />;
|
||||
}
|
||||
|
||||
if (isUnlocked) {
|
||||
return <Redirect to={{ pathname: LOCK_ROUTE }} />;
|
||||
}
|
||||
|
||||
if (!isInitialized) {
|
||||
return <Redirect to={{ pathname: ONBOARDING_GET_STARTED_ROUTE }} />;
|
||||
}
|
||||
|
||||
return <Redirect to={{ pathname: ONBOARDING_UNLOCK_ROUTE }} />;
|
||||
}
|
109
ui/pages/onboarding-flow/onboarding-flow.js
Normal file
109
ui/pages/onboarding-flow/onboarding-flow.js
Normal file
@ -0,0 +1,109 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Switch, Route, useHistory } from 'react-router-dom';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import Unlock from '../unlock-page';
|
||||
import {
|
||||
ONBOARDING_CREATE_PASSWORD_ROUTE,
|
||||
ONBOARDING_REVIEW_SRP_ROUTE,
|
||||
ONBOARDING_CONFIRM_SRP_ROUTE,
|
||||
ONBOARDING_UNLOCK_ROUTE,
|
||||
DEFAULT_ROUTE,
|
||||
} from '../../helpers/constants/routes';
|
||||
import {
|
||||
getCompletedOnboarding,
|
||||
getIsInitialized,
|
||||
getIsUnlocked,
|
||||
getSeedPhraseBackedUp,
|
||||
} from '../../ducks/metamask/metamask';
|
||||
import {
|
||||
createNewVaultAndGetSeedPhrase,
|
||||
unlockAndGetSeedPhrase,
|
||||
} from '../../store/actions';
|
||||
import { getFirstTimeFlowTypeRoute } from '../../selectors';
|
||||
import OnboardingFlowSwitch from './onboarding-flow-switch/onboarding-flow-switch';
|
||||
import NewAccount from './new-account/new-account';
|
||||
import ReviewRecoveryPhrase from './recovery-phrase/review-recovery-phrase';
|
||||
import ConfirmRecoveryPhrase from './recovery-phrase/confirm-recovery-phrase';
|
||||
|
||||
export default function OnboardingFlow() {
|
||||
const [seedPhrase, setSeedPhrase] = useState('');
|
||||
const dispatch = useDispatch();
|
||||
const history = useHistory();
|
||||
const isInitialized = useSelector(getIsInitialized);
|
||||
const isUnlocked = useSelector(getIsUnlocked);
|
||||
const completedOnboarding = useSelector(getCompletedOnboarding);
|
||||
const seedPhraseBackedUp = useSelector(getSeedPhraseBackedUp);
|
||||
const nextRoute = useSelector(getFirstTimeFlowTypeRoute);
|
||||
|
||||
useEffect(() => {
|
||||
// For ONBOARDING_V2 dev purposes,
|
||||
// Remove when ONBOARDING_V2 dev complete
|
||||
if (process.env.ONBOARDING_V2) {
|
||||
history.push(ONBOARDING_CREATE_PASSWORD_ROUTE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (completedOnboarding && seedPhraseBackedUp) {
|
||||
history.push(DEFAULT_ROUTE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isInitialized && !isUnlocked) {
|
||||
history.push(ONBOARDING_UNLOCK_ROUTE);
|
||||
}
|
||||
}, [
|
||||
history,
|
||||
completedOnboarding,
|
||||
isInitialized,
|
||||
isUnlocked,
|
||||
seedPhraseBackedUp,
|
||||
]);
|
||||
|
||||
const handleCreateNewAccount = async (password) => {
|
||||
const newSeedPhrase = await dispatch(
|
||||
createNewVaultAndGetSeedPhrase(password),
|
||||
);
|
||||
setSeedPhrase(newSeedPhrase);
|
||||
};
|
||||
|
||||
const handleUnlock = async (password) => {
|
||||
const retreivedSeedPhrase = await dispatch(
|
||||
unlockAndGetSeedPhrase(password),
|
||||
);
|
||||
setSeedPhrase(retreivedSeedPhrase);
|
||||
history.push(nextRoute);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="onboarding-flow">
|
||||
<div className="onboarding-flow__wrapper">
|
||||
<Switch>
|
||||
<Route
|
||||
path={ONBOARDING_CREATE_PASSWORD_ROUTE}
|
||||
render={(routeProps) => (
|
||||
<NewAccount
|
||||
{...routeProps}
|
||||
createNewAccount={handleCreateNewAccount}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path={ONBOARDING_REVIEW_SRP_ROUTE}
|
||||
render={() => <ReviewRecoveryPhrase seedPhrase={seedPhrase} />}
|
||||
/>
|
||||
<Route
|
||||
path={ONBOARDING_CONFIRM_SRP_ROUTE}
|
||||
render={() => <ConfirmRecoveryPhrase seedPhrase={seedPhrase} />}
|
||||
/>
|
||||
<Route
|
||||
path={ONBOARDING_UNLOCK_ROUTE}
|
||||
render={(routeProps) => (
|
||||
<Unlock {...routeProps} onSubmit={handleUnlock} />
|
||||
)}
|
||||
/>
|
||||
<Route exact path="*" component={OnboardingFlowSwitch} />
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -19,3 +19,4 @@
|
||||
@import 'settings/index';
|
||||
@import 'swaps/index';
|
||||
@import 'unlock-page/index';
|
||||
@import 'onboarding-flow/index';
|
||||
|
@ -53,6 +53,7 @@ import {
|
||||
BUILD_QUOTE_ROUTE,
|
||||
CONFIRMATION_V_NEXT_ROUTE,
|
||||
CONFIRM_IMPORT_TOKEN_ROUTE,
|
||||
ONBOARDING_ROUTE,
|
||||
} from '../../helpers/constants/routes';
|
||||
|
||||
import {
|
||||
@ -62,6 +63,7 @@ import {
|
||||
import { getEnvironmentType } from '../../../app/scripts/lib/util';
|
||||
import { isBeta } from '../../helpers/utils/build-types';
|
||||
import ConfirmationPage from '../confirmation';
|
||||
import OnboardingFlow from '../onboarding-flow/onboarding-flow';
|
||||
|
||||
export default class Routes extends Component {
|
||||
static propTypes = {
|
||||
@ -114,9 +116,11 @@ export default class Routes extends Component {
|
||||
|
||||
renderRoutes() {
|
||||
const { autoLockTimeLimit, setLastActiveTime } = this.props;
|
||||
|
||||
const routes = (
|
||||
<Switch>
|
||||
{process.env.ONBOARDING_V2 && (
|
||||
<Route path={ONBOARDING_ROUTE} component={OnboardingFlow} />
|
||||
)}
|
||||
<Route path={LOCK_ROUTE} component={Lock} exact />
|
||||
<Route path={INITIALIZE_ROUTE} component={FirstTimeFlow} />
|
||||
<Initialized path={UNLOCK_ROUTE} component={UnlockPage} exact />
|
||||
@ -225,7 +229,7 @@ export default class Routes extends Component {
|
||||
|
||||
const isInitializing = Boolean(
|
||||
matchPath(location.pathname, {
|
||||
path: INITIALIZE_ROUTE,
|
||||
path: process.env.ONBOARDING_V2 ? ONBOARDING_ROUTE : INITIALIZE_ROUTE,
|
||||
exact: false,
|
||||
}),
|
||||
);
|
||||
|
@ -2,6 +2,8 @@ import {
|
||||
INITIALIZE_CREATE_PASSWORD_ROUTE,
|
||||
INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE,
|
||||
DEFAULT_ROUTE,
|
||||
ONBOARDING_CREATE_PASSWORD_ROUTE,
|
||||
ONBOARDING_IMPORT_WITH_SRP_ROUTE,
|
||||
} from '../helpers/constants/routes';
|
||||
|
||||
export function getFirstTimeFlowTypeRoute(state) {
|
||||
@ -9,9 +11,13 @@ export function getFirstTimeFlowTypeRoute(state) {
|
||||
|
||||
let nextRoute;
|
||||
if (firstTimeFlowType === 'create') {
|
||||
nextRoute = INITIALIZE_CREATE_PASSWORD_ROUTE;
|
||||
nextRoute = process.env.ONBOARDING_V2
|
||||
? ONBOARDING_CREATE_PASSWORD_ROUTE
|
||||
: INITIALIZE_CREATE_PASSWORD_ROUTE;
|
||||
} else if (firstTimeFlowType === 'import') {
|
||||
nextRoute = INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE;
|
||||
nextRoute = process.env.ONBOARDING_V2
|
||||
? ONBOARDING_IMPORT_WITH_SRP_ROUTE
|
||||
: INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE;
|
||||
} else {
|
||||
nextRoute = DEFAULT_ROUTE;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user