Skip to content

Commit

Permalink
Merge branch 'develop' into feat-402
Browse files Browse the repository at this point in the history
  • Loading branch information
devchenyan authored Jul 7, 2024
2 parents 306b7f2 + fe2082c commit abe1bd4
Show file tree
Hide file tree
Showing 31 changed files with 502 additions and 99 deletions.
2 changes: 1 addition & 1 deletion packages/neuron-ui/src/components/CellManagement/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ export const usePassword = () => {
}

export const useHardWallet = ({ wallet, t }: { wallet: State.WalletIdentity; t: TFunction }) => {
const isWin32 = useMemo(() => {
const isWin32 = useMemo<boolean>(() => {
return getPlatform() === 'win32'
}, [])
const [error, setError] = useState<ErrorCode | string | undefined>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const useRepeatPassword = ({
password: string
t: TFunction
encryptedPassword?: string
onCancel: () => void
onCancel: (success: boolean) => void
}) => {
const dispatch = useDispatch()
const [errMsg, setErrMsg] = useState('')
Expand All @@ -89,7 +89,7 @@ export const useRepeatPassword = ({
updateLockWindowInfo(
encryptedPassword ? { password: updatedRepeatPassword } : { password: updatedRepeatPassword, locked: true }
)(dispatch)
onCancel()
onCancel(true)
}
} else {
setErrMsg('')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const LockWindowDialog = ({
encryptedPassword,
}: {
show: boolean
onCancel: () => void
onCancel: (success?: boolean) => void
encryptedPassword?: string
}) => {
const [t] = useTranslation()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@import '../../styles/mixin.scss';

.container {
width: 680px;

.content {
max-width: 60%;
text-align: center;
margin: 0 auto;
font-size: 14px;
line-height: 24px;
color: var(--main-text-color);

button {
border: none;
background: none;
color: var(--primary-color);
text-decoration: underline;
text-underline-offset: 4px;
cursor: pointer;
}
}
}
38 changes: 38 additions & 0 deletions packages/neuron-ui/src/components/ImportFailureDialog/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import Dialog from 'widgets/Dialog'
import { openExternal } from 'services/remote'
import styles from './importFailureDialog.module.scss'

const ImportFailureDialog = ({ show, onClose }: { show: boolean; onClose: () => void }) => {
const [t] = useTranslation()

const onBtnClick = useCallback(() => {
openExternal(
'https://github.com/nervosnetwork/ckb-cli/wiki/Import-ckb-cli-keystore-from%26to-Neuron-wallet#ckb-cli-and-neuron-use-the-keystore-in-different-way'
)
}, [])

return (
<Dialog
show={show}
title={t('import-keystore.import-failure')}
onCancel={onClose}
onConfirm={onClose}
showCancel={false}
>
<div className={styles.container}>
<p className={styles.content}>
{t('import-keystore.import-failure-msg')}
<button type="button" onClick={onBtnClick}>
{t('navbar.learn-more')}
</button>
</p>
</div>
</Dialog>
)
}

ImportFailureDialog.displayName = 'ImportFailureDialog'

export default ImportFailureDialog
26 changes: 25 additions & 1 deletion packages/neuron-ui/src/components/ImportKeystore/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import ReplaceDuplicateWalletDialog, { useReplaceDuplicateWallet } from 'compone
import { FinishCreateLoading, CreateFirstWalletNav } from 'components/WalletWizard'
import TextField from 'widgets/TextField'
import { importedWalletDialogShown } from 'services/localCache'
import ImportFailureDialog from '../ImportFailureDialog'
import styles from './importKeystore.module.scss'

const { MAX_WALLET_NAME_LENGTH, MAX_PASSWORD_LENGTH } = CONSTANTS
Expand Down Expand Up @@ -49,6 +50,7 @@ const ImportKeystore = () => {
const navigate = useNavigate()
const [fields, setFields] = useState(defaultFields)
const [openingFile, setOpeningFile] = useState(false)
const [isImportFailureDialogShow, setIsImportFailureDialogShow] = useState(false)
const { onImportingExitingWalletError, dialogProps } = useReplaceDuplicateWallet()
const goBack = useGoBack()

Expand Down Expand Up @@ -122,6 +124,11 @@ const ImportKeystore = () => {
return
}

if (res.status === ErrorCode.UnsupportedCkbCliKeystore) {
setIsImportFailureDialogShow(true)
return
}

if (res.message) {
const msg = typeof res.message === 'string' ? res.message : res.message.content || ''
if (msg) {
Expand All @@ -140,7 +147,18 @@ const ImportKeystore = () => {
closeDialog()
})
},
[fields.name, fields.password, fields.path, navigate, openDialog, closeDialog, disabled, setFields, t]
[
fields.name,
fields.password,
fields.path,
navigate,
openDialog,
closeDialog,
disabled,
setFields,
t,
setIsImportFailureDialogShow,
]
)

const handleChange = useCallback(
Expand Down Expand Up @@ -199,6 +217,10 @@ const ImportKeystore = () => {
[setFields, wallets, t]
)

const onCloseImportFailureDialog = useCallback(() => {
setIsImportFailureDialogShow(false)
}, [setIsImportFailureDialogShow])

return (
<>
<form className={styles.container} onSubmit={handleSubmit}>
Expand Down Expand Up @@ -248,6 +270,8 @@ const ImportKeystore = () => {
</form>

<ReplaceDuplicateWalletDialog {...dialogProps} />

<ImportFailureDialog show={isImportFailureDialogShow} onClose={onCloseImportFailureDialog} />
</>
)
}
Expand Down
6 changes: 2 additions & 4 deletions packages/neuron-ui/src/components/MultisigAddress/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -492,10 +492,8 @@ const MultisigAddress = () => {
confirmProps={{ type: 'cancel', className: styles.confirmBtn }}
>
<img src={AttentionCloseDialog} alt="Synchronization Abort" />
<h4>Synchronization Abort</h4>
<p>
Leaving the current window will cause the multisig synchronization to be aborted, so please confirm to leave.
</p>
<h4>{t('multisig-address.synchronization-abort')}</h4>
<p>{t('multisig-address.synchronization-abort-msg')}</p>
</Dialog>

{sendAction.sendFromMultisig && sendAction.isDialogOpen ? (
Expand Down
70 changes: 61 additions & 9 deletions packages/neuron-ui/src/containers/LockWindow/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable jsx-a11y/media-has-caption */
import React, { useCallback, useEffect, useState } from 'react'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { AppActions, getLockWindowInfo, useDispatch, useState as useGlobalState } from 'states'
import Spinner from 'widgets/Spinner'
import Locked from 'widgets/Icons/Locked.png'
Expand All @@ -8,10 +8,13 @@ import UnLockMp4 from 'widgets/Icons/unlock.mp4'
import SplitPasswordInput from 'widgets/SplitPasswordInput'
import { useTranslation } from 'react-i18next'
import { clsx, isSuccessResponse } from 'utils'
import { isDark, unlockWindow } from 'services/remote'
import { isDark, signMessage, unlockWindow } from 'services/remote'
import { retryUnlockWindow } from 'services/localCache'
import { MILLISECS_PER_HOUR, MILLISECS_PER_MIN, MILLISECS_PER_SEC } from 'utils/getSyncLeftTime'
import { ControllerResponse } from 'services/remote/remoteApiWrapper'
import LockWindowDialog from 'components/GeneralSetting/LockWindowDialog'
import styles from './lockWindow.module.scss'
import VerifyWallet from './verifyWallet'

const passwordLen = 4
const wrongEnterTimes = 3
Expand All @@ -24,12 +27,6 @@ const formatterLockMillisecs = (lockMillisecs: number) => {

const getWaitMillisecs = (retryTimes: number) => {
if (retryTimes % wrongEnterTimes === 0) {
if (retryTimes >= 3 * wrongEnterTimes) {
return 24 * MILLISECS_PER_HOUR
}
if (retryTimes > wrongEnterTimes) {
return 30 * MILLISECS_PER_MIN
}
return 5 * MILLISECS_PER_MIN
}
return undefined
Expand All @@ -41,7 +38,7 @@ const LockWindow = ({ children }: { children: React.ReactNode }) => {
useEffect(() => {
getLockWindowInfo(dispatch)
}, [])
const { app } = useGlobalState()
const { app, wallet } = useGlobalState()
const [password, setPassword] = useState<string[]>(new Array(passwordLen).fill(''))
const [errMsg, setErrMsg] = useState('')
const [retryUnlockInfo, setRetryUnlockInfo] = useState(retryUnlockWindow.get())
Expand Down Expand Up @@ -130,6 +127,25 @@ const LockWindow = ({ children }: { children: React.ReactNode }) => {
}
return () => clearInterval(interval)
}, [retryUnlockInfo])
const splitPasswordInputRef = useRef<{ focus: () => void } | null>(null)
const [isVerifyWalletDialogShow, setIsVerifyWalletDialogShow] = useState(false)
const [isResetPasswordDialogShow, setIsResetPasswordDialogShow] = useState(false)
const onVerifyWallet = useCallback(
async (walletPassword?: string) => {
const res: ControllerResponse = await signMessage({
walletID: wallet?.id ?? '',
message: 'verify wallet for reset lock window password',
password: walletPassword ?? '',
})
if (isSuccessResponse(res)) {
setIsVerifyWalletDialogShow(false)
setIsResetPasswordDialogShow(true)
} else {
throw new Error(typeof res.message === 'string' ? res.message : res.message.content)
}
},
[setIsResetPasswordDialogShow, setIsVerifyWalletDialogShow, wallet]
)
if (!app.lockWindowInfo) {
return (
<div className={styles.loading}>
Expand All @@ -156,11 +172,47 @@ const LockWindow = ({ children }: { children: React.ReactNode }) => {
disabled={retryUnlockInfo.retryTimes % wrongEnterTimes === 0 && !!retryUnlockInfo.lastRetryTime}
values={password}
onChange={onUpdatePassword}
ref={splitPasswordInputRef}
/>
</div>
<div className={styles.notice} data-has-err={!!errMsg}>
{errMsg || t('lock-window.enter-lock-password')}
{wallet.isWatchOnly ? null : (
<button
type="button"
onClick={() => {
setIsVerifyWalletDialogShow(true)
}}
>
{t('lock-window.forget-password')}
</button>
)}
</div>
<VerifyWallet
show={isVerifyWalletDialogShow}
wallet={wallet}
onCancel={() => {
setIsVerifyWalletDialogShow(false)
setTimeout(() => {
// wait for dialog close
splitPasswordInputRef.current?.focus()
}, 10)
}}
onConfirm={onVerifyWallet}
/>
<LockWindowDialog
show={isResetPasswordDialogShow}
onCancel={success => {
setIsResetPasswordDialogShow(false)
if (success) {
setPassword(new Array(passwordLen).fill(''))
}
setTimeout(() => {
// wait for dialog close
splitPasswordInputRef.current?.focus()
}, 10)
}}
/>
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@
&[data-has-err='true'] {
color: var(--error-color);
}

& > button {
border: none;
color: var(--primary-color);
background-color: transparent;
cursor: pointer;
}
}

.passwordContainer {
Expand Down Expand Up @@ -53,3 +60,12 @@
height: 88px;
}
}

.verifyWallet {
min-width: 600px;

.hardwalletErr {
justify-content: center;
margin-top: 12px;
}
}
Loading

1 comment on commit abe1bd4

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Packaging for test is done in 9828556942

Please sign in to comment.