Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
2e4117d6
Commit
2e4117d6
authored
Apr 22, 2025
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor sockets for transactions
parent
5e920bb5
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
338 additions
and
260 deletions
+338
-260
AddressTxs.pw.tsx
ui/address/AddressTxs.pw.tsx
+9
-39
AddressTxs.tsx
ui/address/AddressTxs.tsx
+4
-103
LatestTxs.tsx
ui/home/LatestTxs.tsx
+3
-3
ArbitrumL2TxnBatch.tsx
ui/pages/ArbitrumL2TxnBatch.tsx
+1
-1
Block.tsx
ui/pages/Block.tsx
+2
-2
KettleTxs.tsx
ui/pages/KettleTxs.tsx
+1
-4
OptimisticL2TxnBatch.tsx
ui/pages/OptimisticL2TxnBatch.tsx
+1
-1
ScrollL2TxnBatch.tsx
ui/pages/ScrollL2TxnBatch.tsx
+1
-1
Transactions.tsx
ui/pages/Transactions.tsx
+2
-12
ZkEvmL2TxnBatch.tsx
ui/pages/ZkEvmL2TxnBatch.tsx
+1
-1
ZkSyncL2TxnBatch.tsx
ui/pages/ZkSyncL2TxnBatch.tsx
+1
-1
TxsContent.tsx
ui/txs/TxsContent.tsx
+5
-12
TxsList.tsx
ui/txs/TxsList.tsx
+4
-12
TxsTable.pw.tsx
ui/txs/TxsTable.pw.tsx
+0
-2
TxsTable.tsx
ui/txs/TxsTable.tsx
+5
-15
TxsWatchlist.tsx
ui/txs/TxsWatchlist.tsx
+1
-1
TxsWithAPISorting.tsx
ui/txs/TxsWithAPISorting.tsx
+4
-9
TxsWithFrontendSorting.tsx
ui/txs/TxsWithFrontendSorting.tsx
+4
-9
TxsSocketNotice.tsx
ui/txs/socket/TxsSocketNotice.tsx
+38
-0
TxsSocketNoticeTypeAddress.tsx
ui/txs/socket/TxsSocketNoticeTypeAddress.tsx
+44
-0
TxsSocketNoticeTypeAll.tsx
ui/txs/socket/TxsSocketNoticeTypeAll.tsx
+45
-0
types.ts
ui/txs/socket/types.ts
+2
-0
useTxsSocketTypeAddress.tsx
ui/txs/socket/useTxsSocketTypeAddress.tsx
+129
-0
useTxsSocketTypeAll.tsx
ui/txs/socket/useTxsSocketTypeAll.tsx
+31
-32
No files found.
ui/address/AddressTxs.pw.tsx
View file @
2e4117d6
...
...
@@ -85,36 +85,6 @@ test.describe('socket', () => {
// test cases which use socket cannot run in parallel since the socket server always run on the same port
test
.
describe
.
configure
({
mode
:
'
serial
'
});
test
(
'
without overload
'
,
async
({
render
,
mockApiResponse
,
page
,
createSocket
})
=>
{
await
mockApiResponse
(
'
address_txs
'
,
{
items
:
[
txMock
.
base
],
next_page_params
:
DEFAULT_PAGINATION
},
{
pathParams
:
{
hash
:
CURRENT_ADDRESS
}
},
);
await
render
(
<
Box
pt=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
>
<
AddressTxs
/>
</
Box
>,
{
hooksConfig
},
{
withSocket
:
true
},
);
const
socket
=
await
createSocket
();
const
channel
=
await
socketServer
.
joinChannel
(
socket
,
`addresses:
${
CURRENT_ADDRESS
.
toLowerCase
()
}
`
);
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
socketServer
.
sendMessage
(
socket
,
channel
,
'
transaction
'
,
{
transactions
:
[
txMock
.
base2
,
txMock
.
base4
]
});
const
thirdRow
=
page
.
locator
(
'
tbody tr:nth-child(3)
'
);
await
thirdRow
.
waitFor
();
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
4
);
});
test
(
'
with update
'
,
async
({
render
,
mockApiResponse
,
page
,
createSocket
})
=>
{
await
mockApiResponse
(
'
address_txs
'
,
...
...
@@ -136,13 +106,13 @@ test.describe('socket', () => {
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
socketServer
.
sendMessage
(
socket
,
channel
,
'
transaction
'
,
{
transactions
:
[
txMock
.
base
,
txMock
.
base2
]
});
socketServer
.
sendMessage
(
socket
,
channel
,
'
transaction
'
,
{
transactions
:
[
txMock
.
base
]
});
const
thirdRow
=
page
.
locator
(
'
tbody tr:nth-child(3
)
'
);
await
thir
dRow
.
waitFor
();
const
secondRow
=
page
.
locator
(
'
tbody tr:nth-child(2
)
'
);
await
secon
dRow
.
waitFor
();
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
3
);
expect
(
itemsCountNew
).
toBe
(
2
);
});
test
(
'
with overload
'
,
async
({
render
,
mockApiResponse
,
page
,
createSocket
})
=>
{
...
...
@@ -154,7 +124,7 @@ test.describe('socket', () => {
await
render
(
<
Box
pt=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
>
<
AddressTxs
overloadCount=
{
2
}
/>
<
AddressTxs
/>
</
Box
>,
{
hooksConfig
},
{
withSocket
:
true
},
...
...
@@ -205,10 +175,10 @@ test.describe('socket', () => {
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
socketServer
.
sendMessage
(
socket
,
channel
,
'
transaction
'
,
{
transactions
:
[
txMock
.
base2
,
txMock
.
base4
]
});
socketServer
.
sendMessage
(
socket
,
channel
,
'
transaction
'
,
{
transactions
:
[
txMock
.
base2
]
});
const
thirdRow
=
page
.
locator
(
'
tbody tr:nth-child(3
)
'
);
await
thir
dRow
.
waitFor
();
const
secondRow
=
page
.
locator
(
'
tbody tr:nth-child(2
)
'
);
await
secon
dRow
.
waitFor
();
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
3
);
...
...
@@ -229,7 +199,7 @@ test.describe('socket', () => {
await
render
(
<
Box
pt=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
>
<
AddressTxs
overloadCount=
{
2
}
/>
<
AddressTxs
/>
</
Box
>,
{
hooksConfig
:
hooksConfigWithFilter
},
{
withSocket
:
true
},
...
...
ui/address/AddressTxs.tsx
View file @
2e4117d6
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
type
{
SocketMessage
}
from
'
lib/socket/types
'
;
import
type
{
AddressFromToFilter
,
AddressTransactionsResponse
}
from
'
types/api/address
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
{
AddressFromToFilterValues
}
from
'
types/api/address
'
;
import
type
{
Transaction
,
Transaction
sSortingField
,
TransactionsSortingValue
,
TransactionsSorting
}
from
'
types/api/transaction
'
;
import
type
{
TransactionsSortingField
,
TransactionsSortingValue
,
TransactionsSorting
}
from
'
types/api/transaction
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
import
{
TX
}
from
'
stubs/tx
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
ActionBar
,
{
ACTION_BAR_HEIGHT_DESKTOP
}
from
'
ui/shared/ActionBar
'
;
...
...
@@ -21,45 +16,23 @@ import Pagination from 'ui/shared/pagination/Pagination';
import
useQueryWithPages
from
'
ui/shared/pagination/useQueryWithPages
'
;
import
getSortParamsFromValue
from
'
ui/shared/sort/getSortParamsFromValue
'
;
import
getSortValueFromQuery
from
'
ui/shared/sort/getSortValueFromQuery
'
;
import
{
sortTxsFromSocket
}
from
'
ui/txs/sortTxs
'
;
import
TxsWithAPISorting
from
'
ui/txs/TxsWithAPISorting
'
;
import
{
SORT_OPTIONS
}
from
'
ui/txs/useTxsSort
'
;
import
AddressCsvExportLink
from
'
./AddressCsvExportLink
'
;
import
AddressTxsFilter
from
'
./AddressTxsFilter
'
;
const
OVERLOAD_COUNT
=
75
;
const
getFilterValue
=
(
getFilterValueFromQuery
<
AddressFromToFilter
>
).
bind
(
null
,
AddressFromToFilterValues
);
const
matchFilter
=
(
filterValue
:
AddressFromToFilter
,
transaction
:
Transaction
,
address
?:
string
)
=>
{
if
(
!
filterValue
)
{
return
true
;
}
if
(
filterValue
===
'
from
'
)
{
return
transaction
.
from
.
hash
===
address
;
}
if
(
filterValue
===
'
to
'
)
{
return
transaction
.
to
?.
hash
===
address
;
}
};
type
Props
=
{
shouldRender
?:
boolean
;
isQueryEnabled
?:
boolean
;
// for tests only
overloadCount
?:
number
;
};
const
AddressTxs
=
({
overloadCount
=
OVERLOAD_COUNT
,
shouldRender
=
true
,
isQueryEnabled
=
true
}:
Props
)
=>
{
const
AddressTxs
=
({
shouldRender
=
true
,
isQueryEnabled
=
true
}:
Props
)
=>
{
const
router
=
useRouter
();
const
queryClient
=
useQueryClient
();
const
isMounted
=
useIsMounted
();
const
[
socketAlert
,
setSocketAlert
]
=
React
.
useState
(
''
);
const
[
newItemsCount
,
setNewItemsCount
]
=
React
.
useState
(
0
);
const
[
sort
,
setSort
]
=
React
.
useState
<
TransactionsSortingValue
>
(
getSortValueFromQuery
<
TransactionsSortingValue
>
(
router
.
query
,
SORT_OPTIONS
)
||
'
default
'
);
const
isMobile
=
useIsMobile
();
...
...
@@ -90,76 +63,6 @@ const AddressTxs = ({ overloadCount = OVERLOAD_COUNT, shouldRender = true, isQue
addressTxsQuery
.
onFilterChange
({
filter
:
newVal
});
},
[
addressTxsQuery
]);
const
handleNewSocketMessage
:
SocketMessage
.
AddressTxs
[
'
handler
'
]
=
React
.
useCallback
((
payload
)
=>
{
setSocketAlert
(
''
);
queryClient
.
setQueryData
(
getResourceKey
(
'
address_txs
'
,
{
pathParams
:
{
hash
:
currentAddress
},
queryParams
:
{
filter
:
filterValue
}
}),
(
prevData
:
AddressTransactionsResponse
|
undefined
)
=>
{
if
(
!
prevData
)
{
return
;
}
const
newItems
:
Array
<
Transaction
>
=
[];
let
newCount
=
0
;
payload
.
transactions
.
forEach
(
tx
=>
{
const
currIndex
=
prevData
.
items
.
findIndex
((
item
)
=>
item
.
hash
===
tx
.
hash
);
if
(
currIndex
>
-
1
)
{
prevData
.
items
[
currIndex
]
=
tx
;
}
else
{
if
(
matchFilter
(
filterValue
,
tx
,
currentAddress
))
{
if
(
newItems
.
length
+
prevData
.
items
.
length
>=
overloadCount
)
{
newCount
++
;
}
else
{
newItems
.
push
(
tx
);
}
}
}
});
if
(
newCount
>
0
)
{
setNewItemsCount
(
prev
=>
prev
+
newCount
);
}
return
{
...
prevData
,
items
:
[
...
newItems
,
...
prevData
.
items
,
].
sort
(
sortTxsFromSocket
(
sort
)),
};
});
},
[
currentAddress
,
filterValue
,
overloadCount
,
queryClient
,
sort
]);
const
handleSocketClose
=
React
.
useCallback
(()
=>
{
setSocketAlert
(
'
Connection is lost. Please refresh the page to load new transactions.
'
);
},
[]);
const
handleSocketError
=
React
.
useCallback
(()
=>
{
setSocketAlert
(
'
An error has occurred while fetching new transactions. Please refresh the page.
'
);
},
[]);
const
channel
=
useSocketChannel
({
topic
:
`addresses:
${
currentAddress
?.
toLowerCase
()
}
`,
onSocketClose: handleSocketClose,
onSocketError: handleSocketError,
isDisabled: addressTxsQuery.pagination.page !== 1 || addressTxsQuery.isPlaceholderData,
});
useSocketMessage({
channel,
event: 'transaction',
handler: handleNewSocketMessage,
});
useSocketMessage({
channel,
event: 'pending_transaction',
handler: handleNewSocketMessage,
});
if
(
!
isMounted
||
!
shouldRender
)
{
return
null
;
}
...
...
@@ -197,9 +100,7 @@ const AddressTxs = ({ overloadCount = OVERLOAD_COUNT, shouldRender = true, isQue
query=
{
addressTxsQuery
}
currentAddress=
{
typeof
currentAddress
===
'
string
'
?
currentAddress
:
undefined
}
enableTimeIncrement
showSocketInfo={ addressTxsQuery.pagination.page === 1 }
socketInfoAlert={ socketAlert }
socketInfoNum={ newItemsCount }
socketType=
"address_txs"
top=
{
ACTION_BAR_HEIGHT_DESKTOP
}
sorting=
{
sort
}
setSort=
{
setSort
}
...
...
ui/home/LatestTxs.tsx
View file @
2e4117d6
...
...
@@ -6,10 +6,10 @@ import { route } from 'nextjs-routes';
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
{
AddressHighlightProvider
}
from
'
lib/contexts/addressHighlight
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useNewTxsSocket
from
'
lib/hooks/useNewTxsSocket
'
;
import
{
TX
}
from
'
stubs/tx
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
SocketNewItemsNotice
from
'
ui/shared/SocketNewItemsNotice
'
;
import
useNewTxsSocket
from
'
ui/txs/socket/useTxsSocketTypeAll
'
;
import
LatestTxsItem
from
'
./LatestTxsItem
'
;
import
LatestTxsItemMobile
from
'
./LatestTxsItemMobile
'
;
...
...
@@ -23,7 +23,7 @@ const LatestTransactions = () => {
},
});
const
{
num
,
socketAlert
}
=
useNewTxsSocket
(
);
const
{
num
,
alertText
}
=
useNewTxsSocket
({
type
:
'
txs_home
'
,
isLoading
:
isPlaceholderData
}
);
if
(
isError
)
{
return
<
Text
mt=
{
4
}
>
No data. Please reload the page.
</
Text
>;
...
...
@@ -33,7 +33,7 @@ const LatestTransactions = () => {
const
txsUrl
=
route
({
pathname
:
'
/txs
'
});
return
(
<>
<
SocketNewItemsNotice
borderBottomRadius=
{
0
}
url=
{
txsUrl
}
num=
{
num
}
alert=
{
socketAler
t
}
isLoading=
{
isPlaceholderData
}
/>
<
SocketNewItemsNotice
borderBottomRadius=
{
0
}
url=
{
txsUrl
}
num=
{
num
}
alert=
{
alertTex
t
}
isLoading=
{
isPlaceholderData
}
/>
<
Box
mb=
{
3
}
display=
{
{
base
:
'
block
'
,
lg
:
'
none
'
}
}
>
{
data
.
slice
(
0
,
txsCount
).
map
(((
tx
,
index
)
=>
(
<
LatestTxsItemMobile
...
...
ui/pages/ArbitrumL2TxnBatch.tsx
View file @
2e4117d6
...
...
@@ -85,7 +85,7 @@ const ArbitrumL2TxnBatch = () => {
{
id
:
'
txs
'
,
title
:
'
Transactions
'
,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
showSocketInfo=
{
false
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
},
{
id
:
'
blocks
'
,
...
...
ui/pages/Block.tsx
View file @
2e4117d6
...
...
@@ -73,7 +73,7 @@ const BlockPageContent = () => {
component
:
(
<>
{
blockTxsQuery
.
isDegradedData
&&
<
ServiceDegradationWarning
isLoading=
{
blockTxsQuery
.
isPlaceholderData
}
mb=
{
6
}
/>
}
<
TxsWithFrontendSorting
query=
{
blockTxsQuery
}
showBlockInfo=
{
false
}
showSocketInfo=
{
false
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>
<
TxsWithFrontendSorting
query=
{
blockTxsQuery
}
showBlockInfo=
{
false
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>
</>
),
},
...
...
@@ -82,7 +82,7 @@ const BlockPageContent = () => {
id
:
'
blob_txs
'
,
title
:
'
Blob txns
'
,
component
:
(
<
TxsWithFrontendSorting
query=
{
blockBlobTxsQuery
}
showBlockInfo=
{
false
}
showSocketInfo=
{
false
}
/>
<
TxsWithFrontendSorting
query=
{
blockBlobTxsQuery
}
showBlockInfo=
{
false
}
/>
),
}
:
null
,
config
.
features
.
beaconChain
.
isEnabled
&&
Boolean
(
blockQuery
.
data
?.
withdrawals_count
)
?
...
...
ui/pages/KettleTxs.tsx
View file @
2e4117d6
...
...
@@ -31,10 +31,7 @@ const KettleTxs = () => {
<>
<
PageTitle
title=
"Computor transactions"
withTextAd
/>
<
AddressEntity
address=
{
{
hash
}
}
mb=
{
6
}
/>
<
TxsWithFrontendSorting
query=
{
query
}
showSocketInfo=
{
false
}
/>
<
TxsWithFrontendSorting
query=
{
query
}
/>
</>
);
};
...
...
ui/pages/OptimisticL2TxnBatch.tsx
View file @
2e4117d6
...
...
@@ -83,7 +83,7 @@ const OptimisticL2TxnBatch = () => {
{
id
:
'
txs
'
,
title
:
'
Transactions
'
,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
showSocketInfo=
{
false
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
},
{
id
:
'
blocks
'
,
...
...
ui/pages/ScrollL2TxnBatch.tsx
View file @
2e4117d6
...
...
@@ -90,7 +90,7 @@ const ScrollL2TxnBatch = () => {
{
id
:
'
txs
'
,
title
:
'
Transactions
'
,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
showSocketInfo=
{
false
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
},
{
id
:
'
blocks
'
,
...
...
ui/pages/Transactions.tsx
View file @
2e4117d6
...
...
@@ -9,7 +9,6 @@ import { route } from 'nextjs-routes';
import
config
from
'
configs/app
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useNewTxsSocket
from
'
lib/hooks/useNewTxsSocket
'
;
import
getNetworkValidationActionText
from
'
lib/networks/getNetworkValidationActionText
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
TX
}
from
'
stubs/tx
'
;
...
...
@@ -91,8 +90,6 @@ const Transactions = () => {
},
});
const
{
num
,
socketAlert
}
=
useNewTxsSocket
();
const
isAuth
=
useIsAuth
();
const
tabs
:
Array
<
TabItemRegular
>
=
[
...
...
@@ -102,9 +99,7 @@ const Transactions = () => {
component
:
<
TxsWithFrontendSorting
query=
{
txsValidatedQuery
}
showSocketInfo=
{
txsValidatedQuery
.
pagination
.
page
===
1
}
socketInfoNum=
{
num
}
socketInfoAlert=
{
socketAlert
}
socketType=
"txs_validated"
top=
{
TABS_HEIGHT
}
/>
},
{
...
...
@@ -114,9 +109,7 @@ const Transactions = () => {
<
TxsWithFrontendSorting
query=
{
txsPendingQuery
}
showBlockInfo=
{
false
}
showSocketInfo=
{
txsPendingQuery
.
pagination
.
page
===
1
}
socketInfoNum=
{
num
}
socketInfoAlert=
{
socketAlert
}
socketType=
"txs_pending"
top=
{
TABS_HEIGHT
}
/>
),
...
...
@@ -127,9 +120,6 @@ const Transactions = () => {
component
:
(
<
TxsWithFrontendSorting
query=
{
txsWithBlobsQuery
}
showSocketInfo=
{
txsWithBlobsQuery
.
pagination
.
page
===
1
}
socketInfoNum=
{
num
}
socketInfoAlert=
{
socketAlert
}
top=
{
TABS_HEIGHT
}
/>
),
...
...
ui/pages/ZkEvmL2TxnBatch.tsx
View file @
2e4117d6
...
...
@@ -47,7 +47,7 @@ const ZkEvmL2TxnBatch = () => {
const
tabs
:
Array
<
TabItemRegular
>
=
React
.
useMemo
(()
=>
([
{
id
:
'
index
'
,
title
:
'
Details
'
,
component
:
<
ZkEvmL2TxnBatchDetails
query=
{
batchQuery
}
/>
},
{
id
:
'
txs
'
,
title
:
'
Transactions
'
,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
showSocketInfo=
{
false
}
/>
},
{
id
:
'
txs
'
,
title
:
'
Transactions
'
,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
/>
},
].
filter
(
Boolean
)),
[
batchQuery
,
batchTxsQuery
]);
const
backLink
=
React
.
useMemo
(()
=>
{
...
...
ui/pages/ZkSyncL2TxnBatch.tsx
View file @
2e4117d6
...
...
@@ -67,7 +67,7 @@ const ZkSyncL2TxnBatch = () => {
{
id
:
'
txs
'
,
title
:
'
Transactions
'
,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
showSocketInfo=
{
false
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
},
].
filter
(
Boolean
)),
[
batchQuery
,
batchTxsQuery
,
hasPagination
]);
...
...
ui/txs/TxsContent.tsx
View file @
2e4117d6
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
TxsSocketType
}
from
'
./socket/types
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
Transaction
,
TransactionsSortingField
,
TransactionsSortingValue
}
from
'
types/api/transaction
'
;
...
...
@@ -26,9 +27,7 @@ type Props = {
// eslint-disable-next-line max-len
query
:
QueryWithPagesResult
<
'
txs_validated
'
|
'
txs_pending
'
>
|
QueryWithPagesResult
<
'
txs_watchlist
'
>
|
QueryWithPagesResult
<
'
block_txs
'
>
|
QueryWithPagesResult
<
'
zkevm_l2_txn_batch_txs
'
>
;
showBlockInfo
?:
boolean
;
showSocketInfo
?:
boolean
;
socketInfoAlert
?:
string
;
socketInfoNum
?:
number
;
socketType
?:
TxsSocketType
;
currentAddress
?:
string
;
filter
?:
React
.
ReactNode
;
filterValue
?:
AddressFromToFilter
;
...
...
@@ -46,9 +45,7 @@ const TxsContent = ({
filter
,
filterValue
,
showBlockInfo
=
true
,
showSocketInfo
=
true
,
socketInfoAlert
,
socketInfoNum
,
socketType
,
currentAddress
,
enableTimeIncrement
,
top
,
...
...
@@ -72,9 +69,7 @@ const TxsContent = ({
<
Box
hideFrom=
"lg"
>
<
TxsList
showBlockInfo=
{
showBlockInfo
}
showSocketInfo=
{
showSocketInfo
}
socketInfoAlert=
{
socketInfoAlert
}
socketInfoNum=
{
socketInfoNum
}
socketType=
{
socketType
}
isLoading=
{
isPlaceholderData
}
enableTimeIncrement=
{
enableTimeIncrement
}
currentAddress=
{
currentAddress
}
...
...
@@ -87,9 +82,7 @@ const TxsContent = ({
sort=
{
sort
}
onSortToggle=
{
onSortToggle
}
showBlockInfo=
{
showBlockInfo
}
showSocketInfo=
{
showSocketInfo
}
socketInfoAlert=
{
socketInfoAlert
}
socketInfoNum=
{
socketInfoNum
}
socketType=
{
socketType
}
top=
{
top
||
(
query
.
pagination
.
isVisible
?
ACTION_BAR_HEIGHT_DESKTOP
:
0
)
}
currentAddress=
{
currentAddress
}
enableTimeIncrement=
{
enableTimeIncrement
}
...
...
ui/txs/TxsList.tsx
View file @
2e4117d6
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
TxsSocketType
}
from
'
./socket/types
'
;
import
type
{
Transaction
}
from
'
types/api/transaction
'
;
import
useInitialList
from
'
lib/hooks/useInitialList
'
;
import
useLazyRenderedList
from
'
lib/hooks/useLazyRenderedList
'
;
import
*
as
SocketNewItemsNotice
from
'
ui/shared/SocketNewItemsNotice
'
;
import
TxsSocketNotice
from
'
./socket/TxsSocketNotice
'
;
import
TxsListItem
from
'
./TxsListItem
'
;
interface
Props
{
showBlockInfo
:
boolean
;
showSocketInfo
?:
boolean
;
socketInfoAlert
?:
string
;
socketInfoNum
?:
number
;
socketType
?:
TxsSocketType
;
enableTimeIncrement
?:
boolean
;
currentAddress
?:
string
;
isLoading
:
boolean
;
...
...
@@ -30,14 +29,7 @@ const TxsList = (props: Props) => {
return
(
<
Box
>
{
props
.
showSocketInfo
&&
(
<
SocketNewItemsNotice
.
Mobile
url=
{
window
.
location
.
href
}
num=
{
props
.
socketInfoNum
}
alert=
{
props
.
socketInfoAlert
}
isLoading=
{
props
.
isLoading
}
/>
)
}
{
props
.
socketType
&&
<
TxsSocketNotice
type=
{
props
.
socketType
}
place=
"list"
isLoading=
{
props
.
isLoading
}
/>
}
{
props
.
items
.
slice
(
0
,
renderedItemsNum
).
map
((
tx
,
index
)
=>
(
<
TxsListItem
key=
{
tx
.
hash
+
(
props
.
isLoading
?
index
:
''
)
}
...
...
ui/txs/TxsTable.pw.tsx
View file @
2e4117d6
...
...
@@ -15,7 +15,6 @@ test('base view +@dark-mode', async({ render }) => {
onSortToggle=
{
()
=>
{}
}
top=
{
0
}
showBlockInfo
showSocketInfo=
{
false
}
/>,
);
...
...
@@ -36,7 +35,6 @@ test.describe('screen xl', () => {
onSortToggle=
{
()
=>
{}
}
top=
{
0
}
showBlockInfo
showSocketInfo=
{
false
}
/>,
);
...
...
ui/txs/TxsTable.tsx
View file @
2e4117d6
import
React
from
'
react
'
;
import
type
{
TxsSocketType
}
from
'
./socket/types
'
;
import
type
{
Transaction
,
TransactionsSortingField
,
TransactionsSortingValue
}
from
'
types/api/transaction
'
;
import
config
from
'
configs/app
'
;
...
...
@@ -8,8 +9,8 @@ import useInitialList from 'lib/hooks/useInitialList';
import
useLazyRenderedList
from
'
lib/hooks/useLazyRenderedList
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
TableBody
,
TableColumnHeader
,
TableColumnHeaderSortable
,
TableHeaderSticky
,
TableRoot
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
*
as
SocketNewItemsNotice
from
'
ui/shared/SocketNewItemsNotice
'
;
import
TxsSocketNotice
from
'
./socket/TxsSocketNotice
'
;
import
TxsTableItem
from
'
./TxsTableItem
'
;
type
Props
=
{
...
...
@@ -18,9 +19,7 @@ type Props = {
onSortToggle
:
(
field
:
TransactionsSortingField
)
=>
void
;
top
:
number
;
showBlockInfo
:
boolean
;
showSocketInfo
:
boolean
;
socketInfoAlert
?:
string
;
socketInfoNum
?:
number
;
socketType
?:
TxsSocketType
;
currentAddress
?:
string
;
enableTimeIncrement
?:
boolean
;
isLoading
?:
boolean
;
...
...
@@ -32,9 +31,7 @@ const TxsTable = ({
onSortToggle
,
top
,
showBlockInfo
,
showSocketInfo
,
socketInfoAlert
,
socketInfoNum
,
socketType
,
currentAddress
,
enableTimeIncrement
,
isLoading
,
...
...
@@ -96,14 +93,7 @@ const TxsTable = ({
</
TableRow
>
</
TableHeaderSticky
>
<
TableBody
>
{
showSocketInfo
&&
(
<
SocketNewItemsNotice
.
Desktop
url=
{
window
.
location
.
href
}
alert=
{
socketInfoAlert
}
num=
{
socketInfoNum
}
isLoading=
{
isLoading
}
/>
)
}
{
socketType
&&
<
TxsSocketNotice
type=
{
socketType
}
place=
"table"
isLoading=
{
isLoading
}
/>
}
{
txs
.
slice
(
0
,
renderedItemsNum
).
map
((
item
,
index
)
=>
(
<
TxsTableItem
key=
{
item
.
hash
+
(
isLoading
?
index
:
''
)
}
...
...
ui/txs/TxsWatchlist.tsx
View file @
2e4117d6
...
...
@@ -10,7 +10,7 @@ type Props = {
const
TxsWatchlist
=
({
query
}:
Props
)
=>
{
useRedirectForInvalidAuthToken
();
return
<
TxsWithFrontendSorting
query=
{
query
}
showSocketInfo=
{
false
}
top=
{
88
}
/>;
return
<
TxsWithFrontendSorting
query=
{
query
}
top=
{
88
}
/>;
};
export
default
TxsWatchlist
;
ui/txs/TxsWithAPISorting.tsx
View file @
2e4117d6
import
React
from
'
react
'
;
import
type
{
TxsSocketType
}
from
'
./socket/types
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
TransactionsSortingValue
}
from
'
types/api/transaction
'
;
...
...
@@ -12,9 +13,7 @@ type Props = {
query
:
QueryWithPagesResult
<
'
address_txs
'
>
;
showBlockInfo
?:
boolean
;
showSocketInfo
?:
boolean
;
socketInfoAlert
?:
string
;
socketInfoNum
?:
number
;
socketType
?:
TxsSocketType
;
currentAddress
?:
string
;
filter
?:
React
.
ReactNode
;
filterValue
?:
AddressFromToFilter
;
...
...
@@ -29,9 +28,7 @@ const TxsWithAPISorting = ({
filterValue
,
query
,
showBlockInfo
=
true
,
showSocketInfo
=
true
,
socketInfoAlert
,
socketInfoNum
,
socketType
,
currentAddress
,
enableTimeIncrement
,
top
,
...
...
@@ -49,9 +46,7 @@ const TxsWithAPISorting = ({
filter=
{
filter
}
filterValue=
{
filterValue
}
showBlockInfo=
{
showBlockInfo
}
showSocketInfo=
{
showSocketInfo
}
socketInfoAlert=
{
socketInfoAlert
}
socketInfoNum=
{
socketInfoNum
}
socketType=
{
socketType
}
currentAddress=
{
currentAddress
}
enableTimeIncrement=
{
enableTimeIncrement
}
top=
{
top
}
...
...
ui/txs/TxsWithFrontendSorting.tsx
View file @
2e4117d6
import
React
from
'
react
'
;
import
type
{
TxsSocketType
}
from
'
./socket/types
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
QueryWithPagesResult
}
from
'
ui/shared/pagination/useQueryWithPages
'
;
...
...
@@ -11,9 +12,7 @@ type Props = {
// eslint-disable-next-line max-len
query
:
QueryWithPagesResult
<
'
txs_validated
'
|
'
txs_pending
'
>
|
QueryWithPagesResult
<
'
txs_watchlist
'
>
|
QueryWithPagesResult
<
'
block_txs
'
>
|
QueryWithPagesResult
<
'
zkevm_l2_txn_batch_txs
'
>
;
showBlockInfo
?:
boolean
;
showSocketInfo
?:
boolean
;
socketInfoAlert
?:
string
;
socketInfoNum
?:
number
;
socketType
?:
TxsSocketType
;
currentAddress
?:
string
;
filter
?:
React
.
ReactNode
;
filterValue
?:
AddressFromToFilter
;
...
...
@@ -26,9 +25,7 @@ const TxsWithFrontendSorting = ({
filterValue
,
query
,
showBlockInfo
=
true
,
showSocketInfo
=
true
,
socketInfoAlert
,
socketInfoNum
,
socketType
,
currentAddress
,
enableTimeIncrement
,
top
,
...
...
@@ -40,9 +37,7 @@ const TxsWithFrontendSorting = ({
filter=
{
filter
}
filterValue=
{
filterValue
}
showBlockInfo=
{
showBlockInfo
}
showSocketInfo=
{
showSocketInfo
}
socketInfoAlert=
{
socketInfoAlert
}
socketInfoNum=
{
socketInfoNum
}
socketType=
{
socketType
}
currentAddress=
{
currentAddress
}
enableTimeIncrement=
{
enableTimeIncrement
}
top=
{
top
}
...
...
ui/txs/socket/TxsSocketNotice.tsx
0 → 100644
View file @
2e4117d6
import
React
from
'
react
'
;
import
type
{
TxsSocketNoticePlace
,
TxsSocketType
}
from
'
./types
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
TxsSocketNoticeTypeAddress
from
'
./TxsSocketNoticeTypeAddress
'
;
import
TxsSocketNoticeTypeAll
from
'
./TxsSocketNoticeTypeAll
'
;
interface
Props
{
type
:
TxsSocketType
;
place
:
TxsSocketNoticePlace
;
isLoading
?:
boolean
;
}
const
TxsSocketNotice
=
({
type
,
place
,
isLoading
}:
Props
)
=>
{
const
isMobile
=
useIsMobile
();
if
((
isMobile
&&
place
===
'
table
'
)
||
(
!
isMobile
&&
place
===
'
list
'
))
{
return
null
;
}
switch
(
type
)
{
case
'
txs_home
'
:
case
'
txs_validated
'
:
case
'
txs_pending
'
:
{
return
<
TxsSocketNoticeTypeAll
type=
{
type
}
place=
{
place
}
isLoading=
{
isLoading
}
/>;
}
case
'
address_txs
'
:
{
return
<
TxsSocketNoticeTypeAddress
place=
{
place
}
isLoading=
{
isLoading
}
/>;
}
default
:
return
null
;
}
};
export
default
React
.
memo
(
TxsSocketNotice
);
ui/txs/socket/TxsSocketNoticeTypeAddress.tsx
0 → 100644
View file @
2e4117d6
import
React
from
'
react
'
;
import
type
{
TxsSocketNoticePlace
}
from
'
./types
'
;
import
*
as
SocketNewItemsNotice
from
'
ui/shared/SocketNewItemsNotice
'
;
import
useTxsSocketTypeAddress
from
'
./useTxsSocketTypeAddress
'
;
interface
Props
{
place
:
TxsSocketNoticePlace
;
isLoading
?:
boolean
;
}
const
TxsSocketNoticeTypeAddress
=
({
place
,
isLoading
}:
Props
)
=>
{
const
{
num
,
alertText
}
=
useTxsSocketTypeAddress
({
isLoading
});
if
(
num
===
undefined
)
{
return
null
;
}
if
(
place
===
'
table
'
)
{
return
(
<
SocketNewItemsNotice
.
Desktop
url=
{
window
.
location
.
href
}
alert=
{
alertText
}
num=
{
num
}
isLoading=
{
isLoading
}
/>
);
}
if
(
place
===
'
list
'
)
{
return
(
<
SocketNewItemsNotice
.
Mobile
url=
{
window
.
location
.
href
}
num=
{
num
}
alert=
{
alertText
}
isLoading=
{
isLoading
}
/>
);
}
};
export
default
React
.
memo
(
TxsSocketNoticeTypeAddress
);
ui/txs/socket/TxsSocketNoticeTypeAll.tsx
0 → 100644
View file @
2e4117d6
import
React
from
'
react
'
;
import
type
{
TxsSocketNoticePlace
,
TxsSocketType
}
from
'
./types
'
;
import
*
as
SocketNewItemsNotice
from
'
ui/shared/SocketNewItemsNotice
'
;
import
useNewTxsSocketTypeAll
from
'
./useTxsSocketTypeAll
'
;
interface
Props
{
type
:
TxsSocketType
;
place
:
TxsSocketNoticePlace
;
isLoading
?:
boolean
;
}
const
TxsSocketNoticeTypeAll
=
({
type
,
place
,
isLoading
}:
Props
)
=>
{
const
{
num
,
alertText
}
=
useNewTxsSocketTypeAll
({
type
,
isLoading
});
if
(
num
===
undefined
)
{
return
null
;
}
if
(
place
===
'
table
'
)
{
return
(
<
SocketNewItemsNotice
.
Desktop
url=
{
window
.
location
.
href
}
alert=
{
alertText
}
num=
{
num
}
isLoading=
{
isLoading
}
/>
);
}
if
(
place
===
'
list
'
)
{
return
(
<
SocketNewItemsNotice
.
Mobile
url=
{
window
.
location
.
href
}
num=
{
num
}
alert=
{
alertText
}
isLoading=
{
isLoading
}
/>
);
}
};
export
default
React
.
memo
(
TxsSocketNoticeTypeAll
);
ui/txs/socket/types.ts
0 → 100644
View file @
2e4117d6
export
type
TxsSocketType
=
'
txs_validated
'
|
'
txs_pending
'
|
'
txs_home
'
|
'
address_txs
'
;
export
type
TxsSocketNoticePlace
=
'
list
'
|
'
table
'
;
ui/txs/socket/useTxsSocketTypeAddress.tsx
0 → 100644
View file @
2e4117d6
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
type
{
SocketMessage
}
from
'
lib/socket/types
'
;
import
type
{
AddressFromToFilter
,
AddressTransactionsResponse
}
from
'
types/api/address
'
;
import
type
{
Transaction
,
TransactionsSortingValue
}
from
'
types/api/transaction
'
;
import
config
from
'
configs/app
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
import
getSortValueFromQuery
from
'
ui/shared/sort/getSortValueFromQuery
'
;
import
{
sortTxsFromSocket
}
from
'
../sortTxs
'
;
import
{
SORT_OPTIONS
}
from
'
../useTxsSort
'
;
const
matchFilter
=
(
filterValue
:
AddressFromToFilter
,
transaction
:
Transaction
,
address
?:
string
)
=>
{
if
(
!
filterValue
)
{
return
true
;
}
if
(
filterValue
===
'
from
'
)
{
return
transaction
.
from
.
hash
===
address
;
}
if
(
filterValue
===
'
to
'
)
{
return
transaction
.
to
?.
hash
===
address
;
}
};
const
OVERLOAD_COUNT
=
config
.
app
.
isPw
?
2
:
75
;
interface
Params
{
isLoading
?:
boolean
;
}
export
default
function
useTxsSocketTypeAddress
({
isLoading
}:
Params
)
{
const
[
alertText
,
setAlertText
]
=
React
.
useState
(
''
);
const
[
num
,
setNum
]
=
React
.
useState
(
0
);
const
router
=
useRouter
();
const
queryClient
=
useQueryClient
();
const
currentAddress
=
getQueryParamString
(
router
.
query
.
hash
);
const
filterValue
=
getQueryParamString
(
router
.
query
.
filter
);
const
page
=
getQueryParamString
(
router
.
query
.
page
);
const
sort
=
getSortValueFromQuery
<
TransactionsSortingValue
>
(
router
.
query
,
SORT_OPTIONS
)
||
'
default
'
;
const
handleNewSocketMessage
:
SocketMessage
.
AddressTxs
[
'
handler
'
]
=
React
.
useCallback
((
payload
)
=>
{
setAlertText
(
''
);
queryClient
.
setQueryData
(
getResourceKey
(
'
address_txs
'
,
{
pathParams
:
{
hash
:
currentAddress
},
queryParams
:
filterValue
?
{
filter
:
filterValue
}
:
undefined
}),
(
prevData
:
AddressTransactionsResponse
|
undefined
)
=>
{
if
(
!
prevData
)
{
return
;
}
const
newItems
:
Array
<
Transaction
>
=
[];
let
newCount
=
0
;
payload
.
transactions
.
forEach
(
tx
=>
{
const
currIndex
=
prevData
.
items
.
findIndex
((
item
)
=>
item
.
hash
===
tx
.
hash
);
if
(
currIndex
>
-
1
)
{
prevData
.
items
[
currIndex
]
=
tx
;
}
else
{
const
isMatch
=
matchFilter
(
filterValue
as
AddressFromToFilter
,
tx
,
currentAddress
);
if
(
isMatch
)
{
if
(
newItems
.
length
+
prevData
.
items
.
length
>=
OVERLOAD_COUNT
)
{
newCount
++
;
}
else
{
newItems
.
push
(
tx
);
}
}
}
});
if
(
newCount
>
0
)
{
setNum
(
prev
=>
prev
+
newCount
);
}
return
{
...
prevData
,
items
:
[
...
newItems
,
...
prevData
.
items
,
].
sort
(
sortTxsFromSocket
(
sort
)),
};
});
},
[
currentAddress
,
filterValue
,
queryClient
,
sort
]);
const
handleSocketClose
=
React
.
useCallback
(()
=>
{
setAlertText
(
'
Connection is lost. Please refresh the page to load new transactions.
'
);
},
[]);
const
handleSocketError
=
React
.
useCallback
(()
=>
{
setAlertText
(
'
An error has occurred while fetching new transactions. Please refresh the page.
'
);
},
[]);
const
isDisabled
=
Boolean
((
page
&&
page
!==
'
1
'
)
||
isLoading
);
const
channel
=
useSocketChannel
({
topic
:
`addresses:
${
currentAddress
?.
toLowerCase
()
}
`,
onSocketClose: handleSocketClose,
onSocketError: handleSocketError,
isDisabled,
});
useSocketMessage({
channel,
event: 'transaction',
handler: handleNewSocketMessage,
});
useSocketMessage({
channel,
event: 'pending_transaction',
handler: handleNewSocketMessage,
});
if (isDisabled) {
return { };
}
return { num, alertText };
}
lib/hooks/useNewTxsSocket
.tsx
→
ui/txs/socket/useTxsSocketTypeAll
.tsx
View file @
2e4117d6
import
type
{
NextRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
type
{
TxsSocketType
}
from
'
./types
'
;
import
useGradualIncrement
from
'
lib/hooks/useGradualIncrement
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
function
getSocketParams
(
router
:
NextRouter
)
{
if
(
router
.
pathname
===
'
/txs
'
&&
(
router
.
query
.
tab
===
'
validated
'
||
router
.
query
.
tab
===
undefined
)
&&
!
router
.
query
.
block_number
&&
!
router
.
query
.
page
)
{
return
{
topic
:
'
transactions:new_transaction
'
as
const
,
event
:
'
transaction
'
as
const
};
}
if
(
router
.
pathname
===
'
/
'
)
{
return
{
topic
:
'
transactions:new_transaction
'
as
const
,
event
:
'
transaction
'
as
const
};
}
function
getSocketParams
(
type
:
TxsSocketType
,
page
:
string
)
{
if
(
router
.
pathname
===
'
/txs
'
&&
router
.
query
.
tab
===
'
pending
'
&&
!
router
.
query
.
block_number
&&
!
router
.
query
.
page
)
{
return
{
topic
:
'
transactions:new_pending_transaction
'
as
const
,
event
:
'
pending_transaction
'
as
const
};
switch
(
type
)
{
case
'
txs_home
'
:
{
return
{
topic
:
'
transactions:new_transaction
'
as
const
,
event
:
'
transaction
'
as
const
};
}
case
'
txs_validated
'
:
{
return
!
page
||
page
===
'
1
'
?
{
topic
:
'
transactions:new_transaction
'
as
const
,
event
:
'
transaction
'
as
const
}
:
{};
}
case
'
txs_pending
'
:
{
return
!
page
||
page
===
'
1
'
?
{
topic
:
'
transactions:new_pending_transaction
'
as
const
,
event
:
'
pending_transaction
'
as
const
}
:
{};
}
default
:
return
{};
}
return
{};
}
function
assertIsNewTxResponse
(
response
:
unknown
):
response
is
{
transaction
:
number
}
{
...
...
@@ -40,12 +32,19 @@ function assertIsNewPendingTxResponse(response: unknown): response is { pending_
return
typeof
response
===
'
object
'
&&
response
!==
null
&&
'
pending_transaction
'
in
response
;
}
export
default
function
useNewTxsSocket
()
{
interface
Params
{
type
:
TxsSocketType
;
isLoading
?:
boolean
;
}
export
default
function
useNewTxsSocketTypeAll
({
type
,
isLoading
}:
Params
)
{
const
router
=
useRouter
();
const
page
=
getQueryParamString
(
router
.
query
.
page
);
const
[
num
,
setNum
]
=
useGradualIncrement
(
0
);
const
[
socketAlert
,
setSocketAler
t
]
=
React
.
useState
(
''
);
const
[
alertText
,
setAlertTex
t
]
=
React
.
useState
(
''
);
const
{
topic
,
event
}
=
getSocketParams
(
router
);
const
{
topic
,
event
}
=
getSocketParams
(
type
,
page
);
const
handleNewTxMessage
=
React
.
useCallback
((
response
:
{
transaction
:
number
}
|
{
pending_transaction
:
number
}
|
unknown
)
=>
{
if
(
assertIsNewTxResponse
(
response
))
{
...
...
@@ -57,18 +56,18 @@ export default function useNewTxsSocket() {
},
[
setNum
]);
const
handleSocketClose
=
React
.
useCallback
(()
=>
{
set
SocketAler
t
(
'
Connection is lost. Please reload the page.
'
);
set
AlertTex
t
(
'
Connection is lost. Please reload the page.
'
);
},
[]);
const
handleSocketError
=
React
.
useCallback
(()
=>
{
set
SocketAler
t
(
'
An error has occurred while fetching new transactions. Please reload the page.
'
);
set
AlertTex
t
(
'
An error has occurred while fetching new transactions. Please reload the page.
'
);
},
[]);
const
channel
=
useSocketChannel
({
topic
,
onSocketClose
:
handleSocketClose
,
onSocketError
:
handleSocketError
,
isDisabled
:
!
topic
,
isDisabled
:
!
topic
||
Boolean
(
isLoading
)
,
});
useSocketMessage
({
...
...
@@ -78,8 +77,8 @@ export default function useNewTxsSocket() {
});
if
(
!
topic
&&
!
event
)
{
return
{};
return
{
};
}
return
{
num
,
socketAler
t
};
return
{
num
,
alertTex
t
};
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment