feat(wallet) handle multi-transaction update events for activity filter
Bump status-go to include multi-transaction update events Throttle down "update transactions" button to once every two seconds Closes #11233
This commit is contained in:
parent
4a3e8ca1b2
commit
42f2546e4a
|
@ -186,6 +186,7 @@ QtObject:
|
||||||
self.status.setIsFilterDirty(false)
|
self.status.setIsFilterDirty(false)
|
||||||
self.model.resetModel(@[])
|
self.model.resetModel(@[])
|
||||||
self.eventsHandler.updateSubscribedAddresses(self.addresses)
|
self.eventsHandler.updateSubscribedAddresses(self.addresses)
|
||||||
|
self.eventsHandler.updateSubscribedChainIDs(self.chainIds)
|
||||||
self.status.setNewDataAvailable(false)
|
self.status.setNewDataAvailable(false)
|
||||||
|
|
||||||
let response = backend_activity.filterActivityAsync(self.addresses, seq[backend_activity.ChainId](self.chainIds), self.currentActivityFilter, 0, FETCH_BATCH_COUNT_DEFAULT)
|
let response = backend_activity.filterActivityAsync(self.addresses, seq[backend_activity.ChainId](self.chainIds), self.currentActivityFilter, 0, FETCH_BATCH_COUNT_DEFAULT)
|
||||||
|
|
|
@ -27,6 +27,7 @@ QtObject:
|
||||||
# Ignore events older than this relevantTimestamp
|
# Ignore events older than this relevantTimestamp
|
||||||
relevantTimestamp: int
|
relevantTimestamp: int
|
||||||
subscribedAddresses: HashSet[string]
|
subscribedAddresses: HashSet[string]
|
||||||
|
subscribedChainIDs: HashSet[int]
|
||||||
newDataAvailableFn: proc()
|
newDataAvailableFn: proc()
|
||||||
|
|
||||||
proc setup(self: EventsHandler) =
|
proc setup(self: EventsHandler) =
|
||||||
|
@ -73,19 +74,31 @@ QtObject:
|
||||||
if data.at > 0 and self.relevantTimestamp > 0 and data.at < self.relevantTimestamp:
|
if data.at > 0 and self.relevantTimestamp > 0 and data.at < self.relevantTimestamp:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check addresses if any was reported
|
# Check chain, if any was reported
|
||||||
|
if len(self.subscribedChainIDs) > 0 and data.chainID > 0:
|
||||||
|
var contains = false
|
||||||
|
for chainID in self.subscribedChainIDs:
|
||||||
|
if data.chainID == chainID:
|
||||||
|
contains = true
|
||||||
|
break
|
||||||
|
if not contains:
|
||||||
|
return
|
||||||
|
|
||||||
var contains = data.accounts.len == 0
|
var contains = data.accounts.len == 0
|
||||||
|
# Check addresses if any was reported
|
||||||
for address in data.accounts:
|
for address in data.accounts:
|
||||||
if address in self.subscribedAddresses:
|
if address in self.subscribedAddresses:
|
||||||
contains = true
|
contains = true
|
||||||
break
|
break
|
||||||
|
|
||||||
if contains:
|
if not contains:
|
||||||
# TODO: throttle down the number of events to one per 1 seconds until the backend supports subscription
|
return
|
||||||
self.newDataAvailableFn()
|
|
||||||
|
self.newDataAvailableFn()
|
||||||
|
|
||||||
self.walletEventHandlers[EventNewTransfers] = newDataAvailableCallback
|
self.walletEventHandlers[EventNewTransfers] = newDataAvailableCallback
|
||||||
self.walletEventHandlers[EventPendingTransactionUpdate] = newDataAvailableCallback
|
self.walletEventHandlers[EventPendingTransactionUpdate] = newDataAvailableCallback
|
||||||
|
self.walletEventHandlers[EventMTTransactionUpdate] = newDataAvailableCallback
|
||||||
|
|
||||||
proc newEventsHandler*(events: EventEmitter): EventsHandler =
|
proc newEventsHandler*(events: EventEmitter): EventsHandler =
|
||||||
new(result, delete)
|
new(result, delete)
|
||||||
|
@ -93,6 +106,7 @@ QtObject:
|
||||||
result.eventHandlers = initTable[string, EventCallbackProc]()
|
result.eventHandlers = initTable[string, EventCallbackProc]()
|
||||||
|
|
||||||
result.subscribedAddresses = initHashSet[string]()
|
result.subscribedAddresses = initHashSet[string]()
|
||||||
|
result.subscribedChainIDs = initHashSet[int]()
|
||||||
|
|
||||||
result.setup()
|
result.setup()
|
||||||
|
|
||||||
|
@ -110,4 +124,9 @@ QtObject:
|
||||||
proc updateSubscribedAddresses*(self: EventsHandler, addresses: seq[string]) =
|
proc updateSubscribedAddresses*(self: EventsHandler, addresses: seq[string]) =
|
||||||
self.subscribedAddresses.clear()
|
self.subscribedAddresses.clear()
|
||||||
for address in addresses:
|
for address in addresses:
|
||||||
self.subscribedAddresses.incl(address)
|
self.subscribedAddresses.incl(address)
|
||||||
|
|
||||||
|
proc updateSubscribedChainIDs*(self: EventsHandler, chainIDs: seq[int]) =
|
||||||
|
self.subscribedChainIDs.clear()
|
||||||
|
for chainID in chainIDs:
|
||||||
|
self.subscribedChainIDs.incl(chainID)
|
|
@ -39,6 +39,7 @@ const EventNonArchivalNodeDetected*: string = "non-archival-node-detected"
|
||||||
|
|
||||||
# Mirrors the pending transfer event from status-go, status-go/services/wallet/transfer/transaction.go
|
# Mirrors the pending transfer event from status-go, status-go/services/wallet/transfer/transaction.go
|
||||||
const EventPendingTransactionUpdate*: string = "pending-transaction-update"
|
const EventPendingTransactionUpdate*: string = "pending-transaction-update"
|
||||||
|
const EventMTTransactionUpdate*: string = "multi-transaction-update"
|
||||||
|
|
||||||
proc getTransactionByHash*(chainId: int, hash: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
proc getTransactionByHash*(chainId: int, hash: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
core.callPrivateRPCWithChainId("eth_getTransactionByHash", chainId, %* [hash])
|
core.callPrivateRPCWithChainId("eth_getTransactionByHash", chainId, %* [hash])
|
||||||
|
|
|
@ -50,6 +50,15 @@ ColumnLayout {
|
||||||
property var activityFiltersStore: WalletStores.ActivityFiltersStore{}
|
property var activityFiltersStore: WalletStores.ActivityFiltersStore{}
|
||||||
readonly property int loadingSectionWidth: 56
|
readonly property int loadingSectionWidth: 56
|
||||||
readonly property int topSectionMargin: 20
|
readonly property int topSectionMargin: 20
|
||||||
|
|
||||||
|
property bool showRefreshButton: false
|
||||||
|
property double lastRefreshTime
|
||||||
|
readonly property int maxSecondsBetweenRefresh: 3
|
||||||
|
function refreshData() {
|
||||||
|
RootStore.resetFilter()
|
||||||
|
d.lastRefreshTime = Date.now()
|
||||||
|
d.showRefreshButton = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
@ -363,8 +372,8 @@ ColumnLayout {
|
||||||
|
|
||||||
text: qsTr("New transactions")
|
text: qsTr("New transactions")
|
||||||
|
|
||||||
visible: RootStore.newDataAvailable
|
visible: d.showRefreshButton
|
||||||
onClicked: RootStore.resetFilter()
|
onClicked: d.refreshData()
|
||||||
|
|
||||||
icon.name: "arrow-up"
|
icon.name: "arrow-up"
|
||||||
|
|
||||||
|
@ -378,4 +387,33 @@ ColumnLayout {
|
||||||
z: 3
|
z: 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: RootStore
|
||||||
|
|
||||||
|
function onNewDataAvailableChanged() {
|
||||||
|
if (!d.lastRefreshTime || ((Date.now() - d.lastRefreshTime) > (1000 * d.maxSecondsBetweenRefresh))) {
|
||||||
|
d.showRefreshButton = RootStore.newDataAvailable
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showRefreshButtonTimer.running) {
|
||||||
|
if (!RootStore.newDataAvailable) {
|
||||||
|
showRefreshButtonTimer.stop()
|
||||||
|
d.showRefreshButton = false
|
||||||
|
}
|
||||||
|
} else if(RootStore.newDataAvailable) {
|
||||||
|
showRefreshButtonTimer.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: showRefreshButtonTimer
|
||||||
|
|
||||||
|
interval: 2000
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
onTriggered: d.showRefreshButton = RootStore.newDataAvailable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue