From 433ea71d621a486e3d79909213b299465f7a5c1d Mon Sep 17 00:00:00 2001 From: Pascal Precht <445106+0x-r4bbit@users.noreply.github.com> Date: Wed, 8 Feb 2023 14:31:14 +0100 Subject: [PATCH] refactor: load recent stickers asynchronously This postpones the loading of recently used stickers to the point when a) the stickers popup is opened and the recent stickers tab was the last visited one or b) when the sticker popup is open and one switches to the recent stickers tab. Partially closes #9435 --- src/app/modules/main/stickers/controller.nim | 14 ++++++-- .../modules/main/stickers/io_interface.nim | 6 ++++ src/app/modules/main/stickers/module.nim | 9 ++++++ src/app/modules/main/stickers/view.nim | 4 +++ .../service/stickers/async_tasks.nim | 6 ++++ src/app_service/service/stickers/service.nim | 32 +++++++++++++++++++ .../shared/status/StatusStickersPopup.qml | 11 +++++++ 7 files changed, 79 insertions(+), 3 deletions(-) diff --git a/src/app/modules/main/stickers/controller.nim b/src/app/modules/main/stickers/controller.nim index f7e436126d..f35c4482de 100644 --- a/src/app/modules/main/stickers/controller.nim +++ b/src/app/modules/main/stickers/controller.nim @@ -53,9 +53,6 @@ proc delete*(self: Controller) = discard proc init*(self: Controller) = - let recentStickers = self.stickerService.getRecentStickers() - for sticker in recentStickers: - self.delegate.addRecentStickerToList(sticker) let installedStickers = self.stickerService.getInstalledStickerPacks() self.delegate.populateInstalledStickerPacks(installedStickers) @@ -74,6 +71,11 @@ proc init*(self: Controller) = self.obtainMarketStickerPacks() self.disconnected = false + self.events.on(SIGNAL_LOAD_RECENT_STICKERS_DONE) do(e: Args): + let args = StickersArgs(e) + for sticker in args.stickers: + self.delegate.addRecentStickerToList(sticker) + self.events.on(SIGNAL_STICKER_PACK_LOADED) do(e: Args): let args = StickerPackLoadedArgs(e) self.delegate.addStickerPackToList( @@ -114,6 +116,12 @@ proc init*(self: Controller) = proc buy*(self: Controller, packId: string, address: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string, eip1559Enabled: bool): tuple[response: string, success: bool] = self.stickerService.buy(packId, address, gas, gasPrice, maxPriorityFeePerGas, maxFeePerGas, password, eip1559Enabled) +proc getRecentStickers*(self: Controller): seq[StickerDto] = + return self.stickerService.getRecentStickers() + +proc loadRecentStickers*(self: Controller) = + self.stickerService.asyncLoadRecentStickers() + proc estimate*(self: Controller, packId: string, address: string, price: string, uuid: string) = self.stickerService.estimate(packId, address, price, uuid) diff --git a/src/app/modules/main/stickers/io_interface.nim b/src/app/modules/main/stickers/io_interface.nim index 43dd396399..4bb8a7aa30 100644 --- a/src/app/modules/main/stickers/io_interface.nim +++ b/src/app/modules/main/stickers/io_interface.nim @@ -22,6 +22,12 @@ method viewDidLoad*(self: AccessInterface) {.base.} = method authenticateAndBuy*(self: AccessInterface, packId: string, address: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, eip1559Enabled: bool){.base.} = raise newException(ValueError, "No implementation available") +method getRecentStickers*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method loadRecentStickers*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") + method getInstalledStickerPacks*(self: AccessInterface): Table[string, StickerPackDto] {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/stickers/module.nim b/src/app/modules/main/stickers/module.nim index c09461b450..a0589687f1 100644 --- a/src/app/modules/main/stickers/module.nim +++ b/src/app/modules/main/stickers/module.nim @@ -163,6 +163,15 @@ method estimate*(self: Module, packId: string, address: string, price: string, u method addRecentStickerToList*(self: Module, sticker: StickerDto) = self.view.addRecentStickerToList(initItem(sticker.hash, sticker.packId, sticker.url)) +method getRecentStickers*(self: Module) = + let data = self.controller.getRecentStickers() + if data.len > 0: + for sticker in data: + self.addRecentStickerToList(sticker) + return + self.controller.loadRecentStickers() + + method clearStickerPacks*(self: Module) = self.view.clearStickerPacks() diff --git a/src/app/modules/main/stickers/view.nim b/src/app/modules/main/stickers/view.nim index 7a4c09f674..30ea79397d 100644 --- a/src/app/modules/main/stickers/view.nim +++ b/src/app/modules/main/stickers/view.nim @@ -108,6 +108,7 @@ QtObject: proc addRecentStickerToList*(self: View, sticker: Item) = self.recentStickers.addStickerToList(sticker) + self.recentStickersUpdated() proc getAllPacksLoaded(self: View): bool {.slot.} = self.packsLoaded @@ -143,6 +144,9 @@ QtObject: self.delegate.obtainMarketStickerPacks() + proc getRecentStickers(self: View) {.slot.} = + self.delegate.getRecentStickers() + proc send*(self: View, channelId: string, hash: string, replyTo: string, pack: string, url: string) {.slot.} = let sticker = initItem(hash, pack, url) self.addRecentStickerToList(sticker) diff --git a/src/app_service/service/stickers/async_tasks.nim b/src/app_service/service/stickers/async_tasks.nim index 2e2943498b..3f94e38c47 100644 --- a/src/app_service/service/stickers/async_tasks.nim +++ b/src/app_service/service/stickers/async_tasks.nim @@ -13,6 +13,12 @@ type packId*: string chainId*: int hasKey*: bool + AsyncGetRecentStickersTaskArg* = ref object of QObjectTaskArg + +const asyncGetRecentStickersTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = + let arg = decode[AsyncGetRecentStickersTaskArg](argEncoded) + let response = status_stickers.recent() + arg.finish(response) proc getMarketStickerPacks*(chainId: int): tuple[stickers: Table[string, StickerPackDto], error: string] = diff --git a/src/app_service/service/stickers/service.nim b/src/app_service/service/stickers/service.nim index 904981bcca..341ee3be58 100644 --- a/src/app_service/service/stickers/service.nim +++ b/src/app_service/service/stickers/service.nim @@ -51,6 +51,8 @@ type transactionType*: string StickerPackInstalledArgs* = ref object of Args packId*: string + StickersArgs* = ref object of Args + stickers*: seq[StickerDto] # Signals which may be emitted by this service: const SIGNAL_STICKER_PACK_LOADED* = "stickerPackLoaded" @@ -60,6 +62,9 @@ const SIGNAL_STICKER_GAS_ESTIMATED* = "stickerGasEstimated" const SIGNAL_STICKER_TRANSACTION_CONFIRMED* = "stickerTransactionConfirmed" const SIGNAL_STICKER_TRANSACTION_REVERTED* = "stickerTransactionReverted" const SIGNAL_STICKER_PACK_INSTALLED* = "stickerPackInstalled" +const SIGNAL_LOAD_RECENT_STICKERS_STARTED* = "loadRecentStickersStarted" +const SIGNAL_LOAD_RECENT_STICKERS_FAILED* = "loadRecentStickersFailed" +const SIGNAL_LOAD_RECENT_STICKERS_DONE* = "loadRecentStickersDone" QtObject: type Service* = ref object of QObject @@ -330,6 +335,33 @@ QtObject: except RpcException: error "Error getting recent stickers", message = getCurrentExceptionMsg() + proc asyncLoadRecentStickers*(self: Service) = + self.events.emit(SIGNAL_LOAD_RECENT_STICKERS_STARTED, Args()) + try: + let arg = AsyncGetRecentStickersTaskArg( + tptr: cast[ByteAddress](asyncGetRecentStickersTask), + vptr: cast[ByteAddress](self.vptr), + slot: "onAsyncGetRecentStickersDone" + ) + self.threadpool.start(arg) + except Exception as e: + error "Error loading recent stickers", msg = e.msg + + proc onAsyncGetRecentStickersDone*(self: Service, response: string) {.slot.} = + try: + let rpcResponseObj = response.parseJson + if (rpcResponseObj{"error"}.kind != JNull): + let error = Json.decode($rpcResponseObj["error"], RpcError) + error "error loading recent stickers", msg = error.message + return + + let recentStickers = map(rpcResponseObj{"result"}.getElems(), toStickerDto) + self.events.emit(SIGNAL_LOAD_RECENT_STICKERS_DONE, StickersArgs(stickers: recentStickers)) + except Exception as e: + let errMsg = e.msg + error "error: ", errMsg + self.events.emit(SIGNAL_LOAD_RECENT_STICKERS_FAILED, Args()) + proc getNumInstalledStickerPacks*(self: Service): int = try: let installedResponse = status_stickers.installed() diff --git a/ui/imports/shared/status/StatusStickersPopup.qml b/ui/imports/shared/status/StatusStickersPopup.qml index 8bb11e2843..0400feab6a 100644 --- a/ui/imports/shared/status/StatusStickersPopup.qml +++ b/ui/imports/shared/status/StatusStickersPopup.qml @@ -34,6 +34,10 @@ Popup { function loadStickers() { store.stickersModuleInst.loadStickers() } + + function getRecentStickers() { + store.stickersModuleInst.getRecentStickers() + } } enabled: !!d.recentStickers && !!d.stickerPackList @@ -56,6 +60,12 @@ Popup { } } + onAboutToShow: { + if (stickerGrid.packId == -1) { + d.getRecentStickers() + } + } + onClosed: { stickerMarket.visible = false footerContent.visible = true @@ -261,6 +271,7 @@ Popup { onClicked: { highlighted = true stickerPackListView.selectedPackId = -1 + d.getRecentStickers() stickerGrid.model = d.recentStickers } }