Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

connect-popup-refactor [2/3] (passphrase and error screen) #5879

Merged
merged 10 commits into from
Sep 19, 2022
5 changes: 4 additions & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@
},
"dependencies": {
"@tippyjs/react": "^4.2.6",
"@trezor/dom-utils": "*",
"@trezor/react-utils": "*",
"date-fns": "^2.29.1",
"framer-motion": "^6.5.1",
"lottie-react": "^2.3.1",
"polished": "^4.2.2",
"react-date-range": "^1.4.0",
"react-intl": "^6.0.5",
"react-select": "^5.4.0",
"react-svg": "^15.1.6",
"react-truncate": "^2.4.0",
"react-use": "^17.4.0"
"react-use": "^17.4.0",
"zxcvbn": "^4.4.2"
},
"devDependencies": {
"@storybook/addon-actions": "^6.5.10",
Expand Down
2 changes: 2 additions & 0 deletions packages/components/src/components/Icon/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const ICONS = {
COIN: require('../../images/icons/coin.svg'),
COIN_CONTROL: require('../../images/icons/coin_control.svg'),
COINS: require('../../images/icons/coins.svg'),
COOKIE: require('../../images/icons/cookie.svg'),
COPY: require('../../images/icons/copy.svg'),
CROSS: require('../../images/icons/cross.svg'),
CSV: require('../../images/icons/csv.svg'),
Expand All @@ -37,6 +38,7 @@ export const ICONS = {
EXPERIMENTAL_FEATURES: require('../../images/icons/experimental-features.svg'),
EXTERNAL_LINK: require('../../images/icons/external_link.svg'),
FEEDBACK: require('../../images/icons/feedback.svg'),
FINGERPRINT: require('../../images/icons/fingerprint.svg'),
FIRMWARE: require('../../images/icons/firmware.svg'),
FLAG: require('../../images/icons/flag.svg'),
GAS: require('../../images/icons/gas.svg'),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import React, { useState, useRef, useEffect, useCallback } from 'react';
import { FormattedMessage, useIntl } from 'react-intl';

import { AnimatePresence, motion } from 'framer-motion';

import { useKeyPress } from '@trezor/react-utils';
import { setCaretPosition } from '@trezor/dom-utils';
import styled, { css } from 'styled-components';
Expand All @@ -9,19 +12,19 @@ import {
variables,
Input,
Tooltip,
TooltipProps,
Checkbox,
Icon,
motionAnimation,
} 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 '@trezor/env-utils';

const Wrapper = styled.div<Pick<Props, 'type' | 'singleColModal'>>`
import PasswordStrengthIndicator from './PasswordStrengthIndicator';

const MAX_LENGTH = 50;
mroz22 marked this conversation as resolved.
Show resolved Hide resolved

const Wrapper = styled.div<Pick<PassphraseTypeCardProps, 'type' | 'singleColModal'>>`
display: flex;
flex: 1;
/* align-items: center; */
Expand All @@ -48,7 +51,7 @@ const Wrapper = styled.div<Pick<Props, 'type' | 'singleColModal'>>`
`}
`;

const IconWrapper = styled.div<Pick<Props, 'type'>>`
const IconWrapper = styled.div<Pick<PassphraseTypeCardProps, 'type'>>`
width: 38px;
height: 38px;
background: ${props =>
Expand Down Expand Up @@ -83,7 +86,7 @@ const WalletTitle = styled.div<{ withMargin: boolean }>`
${props => props.withMargin && `margin-bottom: 5px;`}
`;

const Description = styled.div<Pick<Props, 'authConfirmation'>>`
const Description = styled.div<Pick<PassphraseTypeCardProps, 'authConfirmation'>>`
display: flex;
color: ${props => props.theme.TYPE_LIGHT_GREY};
font-size: ${variables.FONT_SIZE.TINY};
Expand Down Expand Up @@ -159,7 +162,7 @@ const RetryButton = styled(Button)`
margin-top: 16px;
`;

type Props = {
type PassphraseTypeCardProps = {
title?: React.ReactNode;
description?: React.ReactNode;
submitLabel: React.ReactNode;
Expand All @@ -169,13 +172,17 @@ type Props = {
authConfirmation?: boolean;
onSubmit: (value: string, passphraseOnDevice?: boolean) => void;
recreateWallet?: () => void;
learnMoreTooltipOnClick?: TooltipProps['guideAnchor'];
learnMoreTooltipAppendTo?: TooltipProps['appendTo'];
};

const DOT = '●';

const PassphraseTypeCard = (props: Props) => {
export const PassphraseTypeCard = (props: PassphraseTypeCardProps) => {
console.log('PassphraseTypeCard', props);
mroz22 marked this conversation as resolved.
Show resolved Hide resolved

const theme = useTheme();
const { translationString } = useTranslation();
const intl = useIntl();
const [value, setValue] = useState('');
const [enabled, setEnabled] = useState(!props.authConfirmation);
const [showPassword, setShowPassword] = useState(false);
Expand All @@ -187,7 +194,7 @@ const PassphraseTypeCard = (props: Props) => {
const ref = useRef<HTMLInputElement>(null);
const caretRef = useRef<number>(0);

const isTooLong = countBytesInString(value) > MAX_LENGTH.PASSPHRASE;
const isTooLong = countBytesInString(value) > MAX_LENGTH;

const { onSubmit } = props;
const submit = useCallback(
Expand Down Expand Up @@ -292,15 +299,20 @@ 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}
appendTo={props.learnMoreTooltipAppendTo}
title={
<FormattedMessage
mroz22 marked this conversation as resolved.
Show resolved Hide resolved
id="TR_WHAT_IS_PASSPHRASE"
defaultMessage="Learn more about the difference"
/>
)}
content={<Translation id="TR_HIDDEN_WALLET_TOOLTIP" />}
}
guideAnchor={props.learnMoreTooltipOnClick}
content={
<FormattedMessage
id="TR_HIDDEN_WALLET_TOOLTIP"
defaultMessage="Passphrases add a custom phrase (e.g. a word, sentence, or string of characters) to your recovery seed. This creates a hidden wallet; each hidden wallet can use its own passphrase. Your standard wallet will still be accessible without a passphrase."
/>
}
dashed
>
<>{props.title}</>
Expand All @@ -327,12 +339,21 @@ const PassphraseTypeCard = (props: Props) => {
<InputWrapper authConfirmation={props.authConfirmation}>
<PassphraseInput
data-test="@passphrase/input"
placeholder={translationString('TR_ENTER_PASSPHRASE')}
placeholder={intl.formatMessage({
defaultMessage: 'Enter passphrase',
id: 'TR_ENTER_PASSPHRASE',
})}
onChange={onPassphraseChange}
value={displayValue}
innerRef={ref}
bottomText={
isTooLong ? <Translation id="TR_PASSPHRASE_TOO_LONG" /> : null
isTooLong ? (
// todo: resolve messages sharing https://github.com/trezor/trezor-suite/issues/5325
<FormattedMessage
id="TR_PASSPHRASE_TOO_LONG"
defaultMessage="Passphrase length has exceed the allowed limit."
/>
) : null
}
inputState={isTooLong ? 'error' : undefined}
noTopLabel
Expand Down Expand Up @@ -366,7 +387,10 @@ const PassphraseTypeCard = (props: Props) => {
onClick={() => setEnabled(!enabled)}
isChecked={enabled}
>
<Translation id="TR_I_UNDERSTAND_PASSPHRASE" />
<FormattedMessage
id="TR_I_UNDERSTAND_PASSPHRASE"
defaultMessage="I understand, passphrases cannot be retrieved unlike everyday passwords"
/>
</Checkbox>
</Content>
)}
Expand All @@ -390,19 +414,21 @@ const PassphraseTypeCard = (props: Props) => {
</ActionButton>
</motion.div>
)}

{/* Offer entering passphrase on a device */}
{props.offerPassphraseOnDevice && (
<OnDeviceActionButton
isDisabled={!enabled}
variant="tertiary"
onClick={() => submit(value, true)}
fullWidth
data-test="@passphrase/enter-on-device-button"
>
<Translation id="TR_ENTER_PASSPHRASE_ON_DEVICE" />
<FormattedMessage
id="TR_ENTER_PASSPHRASE_ON_DEVICE"
defaultMessage="Enter passphrase on Trezor"
/>
</OnDeviceActionButton>
)}

{/* Try again button shows while confirming a passphrase */}
{props.recreateWallet && (
<RetryButton
Expand All @@ -411,7 +437,7 @@ const PassphraseTypeCard = (props: Props) => {
color={theme.TYPE_LIGHT_GREY}
onClick={props.recreateWallet}
>
<Translation id="TR_TRY_AGAIN" />
<FormattedMessage id="TR_TRY_AGAIN" defaultMessage="Try again" />
</RetryButton>
)}
</Actions>
Expand All @@ -420,5 +446,3 @@ const PassphraseTypeCard = (props: Props) => {
</Wrapper>
);
};

export default PassphraseTypeCard;
9 changes: 9 additions & 0 deletions packages/components/src/images/icons/cookie.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions packages/components/src/images/icons/fingerprint.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export * from './components/HoverAnimation';
export * from './components/Fade';
export * from './components/Image/Image';
export * from './components/CollapsibleBox';
export * from './components/Passphrase/PassphraseTypeCard';

export * from './constants/keyboardEvents';

Expand Down
5 changes: 4 additions & 1 deletion packages/components/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@
"noUnusedParameters": false
},
"include": ["."],
"references": [{ "path": "../react-utils" }]
"references": [
{ "path": "../dom-utils" },
{ "path": "../react-utils" }
]
}
9 changes: 6 additions & 3 deletions packages/connect-popup/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@
"@trezor/connect-ui": "*",
"@trezor/crypto-utils": "*",
"@trezor/urls": "*",
"react": "17.0.2",
"styled-components": "^5.3.5"
"react": "17.0.2"
},
"devDependencies": {
"@playwright/test": "^1.22.2",
"@trezor/trezor-user-env-link": "*",
"@types/react": "^17.0.0",
"@types/react": "^17.0.48",
"@types/styled-components": "^5.1.25",
"jest": "^26.6.3",
"playwright": "^1.22.2",
Expand All @@ -32,5 +31,9 @@
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.7.4",
"xvfb-maybe": "^0.2.1"
},
"peerDependencies": {
"react": "17.0.2",
"styled-components": "^5.3.5"
}
}
Loading