Skip to content

Commit

Permalink
wip: passhrase view in popup
Browse files Browse the repository at this point in the history
  • Loading branch information
mroz22 committed Jul 29, 2022
1 parent 35f4591 commit d00af10
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 148 deletions.
4 changes: 2 additions & 2 deletions docs/packages/connect/methods/getDeviceState.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Return information about a specific device. Devices without passphrase enabled return the same per instance.

[Device state](commonParams.md) can be used in any method (key derivation or TX signing) to enforce the same passphrase on furhter operations.
[Device state](commonParams.md) can be used in any method (key derivation or TX signing) to enforce the same passphrase on further operations.

```javascript
const result = await TrezorConnect.getDeviceState(params);
Expand All @@ -20,7 +20,7 @@ Get the state of a device.
const capturedDevice = await TrezorConnect.getDeviceState({
device: {
instance: 0, // identificator for wallet A
// `state: undefined` forces the passphrase prompt even if instance 0 is/was already using "some" pasphrase (let say empty). The Trezor forgets the current state, useful when dealing with multiple hidden wallets on one or more devices
// `state: undefined` forces the passphrase prompt even if instance 0 is/was already using "some" passphrase (lets say empty). The Trezor forgets the current state, useful when dealing with multiple hidden wallets on one or more devices
// `state: "string" verifies state is valid, otherwise "invalid passphrase" error is returned
state: undefined,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +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 { ANIMATION } from '@suite-config';
import { setCaretPosition, useKeyPress } from '@suite-utils/dom';
import styled, { css } from 'styled-components';
import { AnimatePresence, motion } from 'framer-motion';

// 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';

// move to another package, shared package should not import from suite
import { setCaretPosition } from '@trezor/suite/src/utils/suite/dom';
import { useKeyPress } from '@trezor/suite/src/hooks/suite/useKeyPress';
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 @@ -150,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 @@ -164,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 @@ -283,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 @@ -318,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 @@ -328,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 @@ -411,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 @@ -43,6 +43,7 @@ export * from './components/Truncate';
export * from './components/form/SelectBar';
export * from './components/HoverAnimation';
export * from './components/Fade';
export * from './components/Passphrase/PassphraseTypeCard';

export * from './constants/keyboardEvents';

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.

83 changes: 83 additions & 0 deletions packages/connect-popup/src/view/react/views/Passphrase.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React from 'react';
import styled from 'styled-components';
import { variables, PassphraseTypeCard } from '@trezor/components';

import { postMessage } from '../../common';
import { UI, createUiResponse } from '@trezor/connect';

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 } = props;
const { features } = device;

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

const onSubmit = (value: string, passphraseOnDevice = false) => {
console.log('onSubmit', value, passphraseOnDevice);
postMessage(
createUiResponse(UI.RECEIVE_PASSPHRASE, {
value,
passphraseOnDevice,
// todo: what is this param?
save: true,
}),
);
};

return (
<>
<h3>Passphrase</h3>

{/* 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={onSubmit}
/>
<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={onSubmit}
/>
</WalletsWrapper>
</Wrapper>
</>
);
};
13 changes: 13 additions & 0 deletions packages/connect-popup/src/view/react/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>
</>
);
};
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import TrezorConnect from '@trezor/connect';
import React, { useState } from 'react';
import styled from 'styled-components';
import { variables } from '@trezor/components';
import { variables, PassphraseTypeCard } from '@trezor/components';
import { useSelector, useActions } from '@suite-hooks';
import * as modalActions from '@suite-actions/modalActions';
import * as discoveryActions from '@wallet-actions/discoveryActions';
import * as deviceUtils from '@suite-utils/device';
import { Translation, Modal } from '@suite-components';
import PassphraseTypeCard from './components/PassphraseTypeCard';
import type { TrezorDevice } from '@suite-types';

const Wrapper = styled.div<{ authConfirmation?: boolean }>`
display: flex;
flex-direction: column;
align-items: center;
/* width: ${props => (props.authConfirmation ? 'auto' : '660px')}; */
@media screen and (max-width: ${variables.SCREEN_SIZE.MD}) {
width: 100%;
Expand Down
1 change: 1 addition & 0 deletions packages/suite/src/components/suite/modals/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { Pin } from './Pin';
export { PinInvalid } from './PinInvalid';
export { PinMismatch } from './PinMismatch';
// todo: sharing with connect-popup
export { Passphrase } from './Passphrase';
export { PassphraseSource } from './PassphraseSource';
export { PassphraseOnDevice } from './PassphraseOnDevice';
Expand Down

0 comments on commit d00af10

Please sign in to comment.