feat: setup UI and state for account create display name step

pull/3056/head
William Grant 1 year ago
parent 3eb7f241bf
commit 4e2101a9e5

@ -583,5 +583,7 @@
"urlOpen": "Open URL",
"urlOpenBrowser": "This will open in your browser.",
"termsOfService": "Terms of Service",
"privacyPolicy": "Privacy Policy"
"privacyPolicy": "Privacy Policy",
"displayNamePick": "Pick your display name",
"displayNameDescription": "It can be your real name, an alias, or anything else you like — and you can change it any time."
}

@ -12,7 +12,7 @@ import { SessionIconButton } from '../icon';
const StyledInputContainer = styled(Flex)<{ error: boolean }>`
position: relative;
width: 280px;
width: 100%;
label {
color: var(--text-primary-color);
@ -39,7 +39,7 @@ const StyledInput = styled(motion.input)`
border: 1px solid var(--input-border-color);
border-radius: 13px;
outline: 0;
width: 280px;
width: 100%;
background: transparent;
color: var(--input-text-color);

@ -1,27 +1,5 @@
import { MAX_USERNAME_BYTES } from '../../session/constants';
import { SpacerLG } from '../basic/Text';
import { SessionInput2 } from '../inputs';
import { BackButtonWithininContainer } from './components/BackButton';
const DisplayNameInput = (props: {
stealAutoFocus?: boolean;
displayName: string;
onDisplayNameChanged: (val: string) => any;
handlePressEnter: () => any;
}) => {
return (
<SessionInput2
autoFocus={props.stealAutoFocus || false}
type="text"
placeholder={window.i18n('enterDisplayName')}
value={props.displayName}
maxLength={MAX_USERNAME_BYTES}
onValueChanged={props.onDisplayNameChanged}
onEnterPressed={props.handlePressEnter}
inputDataTestId="display-name-input"
/>
);
};
const RecoveryPhraseInput = (props: {
recoveryPhrase: string;
@ -60,31 +38,18 @@ export const RegistrationUserDetails = (props: Props) => {
}
return (
<BackButtonWithininContainer margin={'12px 0 0 0'}>
<div style={{ margin: 0 }}>
{props.showSeedField && (
<>
<RecoveryPhraseInput
recoveryPhrase={props.recoveryPhrase as string}
handlePressEnter={props.handlePressEnter}
onSeedChanged={props.onSeedChanged as any}
stealAutoFocus={props.stealAutoFocus}
/>
<SpacerLG />
</>
)}
{props.showDisplayNameField && (
<>
<DisplayNameInput
stealAutoFocus={!props.showSeedField && props.stealAutoFocus}
displayName={props.displayName}
handlePressEnter={props.handlePressEnter}
onDisplayNameChanged={props.onDisplayNameChanged}
/>
<SpacerLG />
</>
)}
</div>
</BackButtonWithininContainer>
<div style={{ margin: 0 }}>
{props.showSeedField && (
<>
<RecoveryPhraseInput
recoveryPhrase={props.recoveryPhrase as string}
handlePressEnter={props.handlePressEnter}
onSeedChanged={props.onSeedChanged as any}
stealAutoFocus={props.stealAutoFocus}
/>
<SpacerLG />
</>
)}
</div>
);
};

@ -4,13 +4,11 @@ import { updateTermsOfServicePrivacyModal } from '../../state/onboarding/ducks/m
import { SessionHtmlRenderer } from '../basic/SessionHTMLRenderer';
const StyledTermsAndConditions = styled.div`
color: var(--text-secondary-color);
text-align: center;
font-size: 12px;
b {
font-weight: bold;
color: var(--text-primary-color);
}
&:hover {

@ -41,7 +41,7 @@ export const BackButton = () => {
onClick={() => {
dispatch(setOnboardingStep(Onboarding.Start));
dispatch(setAccountRestorationStep(AccountRestoration.Start));
dispatch(setAccountCreationStep(AccountCreation.Start));
dispatch(setAccountCreationStep(AccountCreation.DisplayName));
}}
/>
);

@ -1,112 +0,0 @@
import { useEffect, useState } from 'react';
import { useDispatch } from 'react-redux';
import styled from 'styled-components';
import {
AccountCreation,
setAccountCreationStep,
} from '../../../state/onboarding/ducks/registration';
import {
useOnboardAccountCreationStep,
useOnboardGeneratedRecoveryPhrase,
useOnboardHexGeneratedPubKey,
} from '../../../state/onboarding/selectors/registration';
import { Flex } from '../../basic/Flex';
import { SessionButton } from '../../basic/SessionButton';
import { SessionIdEditable } from '../../basic/SessionIdEditable';
import { signUp } from '../RegistrationStages';
import { RegistrationUserDetails } from '../RegistrationUserDetails';
import { TermsAndConditions } from '../TermsAndConditions';
import { BackButtonWithininContainer } from '../components/BackButton';
import { sanitizeDisplayNameOrToast } from './RestoreAccount';
const StyledContainer = styled.div`
width: 100%;
padding-top: 20px;
`;
export const CreateAccount = () => {
const step = useOnboardAccountCreationStep();
const generatedRecoveryPhrase = useOnboardGeneratedRecoveryPhrase();
const hexGeneratedPubKey = useOnboardHexGeneratedPubKey();
const dispatch = useDispatch();
const [displayName, setDisplayName] = useState('');
const [displayNameError, setDisplayNameError] = useState<undefined | string>('');
useEffect(() => {
if (step === AccountCreation.SessionIDShown) {
window.Session.setNewSessionID(hexGeneratedPubKey);
}
}, [step, hexGeneratedPubKey]);
if (step === AccountCreation.SessionIDShown) {
return (
<div>
<Flex
flexDirection="row"
container={true}
alignItems="center"
margin={'0 0 0 calc(var(--margins-sm) * -1)'}
>
<BackButtonWithininContainer margin={'-5px 0 0 0'}>
<div className="session-registration__unique-session-id">
{window.i18n('yourUniqueSessionID')}
</div>
</BackButtonWithininContainer>
</Flex>
<SessionIdEditable
editable={false}
placeholder={undefined}
dataTestId="session-id-signup"
/>
<div className="session-description-long">{window.i18n('allUsersAreRandomly...')}</div>
<SessionButton
onClick={() => {
dispatch(setAccountCreationStep(AccountCreation.DisplayName));
}}
text={window.i18n('continue')}
/>
<TermsAndConditions />
</div>
);
}
// can only be the EnterDetails step
// Display name is required
const displayNameOK = !displayNameError && !!displayName;
const enableCompleteSignUp = displayNameOK;
const signUpWithDetails = async () => {
await signUp({
displayName,
generatedRecoveryPhrase,
});
};
return (
<StyledContainer>
<Flex flexDirection="row" container={true} alignItems="center">
<Flex className="session-registration__welcome-session" padding="20px">
{window.i18n('welcomeToYourSession')}
</Flex>
</Flex>
<RegistrationUserDetails
showDisplayNameField={true}
showSeedField={false}
displayName={displayName}
handlePressEnter={signUpWithDetails}
onDisplayNameChanged={(name: string) => {
sanitizeDisplayNameOrToast(name, setDisplayName, setDisplayNameError);
}}
stealAutoFocus={true}
/>
<SessionButton
onClick={signUpWithDetails}
text={window.i18n('getStarted')}
disabled={!enableCompleteSignUp}
/>
</StyledContainer>
);
};

@ -0,0 +1,90 @@
import { useEffect, useState } from 'react';
import styled from 'styled-components';
import { MAX_USERNAME_BYTES } from '../../../session/constants';
import { AccountCreation } from '../../../state/onboarding/ducks/registration';
import {
useOnboardAccountCreationStep,
useOnboardGeneratedRecoveryPhrase,
useOnboardHexGeneratedPubKey,
} from '../../../state/onboarding/selectors/registration';
import { Flex } from '../../basic/Flex';
import { SessionButton } from '../../basic/SessionButton';
import { SpacerLG, SpacerSM } from '../../basic/Text';
import { SessionInput2 } from '../../inputs';
import { signUp } from '../RegistrationStages';
import { BackButtonWithininContainer } from '../components/BackButton';
import { sanitizeDisplayNameOrToast } from './RestoreAccount';
const StyledContainer = styled.div`
width: 100%;
`;
const StyledHeading = styled.h3`
padding: 0;
margin: 0;
font-size: var(--font-size-h2);
`;
const StyledDescription = styled.p`
padding: 0;
margin: 0;
`;
export const CreateAccount = () => {
const step = useOnboardAccountCreationStep();
const generatedRecoveryPhrase = useOnboardGeneratedRecoveryPhrase();
const hexGeneratedPubKey = useOnboardHexGeneratedPubKey();
// const dispatch = useDispatch();
const [displayName, setDisplayName] = useState('');
const [displayNameError, setDisplayNameError] = useState<undefined | string>('');
useEffect(() => {
if (step === AccountCreation.DisplayName) {
window.Session.setNewSessionID(hexGeneratedPubKey);
}
}, [step, hexGeneratedPubKey]);
// Display name is required
const displayNameOK = !displayNameError && !!displayName;
const enableCompleteSignUp = displayNameOK;
const signUpWithDetails = async () => {
await signUp({
displayName,
generatedRecoveryPhrase,
});
};
return (
<StyledContainer>
<BackButtonWithininContainer margin={'0 0 0 -28px'}>
<Flex container={true} width="100%" flexDirection="column" alignItems="flex-start">
<StyledHeading>{window.i18n('displayNamePick')}</StyledHeading>
<SpacerSM />
<StyledDescription>{window.i18n('displayNameDescription')}</StyledDescription>
<SpacerLG />
<SessionInput2
autoFocus={true}
type="text"
placeholder={window.i18n('enterDisplayName')}
value={displayName}
maxLength={MAX_USERNAME_BYTES}
onValueChanged={(name: string) => {
sanitizeDisplayNameOrToast(name, setDisplayName, setDisplayNameError);
}}
onEnterPressed={signUpWithDetails}
inputDataTestId="display-name-input"
/>
<SpacerLG />
<SessionButton
onClick={signUpWithDetails}
text={window.i18n('continue')}
disabled={!enableCompleteSignUp}
/>
</Flex>
</BackButtonWithininContainer>
</StyledContainer>
);
};

@ -19,7 +19,7 @@ export const Start = () => {
<SessionButton
buttonColor={SessionButtonColor.White}
onClick={() => {
dispatch(setAccountCreationStep(AccountCreation.SessionIDShown));
dispatch(setAccountCreationStep(AccountCreation.DisplayName));
dispatch(setOnboardingStep(Onboarding.CreateAccount));
}}
text={window.i18n('createAccount')}

@ -1,4 +1,4 @@
import { CreateAccount } from './CreatAccount';
import { CreateAccount } from './CreateAccount';
import { RestoreAccount } from './RestoreAccount';
import { Start } from './Start';

@ -10,10 +10,6 @@ export enum Onboarding {
}
export enum AccountCreation {
/** TODO to be removed - current starting screen */
Start,
/** TODO to be removed */
SessionIDShown,
/** starting screen */
DisplayName,
/** show conversation screen */
@ -48,7 +44,7 @@ const initialState: OnboardingState = {
hexGeneratedPubKey: '',
step: Onboarding.Start,
accountRestorationStep: AccountRestoration.Start,
accountCreationStep: AccountCreation.Start,
accountCreationStep: AccountCreation.DisplayName,
};
export const registrationSlice = createSlice({

@ -159,7 +159,9 @@ export type LocalizerKeys =
| 'disappearingMessagesModeOutdated'
| 'disappears'
| 'displayName'
| 'displayNameDescription'
| 'displayNameEmpty'
| 'displayNamePick'
| 'displayNameTooLong'
| 'document'
| 'documents'

Loading…
Cancel
Save