From 96b7a6e27c31d16987e5c2cfe7e7e6c68b353c30 Mon Sep 17 00:00:00 2001 From: karooolis Date: Thu, 9 Jan 2025 10:25:29 +0200 Subject: [PATCH] add latest block url --- .../[worldAddress]/explore/SQLEditor.tsx | 43 ++++++++++++------- .../(explorer)/queries/useTableDataQuery.ts | 11 +++-- .../(explorer)/utils/blockExplorerBlockUrl.ts | 18 ++++++++ .../explorer/src/components/LatestBlock.tsx | 27 +++++++++--- 4 files changed, 74 insertions(+), 25 deletions(-) create mode 100644 packages/explorer/src/app/(explorer)/utils/blockExplorerBlockUrl.ts diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/SQLEditor.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/SQLEditor.tsx index 34f68e5447..397091bc7d 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/SQLEditor.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/SQLEditor.tsx @@ -10,6 +10,7 @@ import Editor from "@monaco-editor/react"; import { Button } from "../../../../../../components/ui/Button"; import { Form, FormField } from "../../../../../../components/ui/Form"; import { cn } from "../../../../../../utils"; +import { useTableDataQuery } from "../../../../queries/useTableDataQuery"; import { monacoOptions } from "./consts"; import { useMonacoSuggestions } from "./useMonacoSuggestions"; import { useQueryValidator } from "./useQueryValidator"; @@ -24,6 +25,7 @@ export function SQLEditor({ table }: Props) { const [isFocused, setIsFocused] = useState(false); const [query, setQuery] = useQueryState("query", { defaultValue: "" }); const validateQuery = useQueryValidator(table); + const { data } = useTableDataQuery({ table, query }); useMonacoSuggestions(table); const form = useForm({ @@ -97,22 +99,31 @@ export function SQLEditor({ table }: Props) { )} /> - +
+ {data?.executionTime && ( + + + {Math.round(data.executionTime)}ms + + )} + + +
); diff --git a/packages/explorer/src/app/(explorer)/queries/useTableDataQuery.ts b/packages/explorer/src/app/(explorer)/queries/useTableDataQuery.ts index 6756d0ef5f..94e9192295 100644 --- a/packages/explorer/src/app/(explorer)/queries/useTableDataQuery.ts +++ b/packages/explorer/src/app/(explorer)/queries/useTableDataQuery.ts @@ -15,6 +15,7 @@ export type TDataRow = Record; export type TData = { columns: string[]; rows: TDataRow[]; + executionTime: number; }; export function useTableDataQuery({ table, query }: Props) { @@ -22,9 +23,10 @@ export function useTableDataQuery({ table, query }: Props) { const { id: chainId } = useChain(); const decodedQuery = decodeURIComponent(query ?? ""); - return useQuery({ + return useQuery({ queryKey: ["tableData", chainName, worldAddress, decodedQuery], queryFn: async () => { + const startTime = performance.now(); const indexer = indexerForChainId(chainId); const response = await fetch(indexer.url, { method: "POST", @@ -40,13 +42,15 @@ export function useTableDataQuery({ table, query }: Props) { }); const data = await response.json(); + const executionTime = performance.now() - startTime; + if (!response.ok) { throw new Error(data.msg || "Network response was not ok"); } - return data; + return { ...data, executionTime }; }, - select: (data: DozerResponse): TData | undefined => { + select: (data: DozerResponse & { executionTime: number }): TData | undefined => { if (!table || !data?.result?.[0]) return undefined; const indexer = indexerForChainId(chainId); @@ -77,6 +81,7 @@ export function useTableDataQuery({ table, query }: Props) { return { columns, rows, + executionTime: data.executionTime, }; }, enabled: !!table && !!query, diff --git a/packages/explorer/src/app/(explorer)/utils/blockExplorerBlockUrl.ts b/packages/explorer/src/app/(explorer)/utils/blockExplorerBlockUrl.ts new file mode 100644 index 0000000000..51a588f0e2 --- /dev/null +++ b/packages/explorer/src/app/(explorer)/utils/blockExplorerBlockUrl.ts @@ -0,0 +1,18 @@ +import { chainIdToName, supportedChains, validateChainId } from "../../../common"; + +export function blockExplorerBlockUrl({ + blockNumber, + chainId, +}: { + blockNumber: bigint; + chainId: number; +}): string | undefined { + if (!blockNumber) return undefined; + validateChainId(chainId); + + const chainName = chainIdToName[chainId]; + const chain = supportedChains[chainName]; + const explorerUrl = "blockExplorers" in chain && chain.blockExplorers?.default.url; + if (!explorerUrl) return undefined; + return `${explorerUrl}/block/${blockNumber.toString()}`; +} diff --git a/packages/explorer/src/components/LatestBlock.tsx b/packages/explorer/src/components/LatestBlock.tsx index c09f57d32a..d1622c689b 100644 --- a/packages/explorer/src/components/LatestBlock.tsx +++ b/packages/explorer/src/components/LatestBlock.tsx @@ -1,24 +1,39 @@ +import Link from "next/link"; import { useBlockNumber } from "wagmi"; import { useChain } from "../app/(explorer)/hooks/useChain"; +import { blockExplorerBlockUrl } from "../app/(explorer)/utils/blockExplorerBlockUrl"; import { Skeleton } from "./ui/Skeleton"; +function BlockView({ blockNumber }: { blockNumber: bigint }) { + return ( +
+ + {blockNumber.toString()} +
+ ); +} + export function LatestBlock() { const { id: chainId } = useChain(); - const { data: block } = useBlockNumber({ + const { data: blockNumber } = useBlockNumber({ watch: true, chainId, query: { refetchInterval: 1000, }, }); + const blockUrl = blockNumber ? blockExplorerBlockUrl({ blockNumber, chainId }) : undefined; return (
- {block ? ( -
- - {block.toString()} -
+ {blockNumber ? ( + blockUrl ? ( + + + + ) : ( + + ) ) : ( )}