feat: Load collectibles async
This commit is contained in:
parent
087bd1d20d
commit
6e62df9109
|
@ -1,5 +1,6 @@
|
||||||
import NimQml, Tables, strformat, strutils, chronicles
|
import NimQml, Tables, strformat, strutils, chronicles, json
|
||||||
import ../../status/[status, wallet]
|
import ../../status/[status, wallet, threads]
|
||||||
|
import ../../status/wallet/collectibles as status_collectibles
|
||||||
import views/[asset_list, account_list, account_item, transaction_list, collectibles_list]
|
import views/[asset_list, account_list, account_item, transaction_list, collectibles_list]
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
|
@ -49,8 +50,6 @@ QtObject:
|
||||||
read = getEtherscanLink
|
read = getEtherscanLink
|
||||||
notify = etherscanLinkChanged
|
notify = etherscanLinkChanged
|
||||||
|
|
||||||
proc currentAccountChanged*(self: WalletView) {.signal.}
|
|
||||||
|
|
||||||
proc setCurrentAssetList*(self: WalletView, assetList: seq[Asset])
|
proc setCurrentAssetList*(self: WalletView, assetList: seq[Asset])
|
||||||
|
|
||||||
proc currentCollectiblesListChanged*(self: WalletView) {.signal.}
|
proc currentCollectiblesListChanged*(self: WalletView) {.signal.}
|
||||||
|
@ -67,6 +66,10 @@ QtObject:
|
||||||
write = setCurrentCollectiblesList
|
write = setCurrentCollectiblesList
|
||||||
notify = currentCollectiblesListChanged
|
notify = currentCollectiblesListChanged
|
||||||
|
|
||||||
|
proc loadCollectiblesForAccount*(self: WalletView, address: string)
|
||||||
|
|
||||||
|
proc currentAccountChanged*(self: WalletView) {.signal.}
|
||||||
|
|
||||||
proc setCurrentAccountByIndex*(self: WalletView, index: int) {.slot.} =
|
proc setCurrentAccountByIndex*(self: WalletView, index: int) {.slot.} =
|
||||||
if(self.accounts.rowCount() == 0): return
|
if(self.accounts.rowCount() == 0): return
|
||||||
|
|
||||||
|
@ -76,6 +79,11 @@ QtObject:
|
||||||
self.currentAccountChanged()
|
self.currentAccountChanged()
|
||||||
self.setCurrentAssetList(selectedAccount.assetList)
|
self.setCurrentAssetList(selectedAccount.assetList)
|
||||||
|
|
||||||
|
# Display currently known collectibles, and get latest from API/Contracts
|
||||||
|
self.setCurrentCollectiblesList(selectedAccount.collectibles)
|
||||||
|
self.loadCollectiblesForAccount(selectedAccount.address)
|
||||||
|
self.currentCollectiblesListChanged()
|
||||||
|
|
||||||
proc getCurrentAccount*(self: WalletView): QVariant {.slot.} =
|
proc getCurrentAccount*(self: WalletView): QVariant {.slot.} =
|
||||||
result = newQVariant(self.currentAccount)
|
result = newQVariant(self.currentAccount)
|
||||||
|
|
||||||
|
@ -211,5 +219,23 @@ QtObject:
|
||||||
proc loadTransactionsForAccount*(self: WalletView, address: string) {.slot.} =
|
proc loadTransactionsForAccount*(self: WalletView, address: string) {.slot.} =
|
||||||
self.setCurrentTransactions(self.status.wallet.getTransfersByAddress(address))
|
self.setCurrentTransactions(self.status.wallet.getTransfersByAddress(address))
|
||||||
|
|
||||||
|
proc loadingCollectibles*(self: WalletView, isLoading: bool) {.signal.}
|
||||||
|
|
||||||
proc loadCollectiblesForAccount*(self: WalletView, address: string) {.slot.} =
|
proc loadCollectiblesForAccount*(self: WalletView, address: string) {.slot.} =
|
||||||
self.setCurrentCollectiblesList(self.status.wallet.getAllCollectibles(address))
|
self.loadingCollectibles(true)
|
||||||
|
spawnAndSend(self, "setCollectiblesResult ") do:
|
||||||
|
$(%*{
|
||||||
|
"address": address,
|
||||||
|
"collectibles": status_collectibles.getAllCollectibles(address)
|
||||||
|
})
|
||||||
|
|
||||||
|
proc setCollectiblesResult(self: WalletView, collectiblesJSON: string) {.slot.} =
|
||||||
|
let collectibleData = parseJson(collectiblesJSON)
|
||||||
|
let collectibles = collectibleData["collectibles"].to(seq[Collectible]);
|
||||||
|
let address = collectibleData["address"].getStr
|
||||||
|
self.accounts.getAccount(self.accounts.getAccountindexByAddress(address)).collectibles = collectibles
|
||||||
|
if address == self.currentAccount.address:
|
||||||
|
self.setCurrentCollectiblesList(collectibles)
|
||||||
|
|
||||||
|
self.loadingCollectibles(false)
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ type PackData* = object
|
||||||
price*: Stuint[256] # uint256
|
price*: Stuint[256] # uint256
|
||||||
contentHash*: DynamicBytes[64] # bytes
|
contentHash*: DynamicBytes[64] # bytes
|
||||||
|
|
||||||
let CONTRACTS: seq[Contract] = @[
|
proc allContracts(): seq[Contract] = @[
|
||||||
Contract(name: "snt", network: Network.Mainnet, address: parseAddress("0x744d70fdbe2ba4cf95131626614a1763df805b9e"),
|
Contract(name: "snt", network: Network.Mainnet, address: parseAddress("0x744d70fdbe2ba4cf95131626614a1763df805b9e"),
|
||||||
methods: [
|
methods: [
|
||||||
("approveAndCall", Method(signature: "approveAndCall(address,uint256,bytes)")),
|
("approveAndCall", Method(signature: "approveAndCall(address,uint256,bytes)")),
|
||||||
|
@ -100,7 +100,7 @@ let CONTRACTS: seq[Contract] = @[
|
||||||
]
|
]
|
||||||
|
|
||||||
proc getContract(network: Network, name: string): Contract =
|
proc getContract(network: Network, name: string): Contract =
|
||||||
let found = CONTRACTS.filter(contract => contract.name == name and contract.network == network)
|
let found = allContracts().filter(contract => contract.name == name and contract.network == network)
|
||||||
result = if found.len > 0: found[0] else: nil
|
result = if found.len > 0: found[0] else: nil
|
||||||
|
|
||||||
proc getContract*(name: string): Contract =
|
proc getContract*(name: string): Contract =
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
import core, ./types, ../../signals/types as statusgo_types, ./accounts/constants, ./utils
|
import core, ./types, ../../signals/types as statusgo_types, ./accounts/constants, ./utils
|
||||||
import json, tables, sugar, sequtils
|
import json, tables, sugar, sequtils
|
||||||
import json_serialization
|
import json_serialization
|
||||||
|
import locks
|
||||||
|
|
||||||
var settings: JsonNode = %*{}
|
var settingsLock: Lock
|
||||||
var dirty: bool = true
|
initLock(settingsLock)
|
||||||
|
|
||||||
|
var settings {.guard: settingsLock.} = %*{}
|
||||||
|
var dirty {.guard: settingsLock.} = true
|
||||||
|
|
||||||
proc saveSetting*(key: Setting, value: string | JsonNode): StatusGoError =
|
proc saveSetting*(key: Setting, value: string | JsonNode): StatusGoError =
|
||||||
let response = callPrivateRPC("settings_saveSetting", %* [
|
let response = callPrivateRPC("settings_saveSetting", %* [
|
||||||
key, value
|
key, value
|
||||||
])
|
])
|
||||||
|
|
||||||
|
withLock settingsLock:
|
||||||
try:
|
try:
|
||||||
result = Json.decode($response, StatusGoError)
|
result = Json.decode($response, StatusGoError)
|
||||||
except:
|
except:
|
||||||
|
@ -18,8 +24,11 @@ proc getWeb3ClientVersion*(): string =
|
||||||
parseJson(callPrivateRPC("web3_clientVersion"))["result"].getStr
|
parseJson(callPrivateRPC("web3_clientVersion"))["result"].getStr
|
||||||
|
|
||||||
proc getSettings*(useCached: bool = true): JsonNode =
|
proc getSettings*(useCached: bool = true): JsonNode =
|
||||||
|
{.gcsafe.}:
|
||||||
|
withLock settingsLock:
|
||||||
if useCached and not dirty:
|
if useCached and not dirty:
|
||||||
return settings
|
result = settings
|
||||||
|
else:
|
||||||
settings = callPrivateRPC("settings_getSettings").parseJSON()["result"]
|
settings = callPrivateRPC("settings_getSettings").parseJSON()["result"]
|
||||||
dirty = false
|
dirty = false
|
||||||
result = settings
|
result = settings
|
||||||
|
|
|
@ -3,6 +3,7 @@ from eth/common/utils import parseAddress
|
||||||
import ../libstatus/core as status
|
import ../libstatus/core as status
|
||||||
import ../libstatus/contracts as contracts
|
import ../libstatus/contracts as contracts
|
||||||
import eth/common/eth_types
|
import eth/common/eth_types
|
||||||
|
import ../libstatus/types
|
||||||
import account
|
import account
|
||||||
|
|
||||||
proc getTokenUri(contract: Contract, tokenId: int): string =
|
proc getTokenUri(contract: Contract, tokenId: int): string =
|
||||||
|
|
|
@ -4,9 +4,39 @@ import "../../../shared"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
StyledText {
|
StyledText {
|
||||||
visible: walletModel.collectibles.rowCount() === 0
|
|
||||||
//% "No collectibles in this account"
|
//% "No collectibles in this account"
|
||||||
text: qsTrId("no-collectibles-in-this-account")
|
text: qsTrId("no-collectibles-in-this-account")
|
||||||
|
visible: walletModel.collectibles.rowCount() === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
SVGImage {
|
||||||
|
id: loadingImg
|
||||||
|
visible: false
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Style.current.padding
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: Style.currentPadding
|
||||||
|
anchors.verticalCenter: txtPassword.verticalCenter
|
||||||
|
// TODO replace by a real loading image
|
||||||
|
source: "../../img/settings.svg"
|
||||||
|
width: 30
|
||||||
|
height: 30
|
||||||
|
fillMode: Image.Stretch
|
||||||
|
RotationAnimator {
|
||||||
|
target: loadingImg;
|
||||||
|
from: 0;
|
||||||
|
to: 360;
|
||||||
|
duration: 1200
|
||||||
|
running: true
|
||||||
|
loops: Animation.Infinite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: walletModel
|
||||||
|
onLoadingCollectibles: {
|
||||||
|
loadingImg.visible = isLoading
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
|
Loading…
Reference in New Issue