mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-26 21:41:11 +00:00
fix(@desktop/wallet) make collection expansion more responsive
Collection fetch is now non-blocking Fixes #8406
This commit is contained in:
parent
473da3790b
commit
f0744ed61d
@ -1,25 +1,31 @@
|
|||||||
import io_interface
|
import io_interface
|
||||||
import ../../../../../../app_service/service/collectible/service as collectible_service
|
import ../../../../../../app_service/service/collectible/service as collectible_service
|
||||||
|
import ../../../../../core/eventemitter
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
Controller* = ref object of RootObj
|
Controller* = ref object of RootObj
|
||||||
delegate: io_interface.AccessInterface
|
delegate: io_interface.AccessInterface
|
||||||
|
events: EventEmitter
|
||||||
collectibleService: collectible_service.Service
|
collectibleService: collectible_service.Service
|
||||||
|
|
||||||
proc newController*(
|
proc newController*(
|
||||||
delegate: io_interface.AccessInterface,
|
delegate: io_interface.AccessInterface,
|
||||||
|
events: EventEmitter,
|
||||||
collectibleService: collectible_service.Service
|
collectibleService: collectible_service.Service
|
||||||
): Controller =
|
): Controller =
|
||||||
result = Controller()
|
result = Controller()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
|
result.events = events
|
||||||
result.collectibleService = collectibleService
|
result.collectibleService = collectibleService
|
||||||
|
|
||||||
proc delete*(self: Controller) =
|
proc delete*(self: Controller) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc init*(self: Controller) =
|
proc init*(self: Controller) =
|
||||||
discard
|
self.events.on(GetCollectibles) do(e:Args):
|
||||||
|
let args = GetCollectiblesArgs(e)
|
||||||
|
self.delegate.setCollectibles(args.collectionSlug, args.collectibles)
|
||||||
|
|
||||||
proc fetch*(self: Controller, address: string, collectionSlug: string): seq[collectible_service.CollectibleDto] =
|
proc fetch*(self: Controller, address: string, collectionSlug: string) =
|
||||||
return self.collectibleService.getCollectibles(address, collectionSlug)
|
self.collectibleService.getCollectiblesAsync(address, collectionSlug)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import ../../../../../../app_service/service/collectible/service as collectible_service
|
||||||
import ./item
|
import ./item
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -13,10 +14,13 @@ method load*(self: AccessInterface) {.base.} =
|
|||||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method setCurrentAddress*(self: AccessInterface, address: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method fetch*(self: AccessInterface, collectionSlug: string) {.base.} =
|
method fetch*(self: AccessInterface, collectionSlug: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method setCurrentAddress*(self: AccessInterface, address: string) {.base.} =
|
method setCollectibles*(self: AccessInterface, collectionSlug: string, collectibles: seq[CollectibleDto]) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getCollectible*(self: AccessInterface, collectionSlug: string, id: int) : Item {.base.} =
|
method getCollectible*(self: AccessInterface, collectionSlug: string, id: int) : Item {.base.} =
|
||||||
|
@ -4,6 +4,7 @@ import ../../../../../global/global_singleton
|
|||||||
import ./io_interface, ./view, ./controller, ./item
|
import ./io_interface, ./view, ./controller, ./item
|
||||||
import ../io_interface as delegate_interface
|
import ../io_interface as delegate_interface
|
||||||
import ../../../../../../app_service/service/collectible/service as collectible_service
|
import ../../../../../../app_service/service/collectible/service as collectible_service
|
||||||
|
import ../../../../../core/eventemitter
|
||||||
|
|
||||||
export io_interface
|
export io_interface
|
||||||
|
|
||||||
@ -15,12 +16,12 @@ type
|
|||||||
moduleLoaded: bool
|
moduleLoaded: bool
|
||||||
currentAddress: string
|
currentAddress: string
|
||||||
|
|
||||||
proc newModule*(delegate: delegate_interface.AccessInterface, collectibleService: collectible_service.Service):
|
proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, collectibleService: collectible_service.Service):
|
||||||
Module =
|
Module =
|
||||||
result = Module()
|
result = Module()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.view = newView(result)
|
result.view = newView(result)
|
||||||
result.controller = controller.newController(result, collectibleService)
|
result.controller = controller.newController(result, events, collectibleService)
|
||||||
result.moduleLoaded = false
|
result.moduleLoaded = false
|
||||||
|
|
||||||
method delete*(self: Module) =
|
method delete*(self: Module) =
|
||||||
@ -43,7 +44,9 @@ method setCurrentAddress*(self: Module, address: string) =
|
|||||||
self.currentAddress = address
|
self.currentAddress = address
|
||||||
|
|
||||||
method fetch*(self: Module, collectionSlug: string) =
|
method fetch*(self: Module, collectionSlug: string) =
|
||||||
let collectibles = self.controller.fetch(self.currentAddress, collectionSlug)
|
self.controller.fetch(self.currentAddress, collectionSlug)
|
||||||
|
|
||||||
|
method setCollectibles*(self: Module, collectionSlug: string, collectibles: seq[CollectibleDto]) =
|
||||||
let items = collectibles.map(c => initItem(
|
let items = collectibles.map(c => initItem(
|
||||||
c.id,
|
c.id,
|
||||||
c.name,
|
c.name,
|
||||||
|
@ -31,7 +31,7 @@ proc newModule*(
|
|||||||
result.controller = newController(result, walletAccountService)
|
result.controller = newController(result, walletAccountService)
|
||||||
result.moduleLoaded = false
|
result.moduleLoaded = false
|
||||||
|
|
||||||
result.collectiblesModule = collectibles_module.newModule(result, collectibleService)
|
result.collectiblesModule = collectibles_module.newModule(result, events, collectibleService)
|
||||||
result.collectionsModule = collectionsModule.newModule(result, events, collectibleService)
|
result.collectionsModule = collectionsModule.newModule(result, events, collectibleService)
|
||||||
result.currentCollectibleModule = currentCollectibleModule.newModule(result, collectibleService, result.collectionsModule, result.collectiblesModule)
|
result.currentCollectibleModule = currentCollectibleModule.newModule(result, collectibleService, result.collectionsModule, result.collectiblesModule)
|
||||||
|
|
||||||
|
@ -5,13 +5,38 @@ type
|
|||||||
|
|
||||||
const getCollectionsTaskArg: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
const getCollectionsTaskArg: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
let arg = decode[GetCollectionsTaskArg](argEncoded)
|
let arg = decode[GetCollectionsTaskArg](argEncoded)
|
||||||
|
let output = %* {
|
||||||
|
"chainId": arg.chainId,
|
||||||
|
"address": arg.address,
|
||||||
|
"collections": ""
|
||||||
|
}
|
||||||
try:
|
try:
|
||||||
let response = backend.getOpenseaCollectionsByOwner(arg.chainId, arg.address)
|
let response = backend.getOpenseaCollectionsByOwner(arg.chainId, arg.address)
|
||||||
arg.finish(response.result)
|
output["collections"] = response.result
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
let errDesription = e.msg
|
let errDesription = e.msg
|
||||||
error "error: ", errDesription
|
error "error getCollectionsTaskArg: ", errDesription
|
||||||
arg.finish("")
|
arg.finish(output)
|
||||||
|
|
||||||
|
type
|
||||||
|
GetCollectiblesTaskArg = ref object of QObjectTaskArg
|
||||||
|
chainId*: int
|
||||||
|
address*: string
|
||||||
|
collectionSlug: string
|
||||||
|
limit: int
|
||||||
|
|
||||||
|
const getCollectiblesTaskArg: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
|
let arg = decode[GetCollectiblesTaskArg](argEncoded)
|
||||||
|
let output = %* {
|
||||||
|
"chainId": arg.chainId,
|
||||||
|
"address": arg.address,
|
||||||
|
"collectionSlug": arg.collectionSlug,
|
||||||
|
"collectibles": ""
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
let response = backend.getOpenseaAssetsByOwnerAndCollection(arg.chainId, arg.address, arg.collectionSlug, arg.limit)
|
||||||
|
output["collectibles"] = response.result
|
||||||
|
except Exception as e:
|
||||||
|
let errDesription = e.msg
|
||||||
|
error "error getCollectiblesTaskArg: ", errDesription
|
||||||
|
arg.finish(output)
|
||||||
|
@ -21,8 +21,20 @@ const GetCollections* = "get-collections"
|
|||||||
|
|
||||||
type
|
type
|
||||||
GetCollectionsArgs* = ref object of Args
|
GetCollectionsArgs* = ref object of Args
|
||||||
|
chainId*: int
|
||||||
|
address*: string
|
||||||
collections*: seq[CollectionDto]
|
collections*: seq[CollectionDto]
|
||||||
|
|
||||||
|
const GetCollectibles* = "get-collectibles"
|
||||||
|
|
||||||
|
type
|
||||||
|
GetCollectiblesArgs* = ref object of Args
|
||||||
|
chainId*: int
|
||||||
|
address*: string
|
||||||
|
collectionSlug*: string
|
||||||
|
collectibles*: seq[CollectibleDto]
|
||||||
|
error*: string
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
Service* = ref object of QObject
|
Service* = ref object of QObject
|
||||||
@ -47,37 +59,74 @@ QtObject:
|
|||||||
proc init*(self: Service) =
|
proc init*(self: Service) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
proc getNetwork*(self: Service): NetworkDto =
|
||||||
|
return self.networkService.getNetworkForCollectibles()
|
||||||
|
|
||||||
proc onGetCollections*(self: Service, response: string) {.slot.} =
|
proc onGetCollections*(self: Service, response: string) {.slot.} =
|
||||||
|
var data = GetCollectionsArgs()
|
||||||
try:
|
try:
|
||||||
let responseObj = response.parseJson
|
let responseObj = response.parseJson
|
||||||
if (responseObj.kind != JArray):
|
if (responseObj.kind == JObject):
|
||||||
self.events.emit(GetCollections, GetCollectionsArgs())
|
let chainIdJson = responseObj["chainId"]
|
||||||
return
|
let addressJson = responseObj["address"]
|
||||||
|
|
||||||
let collections = map(responseObj.getElems(), proc(x: JsonNode): CollectionDto = x.toCollectionDto())
|
let validAccount = (chainIdJson.kind == JInt and
|
||||||
self.events.emit(GetCollections, GetCollectionsArgs(collections: collections))
|
addressJson.kind == JString)
|
||||||
except:
|
if (validAccount):
|
||||||
self.events.emit(GetCollections, GetCollectionsArgs())
|
data.chainId = chainIdJson.getInt()
|
||||||
|
data.address = addressJson.getStr()
|
||||||
|
|
||||||
|
let collectionsJson = responseObj["collections"]
|
||||||
|
if (collectionsJson.kind == JArray):
|
||||||
|
data.collections = map(collectionsJson.getElems(), proc(x: JsonNode): CollectionDto = x.toCollectionDto())
|
||||||
|
except Exception as e:
|
||||||
|
let errDesription = e.msg
|
||||||
|
error "error onGetCollections: ", errDesription
|
||||||
|
self.events.emit(GetCollections, data)
|
||||||
|
|
||||||
proc getCollectionsAsync*(self: Service, address: string) =
|
proc getCollectionsAsync*(self: Service, address: string) =
|
||||||
let arg = GetCollectionsTaskArg(
|
let arg = GetCollectionsTaskArg(
|
||||||
tptr: cast[ByteAddress](getCollectionsTaskArg),
|
tptr: cast[ByteAddress](getCollectionsTaskArg),
|
||||||
vptr: cast[ByteAddress](self.vptr),
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
slot: "onGetCollections",
|
slot: "onGetCollections",
|
||||||
chainId: self.networkService.getNetworkForCollectibles().chainId,
|
chainId: self.getNetwork().chainId,
|
||||||
address: address,
|
address: address,
|
||||||
)
|
)
|
||||||
self.threadpool.start(arg)
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
proc getNetwork*(self: Service): NetworkDto =
|
|
||||||
return self.networkService.getNetworkForCollectibles()
|
|
||||||
|
|
||||||
proc getCollectibles*(self: Service, address: string, collectionSlug: string): seq[CollectibleDto] =
|
proc onGetCollectibles*(self: Service, response: string) {.slot.} =
|
||||||
|
var data = GetCollectiblesArgs()
|
||||||
try:
|
try:
|
||||||
let chainId = self.getNetwork().chainId
|
let responseObj = response.parseJson
|
||||||
let response = backend.getOpenseaAssetsByOwnerAndCollection(chainId, address, collectionSlug, limit)
|
if (responseObj.kind == JObject):
|
||||||
return map(response.result.getElems(), proc(x: JsonNode): CollectibleDto = x.toCollectibleDto())
|
let chainIdJson = responseObj["chainId"]
|
||||||
|
let addressJson = responseObj["address"]
|
||||||
|
let collectionSlugJson = responseObj["collectionSlug"]
|
||||||
|
|
||||||
|
let validCollection = (chainIdJson.kind == JInt and
|
||||||
|
addressJson.kind == JString and
|
||||||
|
collectionSlugJson.kind == JString)
|
||||||
|
if (validCollection):
|
||||||
|
data.chainId = chainIdJson.getInt()
|
||||||
|
data.address = addressJson.getStr()
|
||||||
|
data.collectionSlug = collectionSlugJson.getStr()
|
||||||
|
|
||||||
|
let collectiblesJson = responseObj["collectibles"]
|
||||||
|
if (collectiblesJson.kind == JArray):
|
||||||
|
data.collectibles = map(collectiblesJson.getElems(), proc(x: JsonNode): CollectibleDto = x.toCollectibleDto())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
let errDesription = e.msg
|
let errDesription = e.msg
|
||||||
error "error: ", errDesription
|
error "error onGetCollectibles: ", errDesription
|
||||||
return
|
self.events.emit(GetCollectibles, data)
|
||||||
|
|
||||||
|
proc getCollectiblesAsync*(self: Service, address: string, collectionSlug: string) =
|
||||||
|
let arg = GetCollectiblesTaskArg(
|
||||||
|
tptr: cast[ByteAddress](getCollectiblesTaskArg),
|
||||||
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
|
slot: "onGetCollectibles",
|
||||||
|
chainId: self.getNetwork().chainId,
|
||||||
|
address: address,
|
||||||
|
collectionSlug: collectionSlug,
|
||||||
|
limit: limit
|
||||||
|
)
|
||||||
|
self.threadpool.start(arg)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user