Combining registration steps.

pull/1851/head
Warrick Corfe-Tan 4 years ago
parent 30b6c5da73
commit bf645f36b7

@ -338,7 +338,7 @@
"createAccount": "Create account", "createAccount": "Create account",
"signIn": "Sign In", "signIn": "Sign In",
"yourUniqueSessionID": "Say hello to your Session ID", "yourUniqueSessionID": "Say hello to your Session ID",
"allUsersAreRandomly...": "Your Session ID is the unique address people can use to contact you on Session. With no connection to your real identity, your Session ID is totally anonymous and private by design.", "signupSessionIDBlurb": "Your Session ID is the unique address people can use to contact you on Session. With no connection to your real identity, your Session ID is totally anonymous and private by design.",
"getStarted": "Get started", "getStarted": "Get started",
"createSessionID": "Create Session ID", "createSessionID": "Create Session ID",
"recoveryPhrase": "Recovery Phrase", "recoveryPhrase": "Recovery Phrase",

@ -149,7 +149,7 @@
color: themed('textColor'); color: themed('textColor');
} }
font-weight: bold; font-weight: bold;
padding: 12px; padding: 20px;
} }
&__welcome-session { &__welcome-session {
@ -278,7 +278,7 @@
&-description-long, &-description-long,
&-signin-device-pairing-header { &-signin-device-pairing-header {
padding-top: 10px; padding-top: 0;
padding-bottom: 20px; padding-bottom: 20px;
@include themify($themes) { @include themify($themes) {
@include session-color-subtle(themed('textColor')); @include session-color-subtle(themed('textColor'));

@ -1,7 +1,7 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { AccentText } from './AccentText'; import { AccentText } from './AccentText';
import { RegistrationTabs } from './registration/RegistrationTabs'; import { RegistrationOptions } from './registration/RegistrationTabs';
import { SessionIconButton, SessionIconSize, SessionIconType } from './icon'; import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
import { SessionToastContainer } from './SessionToastContainer'; import { SessionToastContainer } from './SessionToastContainer';
import { lightTheme, SessionTheme } from '../../state/ducks/SessionTheme'; import { lightTheme, SessionTheme } from '../../state/ducks/SessionTheme';
@ -36,7 +36,7 @@ export const SessionRegistrationView = () => {
<AccentText /> <AccentText />
</div> </div>
<div className="session-content-registration"> <div className="session-content-registration">
<RegistrationTabs theme={lightTheme} /> <RegistrationOptions theme={lightTheme} />
</div> </div>
</div> </div>
</div> </div>

@ -1,11 +1,11 @@
import React from 'react'; import React, { useState } from 'react';
import { PromiseUtils, StringUtils, ToastUtils, UserUtils } from '../../../session/utils'; import { PromiseUtils, StringUtils, ToastUtils, UserUtils } from '../../../session/utils';
import { getConversationController } from '../../../session/conversations'; import { getConversationController } from '../../../session/conversations';
import { createOrUpdateItem, removeAll } from '../../../data/data'; import { createOrUpdateItem, removeAll } from '../../../data/data';
import { SignUpTab } from './SignUpTab'; import { SignUpTab } from './SignUpTab';
import { SignInTab } from './SignInTab'; import { SignInTab } from './SignInTab';
import { TabLabel, TabType } from './TabLabel'; import { TabLabel, TabType } from './TabLabel'; // TODO: remove unused tabs
import { trigger } from '../../../shims/events'; import { trigger } from '../../../shims/events';
import { import {
generateMnemonic, generateMnemonic,
@ -17,16 +17,11 @@ import { fromHex } from '../../../session/utils/String';
import { TaskTimedOutError } from '../../../session/utils/Promise'; import { TaskTimedOutError } from '../../../session/utils/Promise';
import { mn_decode } from '../../../session/crypto/mnemonic'; import { mn_decode } from '../../../session/crypto/mnemonic';
import { getSwarmPollingInstance } from '../../../session/snode_api/swarmPolling'; import { getSwarmPollingInstance } from '../../../session/snode_api/swarmPolling';
import { useEffect } from 'react';
export const MAX_USERNAME_LENGTH = 20; export const MAX_USERNAME_LENGTH = 20;
// tslint:disable: use-simple-attributes // tslint:disable: use-simple-attributes
interface State {
selectedTab: TabType;
generatedRecoveryPhrase: string;
hexGeneratedPubKey: string;
}
export async function resetRegistration() { export async function resetRegistration() {
await removeAll(); await removeAll();
await window.storage.reset(); await window.storage.reset();
@ -158,45 +153,27 @@ export async function signInWithLinking(signInDetails: { userRecoveryPhrase: str
window?.log?.warn('exception during registration:', e); window?.log?.warn('exception during registration:', e);
} }
} }
export class RegistrationTabs extends React.Component<any, State> {
constructor(props: any) {
super(props);
this.state = {
selectedTab: TabType.SignUp,
generatedRecoveryPhrase: '',
hexGeneratedPubKey: '',
};
}
public componentDidMount() { export enum RegistrationPhase {
void this.generateMnemonicAndKeyPair(); Start,
void resetRegistration(); SignIn,
} CreateSessionID,
RestoreYourAccount,
LinkDevice
}
public render() { export const RegistrationOptions = (props: any) => {
const { selectedTab } = this.state; const [generatedRecoveryPhrase, setGeneratedRecoveryPhrase] = useState('');
const [hexGeneratedPubKey, setHexGeneratedPubKey] = useState('');
return ( const [registrationPhase, setRegistrationPhase] = useState(RegistrationPhase.Start);
<div className="session-registration-container">
<div className="session-registration__tab-container"> useEffect(() => {
<TabLabel void generateMnemonicAndKeyPair();
type={TabType.SignUp} void resetRegistration();
isSelected={selectedTab === TabType.SignUp} }, [])
onSelect={this.handleTabSelect}
/>
<TabLabel
type={TabType.SignIn}
isSelected={selectedTab === TabType.SignIn}
onSelect={this.handleTabSelect}
/>
</div>
{this.renderSections()}
</div>
);
}
private async generateMnemonicAndKeyPair() { const generateMnemonicAndKeyPair = async () => {
if (this.state.generatedRecoveryPhrase === '') { if (generatedRecoveryPhrase === '') {
const mnemonic = await generateMnemonic(); const mnemonic = await generateMnemonic();
let seedHex = mn_decode(mnemonic); let seedHex = mn_decode(mnemonic);
@ -210,30 +187,28 @@ export class RegistrationTabs extends React.Component<any, State> {
const keyPair = await sessionGenerateKeyPair(seed); const keyPair = await sessionGenerateKeyPair(seed);
const hexGeneratedPubKey = StringUtils.decode(keyPair.pubKey, 'hex'); const hexGeneratedPubKey = StringUtils.decode(keyPair.pubKey, 'hex');
this.setState({ setGeneratedRecoveryPhrase(mnemonic);
generatedRecoveryPhrase: mnemonic, setHexGeneratedPubKey(hexGeneratedPubKey); // our 'frontend' sessionID
hexGeneratedPubKey, // our 'frontend' sessionID
});
} }
} }
private readonly handleTabSelect = (tabType: TabType): void => { return (
this.setState({ <div className="session-registration-container">
selectedTab: tabType, {(registrationPhase === RegistrationPhase.Start ||
}); registrationPhase === RegistrationPhase.CreateSessionID) &&
};
private renderSections() {
const { selectedTab, generatedRecoveryPhrase, hexGeneratedPubKey } = this.state;
if (selectedTab === TabType.SignUp) {
return (
<SignUpTab <SignUpTab
generatedRecoveryPhrase={generatedRecoveryPhrase} generatedRecoveryPhrase={generatedRecoveryPhrase}
hexGeneratedPubKey={hexGeneratedPubKey} hexGeneratedPubKey={hexGeneratedPubKey}
setRegistrationPhase={setRegistrationPhase}
/> />
); }
} {
(registrationPhase === RegistrationPhase.Start ||
return <SignInTab />; registrationPhase === RegistrationPhase.SignIn) &&
} <SignInTab
setRegistrationPhase={setRegistrationPhase}
/>
}
</div>
)
} }

@ -3,7 +3,7 @@ import { Flex } from '../../basic/Flex';
import { SpacerLG } from '../../basic/Text'; import { SpacerLG } from '../../basic/Text';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../SessionButton'; import { SessionButton, SessionButtonColor, SessionButtonType } from '../SessionButton';
import { SessionSpinner } from '../SessionSpinner'; import { SessionSpinner } from '../SessionSpinner';
import { signInWithLinking, signInWithRecovery } from './RegistrationTabs'; import { RegistrationPhase, signInWithLinking, signInWithRecovery } from './RegistrationTabs';
import { RegistrationUserDetails } from './RegistrationUserDetails'; import { RegistrationUserDetails } from './RegistrationUserDetails';
import { TermsAndConditions } from './TermsAndConditions'; import { TermsAndConditions } from './TermsAndConditions';
@ -80,14 +80,17 @@ const SignInButtons = (props: {
<div> <div>
<RestoreUsingRecoveryPhraseButton onRecoveryButtonClicked={props.onRecoveryButtonClicked} /> <RestoreUsingRecoveryPhraseButton onRecoveryButtonClicked={props.onRecoveryButtonClicked} />
<SpacerLG /> <SpacerLG />
<div className="or">{window.i18n('or')}</div>
<SpacerLG />
<LinkDeviceButton onLinkDeviceButtonClicked={props.onLinkDeviceButtonClicked} /> <LinkDeviceButton onLinkDeviceButtonClicked={props.onLinkDeviceButtonClicked} />
</div> </div>
); );
}; };
export const SignInTab = () => { interface Props {
setRegistrationPhase: (phase: any) => any;
}
export const SignInTab = (props: Props) => {
const { setRegistrationPhase } = props;
const [signInMode, setSignInMode] = useState(SignInMode.Default); const [signInMode, setSignInMode] = useState(SignInMode.Default);
const [recoveryPhrase, setRecoveryPhrase] = useState(''); const [recoveryPhrase, setRecoveryPhrase] = useState('');
const [recoveryPhraseError, setRecoveryPhraseError] = useState(undefined as string | undefined); const [recoveryPhraseError, setRecoveryPhraseError] = useState(undefined as string | undefined);
@ -153,12 +156,14 @@ export const SignInTab = () => {
<SignInButtons <SignInButtons
signInMode={signInMode} signInMode={signInMode}
onRecoveryButtonClicked={() => { onRecoveryButtonClicked={() => {
setRegistrationPhase(RegistrationPhase.SignIn);
setSignInMode(SignInMode.UsingRecoveryPhrase); setSignInMode(SignInMode.UsingRecoveryPhrase);
setRecoveryPhrase(''); setRecoveryPhrase('');
setDisplayName(''); setDisplayName('');
setIsLoading(false); setIsLoading(false);
}} }}
onLinkDeviceButtonClicked={() => { onLinkDeviceButtonClicked={() => {
setRegistrationPhase(RegistrationPhase.SignIn);
setSignInMode(SignInMode.LinkDevice); setSignInMode(SignInMode.LinkDevice);
setRecoveryPhrase(''); setRecoveryPhrase('');
setDisplayName(''); setDisplayName('');

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../SessionButton'; import { SessionButton, SessionButtonColor, SessionButtonType } from '../SessionButton';
import { SessionIdEditable } from '../SessionIdEditable'; import { SessionIdEditable } from '../SessionIdEditable';
import { signUp } from './RegistrationTabs'; import { RegistrationPhase, signUp } from './RegistrationTabs';
import { RegistrationUserDetails } from './RegistrationUserDetails'; import { RegistrationUserDetails } from './RegistrationUserDetails';
import { TermsAndConditions } from './TermsAndConditions'; import { TermsAndConditions } from './TermsAndConditions';
@ -15,6 +15,7 @@ export interface Props {
// tslint:disable: react-unused-props-and-state // tslint:disable: react-unused-props-and-state
generatedRecoveryPhrase: string; generatedRecoveryPhrase: string;
hexGeneratedPubKey: string; hexGeneratedPubKey: string;
setRegistrationPhase: (phase: any) => any;
} }
const CreateSessionIdButton = ({ createSessionID }: { createSessionID: any }) => { const CreateSessionIdButton = ({ createSessionID }: { createSessionID: any }) => {
@ -40,10 +41,8 @@ const ContinueSignUpButton = ({ continueSignUp }: { continueSignUp: any }) => {
}; };
const SignUpDefault = (props: { createSessionID: () => void }) => { const SignUpDefault = (props: { createSessionID: () => void }) => {
const allUsersAreRandomly = window.i18n('allUsersAreRandomly...');
return ( return (
<div className="session-registration__content"> <div className="session-registration__content">
<div className="session-description-long">{allUsersAreRandomly}</div>
<CreateSessionIdButton createSessionID={props.createSessionID} /> <CreateSessionIdButton createSessionID={props.createSessionID} />
</div> </div>
); );
@ -55,8 +54,8 @@ const SignUpSessionIDShown = (props: { continueSignUp: () => void }) => {
<div className="session-registration__unique-session-id"> <div className="session-registration__unique-session-id">
{window.i18n('yourUniqueSessionID')} {window.i18n('yourUniqueSessionID')}
</div> </div>
<SessionIdEditable editable={false} placeholder={undefined} /> <SessionIdEditable editable={false} placeholder={undefined} />
<div className="session-description-long">{window.i18n('signupSessionIDBlurb')}</div>
<ContinueSignUpButton continueSignUp={props.continueSignUp} /> <ContinueSignUpButton continueSignUp={props.continueSignUp} />
<TermsAndConditions /> <TermsAndConditions />
</div> </div>
@ -64,8 +63,8 @@ const SignUpSessionIDShown = (props: { continueSignUp: () => void }) => {
}; };
export const SignUpTab = (props: Props) => { export const SignUpTab = (props: Props) => {
const { setRegistrationPhase } = props;
const [signUpMode, setSignUpMode] = useState(SignUpMode.Default); const [signUpMode, setSignUpMode] = useState(SignUpMode.Default);
const [displayName, setDisplayName] = useState(''); const [displayName, setDisplayName] = useState('');
const [displayNameError, setDisplayNameError] = useState(''); const [displayNameError, setDisplayNameError] = useState('');
@ -80,6 +79,7 @@ export const SignUpTab = (props: Props) => {
<SignUpDefault <SignUpDefault
createSessionID={() => { createSessionID={() => {
setSignUpMode(SignUpMode.SessionIDShown); setSignUpMode(SignUpMode.SessionIDShown);
setRegistrationPhase(RegistrationPhase.CreateSessionID)
}} }}
/> />
); );

Loading…
Cancel
Save