Skip to content

Commit

Permalink
Merge pull request #1051 from Keith-CY/add-dao-view
Browse files Browse the repository at this point in the history
[ᚬadd-nervos-dao] feat(neuron-ui): add nervos dao view
  • Loading branch information
ashchan authored Nov 10, 2019
2 parents 4ca2afa + 544becd commit 2a5529a
Show file tree
Hide file tree
Showing 36 changed files with 991 additions and 105 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"packages": [
"packages/*"
],
"version": "0.24.1",
"version": "0.24.2",
"npmClient": "yarn",
"useWorkspaces": true
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "neuron",
"productName": "Neuron",
"description": "CKB Neuron Wallet",
"version": "0.24.1",
"version": "0.24.2",
"private": true,
"author": {
"name": "Nervos Core Dev",
Expand Down
4 changes: 2 additions & 2 deletions packages/neuron-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "neuron-ui",
"version": "0.24.1",
"version": "0.24.2",
"private": true,
"author": {
"name": "Nervos Core Dev",
Expand Down Expand Up @@ -53,7 +53,7 @@
"qr.js": "0.0.0",
"react": "16.9.0",
"react-dom": "16.9.0",
"react-i18next": "10.12.2",
"react-i18next": "11.0.1",
"react-router-dom": "5.0.1",
"react-scripts": "3.2.0",
"styled-components": "5.0.0-beta.0"
Expand Down
143 changes: 143 additions & 0 deletions packages/neuron-ui/src/components/CustomRows/DAORecordRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import React, { useEffect, useState } from 'react'
import { DefaultButton } from 'office-ui-fabric-react'
import { useTranslation } from 'react-i18next'
import { ckbCore, getBlockByNumber } from 'services/chain'
import calculateAPY from 'utils/calculateAPY'
import { shannonToCKBFormatter, uniformTimeFormatter, localNumberFormatter } from 'utils/formatters'
import calculateClaimEpochNumber from 'utils/calculateClaimEpochNumber'
import { epochParser } from 'utils/parsers'

import * as styles from './daoRecordRow.module.scss'

const DAORecord = ({
daoData,
blockNumber,
blockHash,
outPoint: { txHash, index },
tipBlockNumber,
tipBlockHash,
capacity,
actionLabel,
onClick,
timestamp,
depositOutPoint,
epoch,
}: State.NervosDAORecord & {
actionLabel: string
onClick: any
tipBlockNumber: string
tipBlockHash: string
epoch: string
}) => {
const [t] = useTranslation()
const [withdrawValue, setWithdrawValue] = useState('')
const [depositEpoch, setDepositEpoch] = useState('')

useEffect(() => {
const withdrawBlockHash = depositOutPoint ? blockHash : tipBlockHash
if (!withdrawBlockHash) {
return
}
const formattedDepositOutPoint = depositOutPoint
? {
txHash: depositOutPoint.txHash,
index: BigInt(depositOutPoint.index),
}
: {
txHash,
index: BigInt(index),
}
;(ckbCore.rpc as any)
.calculateDaoMaximumWithdraw(formattedDepositOutPoint, withdrawBlockHash)
.then((res: string) => {
setWithdrawValue(BigInt(res).toString())
})
.catch((err: Error) => {
console.error(err)
})
}, [txHash, index, tipBlockHash, depositOutPoint, blockHash])

useEffect(() => {
if (!depositOutPoint) {
return
}
const depositBlockNumber = ckbCore.utils.bytesToHex(ckbCore.utils.hexToBytes(daoData).reverse())
getBlockByNumber(BigInt(depositBlockNumber))
.then(b => {
setDepositEpoch(b.header.epoch)
})
.catch((err: Error) => {
console.error(err)
})
}, [daoData, depositOutPoint])

const interest = BigInt(withdrawValue) - BigInt(capacity)

let ready = false
let metaInfo = 'Ready'
if (!depositOutPoint) {
const duration = BigInt(tipBlockNumber) - BigInt(blockNumber)
metaInfo = t('nervos-dao.interest-accumulated', {
blockNumber: localNumberFormatter(duration >= BigInt(0) ? duration : 0),
})
} else {
const depositEpochInfo = epochParser(depositEpoch)
const currentEpochInfo = epochParser(epoch)
const targetEpochNumber = calculateClaimEpochNumber(depositEpochInfo, currentEpochInfo)
if (targetEpochNumber < currentEpochInfo.number + BigInt(1) && targetEpochNumber >= currentEpochInfo.number) {
metaInfo = 'Ready'
ready = true
} else {
const epochs = targetEpochNumber - currentEpochInfo.number - BigInt(1)
metaInfo = t('nervos-dao.blocks-left', {
epochs: localNumberFormatter(epochs),
blocks: localNumberFormatter(currentEpochInfo.length - currentEpochInfo.index),
days: localNumberFormatter(epochs / BigInt(6)),
})
}
}

return (
<div className={styles.daoRecord}>
<div className={styles.primaryInfo}>
<div>{interest >= BigInt(0) ? `${shannonToCKBFormatter(interest.toString()).toString()} CKB` : ''}</div>
<div>{`${shannonToCKBFormatter(capacity)} CKB`}</div>
<div>
<DefaultButton
text={actionLabel}
data-tx-hash={txHash}
data-index={index}
onClick={onClick}
disabled={depositOutPoint && !ready}
styles={{
flexContainer: {
pointerEvents: 'none',
},
textContainer: {
pointerEvents: 'none',
},
label: {
pointerEvents: 'none',
},
}}
/>
</div>
</div>
<div className={styles.secondaryInfo}>
<span>
{`APY: ~${calculateAPY(
interest >= BigInt(0) ? interest.toString() : '0',
capacity,
`${Date.now() - +timestamp}`
)}%`}
</span>
<span>{uniformTimeFormatter(+timestamp)}</span>
<span>{metaInfo}</span>
</div>
</div>
)
}

DAORecord.displayName = 'DAORecord'

export default DAORecord
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.daoRecord {
display: flex;
flex-direction: column;
border: 1px solid #000;
border-radius: 5px;
margin: 10px 0;
padding: 5px 15px;

.primaryInfo,
.secondaryInfo {
display: flex;
justify-content: space-between;

&>div,
&>span {
flex: 1;
text-align: center;

&:first-child {
text-align: left;
}

&:last-child {
text-align: right;
}
}

}

.secondaryInfo {
font-size: 12px;
color: #666;
}

}
86 changes: 86 additions & 0 deletions packages/neuron-ui/src/components/NervosDAO/DepositDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React from 'react'
import {
Stack,
Dialog,
TextField,
Slider,
Text,
DefaultButton,
PrimaryButton,
DialogType,
DialogFooter,
Spinner,
SpinnerSize,
} from 'office-ui-fabric-react'
import { useTranslation } from 'react-i18next'
import { SHANNON_CKB_RATIO } from 'utils/const'

const DepositDialog = ({
show,
value,
fee,
balance,
onChange,
onSlide,
onSubmit,
onDismiss,
isDepositing,
errorMessage,
}: any) => {
const [t] = useTranslation()
const maxValue = +(BigInt(balance) / BigInt(SHANNON_CKB_RATIO)).toString()

if (!show) {
return null
}

return (
<Dialog
hidden={false}
onDismiss={onDismiss}
dialogContentProps={{
type: DialogType.close,
title: t('nervos-dao.deposit-to-nervos-dao'),
}}
modalProps={{
isBlocking: false,
styles: { main: { maxWidth: '500px!important' } },
}}
>
{isDepositing ? (
<Spinner size={SpinnerSize.large} />
) : (
<>
<TextField label={t('nervos-dao.deposit')} value={value} onChange={onChange} suffix="CKB" />
<Slider value={value} min={0} max={maxValue} step={1} showValue={false} onChange={onSlide} />
<Text as="p" variant="small" block>
{`${t('nervos-dao.fee')}: ${fee}`}
</Text>
<Text as="span" variant="tiny" block styles={{ root: { color: 'red' } }}>
{errorMessage}
</Text>
<Stack>
<Text as="h2" variant="large">
{t('nervos-dao.notice')}
</Text>
{t('nervos-dao.deposit-terms')
.split('\n')
.map(term => (
<Text as="p" key={term}>
{term}
</Text>
))}
</Stack>
<DialogFooter>
<DefaultButton onClick={onDismiss} text={t('nervos-dao.cancel')} />
<PrimaryButton onClick={onSubmit} text={t('nervos-dao.proceed')} disabled={errorMessage} />
</DialogFooter>
</>
)}
</Dialog>
)
}

DepositDialog.displayName = 'DepositDialog'

export default DepositDialog
Loading

0 comments on commit 2a5529a

Please sign in to comment.