From 52e6fddcabf18329835a31f044b3e162a394f94c Mon Sep 17 00:00:00 2001 From: Dario Gabriel Lipicar Date: Thu, 14 Sep 2023 12:22:30 -0300 Subject: [PATCH] feat(@desktop/wallet): implement partial collectibles updates Fixes #12150 --- .../collectibles/controller.nim | 45 ++++++++++++++++--- .../collectibles/events_handler.nim | 22 ++++++--- src/backend/collectibles.nim | 1 + vendor/status-go | 2 +- 4 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/app/modules/shared_modules/collectibles/controller.nim b/src/app/modules/shared_modules/collectibles/controller.nim index b19d19bbe0..4dcaaf2db3 100644 --- a/src/app/modules/shared_modules/collectibles/controller.nim +++ b/src/app/modules/shared_modules/collectibles/controller.nim @@ -1,5 +1,5 @@ import NimQml, std/json, sequtils, sugar, strutils -import stint, logging +import stint, logging, Tables import app/modules/shared_models/collectibles_model import app/modules/shared_models/collectibles_utils @@ -22,6 +22,8 @@ QtObject: addresses: seq[string] chainIds: seq[int] + stateTable: Table[string, Table[int, bool]] # Table[address][chainID] -> isUpdating + requestId: int32 autofetch: bool @@ -40,7 +42,6 @@ QtObject: QtProperty[QVariant] model: read = getModelAsVariant - proc loadMoreItems(self: Controller) {.slot.} = if self.model.getIsFetching(): return @@ -87,17 +88,47 @@ QtObject: if self.autofetch: self.loadMoreItems() + proc resetUpdateState*(self: Controller) = + # Initialize state table + # We assume that ownership is initially not being updated. This will change if an + # update starts or a partial update is received. + # TODO: Get the update state at the time of filter switch from the backend? + self.stateTable = initTable[string, Table[int, bool]]() + for address in self.addresses: + self.stateTable[address] = initTable[int, bool]() + for chainID in self.chainIds: + self.stateTable[address][chainID] = false + self.model.setIsUpdating(false) + + proc setUpdateState*(self: Controller, address: string, chainID: int, isUpdating: bool) = + if not self.stateTable.hasKey(address) or not self.stateTable[address].hasKey(chainID): + return + self.stateTable[address][chainID] = isUpdating + + # If any address+chainID is updating, then the whole model is updating + for address, chainIDsPerAddress in self.stateTable.pairs: + for chainID, isUpdating in chainIDsPerAddress: + if isUpdating: + self.model.setIsUpdating(true) + return + self.model.setIsUpdating(false) + proc setupEventHandlers(self: Controller) = self.eventsHandler.onOwnedCollectiblesFilteringDone(proc (jsonObj: JsonNode) = self.processFilterOwnedCollectiblesResponse(jsonObj) ) - self.eventsHandler.onCollectiblesOwnershipUpdateStarted(proc () = - self.model.setIsUpdating(true) + self.eventsHandler.onCollectiblesOwnershipUpdateStarted(proc (address: string, chainID: int) = + self.setUpdateState(address, chainID, true) ) - self.eventsHandler.onCollectiblesOwnershipUpdateFinished(proc () = - self.model.setIsUpdating(false) + self.eventsHandler.onCollectiblesOwnershipUpdatePartial(proc (address: string, chainID: int) = + self.setUpdateState(address, chainID, true) + self.resetModel() + ) + + self.eventsHandler.onCollectiblesOwnershipUpdateFinished(proc (address: string, chainID: int) = + self.setUpdateState(address, chainID, false) self.resetModel() ) @@ -127,6 +158,8 @@ QtObject: self.chainIds = chainIds self.addresses = addresses + + self.resetUpdateState() self.eventsHandler.updateSubscribedAddresses(self.addresses) self.eventsHandler.updateSubscribedChainIDs(self.chainIds) diff --git a/src/app/modules/shared_modules/collectibles/events_handler.nim b/src/app/modules/shared_modules/collectibles/events_handler.nim index 89d2a7e1a7..81f4a079a1 100644 --- a/src/app/modules/shared_modules/collectibles/events_handler.nim +++ b/src/app/modules/shared_modules/collectibles/events_handler.nim @@ -8,6 +8,7 @@ import backend/collectibles as backend_collectibles type EventCallbackProc = proc (eventObject: JsonNode) type WalletEventCallbackProc = proc (data: WalletSignal) +type OwnershipUpdateCallbackProc = proc (address: string, chainID: int) # EventsHandler responsible for catching collectibles related backend events and reporting them QtObject: @@ -20,8 +21,9 @@ QtObject: subscribedAddresses: HashSet[string] subscribedChainIDs: HashSet[int] - collectiblesOwnershipUpdateStartedFn: proc() - collectiblesOwnershipUpdateFinishedFn: proc() + collectiblesOwnershipUpdateStartedFn: OwnershipUpdateCallbackProc + collectiblesOwnershipUpdatePartialFn: OwnershipUpdateCallbackProc + collectiblesOwnershipUpdateFinishedFn: OwnershipUpdateCallbackProc requestId: int32 @@ -34,10 +36,13 @@ QtObject: proc onOwnedCollectiblesFilteringDone*(self: EventsHandler, handler: EventCallbackProc) = self.eventHandlers[backend_collectibles.eventOwnedCollectiblesFilteringDone] = handler - proc onCollectiblesOwnershipUpdateStarted*(self: EventsHandler, handler: proc()) = + proc onCollectiblesOwnershipUpdateStarted*(self: EventsHandler, handler: OwnershipUpdateCallbackProc) = self.collectiblesOwnershipUpdateStartedFn = handler - proc onCollectiblesOwnershipUpdateFinished*(self: EventsHandler, handler: proc()) = + proc onCollectiblesOwnershipUpdatePartial*(self: EventsHandler, handler: OwnershipUpdateCallbackProc) = + self.collectiblesOwnershipUpdatePartialFn = handler + + proc onCollectiblesOwnershipUpdateFinished*(self: EventsHandler, handler: OwnershipUpdateCallbackProc) = self.collectiblesOwnershipUpdateFinishedFn = handler proc handleApiEvents(self: EventsHandler, e: Args) = @@ -72,12 +77,17 @@ QtObject: self.walletEventHandlers[backend_collectibles.eventCollectiblesOwnershipUpdateStarted] = proc (data: WalletSignal) = if self.collectiblesOwnershipUpdateStartedFn == nil or self.shouldIgnoreEvent(data): return - self.collectiblesOwnershipUpdateStartedFn() + self.collectiblesOwnershipUpdateStartedFn(data.accounts[0], data.chainID) + + self.walletEventHandlers[backend_collectibles.eventCollectiblesOwnershipUpdatePartial] = proc (data: WalletSignal) = + if self.collectiblesOwnershipUpdatePartialFn == nil or self.shouldIgnoreEvent(data): + return + self.collectiblesOwnershipUpdatePartialFn(data.accounts[0], data.chainID) self.walletEventHandlers[backend_collectibles.eventCollectiblesOwnershipUpdateFinished] = proc (data: WalletSignal) = if self.collectiblesOwnershipUpdateFinishedFn == nil or self.shouldIgnoreEvent(data): return - self.collectiblesOwnershipUpdateFinishedFn() + self.collectiblesOwnershipUpdateFinishedFn(data.accounts[0], data.chainID) proc newEventsHandler*(requestId: int32, events: EventEmitter): EventsHandler = new(result, delete) diff --git a/src/backend/collectibles.nim b/src/backend/collectibles.nim index 3c44f4394e..16cb97971c 100644 --- a/src/backend/collectibles.nim +++ b/src/backend/collectibles.nim @@ -16,6 +16,7 @@ type # Declared in services/wallet/collectibles/service.go const eventCollectiblesOwnershipUpdateStarted*: string = "wallet-collectibles-ownership-update-started" +const eventCollectiblesOwnershipUpdatePartial*: string = "wallet-collectibles-ownership-update-partial" const eventCollectiblesOwnershipUpdateFinished*: string = "wallet-collectibles-ownership-update-finished" const eventCollectiblesOwnershipUpdateFinishedWithError*: string = "wallet-collectibles-ownership-update-finished-with-error" diff --git a/vendor/status-go b/vendor/status-go index 5e8300d6a1..e337ab4f13 160000 --- a/vendor/status-go +++ b/vendor/status-go @@ -1 +1 @@ -Subproject commit 5e8300d6a12fe22a97c2219dac17888499003b8f +Subproject commit e337ab4f13e196d2c83d9f99aef68b5b79066695