Skip to content

Commit a36af85

Browse files
explorer: fix home recent transactions table
1 parent e114ce5 commit a36af85

3 files changed

Lines changed: 95 additions & 5 deletions

File tree

cmd/rpc/web/explorer/src/components/Home/OverviewCards.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react'
22
import { motion } from 'framer-motion'
33
import { Link, useNavigate } from 'react-router-dom'
44
import { formatDistanceToNow, isValid, parseISO } from 'date-fns'
5-
import { useAllBlocksCache, useTransactionsWithRealPagination } from '../../hooks/useApi'
5+
import { useAllBlocksCache, useRecentTransactionsPreview } from '../../hooks/useApi'
66
import { extractAmountMicro, toCNPY } from '../../lib/utils'
77
import TransactionTypeBadge from '../transaction/TransactionTypeBadge'
88

@@ -47,8 +47,17 @@ const formatAmount = (amount: number) =>
4747
const normalizeList = (payload: any) => {
4848
if (!payload) return [] as any[]
4949
if (Array.isArray(payload)) return payload
50-
const found = payload.transactions || payload.blocks || payload.results || payload.list || payload.data
51-
return Array.isArray(found) ? found : []
50+
for (const candidate of [
51+
payload.results,
52+
payload.transactions,
53+
payload.txs,
54+
payload.blocks,
55+
payload.list,
56+
payload.data,
57+
]) {
58+
if (Array.isArray(candidate)) return candidate
59+
}
60+
return []
5261
}
5362

5463
const LiveIndicator = () => (
@@ -192,8 +201,8 @@ const WalletPreviewTable: React.FC<WalletPreviewTableProps> = ({
192201
}
193202

194203
const OverviewCards: React.FC = () => {
195-
const { data: txsPage, isLoading: isTransactionsLoading } = useTransactionsWithRealPagination(1, 5)
196204
const { data: blocksPage, isLoading: isBlocksLoading } = useAllBlocksCache()
205+
const { data: txsPage, isLoading: isTransactionsLoading } = useRecentTransactionsPreview(blocksPage, 5)
197206

198207
const txs = normalizeList(txsPage)
199208
const blockList = normalizeList(blocksPage)
@@ -297,7 +306,7 @@ const OverviewCards: React.FC = () => {
297306
viewAllPath="/transactions"
298307
columns={['Type', 'Hash', 'From', 'Amount', 'Time']}
299308
rows={transactionRows}
300-
loading={isTransactionsLoading}
309+
loading={isBlocksLoading || isTransactionsLoading}
301310
emptyLabel="No transactions found"
302311
minWidth="min-w-[760px]"
303312
/>

cmd/rpc/web/explorer/src/hooks/useApi.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Transactions,
66
AllTransactions,
77
getTransactionsWithRealPagination,
8+
getRecentTransactionsPreview,
89
Accounts,
910
Validators,
1011
ValidatorsWithFilters,
@@ -155,6 +156,21 @@ export const useTransactionsWithRealPagination = (page: number, perPage: number
155156
});
156157
};
157158

159+
export const useRecentTransactionsPreview = (blocks: any[] | undefined, limit: number = 5) => {
160+
const latestBlockHeight = Number(blocks?.[0]?.blockHeader?.height ?? blocks?.[0]?.height ?? 0);
161+
162+
return useQuery({
163+
queryKey: ['recentTransactionsPreview', latestBlockHeight, limit],
164+
queryFn: () => getRecentTransactionsPreview(limit, blocks),
165+
staleTime: 5000,
166+
refetchInterval: 10000,
167+
refetchOnWindowFocus: true,
168+
refetchOnMount: 'always',
169+
enabled: Array.isArray(blocks) && blocks.length > 0,
170+
placeholderData: (previousData) => previousData,
171+
});
172+
};
173+
158174
// Hooks for Accounts
159175
export const useAccounts = (page: number, perPage: number = 10) => {
160176
return useQuery({

cmd/rpc/web/explorer/src/lib/api.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,23 @@ function getBlockTransactionCount(block: any): number {
214214
);
215215
}
216216

217+
function getTransactionTimestampMs(tx: any): number {
218+
const value = tx?.blockTime ?? tx?.time ?? tx?.timestamp;
219+
if (typeof value === 'number') {
220+
if (value > 1e15) return Math.floor(value / 1_000_000);
221+
if (value > 1e12) return Math.floor(value);
222+
return Math.floor(value * 1_000);
223+
}
224+
if (typeof value === 'string') {
225+
if (/^\d+$/.test(value)) {
226+
return getTransactionTimestampMs({ time: Number(value) });
227+
}
228+
const parsed = Date.parse(value);
229+
return Number.isNaN(parsed) ? 0 : parsed;
230+
}
231+
return 0;
232+
}
233+
217234
function attachBlockMetadataToTransactions(transactions: any[], block: any): any[] {
218235
const blockHeight = getBlockHeightValue(block);
219236
const blockHash = getBlockHashValue(block);
@@ -256,6 +273,54 @@ async function fetchTransactionsForBlock(block: any): Promise<any[]> {
256273
}
257274
}
258275

276+
export async function getRecentTransactionsPreview(limit: number = 5, cachedBlocks?: any[]): Promise<any[]> {
277+
try {
278+
const fallbackBlocksResponse = Array.isArray(cachedBlocks) && cachedBlocks.length > 0
279+
? null
280+
: await Blocks(1, 25);
281+
const blocks = (
282+
Array.isArray(cachedBlocks) && cachedBlocks.length > 0
283+
? cachedBlocks
284+
: (
285+
fallbackBlocksResponse?.results ||
286+
fallbackBlocksResponse?.blocks ||
287+
fallbackBlocksResponse?.list ||
288+
[]
289+
)
290+
).filter((block: any) => getBlockTransactionCount(block) > 0);
291+
292+
if (!Array.isArray(blocks) || blocks.length === 0) return [];
293+
294+
const recentTransactions: any[] = [];
295+
296+
for (const block of blocks) {
297+
const blockTransactions = await fetchTransactionsForBlock(block);
298+
if (blockTransactions.length > 0) {
299+
recentTransactions.push(...blockTransactions);
300+
}
301+
if (recentTransactions.length >= limit) break;
302+
}
303+
304+
recentTransactions.sort((a, b) => {
305+
const heightDelta = Number(b?.blockHeight ?? b?.height ?? 0) - Number(a?.blockHeight ?? a?.height ?? 0);
306+
if (heightDelta !== 0) return heightDelta;
307+
308+
const indexDelta = Number(b?.index ?? b?.txIndex ?? b?.transactionIndex ?? -1) - Number(a?.index ?? a?.txIndex ?? a?.transactionIndex ?? -1);
309+
if (indexDelta !== 0) return indexDelta;
310+
311+
const timeDelta = getTransactionTimestampMs(b) - getTransactionTimestampMs(a);
312+
if (timeDelta !== 0) return timeDelta;
313+
314+
return String(b?.hash ?? b?.txHash ?? '').localeCompare(String(a?.hash ?? a?.txHash ?? ''));
315+
});
316+
317+
return recentTransactions.slice(0, limit);
318+
} catch (error) {
319+
console.error('Error fetching recent transactions preview:', error);
320+
return [];
321+
}
322+
}
323+
259324
// Optimized function to get transactions with real pagination
260325
export async function getTransactionsWithRealPagination(page: number, perPage: number = 10, filters?: {
261326
type?: string;

0 commit comments

Comments
 (0)