Skip to content

Commit

Permalink
feat: add since
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith-CY committed Nov 18, 2022
1 parent 7f9b325 commit 4d45e6d
Show file tree
Hide file tree
Showing 15 changed files with 186 additions and 19 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"env-cmd": "10.1.0",
"history": "5.0.0",
"i18next": "20.3.5",
"jsbi": "3.2.5",
"query-string": "7.0.1",
"react": "17.0.2",
"react-dom": "17.0.2",
Expand Down
56 changes: 55 additions & 1 deletion src/__tests__/utils/util.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { toCamelcase, shannonToCkb, shannonToCkbDecimal } from '../../utils/util'
import { toCamelcase, shannonToCkb, shannonToCkbDecimal, parseSince } from '../../utils/util'

describe('Number methods tests', () => {
it('pasre simple object to camelcase', async () => {
Expand Down Expand Up @@ -64,4 +64,58 @@ describe('Number methods tests', () => {
expect(shannonToCkbDecimal(-153088822106905372, 2)).toBe(-1530888221.06)
expect(shannonToCkbDecimal(153088822186905372)).toBe(1530888221)
})

describe('parse since', () => {
it('should be absolute epoch', () => {
expect(parseSince('0x20048e022c001984')).toMatchObject({
base: 'absolute',
type: 'epoch',
value: '6532.48',
})
})

it('should be absolute block', () => {
expect(parseSince('0x3039')).toMatchObject({
base: 'absolute',
type: 'block',
value: '12346',
})
})

it('should be absolute timestamp', () => {
expect(parseSince('0x40000000617f7363')).toMatchObject({
base: 'absolute',
type: 'timestamp',
value: '1635742563',
})
})

it('should be relative epoch', () => {
expect(parseSince('0xa0048e022c001984')).toMatchObject({
base: 'relative',
type: 'epoch',
value: '6532.48',
})
})

it('should be relative block', () => {
expect(parseSince('0x8000000000000064')).toMatchObject({
base: 'relative',
type: 'block',
value: '101',
})
})

it('should be relative timestamp', () => {
expect(parseSince('0xc000000000127500')).toMatchObject({
base: 'relative',
type: 'timestamp',
value: '1209600',
})
})

it('should be null', () => {
expect(parseSince('0x0000000000000000')).toBe(null)
})
})
})
3 changes: 3 additions & 0 deletions src/assets/clock.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: 1 addition & 1 deletion src/components/Table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const TableMinerContentItem = ({
smallWidth?: boolean
fontSize?: string
}) => {
let addressText = adaptPCEllipsis(content, smallWidth ? 2 : 14, 60)
let addressText = adaptPCEllipsis(content, smallWidth ? 2 : 10, 60)
if (window.innerWidth <= 1320) {
addressText = adaptPCEllipsis(content, smallWidth ? 2 : 10, 60)
}
Expand Down
12 changes: 6 additions & 6 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -295,14 +295,14 @@
"size_in_block": "{{bytes}} bytes in block",
"since": {
"relative": {
"epoch": "{{since}} epochs since committed",
"block": "{{since}} blocks since committed",
"time": "{{since}} since committed"
"epoch": "After {{since}} epochs since committed",
"block": "After {{since}} blocks since committed",
"timestamp": "After {{since}} since committed"
},
"absolute": {
"epoch": "Epoch {{since}}",
"block": "block {{since}}",
"time": "{{since}}"
"epoch": "After epoch {{since}}",
"block": "After block {{since}}",
"timestamp": "After {{since}}"
}
}
},
Expand Down
8 changes: 4 additions & 4 deletions src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,12 @@
"relative": {
"epoch": "自 committed 之后 {{since}} Epochs",
"block": "自 committed 之后 {{since}} 个区块",
"time": "自 committed 之后 {{since}}"
"timestamp": "自 committed 之后 {{since}}"
},
"absolute": {
"epoch": "Epoch {{since}}",
"block": "区块 {{since}}",
"time": "{{since}}"
"epoch": "Epoch {{since}} 之后",
"block": "区块 {{since}} 之后",
"timestamp": "{{since}} 之后"
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/pages/BlockDetail/BlockComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export const BlockOverview = () => {
},
{
title: i18n.t('block.size'),
content: `${block.size} Bytes`,
content: `${block.size.toLocaleString('en')} Bytes`,
},
{
title: i18n.t('block.epoch_start_number'),
Expand Down
1 change: 1 addition & 0 deletions src/pages/Home/TableCard/styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ export const TransactionCardPanel = styled.div`
.transaction__card__block__height {
color: #000000;
margin-right: 5px;
white-space: nowrap;
}
.transaction__card__block__height__prefix {
Expand Down
30 changes: 29 additions & 1 deletion src/pages/Transaction/TransactionCell/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { Tooltip } from 'antd'
import { CellType } from '../../../constants/common'
import i18n from '../../../utils/i18n'
import { localeNumberString, parseUDTAmount } from '../../../utils/number'
import { parseSimpleDate } from '../../../utils/date'
import { isMobile } from '../../../utils/screen'
import { adaptPCEllipsis, adaptMobileEllipsis, sliceNftName } from '../../../utils/string'
import { shannonToCkb, shannonToCkbDecimal } from '../../../utils/util'
import { shannonToCkb, shannonToCkbDecimal, parseSince } from '../../../utils/util'
import {
TransactionCellContentPanel,
TransactionCellDetailPanel,
Expand All @@ -30,12 +31,14 @@ import NFTClassIcon from '../../../assets/m_nft_class.svg'
import NFTTokenIcon from '../../../assets/m_nft.svg'
import CoTACellIcon from '../../../assets/cota_cell.svg'
import CoTARegCellIcon from '../../../assets/cota_reg_cell.svg'
import { ReactComponent as LockTimeIcon } from '../../../assets/clock.svg'
import TransactionCellScript from '../TransactionCellScript'
import SimpleModal from '../../../components/Modal'
import SimpleButton from '../../../components/SimpleButton'
import TransactionReward from '../TransactionReward'
import Cellbase from '../../../components/Transaction/Cellbase'
import { useDeprecatedAddr, useNewAddr } from '../../../utils/hook'
import styles from './styles.module.scss'

const AddressText = ({ address }: { address: string }) => {
const addressText = isMobile() ? adaptMobileEllipsis(address, 5) : adaptPCEllipsis(address, 4, 80)
Expand Down Expand Up @@ -65,6 +68,21 @@ const TransactionCellIndexAddress = ({
}) => {
const deprecatedAddr = useDeprecatedAddr(cell.addressHash)!
const newAddr = useNewAddr(cell.addressHash)
let since
try {
if (cell.since) {
since = parseSince(cell.since.raw)
if (since && since.type === 'timestamp') {
if (since.base === 'relative') {
since.value = `${+since.value / 3600} Hrs`
} else {
since.value = parseSimpleDate(+since.value * 1000)
}
}
}
} catch {
// ignore
}
return (
<TransactionCellAddressPanel>
<div className="transaction__cell_index">
Expand All @@ -84,6 +102,16 @@ const TransactionCellIndexAddress = ({
</span>
)}
{cellType === CellType.Output && <TransactionCellArrow cell={cell} cellType={cellType} />}
{since ? (
<Tooltip
placement="top"
title={i18n.t(`transaction.since.${since.base}.${since.type}`, {
since: since.value,
})}
>
<LockTimeIcon className={styles.locktime} />
</Tooltip>
) : null}
</TransactionCellHashPanel>
</TransactionCellAddressPanel>
)
Expand Down
11 changes: 11 additions & 0 deletions src/pages/Transaction/TransactionCell/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.locktime {
width: 15px;
height: 15px;
margin-left: 2px;
cursor: pointer;
&:hover {
path {
fill: var(--primary-color);
}
}
}
4 changes: 2 additions & 2 deletions src/pages/Transaction/TransactionComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,11 @@ export const TransactionOverview = () => {
alignItems: 'center',
}}
>
{`${bytes - 4} Bytes`}
{`${(bytes - 4).toLocaleString('en')} Bytes`}
<Tooltip
placement="top"
title={i18n.t('transaction.size_in_block', {
bytes,
bytes: bytes.toLocaleString('en'),
})}
>
<img
Expand Down
4 changes: 4 additions & 0 deletions src/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ declare namespace State {
cellInfo: CellInfo
mNftInfo: NftIssuer | NftClass | NftToken
nrc721TokenInfo: Record<'amount' | 'symbol', string>
since?: {
raw: string
median_timestamp?: string
}
}

export interface CellInfo {
Expand Down
10 changes: 7 additions & 3 deletions src/utils/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@ export const adaptMobileEllipsis = (value: string, length = 8) => {
if (window.innerWidth <= 320) {
return startEndEllipsis(value, length, length)
}
if (window.innerWidth < 700) {
const step = Math.ceil((window.innerWidth - 320) / 15)
if (window.innerWidth < 500) {
const step = Math.ceil((window.innerWidth - 420) / 15)
return startEndEllipsis(value, length + step, length + step)
}
if (window.innerWidth < 750) {
const step = Math.ceil((window.innerWidth - 500) / 15)
return startEndEllipsis(value, length + step, length + step)
}
return value
}

export const adaptPCEllipsis = (value: string, length = 8, factor = 40) => {
if (window.innerWidth < 700) {
if (window.innerWidth < 750) {
return value
}
const width = window.innerWidth > 1200 ? 1200 : window.innerWidth
Expand Down
56 changes: 56 additions & 0 deletions src/utils/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ReactNode } from 'react'
import camelcaseKeys from 'camelcase-keys'
import JSBI from 'jsbi'
import BigNumber from 'bignumber.js'
import { scriptToAddress, addressToScript } from '@nervosnetwork/ckb-sdk-utils'
import { MAX_CONFIRMATION, TOKEN_EMAIL_SUBJECT, TOKEN_EMAIL_BODY, TOKEN_EMAIL_ADDRESS } from '../constants/common'
Expand Down Expand Up @@ -164,6 +165,61 @@ export const patchMibaoImg = (url: string) => {
}
}

/**
*@link https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0017-tx-valid-since/0017-tx-valid-since.md#specification
*/
export const parseSince = (
since: string,
): { base: 'absolute' | 'relative'; type: 'block' | 'epoch' | 'timestamp'; value: string } | null => {
const s = JSBI.BigInt(since)
if (JSBI.equal(s, JSBI.BigInt(0))) {
return null
}

const relativeFlag = JSBI.signedRightShift(s, JSBI.BigInt(63))
const metricFlag = JSBI.bitwiseAnd(JSBI.signedRightShift(s, JSBI.BigInt(61)), JSBI.BigInt(3))

const value = JSBI.bitwiseAnd(s, JSBI.BigInt('0xffffffffffffff'))

const base = relativeFlag.toString() === '0' ? 'absolute' : 'relative'

switch (metricFlag.toString()) {
case '0': {
// use block number
return {
base,
type: 'block',
value: JSBI.add(value, JSBI.BigInt(1)).toString(),
}
}
case '1': {
// use epoch number with fraction
const EFigures = JSBI.BigInt(0xffffff)
const IFigures = JSBI.BigInt(0xffff)
const LFigures = JSBI.BigInt(0xffff)
const E = +JSBI.bitwiseAnd(s, EFigures)
const I = +JSBI.bitwiseAnd(JSBI.signedRightShift(s, JSBI.BigInt(24)), IFigures)
const L = +JSBI.bitwiseAnd(JSBI.signedRightShift(s, JSBI.BigInt(40)), LFigures)
return {
base,
type: 'epoch',
value: `${(E + (I + 1) / L).toFixed(2)}`,
}
}
case '2': {
// use median_timestamp
return {
base,
type: 'timestamp',
value: value.toString(),
}
}
default: {
throw new Error('invalid since')
}
}
}

export default {
copyElementValue,
shannonToCkb,
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9901,6 +9901,11 @@ jsbi@3.1.3:
resolved "https://registry.npmjs.org/jsbi/-/jsbi-3.1.3.tgz#f024b340032f7c7caaa6ca4b32b55e8d33f6e897"
integrity sha512-nBJqA0C6Qns+ZxurbEoIR56wyjiUszpNy70FHvxO5ervMoCbZVE3z3kxr5nKGhlxr/9MhKTSUBs7cAwwuf3g9w==

jsbi@3.2.5:
version "3.2.5"
resolved "https://registry.npmjs.org/jsbi/-/jsbi-3.2.5.tgz#b37bb90e0e5c2814c1c2a1bcd8c729888a2e37d6"
integrity sha512-aBE4n43IPvjaddScbvWRA2YlTzKEynHzu7MqOyTipdHucf/VxS63ViCjxYRg86M8Rxwbt/GfzHl1kKERkt45fQ==

jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
Expand Down

0 comments on commit 4d45e6d

Please sign in to comment.