feat: add block number in home
This commit is contained in:
parent
e9c80277ad
commit
e15ea3f9fa
|
|
@ -2,6 +2,7 @@ import Link from "next/link"
|
|||
import { memo } from "react"
|
||||
|
||||
import { Logo } from "~/components/common/Logo"
|
||||
import { BlockNumber } from "~/components/home/BlockNumber"
|
||||
import { default as OriginEntranceButton } from "~/components/home/EntranceButton"
|
||||
import { Integration } from "~/components/home/Integrations"
|
||||
import { ShowCase } from "~/components/home/Showcase"
|
||||
|
|
@ -110,11 +111,11 @@ async function Home() {
|
|||
return (
|
||||
<div>
|
||||
<div className="h-[calc(100vh-6rem)] w-full flex justify-center flex-col relative text-center">
|
||||
<h2 className="text-6xl sm:text-8xl font-bold mb-5">
|
||||
<h2 className="text-4xl sm:text-8xl font-bold mb-5">
|
||||
{features.map((feature) => (
|
||||
<span
|
||||
key={feature.title}
|
||||
className={`text-feature text-feature-${feature.title.toLocaleLowerCase()} block sm:inline-block sm:mr-1 mb-2`}
|
||||
className={`text-feature text-feature-${feature.title.toLocaleLowerCase()} inline-block sm:mr-1`}
|
||||
>
|
||||
{t(feature.title)}
|
||||
{t(".")}
|
||||
|
|
@ -283,6 +284,7 @@ async function Home() {
|
|||
</span>
|
||||
</div>
|
||||
<div>{t(`features.${feature.title}.extra.description`)}</div>
|
||||
<BlockNumber />
|
||||
<a
|
||||
target="_blank"
|
||||
href={getSiteLink({ subdomain: "xlog" })}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
import { nanoid } from "nanoid"
|
||||
import { memo, useEffect, useRef, useState } from "react"
|
||||
|
||||
import { usePrevious } from "~/hooks/usePrevious"
|
||||
import { cn } from "~/lib/utils"
|
||||
|
||||
const NUMBERS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
|
||||
|
||||
const AnimatedNumber = memo(
|
||||
({
|
||||
animateToNumber,
|
||||
includeComma,
|
||||
height,
|
||||
className,
|
||||
}: {
|
||||
animateToNumber: number
|
||||
includeComma?: boolean
|
||||
height?: number
|
||||
className?: string
|
||||
}) => {
|
||||
const keyCount = useRef(0)
|
||||
const animteTonumberString = includeComma
|
||||
? Math.abs(animateToNumber).toLocaleString()
|
||||
: String(Math.abs(animateToNumber))
|
||||
const animateToNumbersArr = Array.from(animteTonumberString, Number).map(
|
||||
(x, idx) => (isNaN(x) ? animteTonumberString[idx] : x),
|
||||
)
|
||||
const prevAnimateToNumbersArr = usePrevious(animateToNumbersArr)
|
||||
|
||||
const [numberHeight, setNumberHeight] = useState(height || 0)
|
||||
|
||||
const numberDivRef = useRef<HTMLDivElement | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (!numberHeight) {
|
||||
const currentHeight =
|
||||
numberDivRef.current?.getClientRects()?.[0]?.height
|
||||
if (currentHeight) {
|
||||
setNumberHeight(currentHeight)
|
||||
}
|
||||
}
|
||||
}, [numberDivRef, numberHeight])
|
||||
|
||||
return (
|
||||
<>
|
||||
{numberHeight !== 0 && (
|
||||
<div className={cn("flex", className)}>
|
||||
{animateToNumber < 0 && <div>-</div>}
|
||||
{animateToNumbersArr.map((n, index) => {
|
||||
if (
|
||||
typeof n === "string" ||
|
||||
!prevAnimateToNumbersArr ||
|
||||
prevAnimateToNumbersArr[index] === n
|
||||
) {
|
||||
return <div key={index}>{n}</div>
|
||||
}
|
||||
|
||||
const from =
|
||||
-1 * (numberHeight * (prevAnimateToNumbersArr[index] as number))
|
||||
let to =
|
||||
-1 * (numberHeight * (animateToNumbersArr[index] as number))
|
||||
const id = nanoid()
|
||||
if (animateToNumbersArr[index] === 0) {
|
||||
to = -1 * (numberHeight * 10)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
style={{
|
||||
height: numberHeight,
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{/* eslint-disable-next-line react/no-unknown-property */}
|
||||
<style jsx>{`
|
||||
@keyframes move${id} {
|
||||
from {
|
||||
transform: translateY(${from}px);
|
||||
}
|
||||
to {
|
||||
transform: translateY(${to}px);
|
||||
}
|
||||
}
|
||||
`}</style>
|
||||
<div
|
||||
key={`${keyCount.current++}`}
|
||||
style={{
|
||||
animation: `move${id} 0.3s ease-in-out forwards`,
|
||||
}}
|
||||
>
|
||||
{NUMBERS.map((number, i) => (
|
||||
<div key={i}>{number}</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
{!numberHeight && (
|
||||
<div ref={numberDivRef} style={{ position: "absolute", top: -9999 }}>
|
||||
{0}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
},
|
||||
(prevProps, nextProps) => {
|
||||
return (
|
||||
prevProps.animateToNumber === nextProps.animateToNumber &&
|
||||
prevProps.includeComma === nextProps.includeComma
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
AnimatedNumber.displayName = "AnimatedNumber"
|
||||
|
||||
export default AnimatedNumber
|
||||
|
|
@ -27,7 +27,7 @@ export const BlockchainInfo = ({
|
|||
: "page"
|
||||
: "blog"
|
||||
|
||||
const [realBlockNumber, setRealBlockNumber] = useState<bigint | null>(null)
|
||||
const [realBlockNumber, setRealBlockNumber] = useState<number | null>(null)
|
||||
const { data: blockNumber } = useGetBlockNumber()
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -38,7 +38,12 @@ export const BlockchainInfo = ({
|
|||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setRealBlockNumber((prevCount) => (prevCount || BigInt(0)) + BigInt(1))
|
||||
setRealBlockNumber((prevCount) => {
|
||||
if (prevCount) {
|
||||
return prevCount + 1
|
||||
}
|
||||
return null
|
||||
})
|
||||
}, 1000)
|
||||
|
||||
return () => clearInterval(interval)
|
||||
|
|
@ -81,7 +86,7 @@ export const BlockchainInfo = ({
|
|||
`(${t("Confirmed by {{blockNumber}} blocks", {
|
||||
blockNumber:
|
||||
realBlockNumber -
|
||||
BigInt(page?.blockNumber || site?.blockNumber || 0),
|
||||
(page?.blockNumber || site?.blockNumber || 0),
|
||||
})})`}
|
||||
</span>
|
||||
</BlockchainInfoLink>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
"use client"
|
||||
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
import AnimatedNumber from "~/components/common/AnimatedNumber"
|
||||
import { useTranslation } from "~/lib/i18n/client"
|
||||
import { useGetBlockNumber } from "~/queries/site"
|
||||
|
||||
export const BlockNumber = () => {
|
||||
const { t } = useTranslation("common")
|
||||
|
||||
const [realBlockNumber, setRealBlockNumber] = useState<number | null>(null)
|
||||
const { data: blockNumber } = useGetBlockNumber()
|
||||
|
||||
useEffect(() => {
|
||||
if (blockNumber) {
|
||||
setRealBlockNumber(blockNumber)
|
||||
}
|
||||
}, [blockNumber])
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setRealBlockNumber((prevCount) => {
|
||||
if (prevCount) {
|
||||
return prevCount + 1
|
||||
}
|
||||
return null
|
||||
})
|
||||
}, 1000)
|
||||
|
||||
return () => clearInterval(interval)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center">
|
||||
{t("Current Block Height")}
|
||||
<AnimatedNumber
|
||||
animateToNumber={realBlockNumber || blockNumber || 0}
|
||||
includeComma={true}
|
||||
height={24}
|
||||
></AnimatedNumber>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,22 +1,48 @@
|
|||
import { Hydrate, dehydrate } from "@tanstack/react-query"
|
||||
|
||||
import { CharacterFloatCard } from "~/components/common/CharacterFloatCard"
|
||||
import { SearchInput } from "~/components/common/SearchInput"
|
||||
import { Avatar } from "~/components/ui/Avatar"
|
||||
import { UniLink } from "~/components/ui/UniLink"
|
||||
import { getSiteLink } from "~/lib/helpers"
|
||||
import { getTranslation } from "~/lib/i18n"
|
||||
import { Trans, getTranslation } from "~/lib/i18n"
|
||||
import getQueryClient from "~/lib/query-client"
|
||||
import { getShowcase } from "~/queries/home.server"
|
||||
import { getBlockNumber } from "~/queries/site.server"
|
||||
|
||||
import { FollowAllButton } from "../common/FollowAllButton"
|
||||
import { BlockNumber } from "./BlockNumber"
|
||||
import PromotionLinks from "./PromotionLinks"
|
||||
import ShowMoreContainer from "./ShowMoreContainer"
|
||||
|
||||
export async function HomeSidebar({ hideSearch }: { hideSearch?: boolean }) {
|
||||
const showcaseSites = await getShowcase()
|
||||
const { t } = await getTranslation("index")
|
||||
const { t, i18n } = await getTranslation("index")
|
||||
const queryClient = getQueryClient()
|
||||
await getBlockNumber(queryClient)
|
||||
|
||||
const dehydratedState = dehydrate(queryClient)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Hydrate state={dehydratedState}>
|
||||
<PromotionLinks />
|
||||
<UniLink
|
||||
href="/about"
|
||||
className="text-zinc-800 text-center block space-y-4"
|
||||
>
|
||||
<Trans i18n={i18n} i18nKey="description" ns="index">
|
||||
An{" "}
|
||||
<span className="underline decoration-2 text-green-400 font-medium">
|
||||
open-source
|
||||
</span>{" "}
|
||||
creative community written on the{" "}
|
||||
<span className="underline decoration-2 text-yellow-400 font-medium">
|
||||
blockchain
|
||||
</span>
|
||||
.
|
||||
</Trans>
|
||||
<BlockNumber />
|
||||
</UniLink>
|
||||
{!hideSearch && <SearchInput />}
|
||||
<div className="text-center text-zinc-700 space-y-3">
|
||||
<p className="font-bold text-lg">{t("Suggested creators for you")}</p>
|
||||
|
|
@ -63,6 +89,6 @@ export async function HomeSidebar({ hideSearch }: { hideSearch?: boolean }) {
|
|||
</>
|
||||
</ShowMoreContainer>
|
||||
</div>
|
||||
</>
|
||||
</Hydrate>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
import { useEffect, useRef } from "react"
|
||||
|
||||
export const usePrevious = <T>(value: T): T => {
|
||||
const ref = useRef<T>()
|
||||
|
||||
useEffect(() => {
|
||||
ref.current = value
|
||||
})
|
||||
|
||||
return ref.current!
|
||||
}
|
||||
|
|
@ -96,5 +96,6 @@
|
|||
"min": "分钟",
|
||||
"Pinned": "置顶",
|
||||
"Blockchain ID": "区块链标识",
|
||||
"Confirmed by {{blockNumber}} blocks": "已被 {{blockNumber}} 个区块确认"
|
||||
"Confirmed by {{blockNumber}} blocks": "已被 {{blockNumber}} 个区块确认",
|
||||
"Current Block Height": "当前区块高度"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -515,5 +515,5 @@ export async function getBlockNumber() {
|
|||
}),
|
||||
})
|
||||
).json()
|
||||
return BigInt(result.result)
|
||||
return Number(BigInt(result.result))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,3 +219,15 @@ export const getCharacterColors = async (character?: ExpandedCharacter) => {
|
|||
}
|
||||
}>
|
||||
}
|
||||
|
||||
export const getBlockNumber = async (queryClient: QueryClient) => {
|
||||
const key = ["getBlockNumber"]
|
||||
await queryClient.prefetchQuery(key, async () => {
|
||||
return cacheGet({
|
||||
key: key,
|
||||
getValueFun: async () => {
|
||||
return siteModel.getBlockNumber()
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue