Skip to content

Commit

Permalink
fix: some ui issue (#2952)
Browse files Browse the repository at this point in the history
* fix: some ui issue

* fix: some ui issue

* feat: validateCapacity

* fix: syncIcon

* fix: comments

* fix: releaseDate

* fix: Issue on UI withdrawing from NervosDao

* fix: releaseDate

* fix

---------

Co-authored-by: Chen Yu <[email protected]>
  • Loading branch information
devchenyan and Keith-CY authored Dec 15, 2023
1 parent f598a0f commit c2ab3ac
Show file tree
Hide file tree
Showing 19 changed files with 139 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
margin-left: 4px;

path {
fill: #ffffff;
fill: var(--main-text-color);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ $action-button-width: 11.25rem;
background: var(--table-head-background-color);
color: var(--dialog-secondary-text-color);

h1 {
&:first-child {
display: none;
}
}

ul {
list-style-type: disc;
padding-left: 30px;
Expand Down
18 changes: 14 additions & 4 deletions packages/neuron-ui/src/components/GeneralSetting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ interface UpdateDownloadStatusProps {
onCancel: () => void
progress: number
newVersion: string
releaseDate: string
releaseNotes: string
progressInfo: null | State.ProgressInfo
}
Expand All @@ -28,13 +27,13 @@ const UpdateDownloadStatus = ({
onCancel,
progress = 0,
newVersion = '',
releaseDate = '',
releaseNotes = '',
progressInfo,
}: UpdateDownloadStatusProps) => {
const [t] = useTranslation()
const available = newVersion !== '' && progress < 0
const downloaded = progress >= 1
const [publishedAt, setPublishedAt] = useState('')

const handleConfirm = useCallback(
(e: React.FormEvent) => {
Expand All @@ -51,6 +50,18 @@ const UpdateDownloadStatus = ({
[downloadUpdate, installUpdate]
)

useEffect(() => {
if (available) {
fetch(`https://api.github.com/repos/nervosnetwork/neuron/releases/tags/v${newVersion}`)
.then(async res => {
// eslint-disable-next-line camelcase
const { published_at } = await res.json()
setPublishedAt(published_at)
})
.catch(() => {})
}
}, [available, setPublishedAt])

if (available) {
const releaseNotesHtml = () => {
return { __html: releaseNotes }
Expand All @@ -72,7 +83,7 @@ const UpdateDownloadStatus = ({
>
<div className={styles.install}>
<p className={styles.title}>
{newVersion} ({uniformTimeFormatter(new Date(releaseDate)).split(' ')[0]})
{newVersion} {publishedAt ? `(${uniformTimeFormatter(new Date(publishedAt)).split(' ')[0]})` : null}
</p>
<div className={styles.releaseNotesStyle}>
<div dangerouslySetInnerHTML={releaseNotesHtml()} />
Expand Down Expand Up @@ -217,7 +228,6 @@ const GeneralSetting = ({ updater }: GeneralSettingProps) => {
progress={updater.downloadProgress}
progressInfo={updater.progressInfo}
newVersion={updater.version}
releaseDate={updater.releaseDate}
releaseNotes={updater.releaseNotes}
/>

Expand Down
7 changes: 7 additions & 0 deletions packages/neuron-ui/src/components/History/history.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ body {
font-weight: 500;
padding-right: 10px;
}
.searchBoxSuffix {
font-family: inherit;
display: flex;
align-items: center;
padding-left: 10px;
cursor: pointer;
}
.exportButton {
color: var(--main-text-color);
border-color: var(--history-button-border);
Expand Down
10 changes: 9 additions & 1 deletion packages/neuron-ui/src/components/History/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import SUDTAvatar from 'widgets/SUDTAvatar'
import Button from 'widgets/Button'
import Table, { TableProps } from 'widgets/Table'
import TextField from 'widgets/TextField'
import { Download, Search, ArrowNext } from 'widgets/Icons/icon'
import { Download, Search, ArrowNext, Clean } from 'widgets/Icons/icon'

import PageContainer from 'components/PageContainer'
import TransactionStatusWrap from 'components/TransactionStatusWrap'
Expand Down Expand Up @@ -47,6 +47,7 @@ const History = () => {

const { keywords, onKeywordsChange } = useSearch(search, id, dispatch)
const onSearch = useCallback(() => navigate(`${RoutePath.History}?keywords=${keywords}`), [navigate, keywords])
const onClean = useCallback(() => onKeywordsChange(undefined, ''), [onKeywordsChange])
const onExport = useCallback(() => {
setIsExporting(true)
const timer = setTimeout(() => {
Expand Down Expand Up @@ -183,6 +184,13 @@ const History = () => {
<Search onClick={onSearch} />
</span>
}
suffix={
keywords ? (
<span className={styles.searchBoxSuffix}>
<Clean onClick={onClean} />
</span>
) : null
}
placeholder={t('history.search.placeholder')}
className={styles.tableHeaderInput}
stack={false}
Expand Down
6 changes: 5 additions & 1 deletion packages/neuron-ui/src/components/NetworkSetting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,11 @@ const NetworkSetting = ({ chain = chainState, settings: { networks = [] } }: Sta
value: network.id,
label: (
<div className={styles.networkLabel}>
<p>{`${network.name} (${network.remote})`}</p>
<p>{`${network.name} (${
network.remote.length > 40
? `${network.remote.slice(0, 20)}...${network.remote.slice(-20)}`
: network.remote
})`}</p>
<div className={styles.tag}>{t(getNetworkLabelI18nkey(network.chain))}</div>
</div>
),
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-ui/src/components/Send/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ const Send = () => {
!send.generatedTx ||
outputs.some(v => !v.address)

const outputErrors = useOutputErrors(outputs, isMainnet)
const outputErrors = useOutputErrors(outputs, isMainnet, isSendMax)

const isMaxBtnDisabled = (() => {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ export const useSendInfo = ({
},
[setSendInfoList]
)
const outputErrors = useOutputErrors(sendInfoList, isMainnet)
const [isSendMax, setIsSendMax] = useState(false)
const outputErrors = useOutputErrors(sendInfoList, isMainnet, isSendMax)
const totalAmount = useMemo(
() => outputsToTotalAmount(sendInfoList.filter((v, idx) => !!v.amount && !outputErrors[idx].amountError)),
[sendInfoList, outputErrors]
Expand Down Expand Up @@ -172,7 +173,6 @@ export const useSendInfo = ({
}
}, 300)
}, [sendInfoList, setErrorMessage, multisigConfig, dispatch, t, isMainnet, outputErrors])
const [isSendMax, setIsSendMax] = useState(false)
const onSendMaxClick = useCallback(() => {
if (!isSendMax) {
setIsSendMax(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@
color: #999;
font-size: 12px;
margin-left: 4px;
white-space: nowrap;
}
}
1 change: 1 addition & 0 deletions packages/neuron-ui/src/containers/Main/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ export const useSubscription = ({
})
CONNECTING_DEADLINE = Date.now() + CONNECTING_BUFFER
currentNetworkIDCache.save(currentNetworkID)
updateAddressListAndBalance(walletID)(dispatch)
})
const connectionStatusSubscription = ConnectionStatusSubject.subscribe(status => {
if (isCurrentUrl(status.url)) {
Expand Down
12 changes: 12 additions & 0 deletions packages/neuron-ui/src/exceptions/amount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,15 @@ export class AmountNegativeException extends RangeError {
this.i18n.fieldValue = value
}
}

export class CapacityTooSmallException extends Error {
public code = ErrorCode.CapacityTooSmall
public i18n: {
bytes: string
}

constructor(bytes: string) {
super(`${I18N_PATH}${ErrorCode.CapacityTooSmall}`)
this.i18n = { bytes }
}
}
4 changes: 2 additions & 2 deletions packages/neuron-ui/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@
"cancel": "Cancel",
"proceed": "Proceed",
"compensation": "Compensation",
"notice-wait-time": "Notice: You are initiating withdrawn and the final withdrawn will need to wait for {{epochs}} epochs {{blocks}} blocks (about {{days} days).",
"notice-wait-time": "Notice: You are initiating withdrawn and the final withdrawn will need to wait for {{epochs}} epochs {{blocks}} blocks (about {{days}} days).",
"deposit-dialog-title": "Deposit",
"deposit-terms": "Nervos DAO needs 102 CKBytes for deposit cell storage, which is not compensation-bearing. <br />Please visit the <0>Nervos DAO RFC</0> for more information about Nervos DAO",
"minimal-fee-required": "The minimum deposit capacity is {{minimal}} CKBytes",
Expand Down Expand Up @@ -728,7 +728,7 @@
"nervos-dao-detail": {
"tx-detail": "Transaction Detail",
"deposited": "Deposited",
"withdrawn": "Withdrawn",
"withdrawn": "Withdraw",
"unlocked": "Unlocked",
"basic-information": "Basic Information",
"transaction-hash": "Transaction Hash",
Expand Down
20 changes: 20 additions & 0 deletions packages/neuron-ui/src/tests/validators/capacity/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ErrorCode } from 'utils/enums'

export default {
'Should throw an error when address is not a string': {
params: {
address: 'ckb1qrgqep8saj8agswr30pls73hra28ry8jlnlc3ejzh3dl2ju7xxpjxqgqqy28n5m69va267nv0wvsudngtxz8t9jwss3xkhpk',
amount: '62',
unit: 'ckb',
},
exception: ErrorCode.CapacityTooSmall,
},
'Should throw an error when address is required but not provided': {
params: {
address: 'ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq2n0egquval9ljqm2ga6t9509kwcex5ejq3hy6dk',
amount: '62',
unit: 'ckb',
},
exception: null,
},
}
25 changes: 25 additions & 0 deletions packages/neuron-ui/src/tests/validators/capacity/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { describe, test, expect } from '@jest/globals'
import { isErrorWithI18n } from 'exceptions'
import { validateCapacity } from 'utils/validators'
import fixtures from './fixtures'

const fixtureTable: Fixture.Validator<typeof validateCapacity>[] = Object.entries(fixtures).map(
([title, { params, exception }]) => [title, [params], exception]
)

describe(`Test capacity validator`, () => {
test.each(fixtureTable)(`%s`, (_title, [params], exception) => {
if (exception) {
expect.assertions(2)
try {
validateCapacity(params)
} catch (err) {
expect(isErrorWithI18n(err)).toBeTruthy()
expect((err as { code: number }).code).toBe(exception)
}
} else {
expect.assertions(1)
expect(validateCapacity(params)).toBeTruthy()
}
})
})
11 changes: 8 additions & 3 deletions packages/neuron-ui/src/utils/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
validateAmount,
validateAddress,
validateAmountRange,
validateCapacity,
} from 'utils/validators'
import { MenuItemConstructorOptions, shell } from 'electron'
import { ErrorWithI18n, isErrorWithI18n } from 'exceptions'
Expand Down Expand Up @@ -499,18 +500,22 @@ export const useForceUpdate = <T extends (...args: any[]) => void>(cb: T) => {
}

export const useOutputErrors = (
outputs: Partial<Record<'address' | 'amount' | 'date', string>>[],
isMainnet: boolean
outputs: Partial<Record<'address' | 'amount' | 'date' | 'unit', string>>[],
isMainnet: boolean,
isSendMax?: boolean
) => {
return useMemo(
() =>
outputs.map(({ address, amount, date }) => {
outputs.map(({ address, amount, date, unit }, index) => {
let amountError: ErrorWithI18n | undefined
if (amount !== undefined) {
try {
const extraSize = date ? CONSTANTS.SINCE_FIELD_SIZE : 0
validateAmount(amount)
validateAmountRange(amount, extraSize)
if (!(isSendMax && index === outputs.length - 1)) {
validateCapacity({ address, amount, unit })
}
} catch (err) {
if (isErrorWithI18n(err)) {
amountError = err
Expand Down
19 changes: 19 additions & 0 deletions packages/neuron-ui/src/utils/validators/capacity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { CKBToShannonFormatter } from 'utils/formatters'
import { CapacityTooSmallException } from 'exceptions'
import { bytes as byteUtils } from '@ckb-lumos/codec'
import { ckbCore } from 'services/chain'

export const validateCapacity = (item: State.Output) => {
const { amount, unit, address } = item
const capacity = CKBToShannonFormatter(amount, unit)
const script = ckbCore.utils.addressToScript(address as string)
const size = 1 + byteUtils.concat(script.args, script.codeHash).byteLength
const outputSize = 8 + byteUtils.bytify('0x').byteLength + size

if (BigInt(capacity) < BigInt(outputSize) * BigInt(10 ** 8)) {
throw new CapacityTooSmallException(outputSize.toString())
}

return true
}
export default validateCapacity
1 change: 1 addition & 0 deletions packages/neuron-ui/src/utils/validators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export * from './tokenId'
export * from './tokenName'
export * from './symbol'
export * from './decimal'
export * from './capacity'
3 changes: 3 additions & 0 deletions packages/neuron-ui/src/widgets/Icons/Clean.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions packages/neuron-ui/src/widgets/Icons/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { ReactComponent as AddressbookSvg } from './Addressbook.svg'
import { ReactComponent as AddSvg } from './Add.svg'
import { ReactComponent as AddSimpleSvg } from './AddSimple.svg'
import { ReactComponent as SwitchSvg } from './Switch.svg'
import { ReactComponent as CleanSvg } from './Clean.svg'
import { ReactComponent as CellManageSvg } from './CellManage.svg'
import { ReactComponent as LockSvg } from './Lock.svg'
import { ReactComponent as LockCellSvg } from './LockCell.svg'
Expand Down Expand Up @@ -113,6 +114,7 @@ export const Addressbook = WrapSvg(AddressbookSvg, styles.withTheme)
export const Add = WrapSvg(AddSvg)
export const Switch = WrapSvg(SwitchSvg)
export const AddSimple = WrapSvg(AddSimpleSvg)
export const Clean = WrapSvg(CleanSvg)
export const CellManage = WrapSvg(CellManageSvg, styles.withTheme)
export const Lock = WrapSvg(LockSvg, styles.withTheme)
export const LockCell = WrapSvg(LockCellSvg)
Expand Down

2 comments on commit c2ab3ac

@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 7222884975

@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 7222883739

Please sign in to comment.