Skip to content

Commit

Permalink
Merge pull request #1812 from nervosnetwork/testnet
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith-CY authored Nov 29, 2024
2 parents faa1143 + 516dc16 commit 2b7a0ce
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 1 deletion.
2 changes: 2 additions & 0 deletions _typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ rd='rd'
th='th'
# typo in api, should be fixed later
toekn='toekn'
# echart config
metalness = 'metalness'
52 changes: 52 additions & 0 deletions src/components/ui/NumberTicker/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useEffect, useRef, useState } from 'react'

interface NumberTickerProps {
value: number | null
duration?: number // duration in milliseconds
className?: string
}

export function NumberTicker({
value,
duration = 1000, // default animation duration: 1 second
className = '',
}: NumberTickerProps) {
const [displayValue, setDisplayValue] = useState(value)
const prevValueRef = useRef(value ?? 0) // Store the previous value
const animationFrame = useRef<number>()

useEffect(() => {
if (typeof value !== 'number') {
return
}
const startValue = prevValueRef.current // Previous value
const targetValue = value // New value
const startTime = performance.now()

const animate = (currentTime: number) => {
const elapsed = currentTime - startTime
const progress = Math.min(elapsed / duration, 1) // Progress between 0 and 1

// Calculate interpolated value
const interpolatedValue = Math.floor(startValue + (targetValue - startValue) * progress)
setDisplayValue(interpolatedValue)

if (progress < 1) {
animationFrame.current = requestAnimationFrame(animate)
}
}

// Start animation
if (animationFrame.current) cancelAnimationFrame(animationFrame.current)
animationFrame.current = requestAnimationFrame(animate)

// Update the previous value reference
prevValueRef.current = value

return () => {
if (animationFrame.current) cancelAnimationFrame(animationFrame.current)
}
}, [value, duration])

return <span className={className}>{displayValue?.toLocaleString('en') ?? '--,---,---'}</span>
}
28 changes: 28 additions & 0 deletions src/pages/Home/Banner/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ $backgroundColor: #232323;
background-repeat: no-repeat;
background-position: center center;
background-size: auto 100%;
color: white;
display: flex;
align-items: center;
justify-content: center;

@media (width <= $mobileBreakPoint) {
background-image: url('./ckb_explorer_banner_phone.svg');
Expand Down Expand Up @@ -121,3 +125,27 @@ $backgroundColor: #232323;
padding: 16px 24px;
}
}

.knowledgeBase {
text-align: center;
font-weight: bold;
font-optical-sizing: auto;
mix-blend-mode: difference;
line-height: 1.2;
font-size: 50px;
outline: none;
background: url('./ticker_bg.gif');
background-size: cover;
background-position: center center;
background-clip: text;
color: transparent;

.ticker {
display: flex;
gap: 8px;
}

@media screen and (width <= 500px) {
font-size: 30px;
}
}
40 changes: 39 additions & 1 deletion src/pages/Home/Banner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
import { useQuery } from '@tanstack/react-query'
import config from '../../../config'
import styles from './index.module.scss'
import { getKnowledgeSize } from './utils'
import { NumberTicker } from '../../../components/ui/NumberTicker'

export default () => <div className={styles.root} />
const { BACKUP_NODES: backupNodes } = config

export default () => {
const { data: size } = useQuery(
['backup_nodes'],
async () => {
try {
if (backupNodes.length === 0) return null

const [size1, size2] = await Promise.race(backupNodes.map(getKnowledgeSize))
return size1 ?? size2
} catch {
return null
}
},
{ refetchInterval: 12 * 1000 },
)
return (
<div className={styles.root}>
<a
className={styles.knowledgeBase}
target="_blank"
rel="noopener noreferrer"
href="https://talk.nervos.org/t/how-to-get-the-average-occupied-bytes-per-live-cell-in-ckb/7138/2?u=keith"
>
<span>Knowledge Size</span>
<br />
<div className={styles.ticker}>
<NumberTicker value={size ? +size : null} />
<span>CKBytes</span>
</div>
</a>
</div>
)
}
Binary file added src/pages/Home/Banner/ticker_bg.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions src/pages/Home/Banner/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import BigNumber from 'bignumber.js'

/**
* 6/10 of 7th output in the genesis should be excluded because they are expected to be burnt.
* ref: https://talk.nervos.org/t/how-to-get-the-average-occupied-bytes-per-live-cell-in-ckb/7138/2?u=keith
* */
const EXCLUDE = BigNumber('504000000000000000')

export const getKnowledgeSize = async (nodeUrl: string) => {
const header = await fetch(nodeUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: 1,
jsonrpc: '2.0',
method: 'get_tip_header',
params: [],
}),
})
.then(res => res.json())
.then(res => res.result)
const { dao } = header

const [, , , u] = dao
.slice(2)
.match(/\w{16}/g)
.map((i: string) => i.match(/\w{2}/g)?.reverse().join('') ?? '')
const total = BigNumber(`0x${u}`).minus(EXCLUDE).toFormat()
return total
}

0 comments on commit 2b7a0ce

Please sign in to comment.