Skip to content

Commit

Permalink
Redesign passphrase UX
Browse files Browse the repository at this point in the history
  • Loading branch information
mvaivre committed Jan 26, 2025
1 parent c6c8485 commit 7ec3475
Show file tree
Hide file tree
Showing 14 changed files with 191 additions and 158 deletions.
4 changes: 3 additions & 1 deletion apps/desktop-wallet/locales/en-US/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -525,5 +525,7 @@
"Sign and Send Unsigned Transaction": "Sign and Send Unsigned Transaction",
"Sign and Send": "Sign and Send",
"Unlock a wallet to connect to the dApp.": "Unlock a wallet to connect to the dApp.",
"Activity": "Activity"
"Activity": "Activity",
"Passphrase warning": "Passphrase warning",
"Don't use passphrase": "Don't use passphrase"
}
7 changes: 5 additions & 2 deletions apps/desktop-wallet/src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,10 @@ export default styled(Button)`
faded: colord(theme.global.accent).darken(0.04).toRgbString()
}[variant],
secondary: {
default: colord(theme.bg.primary).lighten(0.04).toRgbString(),
default:
theme.name === 'light'
? colord(theme.bg.primary).lighten(0.5).toRgbString()
: colord(theme.bg.primary).darken(0.7).toRgbString(),
contrast: colord(theme.bg.background2).lighten(0.04).toRgbString(),
valid: colord(theme.global.valid).darken(0.04).toRgbString(),
alert: colord(theme.global.alert).alpha(0.2).toRgbString(),
Expand Down Expand Up @@ -236,7 +239,7 @@ export default styled(Button)`
font-size: ${({ tall }) => (tall ? 14 : 13)}px;
font-family: inherit;
margin: ${({ circle }) => (circle ? '0' : '10px 0')};
padding: ${({ circle, Icon }) => (circle ? 'var(--spacing-2)' : Icon ? '0 28px 0 14px' : '0 14px')};
padding: ${({ circle, Icon }) => (circle ? 'var(--spacing-2)' : '0 14px')};
min-width: ${({ circle, tiny }) => (tiny ? '28px' : circle ? '34px' : '60px')};
text-align: center;
cursor: ${({ disablePointer }) => !disablePointer && 'pointer'};
Expand Down
123 changes: 0 additions & 123 deletions apps/desktop-wallet/src/components/Inputs/WalletPassphrase.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const LabeledWorthOverviewStyled = styled.div`
flex-direction: column;
align-items: center;
position: relative;
margin: var(--spacing-6);
margin: var(--spacing-4);
gap: var(--spacing-2);
`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,8 @@ const FloatingPanelStyled = styled(motion.div)<MainPanelProps>`
z-index: 1;
@media ${deviceBreakPoints.mobile} {
box-shadow: none;
max-width: initial;
}
@media ${deviceBreakPoints.short} {
box-shadow: none;
}
`

export const PanelContentContainer = styled.div`
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop-wallet/src/components/TabBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const TabBarStyled = styled.div`

const TabsContainer = styled.div`
display: flex;
background-color: ${({ theme }) => theme.bg.tertiary};
background-color: ${({ theme }) => theme.bg.secondary};
gap: 10px;
padding: 4px;
border-radius: 100px;
Expand Down
10 changes: 8 additions & 2 deletions apps/desktop-wallet/src/features/modals/modalTypes.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { AddressHash, WalletConnectSessionProposalModalProps } from '@alephium/shared'

import { BuyModalProps } from '@/features/buy/BuyModal'
import { WalletPassphraseDisclaimerModalProps } from '@/features/passphrase/WalletPassphraseDisclaimerModal'
import { CallContractSendModalProps } from '@/features/send/sendModals/callContract/CallContractSendModal'
import { DeployContractSendModalProps } from '@/features/send/sendModals/deployContract/DeployContractSendModal'
import { ConfirmLockTimeModalProps } from '@/features/send/sendModals/transfer/ConfirmLockTimeModal'
import { TransferSendModalProps } from '@/features/send/sendModals/transfer/activityendModal'
import { TransferSendModalProps } from '@/features/send/sendModals/transfer/TransferSendModal'
import { WalletUnlockModalProps } from '@/features/switch-wallet/WalletUnlockModal'
import { TransactionDetailsModalProps } from '@/features/transactionsDisplay/transactionDetailsModal/TransactionDetailsModal'
import { SignMessageModalProps } from '@/features/walletConnect/SignMessageModal'
Expand Down Expand Up @@ -50,7 +51,8 @@ const ModalNames = {
AddressSweepModal: 'AddressSweepModal',
WalletRemovalModal: 'WalletRemovalModal',
DeleteAddressesModal: 'DeleteAddressesModal',
BuyModal: 'BuyModal'
BuyModal: 'BuyModal',
WalletPassphraseDisclaimerModal: 'WalletPassphraseDisclaimerModal'
} as const

export type ModalName = keyof typeof ModalNames
Expand Down Expand Up @@ -173,6 +175,10 @@ export type OpenModalParams =
name: typeof ModalNames.BuyModal
props: BuyModalProps
}
| {
name: typeof ModalNames.WalletPassphraseDisclaimerModal
props: WalletPassphraseDisclaimerModalProps
}

export type ModalInstance = {
id: number
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { t } from 'i18next'
import { memo, useState } from 'react'
import { Trans } from 'react-i18next'
import styled from 'styled-components'

import ActionLink from '@/components/ActionLink'
import FooterButton from '@/components/Buttons/FooterButton'
import InfoBox from '@/components/InfoBox'
import { closeModal } from '@/features/modals/modalActions'
import { ModalBaseProp } from '@/features/modals/modalTypes'
import { useAppDispatch } from '@/hooks/redux'
import CenteredModal from '@/modals/CenteredModal'
import { links } from '@/utils/links'
import { openInWebBrowser } from '@/utils/misc'

export interface WalletPassphraseDisclaimerModalProps {
onConsentChange: (consent: boolean) => void
}

const WalletPassphraseDisclaimerModal = memo(
({ id, onConsentChange }: WalletPassphraseDisclaimerModalProps & ModalBaseProp) => {
const dispatch = useAppDispatch()
const [isConsentActive, setIsConsentActive] = useState(false)

const handleClose = () => {
onConsentChange(isConsentActive)
dispatch(closeModal({ id }))
}

return (
<CenteredModal id={id} title={t('Passphrase warning')} dynamicContent>
<InfoBox importance="alert">
<p>
<Trans t={t} i18nKey="passphraseWarningMessage">
<WarningEmphasis>This is an advanced feature!</WarningEmphasis>
<br />
Use it only if you know what you are doing.
<br />
Please, read our <ActionLink onClick={() => openInWebBrowser(links.passphrase)}>documentation</ActionLink>
to learn about it.
</Trans>
</p>
</InfoBox>
<ConsentCheckbox>
<input
type="checkbox"
id="passphrase-consent"
checked={isConsentActive}
onChange={() => setIsConsentActive(!isConsentActive)}
/>
<label htmlFor="passphrase-consent">{t('I have read and understood the documentation')}</label>
</ConsentCheckbox>

<FooterButton disabled={!isConsentActive} onClick={handleClose} role="primary" tall>
{t('Continue')}
</FooterButton>
</CenteredModal>
)
}
)

export default WalletPassphraseDisclaimerModal

const WarningEmphasis = styled.strong`
color: ${({ theme }) => theme.global.alert};
`

const CenteredContent = styled.div`

Check warning on line 68 in apps/desktop-wallet/src/features/passphrase/WalletPassphraseDisclaimerModal.tsx

View workflow job for this annotation

GitHub Actions / static-analysis

'CenteredContent' is assigned a value but never used
display: flex;
flex-direction: column;
justify-content: center;
`

const ConsentCheckbox = styled.div`
display: flex;
align-items: center;
justify-content: center;
gap: 5px;
margin-bottom: 16px;
text-align: left;
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'

import Input from '@/components/Inputs/Input'

interface WalletPassphraseFormProps {
onPassphraseConfirmed: (passphrase: string) => void
className?: string
}

const WalletPassphraseForm = ({ onPassphraseConfirmed, className }: WalletPassphraseFormProps) => {
const { t } = useTranslation()
const [value, setValue] = useState('')
const [confirmValue, setConfirmValue] = useState('')

const passphraseIsNotUsed = !value && !confirmValue
const showConfirmError = confirmValue.length >= value.length && value !== confirmValue

useEffect(() => {
const isPassphraseConfirmed = value === confirmValue || passphraseIsNotUsed
onPassphraseConfirmed(isPassphraseConfirmed ? confirmValue : '')
}, [onPassphraseConfirmed, confirmValue, value, passphraseIsNotUsed])

useEffect(() => {
if (!value && !!confirmValue) setConfirmValue('')
}, [confirmValue, value])

return (
<Container className={className}>
<Input
id="optional-passphrase"
value={value}
label={t('Optional passphrase')}
type="password"
onChange={(e) => setValue(e.target.value)}
heightSize="big"
/>
<Input
id="optional-passphrase-confirm"
value={confirmValue}
label={t('Confirm passphrase')}
type="password"
onChange={(e) => setConfirmValue(e.target.value)}
error={showConfirmError && t("Passphrases don't match")}
heightSize="big"
/>
</Container>
)
}

export default WalletPassphraseForm

const Container = styled.div`
width: 100%;
display: flex;
flex-direction: column;
margin-top: 10px;
padding-top: 10px;
border-top: 1px solid ${({ theme }) => theme.border.primary};
`
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router-dom'
import styled from 'styled-components'

import WalletPassphrase from '@/components/Inputs/WalletPassphrase'
import WalletPassphrase from '@/features/passphrase/WalletPassphraseForm'
import PasswordConfirmation from '@/components/PasswordConfirmation'
import { closeModal } from '@/features/modals/modalActions'
import { ModalBaseProp } from '@/features/modals/modalTypes'
Expand Down
10 changes: 5 additions & 5 deletions apps/desktop-wallet/src/features/theme/themes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export const lightTheme: DefaultTheme = {
name: 'light',
bg: {
primary: 'rgba(0, 0, 0, 0.04)',
secondary: 'rgba(0, 0, 0, 0.03)',
tertiary: 'rgba(0, 0, 0, 0.02)',
secondary: 'rgba(0, 0, 0, 0.02)',
tertiary: 'rgba(0, 0, 0, 0.01)',
contrast: '#000',
background1: '#fff',
background2: '#fafafa',
Expand Down Expand Up @@ -45,9 +45,9 @@ export const lightTheme: DefaultTheme = {
export const darkTheme: DefaultTheme = {
name: 'dark',
bg: {
primary: 'rgba(255, 255, 255, 0.04)',
secondary: 'rgba(255, 255, 255, 0.03)',
tertiary: 'rgba(255, 255, 255, 0.02)',
primary: 'rgba(255, 255, 255, 0.03)',
secondary: 'rgba(255, 255, 255, 0.02)',
tertiary: 'rgba(255, 255, 255, 0.01)',
contrast: 'rgba(255, 255, 255, 1)',
background1: '#121214',
background2: '#0d0d0f',
Expand Down
Loading

0 comments on commit 7ec3475

Please sign in to comment.