fix(@wallet): switch account being slow

Now when switching account all remote call are non blocking

fixes #7430
This commit is contained in:
Anthony Laibe 2022-11-15 10:13:08 +01:00 committed by Anthony Laibe
parent 48f5a9d256
commit 6e6f708d49
7 changed files with 101 additions and 36 deletions

View File

@ -151,7 +151,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.tokenService = token_service.newService(
statusFoundation.events, statusFoundation.threadpool, result.networkService
)
result.collectibleService = collectible_service.newService(result.networkService)
result.collectibleService = collectible_service.newService(statusFoundation.events, statusFoundation.threadpool, result.networkService)
result.walletAccountService = wallet_account_service.newService(
statusFoundation.events, statusFoundation.threadpool, result.settingsService, result.accountsService,
result.tokenService, result.networkService,

View File

@ -1,24 +1,30 @@
import io_interface
import ../../../../../../app_service/service/collectible/service as collectible_service
import ../../../../../core/eventemitter
type
Controller* = ref object of RootObj
delegate: io_interface.AccessInterface
events: EventEmitter
collectibleService: collectible_service.Service
proc newController*(
delegate: io_interface.AccessInterface,
events: EventEmitter,
collectibleService: collectible_service.Service
): Controller =
result = Controller()
result.delegate = delegate
result.events = events
result.collectibleService = collectibleService
proc delete*(self: Controller) =
discard
proc init*(self: Controller) =
discard
self.events.on(GetCollections) do(e:Args):
let args = GetCollectionsArgs(e)
self.delegate.setCollections(args.collections)
proc getCollections*(self: Controller, address: string): seq[collectible_service.CollectionDto] =
return self.collectibleService.getCollections(address)
proc getCollections*(self: Controller, address: string) =
self.collectibleService.getCollectionsAsync(address)

View File

@ -1,3 +1,5 @@
import ../../../../../../app_service/service/collectible/service as collectible_service
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
## Abstract class for any input/interaction with this module.
@ -14,6 +16,10 @@ method isLoaded*(self: AccessInterface): bool {.base.} =
method loadCollections*(self: AccessInterface, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
method setCollections*(self: AccessInterface, collections: seq[CollectionDto]) {.base.} =
raise newException(ValueError, "No implementation available")
# View Delegate Interface
# Delegate for the view must be declared here due to use of QtObject and multi
# inheritance, which is not well supported in Nim.

View File

@ -4,6 +4,7 @@ import ../../../../../global/global_singleton
import ./io_interface, ./view, ./controller, ./item
import ../io_interface as delegate_interface
import ../../../../../../app_service/service/collectible/service as collectible_service
import ../../../../../core/eventemitter
export io_interface
@ -14,12 +15,12 @@ type
controller: Controller
moduleLoaded: bool
proc newModule*(delegate: delegate_interface.AccessInterface, collectibleService: collectible_service.Service):
proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, collectibleService: collectible_service.Service):
Module =
result = Module()
result.delegate = delegate
result.view = newView(result)
result.controller = controller.newController(result, collectibleService)
result.controller = controller.newController(result, events, collectibleService)
result.moduleLoaded = false
method delete*(self: Module) =
@ -39,7 +40,9 @@ method viewDidLoad*(self: Module) =
self.delegate.collectionsModuleDidLoad()
method loadCollections*(self: Module, address: string) =
let collections = self.controller.getCollections(address)
self.controller.getCollections(address)
method setCollections*(self: Module, collections: seq[CollectionDto]) =
self.view.setItems(
collections.map(c => initItem(
c.name,

View File

@ -32,7 +32,7 @@ proc newModule*(
result.moduleLoaded = false
result.collectiblesModule = collectibles_module.newModule(result, collectibleService)
result.collectionsModule = collectionsModule.newModule(result, collectibleService)
result.collectionsModule = collectionsModule.newModule(result, events, collectibleService)
result.collectibleModule = collectibleModule.newModule(result, collectibleService)
method delete*(self: Module) =

View File

@ -0,0 +1,17 @@
type
GetCollectionsTaskArg = ref object of QObjectTaskArg
chainId*: int
address*: string
const getCollectionsTaskArg: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[GetCollectionsTaskArg](argEncoded)
try:
let response = backend.getOpenseaCollectionsByOwner(arg.chainId, arg.address)
arg.finish(response.result)
except Exception as e:
let errDesription = e.msg
error "error: ", errDesription
arg.finish("")

View File

@ -1,10 +1,15 @@
import chronicles, sequtils, json
import NimQml, chronicles, sequtils, json
import ../../../app/core/eventemitter
import ../../../app/core/tasks/[qt, threadpool]
import dto
import ../network/service as network_service
import ../../../backend/backend
include ../../common/json_utils
include async_tasks
export dto
logScope:
@ -12,31 +17,59 @@ logScope:
const limit = 200
const GetCollections* = "get-collections"
type
Service* = ref object of RootObj
GetCollectionsArgs* = ref object of Args
collections*: seq[CollectionDto]
QtObject:
type
Service* = ref object of QObject
events: EventEmitter
threadpool: ThreadPool
networkService: network_service.Service
proc delete*(self: Service) =
discard
proc delete*(self: Service) =
self.QObject.delete
proc newService*(networkService: network_service.Service): Service =
proc newService*(
events: EventEmitter,
threadpool: ThreadPool,
networkService: network_service.Service,
): Service =
result = Service()
result.QObject.setup
result.events = events
result.threadpool = threadpool
result.networkService = networkService
proc init*(self: Service) =
proc init*(self: Service) =
discard
proc getCollections*(self: Service, address: string): seq[CollectionDto] =
proc onGetCollections*(self: Service, response: string) {.slot.} =
try:
let chainId = self.networkService.getNetworkForCollectibles().chainId
let response = backend.getOpenseaCollectionsByOwner(chainId, address)
return map(response.result.getElems(), proc(x: JsonNode): CollectionDto = x.toCollectionDto())
except Exception as e:
let errDesription = e.msg
error "error: ", errDesription
let responseObj = response.parseJson
if (responseObj.kind != JArray):
self.events.emit(GetCollections, GetCollectionsArgs())
return
proc getCollectibles*(self: Service, address: string, collectionSlug: string): seq[CollectibleDto] =
let collections = map(responseObj.getElems(), proc(x: JsonNode): CollectionDto = x.toCollectionDto())
self.events.emit(GetCollections, GetCollectionsArgs(collections: collections))
except:
self.events.emit(GetCollections, GetCollectionsArgs())
proc getCollectionsAsync*(self: Service, address: string) =
let arg = GetCollectionsTaskArg(
tptr: cast[ByteAddress](getCollectionsTaskArg),
vptr: cast[ByteAddress](self.vptr),
slot: "onGetCollections",
chainId: self.networkService.getNetworkForCollectibles().chainId,
address: address,
)
self.threadpool.start(arg)
proc getCollectibles*(self: Service, address: string, collectionSlug: string): seq[CollectibleDto] =
try:
let chainId = self.networkService.getNetworkForCollectibles().chainId
let response = backend.getOpenseaAssetsByOwnerAndCollection(chainId, address, collectionSlug, limit)