Skip to content

Commit

Permalink
Make lists with polling and pagination more stable
Browse files Browse the repository at this point in the history
  • Loading branch information
buberdds committed Sep 11, 2024
1 parent 9b82575 commit 5b4e778
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 67 deletions.
1 change: 1 addition & 0 deletions .changelog/1534.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make lists with polling and pagination more stable
43 changes: 27 additions & 16 deletions src/app/pages/ConsensusBlocksPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export const ConsensusBlocksPage: FC = () => {
const pagination = useSearchParamsPagination('page')
const offset = (pagination.selectedPage - 1) * PAGE_SIZE
const scope = useRequiredScopeParam()
const [beforeDate, setBeforeDate] = useState<string | undefined>(undefined)
const enablePolling = offset === 0

useEffect(() => {
if (!isMobile) {
Expand All @@ -47,25 +49,28 @@ export const ConsensusBlocksPage: FC = () => {
{
limit: tableView === TableLayout.Vertical ? offset + PAGE_SIZE : PAGE_SIZE,
offset: tableView === TableLayout.Vertical ? 0 : offset,
before: enablePolling ? undefined : beforeDate,
},
{
query: {
refetchInterval: REFETCH_INTERVAL,
structuralSharing: (previousState, nextState) => {
const oldBlockIds = new Set(previousState?.data.blocks.map(block => block.height))
return {
...nextState,
data: {
...nextState.data,
blocks: nextState.data.blocks.map(block => {
return {
...block,
markAsNew: previousState ? !oldBlockIds.has(block.height) : false,
}
}),
},
}
},
refetchInterval: enablePolling ? REFETCH_INTERVAL : undefined,
structuralSharing: enablePolling
? (previousState, nextState) => {
const oldBlockIds = new Set(previousState?.data.blocks.map(block => block.height))
return {
...nextState,
data: {
...nextState.data,
blocks: nextState.data.blocks.map(block => {
return {
...block,
markAsNew: previousState ? !oldBlockIds.has(block.height) : false,
}
}),
},
}
}
: undefined,
// Keep showing data while loading more
keepPreviousData: tableView === TableLayout.Vertical,
},
Expand All @@ -75,6 +80,12 @@ export const ConsensusBlocksPage: FC = () => {
const { isLoading, isFetched, data } = blocksQuery
const blocks = data?.data.blocks

useEffect(() => {
if (!beforeDate || offset === 0) {
setBeforeDate(blocks?.[0].timestamp)
}
}, [beforeDate, offset, blocks])

if (isFetched && offset && !blocks?.length) {
throw AppErrors.PageDoesNotExist
}
Expand Down
44 changes: 27 additions & 17 deletions src/app/pages/ConsensusTransactionsPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,41 @@ export const ConsensusTransactionsPage: FC = () => {
const pagination = useSearchParamsPagination('page')
const offset = (pagination.selectedPage - 1) * limit
const scope = useRequiredScopeParam()
const [beforeDate, setBeforeDate] = useState<string | undefined>(undefined)
const enablePolling = offset === 0

useEffect(() => {
if (!isMobile) {
setTableView(TableLayout.Horizontal)
}
}, [isMobile, setTableView])

const transactionsQuery = useGetConsensusTransactions<AxiosResponse<TableConsensusTransactionList>>(
scope.network,
{
limit: tableView === TableLayout.Vertical ? offset + limit : limit,
offset: tableView === TableLayout.Vertical ? 0 : offset,
before: enablePolling ? undefined : beforeDate,
},
{
query: {
refetchInterval: REFETCH_INTERVAL,
structuralSharing: (previousState, nextState) => {
const oldTxHashes = new Set(previousState?.data.transactions.map(tx => tx.hash))
return {
...nextState,
data: {
...nextState.data,
transactions: nextState.data.transactions.map(tx => {
return {
...tx,
markAsNew: previousState ? !oldTxHashes.has(tx.hash) : false,
}
}),
},
}
},
refetchInterval: enablePolling ? REFETCH_INTERVAL : undefined,
structuralSharing: enablePolling
? (previousState, nextState) => {
const oldTxHashes = new Set(previousState?.data.transactions.map(tx => tx.hash))
return {
...nextState,
data: {
...nextState.data,
transactions: nextState.data.transactions.map(tx => {
return {
...tx,
markAsNew: previousState ? !oldTxHashes.has(tx.hash) : false,
}
}),
},
}
}
: undefined,
keepPreviousData: tableView === TableLayout.Vertical,
},
},
Expand All @@ -63,6 +67,12 @@ export const ConsensusTransactionsPage: FC = () => {

const transactions = data?.data.transactions

useEffect(() => {
if (!beforeDate || offset === 0) {
setBeforeDate(transactions?.[0].timestamp)
}
}, [beforeDate, offset, transactions])

if (isFetched && pagination.selectedPage > 1 && !transactions?.length) {
throw AppErrors.PageDoesNotExist
}
Expand Down
44 changes: 27 additions & 17 deletions src/app/pages/RuntimeBlocksPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export const RuntimeBlocksPage: FC = () => {
const pagination = useSearchParamsPagination('page')
const offset = (pagination.selectedPage - 1) * PAGE_SIZE
const scope = useRequiredScopeParam()
const [beforeDate, setBeforeDate] = useState<string | undefined>(undefined)
const enablePolling = offset === 0
// Consensus is not yet enabled in ENABLED_LAYERS, just some preparation
if (scope.layer === Layer.consensus) {
throw AppErrors.UnsupportedLayer
Expand All @@ -37,32 +39,34 @@ export const RuntimeBlocksPage: FC = () => {
setTableView(TableLayout.Horizontal)
}
}, [isMobile, setTableView])

const blocksQuery = useGetRuntimeBlocks<AxiosResponse<TableRuntimeBlockList>>(
scope.network,
scope.layer, // This is OK, since consensus is already handled separately
{
limit: tableView === TableLayout.Vertical ? offset + PAGE_SIZE : PAGE_SIZE,
offset: tableView === TableLayout.Vertical ? 0 : offset,
before: enablePolling ? undefined : beforeDate,
},
{
query: {
refetchInterval: REFETCH_INTERVAL,
structuralSharing: (previousState, nextState) => {
const oldBlockIds = new Set(previousState?.data.blocks.map(block => block.round))
return {
...nextState,
data: {
...nextState.data,
blocks: nextState.data.blocks.map(block => {
return {
...block,
markAsNew: previousState ? !oldBlockIds.has(block.round) : false,
}
}),
},
}
},
refetchInterval: enablePolling ? REFETCH_INTERVAL : undefined,
structuralSharing: enablePolling
? (previousState, nextState) => {
const oldBlockIds = new Set(previousState?.data.blocks.map(block => block.round))
return {
...nextState,
data: {
...nextState.data,
blocks: nextState.data.blocks.map(block => {
return {
...block,
markAsNew: previousState ? !oldBlockIds.has(block.round) : false,
}
}),
},
}
}
: undefined,
// Keep showing data while loading more
keepPreviousData: tableView === TableLayout.Vertical,
},
Expand All @@ -72,6 +76,12 @@ export const RuntimeBlocksPage: FC = () => {
const { isLoading, isFetched, data } = blocksQuery
const blocks = data?.data.blocks

useEffect(() => {
if (!beforeDate || offset === 0) {
setBeforeDate(blocks?.[0].timestamp)
}
}, [beforeDate, offset, blocks])

if (isFetched && offset && !blocks?.length) {
throw AppErrors.PageDoesNotExist
}
Expand Down
44 changes: 27 additions & 17 deletions src/app/pages/RuntimeTransactionsPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export const RuntimeTransactionsPage: FC = () => {
const pagination = useSearchParamsPagination('page')
const offset = (pagination.selectedPage - 1) * limit
const scope = useRequiredScopeParam()
const [beforeDate, setBeforeDate] = useState<string | undefined>(undefined)
const enablePolling = offset === 0

// Consensus is not yet enabled in ENABLED_LAYERS, just some preparation
if (scope.layer === Layer.consensus) {
Expand All @@ -42,32 +44,34 @@ export const RuntimeTransactionsPage: FC = () => {
setTableView(TableLayout.Horizontal)
}
}, [isMobile, setTableView])

const transactionsQuery = useGetRuntimeTransactions<AxiosResponse<TableRuntimeTransactionList>>(
scope.network,
scope.layer, // This is OK, since consensus is already handled separately
{
limit: tableView === TableLayout.Vertical ? offset + limit : limit,
offset: tableView === TableLayout.Vertical ? 0 : offset,
before: enablePolling ? undefined : beforeDate,
},
{
query: {
refetchInterval: REFETCH_INTERVAL,
structuralSharing: (previousState, nextState) => {
const oldTxHashes = new Set(previousState?.data.transactions.map(tx => tx.hash))
return {
...nextState,
data: {
...nextState.data,
transactions: nextState.data.transactions.map(tx => {
return {
...tx,
markAsNew: previousState ? !oldTxHashes.has(tx.hash) : false,
}
}),
},
}
},
refetchInterval: enablePolling ? REFETCH_INTERVAL : undefined,
structuralSharing: enablePolling
? (previousState, nextState) => {
const oldTxHashes = new Set(previousState?.data.transactions.map(tx => tx.hash))
return {
...nextState,
data: {
...nextState.data,
transactions: nextState.data.transactions.map(tx => {
return {
...tx,
markAsNew: previousState ? !oldTxHashes.has(tx.hash) : false,
}
}),
},
}
}
: undefined,
// Keep showing data while loading more
keepPreviousData: tableView === TableLayout.Vertical,
},
Expand All @@ -78,6 +82,12 @@ export const RuntimeTransactionsPage: FC = () => {

const transactions = data?.data.transactions

useEffect(() => {
if (!beforeDate || offset === 0) {
setBeforeDate(transactions?.[0].timestamp)
}
}, [beforeDate, offset, transactions])

if (isFetched && pagination.selectedPage > 1 && !transactions?.length) {
throw AppErrors.PageDoesNotExist
}
Expand Down

0 comments on commit 5b4e778

Please sign in to comment.