diff --git a/src/app/boot/app_controller.nim b/src/app/boot/app_controller.nim index a76ce7cdf7..e71bf86809 100644 --- a/src/app/boot/app_controller.nim +++ b/src/app/boot/app_controller.nim @@ -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, diff --git a/src/app/modules/main/wallet_section/collectibles/collections/controller.nim b/src/app/modules/main/wallet_section/collectibles/collections/controller.nim index 1eeaaab57a..b15d4aca0c 100644 --- a/src/app/modules/main/wallet_section/collectibles/collections/controller.nim +++ b/src/app/modules/main/wallet_section/collectibles/collections/controller.nim @@ -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) diff --git a/src/app/modules/main/wallet_section/collectibles/collections/io_interface.nim b/src/app/modules/main/wallet_section/collectibles/collections/io_interface.nim index 04840072cb..aaac0587fa 100644 --- a/src/app/modules/main/wallet_section/collectibles/collections/io_interface.nim +++ b/src/app/modules/main/wallet_section/collectibles/collections/io_interface.nim @@ -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. diff --git a/src/app/modules/main/wallet_section/collectibles/collections/module.nim b/src/app/modules/main/wallet_section/collectibles/collections/module.nim index a962f148f9..dd0c12d0a0 100644 --- a/src/app/modules/main/wallet_section/collectibles/collections/module.nim +++ b/src/app/modules/main/wallet_section/collectibles/collections/module.nim @@ -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, diff --git a/src/app/modules/main/wallet_section/collectibles/module.nim b/src/app/modules/main/wallet_section/collectibles/module.nim index df25437dfa..0d698141d8 100644 --- a/src/app/modules/main/wallet_section/collectibles/module.nim +++ b/src/app/modules/main/wallet_section/collectibles/module.nim @@ -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) = diff --git a/src/app_service/service/collectible/async_tasks.nim b/src/app_service/service/collectible/async_tasks.nim new file mode 100644 index 0000000000..15b4729446 --- /dev/null +++ b/src/app_service/service/collectible/async_tasks.nim @@ -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("") + + \ No newline at end of file diff --git a/src/app_service/service/collectible/service.nim b/src/app_service/service/collectible/service.nim index 959cd95b15..6cda1a7e69 100644 --- a/src/app_service/service/collectible/service.nim +++ b/src/app_service/service/collectible/service.nim @@ -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,36 +17,64 @@ logScope: const limit = 200 +const GetCollections* = "get-collections" + type - Service* = ref object of RootObj - networkService: network_service.Service + GetCollectionsArgs* = ref object of Args + collections*: seq[CollectionDto] -proc delete*(self: Service) = - discard +QtObject: + type + Service* = ref object of QObject + events: EventEmitter + threadpool: ThreadPool + networkService: network_service.Service -proc newService*(networkService: network_service.Service): Service = - result = Service() - result.networkService = networkService + proc delete*(self: Service) = + self.QObject.delete -proc init*(self: Service) = - discard + 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 getCollections*(self: Service, address: string): seq[CollectionDto] = - 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 - return + proc init*(self: Service) = + discard -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) - return map(response.result.getElems(), proc(x: JsonNode): CollectibleDto = x.toCollectibleDto()) - except Exception as e: - let errDesription = e.msg - error "error: ", errDesription - return + proc onGetCollections*(self: Service, response: string) {.slot.} = + try: + let responseObj = response.parseJson + if (responseObj.kind != JArray): + self.events.emit(GetCollections, GetCollectionsArgs()) + return + + 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) + return map(response.result.getElems(), proc(x: JsonNode): CollectibleDto = x.toCollectibleDto()) + except Exception as e: + let errDesription = e.msg + error "error: ", errDesription + return