Skip to content

Commit

Permalink
feat(connect-popup): passphrase redesign [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
mroz22 committed Aug 17, 2022
1 parent e36212c commit e581fe3
Show file tree
Hide file tree
Showing 15 changed files with 221 additions and 149 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
// pull this component up to some share logic.

// todo: reorganize imports

import React, { useState, useRef, useEffect, useCallback } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import { useKeyPress } from '@trezor/react-utils';
import { ANIMATION } from '@suite-config';
import { setCaretPosition } from '@suite-utils/dom';
import styled, { css } from 'styled-components';

// ok
import { Button, useTheme, variables, Input, Tooltip, Checkbox, Icon } from '@trezor/components';
import { Translation } from '@suite-components/Translation';
import { MAX_LENGTH } from '@suite-constants/inputs';
import { countBytesInString } from '@trezor/utils';
import { OpenGuideFromTooltip } from '@guide-components';
import PasswordStrengthIndicator from '@suite-components/PasswordStrengthIndicator';
import { useTranslation } from '@suite-hooks';
import { isAndroid } from '@suite-utils/env';
import { useKeyPress } from '@trezor/react-utils';

// move to another package, shared package should not import from suite
import { setCaretPosition } from '@trezor/suite/src/utils/suite/dom';
import ANIMATION from '@trezor/suite/src/config/suite/animation';

// moved
import PasswordStrengthIndicator from './PasswordStrengthIndicator';

// import { MAX_LENGTH } from '@suite-constants/inputs';
const MAX_LENGTH = {
PASSPHRASE: 50,
}; // probably should become PROP or be imported from some @trezor/constants/common package

// todo: refactor these, translations, modal, etc
// import { useTranslation } from '@suite-hooks';
// import { OpenGuideFromTooltip } from '@guide-components';
// import { Translation } from '@suite-components/Translation';
// import { isAndroid } from '@trezor/suite/src/utils/suite/env';

const Wrapper = styled.div<Pick<Props, 'type' | 'singleColModal'>>`
display: flex;
Expand Down Expand Up @@ -151,6 +167,9 @@ const RetryButton = styled(Button)`
margin-top: 16px;
`;

// todo: how about translations? pass translation component? pass translated string?
const Translation = ({ id }: { id: string }) => <div>{id}</div>;

type Props = {
title?: React.ReactNode;
description?: React.ReactNode;
Expand All @@ -165,9 +184,9 @@ type Props = {

const DOT = '●';

const PassphraseTypeCard = (props: Props) => {
export const PassphraseTypeCard = (props: Props) => {
const theme = useTheme();
const { translationString } = useTranslation();
// const { translationString } = useTranslation();
const [value, setValue] = useState('');
const [enabled, setEnabled] = useState(!props.authConfirmation);
const [showPassword, setShowPassword] = useState(false);
Expand Down Expand Up @@ -284,15 +303,16 @@ const PassphraseTypeCard = (props: Props) => {
>
{props.type === 'hidden' ? (
<Tooltip
title={<Translation id="TR_WHAT_IS_PASSPHRASE" />}
guideAnchor={instance => (
<OpenGuideFromTooltip
dataTest="@tooltip/guideAnchor"
id="/security/passphrase.md"
instance={instance}
/>
)}
content={<Translation id="TR_HIDDEN_WALLET_TOOLTIP" />}
// title={<Translation id="TR_WHAT_IS_PASSPHRASE" />}
// guideAnchor={instance => (
// <OpenGuideFromTooltip
// dataTest="@tooltip/guideAnchor"
// id="/security/passphrase.md"
// instance={instance}
// />
// )}
// content={<Translation id="TR_HIDDEN_WALLET_TOOLTIP" />}
title={<div>"todo: pass tooltip as prop?"</div>}
dashed
>
<>{props.title}</>
Expand All @@ -319,7 +339,8 @@ const PassphraseTypeCard = (props: Props) => {
<InputWrapper authConfirmation={props.authConfirmation}>
<PassphraseInput
data-test="@passphrase/input"
placeholder={translationString('TR_ENTER_PASSPHRASE')}
// placeholder={translationString('TR_ENTER_PASSPHRASE')}
placeholder="todo: pass as prop? translation?"
onChange={onPassphraseChange}
value={displayValue}
innerRef={ref}
Expand All @@ -329,7 +350,8 @@ const PassphraseTypeCard = (props: Props) => {
inputState={isTooLong ? 'error' : undefined}
noTopLabel
noError
autoFocus={!isAndroid()}
// autoFocus={!isAndroid()}
autoFocus
innerAddon={
<Icon
size={18}
Expand Down Expand Up @@ -412,5 +434,3 @@ const PassphraseTypeCard = (props: Props) => {
</Wrapper>
);
};

export default PassphraseTypeCard;
1 change: 1 addition & 0 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export * from './components/form/SelectBar';
export * from './components/HoverAnimation';
export * from './components/Fade';
export * from './components/Image/Image';
export * from './components/Passphrase/PassphraseTypeCard';

export * from './constants/keyboardEvents';

Expand Down
22 changes: 19 additions & 3 deletions packages/connect-popup/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import {
PopupEvent,
PopupInit,
PopupHandshake,
UI,
createUiResponse,
} from '@trezor/connect';
import { Transport } from '@trezor/connect-ui';
import { Transport, Passphrase, PassphraseOnDevice } from '@trezor/connect-ui';

import * as view from './view';
import {
Expand Down Expand Up @@ -149,11 +151,25 @@ const handleMessage = (event: MessageEvent<PopupEvent | UiEvent>) => {
break;
// comes first
case UI_REQUEST.REQUEST_PASSPHRASE:
view.initPassphraseView(message.payload);
showView(
<Passphrase
{...message.payload}
onPassphraseSubmit={(value: string, passphraseOnDevice: boolean) => {
postMessage(
createUiResponse(UI.RECEIVE_PASSPHRASE, {
value,
passphraseOnDevice,
// todo: what is this param?
save: true,
}),
);
}}
/>,
);
break;
// comes when user clicks "enter on device"
case UI_REQUEST.REQUEST_PASSPHRASE_ON_DEVICE:
view.passphraseOnDeviceView(message.payload);
showView(<PassphraseOnDevice />);
break;
case UI_REQUEST.INVALID_PASSPHRASE:
view.initInvalidPassphraseView(message.payload);
Expand Down
1 change: 0 additions & 1 deletion packages/connect-popup/src/view/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

export { showView, postMessage } from './common';
export { initPinView } from './pin';
export { initPassphraseView } from './passphrase';
export { initInvalidPassphraseView } from './invalidPassphrase';
export { initWordView } from './word';
export { selectDevice } from './selectDevice';
Expand Down
118 changes: 0 additions & 118 deletions packages/connect-popup/src/view/passphrase.ts

This file was deleted.

1 change: 1 addition & 0 deletions packages/connect-popup/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"types": ["web"]
},
"references": [
{ "path": "../components" },
{ "path": "../connect" },
{ "path": "../components" },
{ "path": "../connect-ui" },
Expand Down
2 changes: 2 additions & 0 deletions packages/connect-ui/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export * from './views/Transport';
export * from './views/Passphrase';
export * from './views/PassphraseOnDevice';

// this export will be removed in the future but it is required now
// future => connect-ui will have its own entrypoint
Expand Down
69 changes: 69 additions & 0 deletions packages/connect-ui/src/views/Passphrase.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react';
import styled from 'styled-components';

import { variables, PassphraseTypeCard } from '@trezor/components';

import { View } from '../components/View';

const Wrapper = styled.div<{ authConfirmation?: boolean }>`
display: flex;
flex-direction: column;
align-items: center;
@media screen and (max-width: ${variables.SCREEN_SIZE.MD}) {
width: 100%;
}
`;

const WalletsWrapper = styled.div`
display: flex;
flex-direction: column;
width: 100%;
`;

const Divider = styled.div`
margin: 16px 16px;
height: 1px;
background: ${props => props.theme.STROKE_GREY};
`;

// todo:
const Translation = (props: any) => <span>{props.id}</span>;

// todo:
export const Passphrase = (props: any) => {
console.log('Passphrase.props', props);
const { device, onPassphraseSubmit } = props;
const { features } = device;

const offerPassphraseOnDevice =
features &&
features.capabilities &&
features.capabilities.includes('Capability_PassphraseEntry');

return (
<View title="Passphrase">
{/* todo: this part could be shared with suite? */}
<Wrapper>
<WalletsWrapper>
<PassphraseTypeCard
title={<Translation id="TR_NO_PASSPHRASE_WALLET" />}
description={<Translation id="TR_STANDARD_WALLET_DESCRIPTION" />}
submitLabel={<Translation id="TR_ACCESS_STANDARD_WALLET" />}
type="standard"
onSubmit={onPassphraseSubmit}
/>
<Divider />
<PassphraseTypeCard
title={<Translation id="TR_WALLET_SELECTION_HIDDEN_WALLET" />}
description={<Translation id="TR_HIDDEN_WALLET_DESCRIPTION" />}
submitLabel={<Translation id="TR_WALLET_SELECTION_ACCESS_HIDDEN_WALLET" />}
type="hidden"
offerPassphraseOnDevice={offerPassphraseOnDevice}
onSubmit={onPassphraseSubmit}
/>
</WalletsWrapper>
</Wrapper>
</View>
);
};
13 changes: 13 additions & 0 deletions packages/connect-ui/src/views/PassphraseOnDevice.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';

// todo: maybe follow instructions on device would be enough?
// todo:
export const PassphraseOnDevice = (props: any) => {
console.log('Passphrase.props', props);

return (
<>
<h3>Passphrase on device</h3>
</>
);
};
Loading

0 comments on commit e581fe3

Please sign in to comment.