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', () => {
...
@@ -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 cases which use socket cannot run in parallel since the socket server always run on the same port
test
.
describe
.
configure
({
mode
:
'
serial
'
});
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
})
=>
{
test
(
'
with update
'
,
async
({
render
,
mockApiResponse
,
page
,
createSocket
})
=>
{
await
mockApiResponse
(
await
mockApiResponse
(
'
address_txs
'
,
'
address_txs
'
,
...
@@ -136,13 +106,13 @@ test.describe('socket', () => {
...
@@ -136,13 +106,13 @@ test.describe('socket', () => {
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
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
)
'
);
const
secondRow
=
page
.
locator
(
'
tbody tr:nth-child(2
)
'
);
await
thir
dRow
.
waitFor
();
await
secon
dRow
.
waitFor
();
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
3
);
expect
(
itemsCountNew
).
toBe
(
2
);
});
});
test
(
'
with overload
'
,
async
({
render
,
mockApiResponse
,
page
,
createSocket
})
=>
{
test
(
'
with overload
'
,
async
({
render
,
mockApiResponse
,
page
,
createSocket
})
=>
{
...
@@ -154,7 +124,7 @@ test.describe('socket', () => {
...
@@ -154,7 +124,7 @@ test.describe('socket', () => {
await
render
(
await
render
(
<
Box
pt=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
>
<
Box
pt=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
>
<
AddressTxs
overloadCount=
{
2
}
/>
<
AddressTxs
/>
</
Box
>,
</
Box
>,
{
hooksConfig
},
{
hooksConfig
},
{
withSocket
:
true
},
{
withSocket
:
true
},
...
@@ -205,10 +175,10 @@ test.describe('socket', () => {
...
@@ -205,10 +175,10 @@ test.describe('socket', () => {
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
const
itemsCount
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCount
).
toBe
(
2
);
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
)
'
);
const
secondRow
=
page
.
locator
(
'
tbody tr:nth-child(2
)
'
);
await
thir
dRow
.
waitFor
();
await
secon
dRow
.
waitFor
();
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
const
itemsCountNew
=
await
page
.
locator
(
'
tbody tr
'
).
count
();
expect
(
itemsCountNew
).
toBe
(
3
);
expect
(
itemsCountNew
).
toBe
(
3
);
...
@@ -229,7 +199,7 @@ test.describe('socket', () => {
...
@@ -229,7 +199,7 @@ test.describe('socket', () => {
await
render
(
await
render
(
<
Box
pt=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
>
<
Box
pt=
{
{
base
:
'
134px
'
,
lg
:
6
}
}
>
<
AddressTxs
overloadCount=
{
2
}
/>
<
AddressTxs
/>
</
Box
>,
</
Box
>,
{
hooksConfig
:
hooksConfigWithFilter
},
{
hooksConfig
:
hooksConfigWithFilter
},
{
withSocket
:
true
},
{
withSocket
:
true
},
...
...
ui/address/AddressTxs.tsx
View file @
2e4117d6
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
SocketMessage
}
from
'
lib/socket/types
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
AddressFromToFilter
,
AddressTransactionsResponse
}
from
'
types/api/address
'
;
import
{
AddressFromToFilterValues
}
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
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
import
{
TX
}
from
'
stubs/tx
'
;
import
{
TX
}
from
'
stubs/tx
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
ActionBar
,
{
ACTION_BAR_HEIGHT_DESKTOP
}
from
'
ui/shared/ActionBar
'
;
import
ActionBar
,
{
ACTION_BAR_HEIGHT_DESKTOP
}
from
'
ui/shared/ActionBar
'
;
...
@@ -21,45 +16,23 @@ import Pagination from 'ui/shared/pagination/Pagination';
...
@@ -21,45 +16,23 @@ import Pagination from 'ui/shared/pagination/Pagination';
import
useQueryWithPages
from
'
ui/shared/pagination/useQueryWithPages
'
;
import
useQueryWithPages
from
'
ui/shared/pagination/useQueryWithPages
'
;
import
getSortParamsFromValue
from
'
ui/shared/sort/getSortParamsFromValue
'
;
import
getSortParamsFromValue
from
'
ui/shared/sort/getSortParamsFromValue
'
;
import
getSortValueFromQuery
from
'
ui/shared/sort/getSortValueFromQuery
'
;
import
getSortValueFromQuery
from
'
ui/shared/sort/getSortValueFromQuery
'
;
import
{
sortTxsFromSocket
}
from
'
ui/txs/sortTxs
'
;
import
TxsWithAPISorting
from
'
ui/txs/TxsWithAPISorting
'
;
import
TxsWithAPISorting
from
'
ui/txs/TxsWithAPISorting
'
;
import
{
SORT_OPTIONS
}
from
'
ui/txs/useTxsSort
'
;
import
{
SORT_OPTIONS
}
from
'
ui/txs/useTxsSort
'
;
import
AddressCsvExportLink
from
'
./AddressCsvExportLink
'
;
import
AddressCsvExportLink
from
'
./AddressCsvExportLink
'
;
import
AddressTxsFilter
from
'
./AddressTxsFilter
'
;
import
AddressTxsFilter
from
'
./AddressTxsFilter
'
;
const
OVERLOAD_COUNT
=
75
;
const
getFilterValue
=
(
getFilterValueFromQuery
<
AddressFromToFilter
>
).
bind
(
null
,
AddressFromToFilterValues
);
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
=
{
type
Props
=
{
shouldRender
?:
boolean
;
shouldRender
?:
boolean
;
isQueryEnabled
?:
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
router
=
useRouter
();
const
queryClient
=
useQueryClient
();
const
isMounted
=
useIsMounted
();
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
[
sort
,
setSort
]
=
React
.
useState
<
TransactionsSortingValue
>
(
getSortValueFromQuery
<
TransactionsSortingValue
>
(
router
.
query
,
SORT_OPTIONS
)
||
'
default
'
);
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
...
@@ -90,76 +63,6 @@ const AddressTxs = ({ overloadCount = OVERLOAD_COUNT, shouldRender = true, isQue
...
@@ -90,76 +63,6 @@ const AddressTxs = ({ overloadCount = OVERLOAD_COUNT, shouldRender = true, isQue
addressTxsQuery
.
onFilterChange
({
filter
:
newVal
});
addressTxsQuery
.
onFilterChange
({
filter
:
newVal
});
},
[
addressTxsQuery
]);
},
[
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
)
{
if
(
!
isMounted
||
!
shouldRender
)
{
return
null
;
return
null
;
}
}
...
@@ -197,9 +100,7 @@ const AddressTxs = ({ overloadCount = OVERLOAD_COUNT, shouldRender = true, isQue
...
@@ -197,9 +100,7 @@ const AddressTxs = ({ overloadCount = OVERLOAD_COUNT, shouldRender = true, isQue
query=
{
addressTxsQuery
}
query=
{
addressTxsQuery
}
currentAddress=
{
typeof
currentAddress
===
'
string
'
?
currentAddress
:
undefined
}
currentAddress=
{
typeof
currentAddress
===
'
string
'
?
currentAddress
:
undefined
}
enableTimeIncrement
enableTimeIncrement
showSocketInfo={ addressTxsQuery.pagination.page === 1 }
socketType=
"address_txs"
socketInfoAlert={ socketAlert }
socketInfoNum={ newItemsCount }
top=
{
ACTION_BAR_HEIGHT_DESKTOP
}
top=
{
ACTION_BAR_HEIGHT_DESKTOP
}
sorting=
{
sort
}
sorting=
{
sort
}
setSort=
{
setSort
}
setSort=
{
setSort
}
...
...
ui/home/LatestTxs.tsx
View file @
2e4117d6
...
@@ -6,10 +6,10 @@ import { route } from 'nextjs-routes';
...
@@ -6,10 +6,10 @@ import { route } from 'nextjs-routes';
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
{
AddressHighlightProvider
}
from
'
lib/contexts/addressHighlight
'
;
import
{
AddressHighlightProvider
}
from
'
lib/contexts/addressHighlight
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useNewTxsSocket
from
'
lib/hooks/useNewTxsSocket
'
;
import
{
TX
}
from
'
stubs/tx
'
;
import
{
TX
}
from
'
stubs/tx
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
SocketNewItemsNotice
from
'
ui/shared/SocketNewItemsNotice
'
;
import
SocketNewItemsNotice
from
'
ui/shared/SocketNewItemsNotice
'
;
import
useNewTxsSocket
from
'
ui/txs/socket/useTxsSocketTypeAll
'
;
import
LatestTxsItem
from
'
./LatestTxsItem
'
;
import
LatestTxsItem
from
'
./LatestTxsItem
'
;
import
LatestTxsItemMobile
from
'
./LatestTxsItemMobile
'
;
import
LatestTxsItemMobile
from
'
./LatestTxsItemMobile
'
;
...
@@ -23,7 +23,7 @@ const LatestTransactions = () => {
...
@@ -23,7 +23,7 @@ const LatestTransactions = () => {
},
},
});
});
const
{
num
,
socketAlert
}
=
useNewTxsSocket
(
);
const
{
num
,
alertText
}
=
useNewTxsSocket
({
type
:
'
txs_home
'
,
isLoading
:
isPlaceholderData
}
);
if
(
isError
)
{
if
(
isError
)
{
return
<
Text
mt=
{
4
}
>
No data. Please reload the page.
</
Text
>;
return
<
Text
mt=
{
4
}
>
No data. Please reload the page.
</
Text
>;
...
@@ -33,7 +33,7 @@ const LatestTransactions = () => {
...
@@ -33,7 +33,7 @@ const LatestTransactions = () => {
const
txsUrl
=
route
({
pathname
:
'
/txs
'
});
const
txsUrl
=
route
({
pathname
:
'
/txs
'
});
return
(
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
'
}
}
>
<
Box
mb=
{
3
}
display=
{
{
base
:
'
block
'
,
lg
:
'
none
'
}
}
>
{
data
.
slice
(
0
,
txsCount
).
map
(((
tx
,
index
)
=>
(
{
data
.
slice
(
0
,
txsCount
).
map
(((
tx
,
index
)
=>
(
<
LatestTxsItemMobile
<
LatestTxsItemMobile
...
...
ui/pages/ArbitrumL2TxnBatch.tsx
View file @
2e4117d6
...
@@ -85,7 +85,7 @@ const ArbitrumL2TxnBatch = () => {
...
@@ -85,7 +85,7 @@ const ArbitrumL2TxnBatch = () => {
{
{
id
:
'
txs
'
,
id
:
'
txs
'
,
title
:
'
Transactions
'
,
title
:
'
Transactions
'
,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
showSocketInfo=
{
false
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
},
},
{
{
id
:
'
blocks
'
,
id
:
'
blocks
'
,
...
...
ui/pages/Block.tsx
View file @
2e4117d6
...
@@ -73,7 +73,7 @@ const BlockPageContent = () => {
...
@@ -73,7 +73,7 @@ const BlockPageContent = () => {
component
:
(
component
:
(
<>
<>
{
blockTxsQuery
.
isDegradedData
&&
<
ServiceDegradationWarning
isLoading=
{
blockTxsQuery
.
isPlaceholderData
}
mb=
{
6
}
/>
}
{
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 = () => {
...
@@ -82,7 +82,7 @@ const BlockPageContent = () => {
id
:
'
blob_txs
'
,
id
:
'
blob_txs
'
,
title
:
'
Blob txns
'
,
title
:
'
Blob txns
'
,
component
:
(
component
:
(
<
TxsWithFrontendSorting
query=
{
blockBlobTxsQuery
}
showBlockInfo=
{
false
}
showSocketInfo=
{
false
}
/>
<
TxsWithFrontendSorting
query=
{
blockBlobTxsQuery
}
showBlockInfo=
{
false
}
/>
),
),
}
:
null
,
}
:
null
,
config
.
features
.
beaconChain
.
isEnabled
&&
Boolean
(
blockQuery
.
data
?.
withdrawals_count
)
?
config
.
features
.
beaconChain
.
isEnabled
&&
Boolean
(
blockQuery
.
data
?.
withdrawals_count
)
?
...
...
ui/pages/KettleTxs.tsx
View file @
2e4117d6
...
@@ -31,10 +31,7 @@ const KettleTxs = () => {
...
@@ -31,10 +31,7 @@ const KettleTxs = () => {
<>
<>
<
PageTitle
title=
"Computor transactions"
withTextAd
/>
<
PageTitle
title=
"Computor transactions"
withTextAd
/>
<
AddressEntity
address=
{
{
hash
}
}
mb=
{
6
}
/>
<
AddressEntity
address=
{
{
hash
}
}
mb=
{
6
}
/>
<
TxsWithFrontendSorting
<
TxsWithFrontendSorting
query=
{
query
}
/>
query=
{
query
}
showSocketInfo=
{
false
}
/>
</>
</>
);
);
};
};
...
...
ui/pages/OptimisticL2TxnBatch.tsx
View file @
2e4117d6
...
@@ -83,7 +83,7 @@ const OptimisticL2TxnBatch = () => {
...
@@ -83,7 +83,7 @@ const OptimisticL2TxnBatch = () => {
{
{
id
:
'
txs
'
,
id
:
'
txs
'
,
title
:
'
Transactions
'
,
title
:
'
Transactions
'
,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
showSocketInfo=
{
false
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
},
},
{
{
id
:
'
blocks
'
,
id
:
'
blocks
'
,
...
...
ui/pages/ScrollL2TxnBatch.tsx
View file @
2e4117d6
...
@@ -90,7 +90,7 @@ const ScrollL2TxnBatch = () => {
...
@@ -90,7 +90,7 @@ const ScrollL2TxnBatch = () => {
{
{
id
:
'
txs
'
,
id
:
'
txs
'
,
title
:
'
Transactions
'
,
title
:
'
Transactions
'
,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
showSocketInfo=
{
false
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
component
:
<
TxsWithFrontendSorting
query=
{
batchTxsQuery
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>,
},
},
{
{
id
:
'
blocks
'
,
id
:
'
blocks
'
,
...
...
ui/pages/Transactions.tsx
View file @
2e4117d6
...
@@ -9,7 +9,6 @@ import { route } from 'nextjs-routes';
...
@@ -9,7 +9,6 @@ import { route } from 'nextjs-routes';
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useNewTxsSocket
from
'
lib/hooks/useNewTxsSocket
'
;
import
getNetworkValidationActionText
from
'
lib/networks/getNetworkValidationActionText
'
;
import
getNetworkValidationActionText
from
'
lib/networks/getNetworkValidationActionText
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
TX
}
from
'
stubs/tx
'
;
import
{
TX
}
from
'
stubs/tx
'
;
...
@@ -91,8 +90,6 @@ const Transactions = () => {
...
@@ -91,8 +90,6 @@ const Transactions = () => {
},
},
});
});
const
{
num
,
socketAlert
}
=
useNewTxsSocket
();
const
isAuth
=
useIsAuth
();
const
isAuth
=
useIsAuth
();
const
tabs
:
Array
<
TabItemRegular
>
=
[
const
tabs
:
Array
<
TabItemRegular
>
=
[
...
@@ -102,9 +99,7 @@ const Transactions = () => {
...
@@ -102,9 +99,7 @@ const Transactions = () => {
component
:
component
:
<
TxsWithFrontendSorting
<
TxsWithFrontendSorting
query=
{
txsValidatedQuery
}
query=
{
txsValidatedQuery
}
showSocketInfo=
{
txsValidatedQuery
.
pagination
.
page
===
1
}
socketType=
"txs_validated"
socketInfoNum=
{
num
}
socketInfoAlert=
{
socketAlert
}
top=
{
TABS_HEIGHT
}
top=
{
TABS_HEIGHT
}
/>
},
/>
},
{
{
...
@@ -114,9 +109,7 @@ const Transactions = () => {
...
@@ -114,9 +109,7 @@ const Transactions = () => {
<
TxsWithFrontendSorting
<
TxsWithFrontendSorting
query=
{
txsPendingQuery
}
query=
{
txsPendingQuery
}
showBlockInfo=
{
false
}
showBlockInfo=
{
false
}
showSocketInfo=
{
txsPendingQuery
.
pagination
.
page
===
1
}
socketType=
"txs_pending"
socketInfoNum=
{
num
}
socketInfoAlert=
{
socketAlert
}
top=
{
TABS_HEIGHT
}
top=
{
TABS_HEIGHT
}
/>
/>
),
),
...
@@ -127,9 +120,6 @@ const Transactions = () => {
...
@@ -127,9 +120,6 @@ const Transactions = () => {
component
:
(
component
:
(
<
TxsWithFrontendSorting
<
TxsWithFrontendSorting
query=
{
txsWithBlobsQuery
}
query=
{
txsWithBlobsQuery
}
showSocketInfo=
{
txsWithBlobsQuery
.
pagination
.
page
===
1
}
socketInfoNum=
{
num
}
socketInfoAlert=
{
socketAlert
}
top=
{
TABS_HEIGHT
}
top=
{
TABS_HEIGHT
}
/>
/>
),
),
...
...
ui/pages/ZkEvmL2TxnBatch.tsx
View file @
2e4117d6
...
@@ -47,7 +47,7 @@ const ZkEvmL2TxnBatch = () => {
...
@@ -47,7 +47,7 @@ const ZkEvmL2TxnBatch = () => {
const
tabs
:
Array
<
TabItemRegular
>
=
React
.
useMemo
(()
=>
([
const
tabs
:
Array
<
TabItemRegular
>
=
React
.
useMemo
(()
=>
([
{
id
:
'
index
'
,
title
:
'
Details
'
,
component
:
<
ZkEvmL2TxnBatchDetails
query=
{
batchQuery
}
/>
},
{
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
]);
].
filter
(
Boolean
)),
[
batchQuery
,
batchTxsQuery
]);
const
backLink
=
React
.
useMemo
(()
=>
{
const
backLink
=
React
.
useMemo
(()
=>
{
...
...
ui/pages/ZkSyncL2TxnBatch.tsx
View file @
2e4117d6
...
@@ -67,7 +67,7 @@ const ZkSyncL2TxnBatch = () => {
...
@@ -67,7 +67,7 @@ const ZkSyncL2TxnBatch = () => {
{
{
id
:
'
txs
'
,
id
:
'
txs
'
,
title
:
'
Transactions
'
,
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
]);
].
filter
(
Boolean
)),
[
batchQuery
,
batchTxsQuery
,
hasPagination
]);
...
...
ui/txs/TxsContent.tsx
View file @
2e4117d6
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
TxsSocketType
}
from
'
./socket/types
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
Transaction
,
TransactionsSortingField
,
TransactionsSortingValue
}
from
'
types/api/transaction
'
;
import
type
{
Transaction
,
TransactionsSortingField
,
TransactionsSortingValue
}
from
'
types/api/transaction
'
;
...
@@ -26,9 +27,7 @@ type Props = {
...
@@ -26,9 +27,7 @@ type Props = {
// eslint-disable-next-line max-len
// eslint-disable-next-line max-len
query
:
QueryWithPagesResult
<
'
txs_validated
'
|
'
txs_pending
'
>
|
QueryWithPagesResult
<
'
txs_watchlist
'
>
|
QueryWithPagesResult
<
'
block_txs
'
>
|
QueryWithPagesResult
<
'
zkevm_l2_txn_batch_txs
'
>
;
query
:
QueryWithPagesResult
<
'
txs_validated
'
|
'
txs_pending
'
>
|
QueryWithPagesResult
<
'
txs_watchlist
'
>
|
QueryWithPagesResult
<
'
block_txs
'
>
|
QueryWithPagesResult
<
'
zkevm_l2_txn_batch_txs
'
>
;
showBlockInfo
?:
boolean
;
showBlockInfo
?:
boolean
;
showSocketInfo
?:
boolean
;
socketType
?:
TxsSocketType
;
socketInfoAlert
?:
string
;
socketInfoNum
?:
number
;
currentAddress
?:
string
;
currentAddress
?:
string
;
filter
?:
React
.
ReactNode
;
filter
?:
React
.
ReactNode
;
filterValue
?:
AddressFromToFilter
;
filterValue
?:
AddressFromToFilter
;
...
@@ -46,9 +45,7 @@ const TxsContent = ({
...
@@ -46,9 +45,7 @@ const TxsContent = ({
filter
,
filter
,
filterValue
,
filterValue
,
showBlockInfo
=
true
,
showBlockInfo
=
true
,
showSocketInfo
=
true
,
socketType
,
socketInfoAlert
,
socketInfoNum
,
currentAddress
,
currentAddress
,
enableTimeIncrement
,
enableTimeIncrement
,
top
,
top
,
...
@@ -72,9 +69,7 @@ const TxsContent = ({
...
@@ -72,9 +69,7 @@ const TxsContent = ({
<
Box
hideFrom=
"lg"
>
<
Box
hideFrom=
"lg"
>
<
TxsList
<
TxsList
showBlockInfo=
{
showBlockInfo
}
showBlockInfo=
{
showBlockInfo
}
showSocketInfo=
{
showSocketInfo
}
socketType=
{
socketType
}
socketInfoAlert=
{
socketInfoAlert
}
socketInfoNum=
{
socketInfoNum
}
isLoading=
{
isPlaceholderData
}
isLoading=
{
isPlaceholderData
}
enableTimeIncrement=
{
enableTimeIncrement
}
enableTimeIncrement=
{
enableTimeIncrement
}
currentAddress=
{
currentAddress
}
currentAddress=
{
currentAddress
}
...
@@ -87,9 +82,7 @@ const TxsContent = ({
...
@@ -87,9 +82,7 @@ const TxsContent = ({
sort=
{
sort
}
sort=
{
sort
}
onSortToggle=
{
onSortToggle
}
onSortToggle=
{
onSortToggle
}
showBlockInfo=
{
showBlockInfo
}
showBlockInfo=
{
showBlockInfo
}
showSocketInfo=
{
showSocketInfo
}
socketType=
{
socketType
}
socketInfoAlert=
{
socketInfoAlert
}
socketInfoNum=
{
socketInfoNum
}
top=
{
top
||
(
query
.
pagination
.
isVisible
?
ACTION_BAR_HEIGHT_DESKTOP
:
0
)
}
top=
{
top
||
(
query
.
pagination
.
isVisible
?
ACTION_BAR_HEIGHT_DESKTOP
:
0
)
}
currentAddress=
{
currentAddress
}
currentAddress=
{
currentAddress
}
enableTimeIncrement=
{
enableTimeIncrement
}
enableTimeIncrement=
{
enableTimeIncrement
}
...
...
ui/txs/TxsList.tsx
View file @
2e4117d6
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
TxsSocketType
}
from
'
./socket/types
'
;
import
type
{
Transaction
}
from
'
types/api/transaction
'
;
import
type
{
Transaction
}
from
'
types/api/transaction
'
;
import
useInitialList
from
'
lib/hooks/useInitialList
'
;
import
useInitialList
from
'
lib/hooks/useInitialList
'
;
import
useLazyRenderedList
from
'
lib/hooks/useLazyRenderedList
'
;
import
useLazyRenderedList
from
'
lib/hooks/useLazyRenderedList
'
;
import
*
as
SocketNewItemsNotice
from
'
ui/shared/SocketNewItemsNotice
'
;
import
TxsSocketNotice
from
'
./socket/TxsSocketNotice
'
;
import
TxsListItem
from
'
./TxsListItem
'
;
import
TxsListItem
from
'
./TxsListItem
'
;
interface
Props
{
interface
Props
{
showBlockInfo
:
boolean
;
showBlockInfo
:
boolean
;
showSocketInfo
?:
boolean
;
socketType
?:
TxsSocketType
;
socketInfoAlert
?:
string
;
socketInfoNum
?:
number
;
enableTimeIncrement
?:
boolean
;
enableTimeIncrement
?:
boolean
;
currentAddress
?:
string
;
currentAddress
?:
string
;
isLoading
:
boolean
;
isLoading
:
boolean
;
...
@@ -30,14 +29,7 @@ const TxsList = (props: Props) => {
...
@@ -30,14 +29,7 @@ const TxsList = (props: Props) => {
return
(
return
(
<
Box
>
<
Box
>
{
props
.
showSocketInfo
&&
(
{
props
.
socketType
&&
<
TxsSocketNotice
type=
{
props
.
socketType
}
place=
"list"
isLoading=
{
props
.
isLoading
}
/>
}
<
SocketNewItemsNotice
.
Mobile
url=
{
window
.
location
.
href
}
num=
{
props
.
socketInfoNum
}
alert=
{
props
.
socketInfoAlert
}
isLoading=
{
props
.
isLoading
}
/>
)
}
{
props
.
items
.
slice
(
0
,
renderedItemsNum
).
map
((
tx
,
index
)
=>
(
{
props
.
items
.
slice
(
0
,
renderedItemsNum
).
map
((
tx
,
index
)
=>
(
<
TxsListItem
<
TxsListItem
key=
{
tx
.
hash
+
(
props
.
isLoading
?
index
:
''
)
}
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 }) => {
...
@@ -15,7 +15,6 @@ test('base view +@dark-mode', async({ render }) => {
onSortToggle=
{
()
=>
{}
}
onSortToggle=
{
()
=>
{}
}
top=
{
0
}
top=
{
0
}
showBlockInfo
showBlockInfo
showSocketInfo=
{
false
}
/>,
/>,
);
);
...
@@ -36,7 +35,6 @@ test.describe('screen xl', () => {
...
@@ -36,7 +35,6 @@ test.describe('screen xl', () => {
onSortToggle=
{
()
=>
{}
}
onSortToggle=
{
()
=>
{}
}
top=
{
0
}
top=
{
0
}
showBlockInfo
showBlockInfo
showSocketInfo=
{
false
}
/>,
/>,
);
);
...
...
ui/txs/TxsTable.tsx
View file @
2e4117d6
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
TxsSocketType
}
from
'
./socket/types
'
;
import
type
{
Transaction
,
TransactionsSortingField
,
TransactionsSortingValue
}
from
'
types/api/transaction
'
;
import
type
{
Transaction
,
TransactionsSortingField
,
TransactionsSortingValue
}
from
'
types/api/transaction
'
;
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
...
@@ -8,8 +9,8 @@ import useInitialList from 'lib/hooks/useInitialList';
...
@@ -8,8 +9,8 @@ import useInitialList from 'lib/hooks/useInitialList';
import
useLazyRenderedList
from
'
lib/hooks/useLazyRenderedList
'
;
import
useLazyRenderedList
from
'
lib/hooks/useLazyRenderedList
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
TableBody
,
TableColumnHeader
,
TableColumnHeaderSortable
,
TableHeaderSticky
,
TableRoot
,
TableRow
}
from
'
toolkit/chakra/table
'
;
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
'
;
import
TxsTableItem
from
'
./TxsTableItem
'
;
type
Props
=
{
type
Props
=
{
...
@@ -18,9 +19,7 @@ type Props = {
...
@@ -18,9 +19,7 @@ type Props = {
onSortToggle
:
(
field
:
TransactionsSortingField
)
=>
void
;
onSortToggle
:
(
field
:
TransactionsSortingField
)
=>
void
;
top
:
number
;
top
:
number
;
showBlockInfo
:
boolean
;
showBlockInfo
:
boolean
;
showSocketInfo
:
boolean
;
socketType
?:
TxsSocketType
;
socketInfoAlert
?:
string
;
socketInfoNum
?:
number
;
currentAddress
?:
string
;
currentAddress
?:
string
;
enableTimeIncrement
?:
boolean
;
enableTimeIncrement
?:
boolean
;
isLoading
?:
boolean
;
isLoading
?:
boolean
;
...
@@ -32,9 +31,7 @@ const TxsTable = ({
...
@@ -32,9 +31,7 @@ const TxsTable = ({
onSortToggle
,
onSortToggle
,
top
,
top
,
showBlockInfo
,
showBlockInfo
,
showSocketInfo
,
socketType
,
socketInfoAlert
,
socketInfoNum
,
currentAddress
,
currentAddress
,
enableTimeIncrement
,
enableTimeIncrement
,
isLoading
,
isLoading
,
...
@@ -96,14 +93,7 @@ const TxsTable = ({
...
@@ -96,14 +93,7 @@ const TxsTable = ({
</
TableRow
>
</
TableRow
>
</
TableHeaderSticky
>
</
TableHeaderSticky
>
<
TableBody
>
<
TableBody
>
{
showSocketInfo
&&
(
{
socketType
&&
<
TxsSocketNotice
type=
{
socketType
}
place=
"table"
isLoading=
{
isLoading
}
/>
}
<
SocketNewItemsNotice
.
Desktop
url=
{
window
.
location
.
href
}
alert=
{
socketInfoAlert
}
num=
{
socketInfoNum
}
isLoading=
{
isLoading
}
/>
)
}
{
txs
.
slice
(
0
,
renderedItemsNum
).
map
((
item
,
index
)
=>
(
{
txs
.
slice
(
0
,
renderedItemsNum
).
map
((
item
,
index
)
=>
(
<
TxsTableItem
<
TxsTableItem
key=
{
item
.
hash
+
(
isLoading
?
index
:
''
)
}
key=
{
item
.
hash
+
(
isLoading
?
index
:
''
)
}
...
...
ui/txs/TxsWatchlist.tsx
View file @
2e4117d6
...
@@ -10,7 +10,7 @@ type Props = {
...
@@ -10,7 +10,7 @@ type Props = {
const
TxsWatchlist
=
({
query
}:
Props
)
=>
{
const
TxsWatchlist
=
({
query
}:
Props
)
=>
{
useRedirectForInvalidAuthToken
();
useRedirectForInvalidAuthToken
();
return
<
TxsWithFrontendSorting
query=
{
query
}
showSocketInfo=
{
false
}
top=
{
88
}
/>;
return
<
TxsWithFrontendSorting
query=
{
query
}
top=
{
88
}
/>;
};
};
export
default
TxsWatchlist
;
export
default
TxsWatchlist
;
ui/txs/TxsWithAPISorting.tsx
View file @
2e4117d6
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
TxsSocketType
}
from
'
./socket/types
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
TransactionsSortingValue
}
from
'
types/api/transaction
'
;
import
type
{
TransactionsSortingValue
}
from
'
types/api/transaction
'
;
...
@@ -12,9 +13,7 @@ type Props = {
...
@@ -12,9 +13,7 @@ type Props = {
query
:
QueryWithPagesResult
<
'
address_txs
'
>
;
query
:
QueryWithPagesResult
<
'
address_txs
'
>
;
showBlockInfo
?:
boolean
;
showBlockInfo
?:
boolean
;
showSocketInfo
?:
boolean
;
socketType
?:
TxsSocketType
;
socketInfoAlert
?:
string
;
socketInfoNum
?:
number
;
currentAddress
?:
string
;
currentAddress
?:
string
;
filter
?:
React
.
ReactNode
;
filter
?:
React
.
ReactNode
;
filterValue
?:
AddressFromToFilter
;
filterValue
?:
AddressFromToFilter
;
...
@@ -29,9 +28,7 @@ const TxsWithAPISorting = ({
...
@@ -29,9 +28,7 @@ const TxsWithAPISorting = ({
filterValue
,
filterValue
,
query
,
query
,
showBlockInfo
=
true
,
showBlockInfo
=
true
,
showSocketInfo
=
true
,
socketType
,
socketInfoAlert
,
socketInfoNum
,
currentAddress
,
currentAddress
,
enableTimeIncrement
,
enableTimeIncrement
,
top
,
top
,
...
@@ -49,9 +46,7 @@ const TxsWithAPISorting = ({
...
@@ -49,9 +46,7 @@ const TxsWithAPISorting = ({
filter=
{
filter
}
filter=
{
filter
}
filterValue=
{
filterValue
}
filterValue=
{
filterValue
}
showBlockInfo=
{
showBlockInfo
}
showBlockInfo=
{
showBlockInfo
}
showSocketInfo=
{
showSocketInfo
}
socketType=
{
socketType
}
socketInfoAlert=
{
socketInfoAlert
}
socketInfoNum=
{
socketInfoNum
}
currentAddress=
{
currentAddress
}
currentAddress=
{
currentAddress
}
enableTimeIncrement=
{
enableTimeIncrement
}
enableTimeIncrement=
{
enableTimeIncrement
}
top=
{
top
}
top=
{
top
}
...
...
ui/txs/TxsWithFrontendSorting.tsx
View file @
2e4117d6
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
TxsSocketType
}
from
'
./socket/types
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
QueryWithPagesResult
}
from
'
ui/shared/pagination/useQueryWithPages
'
;
import
type
{
QueryWithPagesResult
}
from
'
ui/shared/pagination/useQueryWithPages
'
;
...
@@ -11,9 +12,7 @@ type Props = {
...
@@ -11,9 +12,7 @@ type Props = {
// eslint-disable-next-line max-len
// eslint-disable-next-line max-len
query
:
QueryWithPagesResult
<
'
txs_validated
'
|
'
txs_pending
'
>
|
QueryWithPagesResult
<
'
txs_watchlist
'
>
|
QueryWithPagesResult
<
'
block_txs
'
>
|
QueryWithPagesResult
<
'
zkevm_l2_txn_batch_txs
'
>
;
query
:
QueryWithPagesResult
<
'
txs_validated
'
|
'
txs_pending
'
>
|
QueryWithPagesResult
<
'
txs_watchlist
'
>
|
QueryWithPagesResult
<
'
block_txs
'
>
|
QueryWithPagesResult
<
'
zkevm_l2_txn_batch_txs
'
>
;
showBlockInfo
?:
boolean
;
showBlockInfo
?:
boolean
;
showSocketInfo
?:
boolean
;
socketType
?:
TxsSocketType
;
socketInfoAlert
?:
string
;
socketInfoNum
?:
number
;
currentAddress
?:
string
;
currentAddress
?:
string
;
filter
?:
React
.
ReactNode
;
filter
?:
React
.
ReactNode
;
filterValue
?:
AddressFromToFilter
;
filterValue
?:
AddressFromToFilter
;
...
@@ -26,9 +25,7 @@ const TxsWithFrontendSorting = ({
...
@@ -26,9 +25,7 @@ const TxsWithFrontendSorting = ({
filterValue
,
filterValue
,
query
,
query
,
showBlockInfo
=
true
,
showBlockInfo
=
true
,
showSocketInfo
=
true
,
socketType
,
socketInfoAlert
,
socketInfoNum
,
currentAddress
,
currentAddress
,
enableTimeIncrement
,
enableTimeIncrement
,
top
,
top
,
...
@@ -40,9 +37,7 @@ const TxsWithFrontendSorting = ({
...
@@ -40,9 +37,7 @@ const TxsWithFrontendSorting = ({
filter=
{
filter
}
filter=
{
filter
}
filterValue=
{
filterValue
}
filterValue=
{
filterValue
}
showBlockInfo=
{
showBlockInfo
}
showBlockInfo=
{
showBlockInfo
}
showSocketInfo=
{
showSocketInfo
}
socketType=
{
socketType
}
socketInfoAlert=
{
socketInfoAlert
}
socketInfoNum=
{
socketInfoNum
}
currentAddress=
{
currentAddress
}
currentAddress=
{
currentAddress
}
enableTimeIncrement=
{
enableTimeIncrement
}
enableTimeIncrement=
{
enableTimeIncrement
}
top=
{
top
}
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
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
TxsSocketType
}
from
'
./types
'
;
import
useGradualIncrement
from
'
lib/hooks/useGradualIncrement
'
;
import
useGradualIncrement
from
'
lib/hooks/useGradualIncrement
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
function
getSocketParams
(
router
:
NextRouter
)
{
function
getSocketParams
(
type
:
TxsSocketType
,
page
:
string
)
{
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
};
}
if
(
switch
(
type
)
{
router
.
pathname
===
'
/txs
'
&&
case
'
txs_home
'
:
{
router
.
query
.
tab
===
'
pending
'
&&
return
{
topic
:
'
transactions:new_transaction
'
as
const
,
event
:
'
transaction
'
as
const
};
!
router
.
query
.
block_number
&&
}
!
router
.
query
.
page
case
'
txs_validated
'
:
{
)
{
return
!
page
||
page
===
'
1
'
?
{
topic
:
'
transactions:new_transaction
'
as
const
,
event
:
'
transaction
'
as
const
}
:
{};
return
{
topic
:
'
transactions:new_pending_transaction
'
as
const
,
event
:
'
pending_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
}
{
function
assertIsNewTxResponse
(
response
:
unknown
):
response
is
{
transaction
:
number
}
{
...
@@ -40,12 +32,19 @@ function assertIsNewPendingTxResponse(response: unknown): response is { pending_
...
@@ -40,12 +32,19 @@ function assertIsNewPendingTxResponse(response: unknown): response is { pending_
return
typeof
response
===
'
object
'
&&
response
!==
null
&&
'
pending_transaction
'
in
response
;
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
router
=
useRouter
();
const
page
=
getQueryParamString
(
router
.
query
.
page
);
const
[
num
,
setNum
]
=
useGradualIncrement
(
0
);
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
)
=>
{
const
handleNewTxMessage
=
React
.
useCallback
((
response
:
{
transaction
:
number
}
|
{
pending_transaction
:
number
}
|
unknown
)
=>
{
if
(
assertIsNewTxResponse
(
response
))
{
if
(
assertIsNewTxResponse
(
response
))
{
...
@@ -57,18 +56,18 @@ export default function useNewTxsSocket() {
...
@@ -57,18 +56,18 @@ export default function useNewTxsSocket() {
},
[
setNum
]);
},
[
setNum
]);
const
handleSocketClose
=
React
.
useCallback
(()
=>
{
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
(()
=>
{
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
({
const
channel
=
useSocketChannel
({
topic
,
topic
,
onSocketClose
:
handleSocketClose
,
onSocketClose
:
handleSocketClose
,
onSocketError
:
handleSocketError
,
onSocketError
:
handleSocketError
,
isDisabled
:
!
topic
,
isDisabled
:
!
topic
||
Boolean
(
isLoading
)
,
});
});
useSocketMessage
({
useSocketMessage
({
...
@@ -78,8 +77,8 @@ export default function useNewTxsSocket() {
...
@@ -78,8 +77,8 @@ export default function useNewTxsSocket() {
});
});
if
(
!
topic
&&
!
event
)
{
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