parent
df121445ca
commit
072537f61a
|
@ -190,7 +190,8 @@ proc newModule*[T](
|
|||
result.walletSectionModule = wallet_section_module.newModule(
|
||||
result, events, tokenService, currencyService,
|
||||
transactionService, collectible_service, walletAccountService,
|
||||
settingsService, savedAddressService, networkService, accountsService, keycardService
|
||||
settingsService, savedAddressService, networkService, accountsService,
|
||||
keycardService, nodeService, networkConnectionService
|
||||
)
|
||||
result.browserSectionModule = browser_section_module.newModule(
|
||||
result, events, bookmarkService, settingsService, networkService,
|
||||
|
|
|
@ -50,7 +50,7 @@ method viewDidLoad*(self: Module) =
|
|||
self.checkIfModuleDidLoad()
|
||||
|
||||
method networkConnectionStatusUpdate*(self: Module, website: string, completelyDown: bool, connectionState: int, chainIds: string, lastCheckedAt: int, timeToAutoRetryInSecs: int, withCache: bool) =
|
||||
self.view.networkConnectionStatusUpdate(website, completelyDown, connectionState, chainIds, lastCheckedAt, timeToAutoRetryInSecs, withCache)
|
||||
self.view.updateNetworkConnectionStatus(website, completelyDown, connectionState, chainIds, lastCheckedAt, timeToAutoRetryInSecs, withCache)
|
||||
|
||||
method refreshBlockchainValues*(self: Module) =
|
||||
self.controller.refreshBlockchainValues()
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
import NimQml, strformat
|
||||
|
||||
QtObject:
|
||||
type NetworkConnectionItem* = ref object of QObject
|
||||
completelyDown: bool
|
||||
connectionState: int
|
||||
chainIds: string
|
||||
lastCheckedAt: int
|
||||
timeToAutoRetryInSecs: int
|
||||
withCache: bool
|
||||
|
||||
proc delete*(self: NetworkConnectionItem) =
|
||||
self.QObject.delete
|
||||
|
||||
proc newNetworkConnectionItem*(completelyDown = false, connectionState = 0, chainIds = "", lastCheckedAt = 0, timeToAutoRetryInSecs = 0, withCache = false,): NetworkConnectionItem =
|
||||
new(result, delete)
|
||||
result.QObject.setup
|
||||
result.completelyDown = completelyDown
|
||||
result.connectionState = connectionState
|
||||
result.chainIds = chainIds
|
||||
result.lastCheckedAt = lastCheckedAt
|
||||
result.timeToAutoRetryInSecs = timeToAutoRetryInSecs
|
||||
result.withCache = withCache
|
||||
|
||||
proc `$`*(self: NetworkConnectionItem): string =
|
||||
result = fmt"""NetworkConnectionItem[
|
||||
completelyDown: {self.completelyDown},
|
||||
connectionState: {self.connectionState},
|
||||
chainIds: {self.chainIds},
|
||||
lastCheckedAt: {self.lastCheckedAt},
|
||||
timeToAutoRetryInSecs: {self.timeToAutoRetryInSecs},
|
||||
withCache: {self.withCache}
|
||||
]"""
|
||||
|
||||
proc completelyDownChanged*(self: NetworkConnectionItem) {.signal.}
|
||||
proc getCompletelyDown*(self: NetworkConnectionItem): bool {.slot.} =
|
||||
return self.completelyDown
|
||||
QtProperty[bool] completelyDown:
|
||||
read = getCompletelyDown
|
||||
notify = completelyDownChanged
|
||||
|
||||
proc connectionStateChanged*(self: NetworkConnectionItem) {.signal.}
|
||||
proc getConnectionState*(self: NetworkConnectionItem): int {.slot.} =
|
||||
return self.connectionState
|
||||
QtProperty[int] connectionState:
|
||||
read = getConnectionState
|
||||
notify = connectionStateChanged
|
||||
|
||||
proc chainIdsChanged*(self: NetworkConnectionItem) {.signal.}
|
||||
proc getChainIds*(self: NetworkConnectionItem): string {.slot.} =
|
||||
return self.chainIds
|
||||
QtProperty[string] chainIds:
|
||||
read = getChainIds
|
||||
notify = chainIdsChanged
|
||||
|
||||
proc lastCheckedAtChanged*(self: NetworkConnectionItem) {.signal.}
|
||||
proc getLastCheckedAt*(self: NetworkConnectionItem): int {.slot.} =
|
||||
return self.lastCheckedAt
|
||||
QtProperty[int] lastCheckedAt:
|
||||
read = getLastCheckedAt
|
||||
notify = lastCheckedAtChanged
|
||||
|
||||
proc timeToAutoRetryInSecsChanged*(self: NetworkConnectionItem) {.signal.}
|
||||
proc getTimeToAutoRetryInSecs*(self: NetworkConnectionItem): int {.slot.} =
|
||||
return self.timeToAutoRetryInSecs
|
||||
QtProperty[int] timeToAutoRetryInSecs:
|
||||
read = getTimeToAutoRetryInSecs
|
||||
notify = timeToAutoRetryInSecsChanged
|
||||
|
||||
proc withCacheChanged*(self: NetworkConnectionItem) {.signal.}
|
||||
proc getWithCache*(self: NetworkConnectionItem): bool {.slot.} =
|
||||
return self.withCache
|
||||
QtProperty[bool] withCache:
|
||||
read = getWithCache
|
||||
notify = withCacheChanged
|
||||
|
||||
proc updateValues*(self: NetworkConnectionItem, completelyDown: bool, connectionState: int,
|
||||
chainIds: string, lastCheckedAt: int, timeToAutoRetryInSecs: int, withCache: bool) =
|
||||
if self.completelyDown != completelyDown :
|
||||
self.completelyDown = completelyDown
|
||||
self.completelyDownChanged()
|
||||
|
||||
if self.connectionState != connectionState :
|
||||
self.connectionState = connectionState
|
||||
self.connectionStateChanged()
|
||||
|
||||
if self.chainIds != chainIds :
|
||||
self.chainIds = chainIds
|
||||
self.chainIdsChanged()
|
||||
|
||||
if self.lastCheckedAt != lastCheckedAt :
|
||||
self.lastCheckedAt = lastCheckedAt
|
||||
self.lastCheckedAtChanged()
|
||||
|
||||
if self.timeToAutoRetryInSecs != timeToAutoRetryInSecs :
|
||||
self.timeToAutoRetryInSecs = timeToAutoRetryInSecs
|
||||
self.timeToAutoRetryInSecsChanged()
|
||||
|
||||
if self.withCache != withCache :
|
||||
self.withCache = withCache
|
||||
self.withCacheChanged()
|
|
@ -1,27 +1,57 @@
|
|||
import NimQml
|
||||
|
||||
import ./io_interface
|
||||
import ./network_connection_item
|
||||
import ../../../../app_service/service/network_connection/service as network_connection_service
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
blockchainNetworkConnection: NetworkConnectionItem
|
||||
collectiblesNetworkConnection: NetworkConnectionItem
|
||||
marketValuesNetworkConnection: NetworkConnectionItem
|
||||
|
||||
proc setup(self: View) =
|
||||
self.QObject.setup
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.QObject.delete
|
||||
self.blockchainNetworkConnection.delete
|
||||
self.collectiblesNetworkConnection.delete
|
||||
self.marketValuesNetworkConnection.delete
|
||||
|
||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||
new(result, delete)
|
||||
result.delegate = delegate
|
||||
result.blockchainNetworkConnection = newNetworkConnectionItem()
|
||||
result.collectiblesNetworkConnection = newNetworkConnectionItem()
|
||||
result.marketValuesNetworkConnection = newNetworkConnectionItem()
|
||||
result.setup()
|
||||
|
||||
proc load*(self: View) =
|
||||
self.delegate.viewDidLoad()
|
||||
|
||||
proc networkConnectionStatusUpdate*(self: View, website: string, completelyDown: bool, connectionState: int, chainIds: string, lastCheckedAt: int, timeToAutoRetryInSecs: int, withCache: bool) {.signal.}
|
||||
proc blockchainNetworkConnectionChanged*(self:View) {.signal.}
|
||||
proc getBlockchainNetworkConnection(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.blockchainNetworkConnection)
|
||||
QtProperty[QVariant] blockchainNetworkConnection:
|
||||
read = getBlockchainNetworkConnection
|
||||
notify = blockchainNetworkConnectionChanged
|
||||
|
||||
proc collectiblesNetworkConnectionChanged*(self:View) {.signal.}
|
||||
proc getCollectiblesNetworkConnection(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.collectiblesNetworkConnection)
|
||||
QtProperty[QVariant] collectiblesNetworkConnection:
|
||||
read = getCollectiblesNetworkConnection
|
||||
notify = collectiblesNetworkConnectionChanged
|
||||
|
||||
proc marketValuesNetworkConnectionChanged*(self:View) {.signal.}
|
||||
proc getMarketValuesNetworkConnection(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.marketValuesNetworkConnection)
|
||||
QtProperty[QVariant] marketValuesNetworkConnection:
|
||||
read = getMarketValuesNetworkConnection
|
||||
notify = marketValuesNetworkConnectionChanged
|
||||
|
||||
proc refreshBlockchainValues*(self: View) {.slot.} =
|
||||
self.delegate.refreshBlockchainValues()
|
||||
|
@ -32,3 +62,19 @@ QtObject:
|
|||
proc refreshCollectiblesValues*(self: View) {.slot.} =
|
||||
self.delegate.refreshCollectiblesValues()
|
||||
|
||||
proc networkConnectionStatusUpdate*(self: View, website: string, completelyDown: bool, connectionState: int, chainIds: string, lastCheckedAt: int, timeToAutoRetryInSecs: int, withCache: bool) {.signal.}
|
||||
|
||||
proc updateNetworkConnectionStatus*(self: View, website: string, completelyDown: bool, connectionState: int, chainIds: string, lastCheckedAt: int, timeToAutoRetryInSecs: int, withCache: bool) =
|
||||
case website:
|
||||
of BLOCKCHAINS:
|
||||
self.blockchainNetworkConnection.updateValues(completelyDown, connectionState, chainIds, lastCheckedAt, timeToAutoRetryInSecs, withCache)
|
||||
self.blockchainNetworkConnectionChanged()
|
||||
of COLLECTIBLES:
|
||||
self.collectiblesNetworkConnection.updateValues(completelyDown, connectionState, chainIds, lastCheckedAt, timeToAutoRetryInSecs, withCache)
|
||||
self.collectiblesNetworkConnectionChanged()
|
||||
of MARKET:
|
||||
self.marketValuesNetworkConnection.updateValues(completelyDown, connectionState, chainIds, lastCheckedAt, timeToAutoRetryInSecs, withCache)
|
||||
self.marketValuesNetworkConnectionChanged()
|
||||
self.networkConnectionStatusUpdate(website, completelyDown, connectionState, chainIds, lastCheckedAt, timeToAutoRetryInSecs, withCache)
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import ../../../../../app_service/service/collectible/service as collectible_ser
|
|||
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
import ../../../../../app_service/service/network/service as network_service
|
||||
import ../../../../../app_service/service/network_connection/service as network_connection_service
|
||||
import ../../../../../app_service/service/node/service as node_service
|
||||
import ../../../../core/eventemitter
|
||||
|
||||
type
|
||||
|
@ -13,13 +14,20 @@ type
|
|||
collectibleService: collectible_service.Service
|
||||
walletAccountService: wallet_account_service.Service
|
||||
networkService: network_service.Service
|
||||
nodeService: node_service.Service
|
||||
networkConnectionService: network_connection_service.Service
|
||||
|
||||
# Forward declaration
|
||||
proc resetOwnedCollectibles*(self: Controller, chainId: int, address: string)
|
||||
|
||||
proc newController*(
|
||||
delegate: io_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
collectibleService: collectible_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
networkService: network_service.Service
|
||||
networkService: network_service.Service,
|
||||
nodeService: node_service.Service,
|
||||
networkConnectionService: network_connection_service.Service
|
||||
): Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
|
@ -27,6 +35,8 @@ proc newController*(
|
|||
result.collectibleService = collectibleService
|
||||
result.walletAccountService = walletAccountService
|
||||
result.networkService = networkService
|
||||
result.nodeService = nodeService
|
||||
result.networkConnectionService = networkConnectionService
|
||||
|
||||
proc delete*(self: Controller) =
|
||||
discard
|
||||
|
@ -37,6 +47,8 @@ proc refreshCollectibles(self: Controller, chainId: int, address: string) =
|
|||
self.delegate.setCollectibles(chainId, address, data)
|
||||
else:
|
||||
self.delegate.appendCollectibles(chainId, address, data)
|
||||
if not self.nodeService.isConnected() or not self.networkConnectionService.checkIfConnected(COLLECTIBLES):
|
||||
self.delegate.noConnectionToOpenSea()
|
||||
|
||||
proc init*(self: Controller) =
|
||||
self.events.on(SIGNAL_OWNED_COLLECTIBLES_RESET) do(e:Args):
|
||||
|
@ -55,7 +67,15 @@ proc init*(self: Controller) =
|
|||
let args = RetryCollectibleArgs(e)
|
||||
let chainId = self.networkService.getNetworkForCollectibles().chainId
|
||||
for address in args.addresses:
|
||||
self.refreshCollectibles(chainId, address)
|
||||
self.resetOwnedCollectibles(chainId, address)
|
||||
|
||||
self.events.on(SIGNAL_NETWORK_DISCONNECTED) do(e: Args):
|
||||
self.delegate.noConnectionToOpenSea()
|
||||
|
||||
self.events.on(SIGNAL_CONNECTION_UPDATE) do(e:Args):
|
||||
let args = NetworkConnectionsArgs(e)
|
||||
if args.website == COLLECTIBLES and args.completelyDown:
|
||||
self.delegate.noConnectionToOpenSea()
|
||||
|
||||
proc getWalletAccount*(self: Controller, accountIndex: int): wallet_account_service.WalletAccountDto =
|
||||
return self.walletAccountService.getWalletAccount(accountIndex)
|
||||
|
|
|
@ -37,3 +37,6 @@ method collectiblesModuleDidLoad*(self: AccessInterface) {.base.} =
|
|||
|
||||
method currentCollectibleModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method noConnectionToOpenSea*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
|
|
@ -203,3 +203,8 @@ QtObject:
|
|||
self.items = concat(self.items, items)
|
||||
self.endInsertRows()
|
||||
self.countChanged()
|
||||
|
||||
# in case loading is still going on and no items are present, show loading items when there is no connection to opensea possible
|
||||
proc noConnectionToOpenSea*(self: Model) =
|
||||
if self.items.len == 0:
|
||||
self.setIsFetching(true)
|
||||
|
|
|
@ -8,6 +8,8 @@ import ../io_interface as delegate_interface
|
|||
import ../../../../../app_service/service/collectible/service as collectible_service
|
||||
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
import ../../../../../app_service/service/network/service as network_service
|
||||
import ../../../../../app_service/service/node/service as node_service
|
||||
import ../../../../../app_service/service/network_connection/service as network_connection_service
|
||||
|
||||
import ./current_collectible/module as current_collectible_module
|
||||
|
||||
|
@ -34,12 +36,14 @@ proc newModule*(
|
|||
events: EventEmitter,
|
||||
collectibleService: collectible_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
networkService: network_service.Service
|
||||
networkService: network_service.Service,
|
||||
nodeService: node_service.Service,
|
||||
networkConnectionService: network_connection_service.Service
|
||||
): Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.view = newView(result)
|
||||
result.controller = newController(result, events, collectibleService, walletAccountService, networkService)
|
||||
result.controller = newController(result, events, collectibleService, walletAccountService, networkService, nodeService, networkConnectionService)
|
||||
result.moduleLoaded = false
|
||||
result.currentCollectibleModule = currentCollectibleModule.newModule(result, collectibleService)
|
||||
|
||||
|
@ -109,7 +113,6 @@ method setCollectibles*(self: Module, chainId: int, address: string, data: Colle
|
|||
self.view.setCollectibles(newCollectibles)
|
||||
self.view.setAllLoaded(data.allLoaded)
|
||||
|
||||
|
||||
method appendCollectibles*(self: Module, chainId: int, address: string, data: CollectiblesData) =
|
||||
if self.chainId == chainId and self.address == address:
|
||||
self.view.setIsFetching(data.isFetching)
|
||||
|
@ -122,3 +125,6 @@ method appendCollectibles*(self: Module, chainId: int, address: string, data: Co
|
|||
|
||||
self.view.appendCollectibles(newCollectibles)
|
||||
self.view.setAllLoaded(data.allLoaded)
|
||||
|
||||
method noConnectionToOpenSea*(self: Module) =
|
||||
self.view.noConnectionToOpenSea()
|
||||
|
|
|
@ -45,3 +45,6 @@ QtObject:
|
|||
|
||||
proc appendCollectibles*(self: View, collectibles: seq[Item]) =
|
||||
self.model.appendItems(collectibles)
|
||||
|
||||
proc noConnectionToOpenSea*(self: View) =
|
||||
self.model.noConnectionToOpenSea()
|
||||
|
|
|
@ -24,6 +24,8 @@ import ../../../../app_service/service/settings/service as settings_service
|
|||
import ../../../../app_service/service/saved_address/service as saved_address_service
|
||||
import ../../../../app_service/service/network/service as network_service
|
||||
import ../../../../app_service/service/accounts/service as accounts_service
|
||||
import ../../../../app_service/service/node/service as node_service
|
||||
import ../../../../app_service/service/network_connection/service as network_connection_service
|
||||
|
||||
import io_interface
|
||||
export io_interface
|
||||
|
@ -57,7 +59,9 @@ proc newModule*(
|
|||
savedAddressService: saved_address_service.Service,
|
||||
networkService: network_service.Service,
|
||||
accountsService: accounts_service.Service,
|
||||
keycardService: keycard_service.Service
|
||||
keycardService: keycard_service.Service,
|
||||
nodeService: node_service.Service,
|
||||
networkConnectionService: network_connection_service.Service
|
||||
): Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
|
@ -68,7 +72,7 @@ proc newModule*(
|
|||
|
||||
result.accountsModule = accounts_module.newModule(result, events, keycardService, walletAccountService, accountsService, networkService, tokenService, currencyService)
|
||||
result.allTokensModule = all_tokens_module.newModule(result, events, tokenService, walletAccountService)
|
||||
result.collectiblesModule = collectibles_module.newModule(result, events, collectibleService, walletAccountService, networkService)
|
||||
result.collectiblesModule = collectibles_module.newModule(result, events, collectibleService, walletAccountService, networkService, nodeService, networkConnectionService)
|
||||
result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService, networkService, tokenService, currencyService)
|
||||
result.transactionsModule = transactions_module.newModule(result, events, transactionService, walletAccountService, networkService, currencyService)
|
||||
result.savedAddressesModule = saved_addresses_module.newModule(result, events, savedAddressService)
|
||||
|
@ -121,6 +125,8 @@ method load*(self: Module) =
|
|||
self.events.on(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT) do(e:Args):
|
||||
self.setTotalCurrencyBalance()
|
||||
self.view.setTokensLoading(false)
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_TOKENS_BEING_FETCHED) do(e:Args):
|
||||
self.view.setTokensLoading(true)
|
||||
self.events.on(SIGNAL_CURRENCY_FORMATS_UPDATED) do(e:Args):
|
||||
self.setTotalCurrencyBalance()
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ const fetchOwnedCollectiblesTaskArg: Task = proc(argEncoded: string) {.gcsafe, n
|
|||
"chainId": arg.chainId,
|
||||
"address": arg.address,
|
||||
"cursor": arg.cursor,
|
||||
"collectibles": ""
|
||||
"collectibles": {"assets":nil,"next":"","previous":""}
|
||||
}
|
||||
try:
|
||||
let response = collectibles.getOpenseaAssetsByOwnerWithCursor(arg.chainId, arg.address, arg.cursor, arg.limit)
|
||||
|
|
|
@ -157,9 +157,9 @@ QtObject:
|
|||
|
||||
# needs to be re-written once cache for colletibles works
|
||||
proc areCollectionsLoaded*(self: Service): bool =
|
||||
for chainId, adressesData in self.ownershipData:
|
||||
for address, collectionsData in adressesData:
|
||||
if collectionsData.allLoaded:
|
||||
for chainId, adressesData in self.accountsOwnershipData:
|
||||
for address, ownershipData in adressesData:
|
||||
if ownershipData.data.anyLoaded:
|
||||
return true
|
||||
return false
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ QtObject:
|
|||
of BLOCKCHAINS:
|
||||
return self.walletService.hasCache()
|
||||
of MARKET:
|
||||
return self.walletService.hasCache()
|
||||
return self.walletService.hasMarketCache()
|
||||
of COLLECTIBLES:
|
||||
return self.collectibleService.areCollectionsLoaded()
|
||||
|
||||
|
@ -246,9 +246,6 @@ QtObject:
|
|||
self.events.emit(SIGNAL_CONNECTION_UPDATE, self.convertConnectionStatusToNetworkConnectionsArgs(website, self.connectionStatus[website]))
|
||||
|
||||
proc checkConnected(self: Service) =
|
||||
if(not singletonInstance.localAccountSensitiveSettings.getIsWalletEnabled()):
|
||||
return
|
||||
|
||||
try:
|
||||
if self.nodeService.isConnected():
|
||||
let response = backend.checkConnected()
|
||||
|
@ -263,3 +260,9 @@ QtObject:
|
|||
proc networkConnected*(self: Service) =
|
||||
self.walletService.reloadAccountTokens()
|
||||
self.events.emit(SIGNAL_REFRESH_COLLECTIBLES, RetryCollectibleArgs(addresses: self.walletService.getAddresses()))
|
||||
|
||||
proc checkIfConnected*(self: Service, website: string): bool =
|
||||
if self.connectionStatus.hasKey(website) and self.connectionStatus[website].completelyDown:
|
||||
return false
|
||||
return true
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ const SIGNAL_WALLET_ACCOUNT_UPDATED* = "walletAccount/walletAccountUpdated"
|
|||
const SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED* = "walletAccount/networkEnabledUpdated"
|
||||
const SIGNAL_WALLET_ACCOUNT_DERIVED_ADDRESS_READY* = "walletAccount/derivedAddressesReady"
|
||||
const SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT* = "walletAccount/tokensRebuilt"
|
||||
const SIGNAL_WALLET_ACCOUNT_TOKENS_BEING_FETCHED* = "walletAccount/tokenFetching"
|
||||
const SIGNAL_WALLET_ACCOUNT_DERIVED_ADDRESS_DETAILS_FETCHED* = "walletAccount/derivedAddressDetailsFetched"
|
||||
|
||||
const SIGNAL_KEYCARDS_SYNCHRONIZED* = "keycardsSynchronized"
|
||||
|
@ -579,6 +580,7 @@ QtObject:
|
|||
accounts: accounts,
|
||||
storeResult: store
|
||||
)
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_TOKENS_BEING_FETCHED, Args())
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc getCurrentCurrencyIfEmpty(self: Service, currency = ""): string =
|
||||
|
@ -851,3 +853,13 @@ QtObject:
|
|||
if self.walletAccounts[address].tokens.len > 0:
|
||||
return true
|
||||
return false
|
||||
|
||||
proc hasMarketCache*(self: Service): bool =
|
||||
withLock self.walletAccountsLock:
|
||||
for address, accountDto in self.walletAccounts:
|
||||
for token in self.walletAccounts[address].tokens:
|
||||
for currency, marketValues in token.marketValuesPerCurrency:
|
||||
if marketValues.highDay > 0:
|
||||
return true
|
||||
return false
|
||||
|
||||
|
|
|
@ -301,6 +301,8 @@ class StatusWalletScreen:
|
|||
|
||||
for index in range(list.count):
|
||||
tokenListItem = list.itemAtIndex(index)
|
||||
if tokenListItem != None and tokenListItem.objectName == "AssetView_LoadingTokenDelegate_"+str(index):
|
||||
return (False, )
|
||||
if tokenListItem != None and tokenListItem.objectName == "AssetView_TokenListItem_" + symbol and tokenListItem.balance != "0":
|
||||
return (True, tokenListItem)
|
||||
return (False, )
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
GANACHE_RPC_PORT=9545
|
||||
GANACHE_MNEMONIC='pelican chief sudden oval media rare swamp elephant lawsuit wheat knife initial'
|
||||
GANACHE_DB_FOLDER="./../../../../../test/ui-test/fixtures/ganache-dbs/goerli"
|
||||
GANACHE_DB_FOLDER=./../../../../../test/ui-test/fixtures/ganache-dbs/goerli
|
||||
|
|
|
@ -21,7 +21,7 @@ Feature: Status Desktop Transaction
|
|||
|
||||
Examples:
|
||||
| amount | token | chain_name |
|
||||
| 0.1 | ETH | Ethereum Mainnet |
|
||||
| 1 | ETH | Ethereum Mainnet |
|
||||
# | 1 | ETH | Goerli |
|
||||
# | 1 | STT | Goerli |
|
||||
# | 100 | STT | Goerli |
|
||||
|
|
|
@ -33,6 +33,7 @@ Rectangle {
|
|||
property var inlineTagModel: []
|
||||
property Component inlineTagDelegate
|
||||
property bool loading: false
|
||||
property bool errorMode: false
|
||||
|
||||
property StatusAssetSettings asset: StatusAssetSettings {
|
||||
height: isImage ? 40 : 20
|
||||
|
@ -78,6 +79,7 @@ Rectangle {
|
|||
property alias statusListItemInlineTagsSlot: statusListItemTagsSlotInline
|
||||
property alias statusListItemLabel: statusListItemLabel
|
||||
property alias subTitleBadgeComponent: subTitleBadgeLoader.sourceComponent
|
||||
property alias errorIcon: errorIcon
|
||||
|
||||
signal clicked(string itemId, var mouse)
|
||||
signal titleClicked(string titleId)
|
||||
|
@ -251,11 +253,24 @@ Rectangle {
|
|||
anchors.leftMargin: 4
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: errorIcon
|
||||
anchors.top: statusListItemTitle.bottom
|
||||
width: 14
|
||||
height: visible ? 14 : 0
|
||||
icon.width: 14
|
||||
icon.height: 14
|
||||
icon.name: "tiny/warning"
|
||||
icon.color: Theme.palette.dangerColor1
|
||||
visible: root.errorMode && !!toolTip.text
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: statusListItemSubtitleTagsRow
|
||||
anchors.top: statusListItemTitle.bottom
|
||||
width: parent.width
|
||||
spacing: 4
|
||||
visible: !errorMode
|
||||
|
||||
Loader {
|
||||
id: subTitleBadgeLoader
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import QtQuick 2.14
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
Item {
|
||||
property alias button: button
|
||||
property alias text: button.text
|
||||
property alias icon: button.icon.name
|
||||
property alias tooltipText: tooltip.text
|
||||
|
||||
implicitWidth: button.width
|
||||
implicitHeight: button.height
|
||||
|
||||
StatusFlatButton {
|
||||
id: button
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: button
|
||||
hoverEnabled: !button.enabled
|
||||
enabled: !button.enabled
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
StatusToolTip {
|
||||
id: tooltip
|
||||
visible: mouseArea.containsMouse
|
||||
}
|
||||
}
|
|
@ -9,12 +9,14 @@ import StatusQ.Core.Theme 0.1
|
|||
import utils 1.0
|
||||
|
||||
import "../popups"
|
||||
import "../controls"
|
||||
|
||||
Rectangle {
|
||||
id: walletFooter
|
||||
|
||||
property var sendModal
|
||||
property var walletStore
|
||||
property var networkConnectionStore
|
||||
|
||||
height: 61
|
||||
color: Theme.palette.statusAppLayout.rightPanelBackgroundColor
|
||||
|
@ -29,13 +31,15 @@ Rectangle {
|
|||
height: parent.height
|
||||
spacing: Style.current.padding
|
||||
|
||||
StatusFlatButton {
|
||||
objectName: "walletFooterSendButton"
|
||||
icon.name: "send"
|
||||
text: qsTr("Send")
|
||||
onClicked: function() {
|
||||
FooterTooltipButton {
|
||||
button.objectName: "walletFooterSendButton"
|
||||
button.icon.name: "send"
|
||||
button.text: qsTr("Send")
|
||||
button.enabled: networkConnectionStore.sendBuyBridgeEnabled
|
||||
button.onClicked: function() {
|
||||
sendModal.open()
|
||||
}
|
||||
tooltipText: networkConnectionStore.sendBuyBridgeToolTipText
|
||||
}
|
||||
|
||||
StatusFlatButton {
|
||||
|
@ -46,14 +50,15 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
StatusFlatButton {
|
||||
id: bridgeBtn
|
||||
icon.name: "bridge"
|
||||
text: qsTr("Bridge")
|
||||
onClicked: function () {
|
||||
FooterTooltipButton {
|
||||
button.icon.name: "bridge"
|
||||
button.text: qsTr("Bridge")
|
||||
button.enabled: networkConnectionStore.sendBuyBridgeEnabled
|
||||
button.onClicked: function() {
|
||||
sendModal.isBridgeTx = true
|
||||
sendModal.open()
|
||||
}
|
||||
tooltipText: networkConnectionStore.sendBuyBridgeToolTipText
|
||||
}
|
||||
|
||||
StatusFlatButton {
|
||||
|
|
|
@ -18,6 +18,7 @@ import "../stores"
|
|||
Item {
|
||||
id: root
|
||||
|
||||
property var networkConnectionStore
|
||||
property string currency: ""
|
||||
property var currentAccount
|
||||
property var store
|
||||
|
@ -47,6 +48,7 @@ Item {
|
|||
customColor: Theme.palette.baseColor1
|
||||
text: LocaleUtils.currencyAmountToLocaleString(root.currentAccount.currencyBalance)
|
||||
loading: root.walletStore.tokensLoading
|
||||
visible: !networkConnectionStore.tokenBalanceNotAvailable
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ Item {
|
|||
id: root
|
||||
|
||||
property var token: ({})
|
||||
property var networkConnectionStore
|
||||
/*required*/ property string address: ""
|
||||
|
||||
QtObject {
|
||||
|
@ -51,10 +52,12 @@ Item {
|
|||
width: parent.width
|
||||
asset.name: token && token.symbol ? Style.png("tokens/%1".arg(token.symbol)) : ""
|
||||
asset.isImage: true
|
||||
primaryText: token.name ?? ""
|
||||
secondaryText: token ? LocaleUtils.currencyAmountToLocaleString(token.enabledNetworkBalance) : ""
|
||||
tertiaryText: token ? LocaleUtils.currencyAmountToLocaleString(token.enabledNetworkCurrencyBalance) : ""
|
||||
primaryText: token.name ?? Constants.dummyText
|
||||
secondaryText: token ? LocaleUtils.currencyAmountToLocaleString(token.enabledNetworkBalance) : Constants.dummyText
|
||||
tertiaryText: token ? LocaleUtils.currencyAmountToLocaleString(token.enabledNetworkCurrencyBalance) : Constants.dummyText
|
||||
balances: token && token.balances ? token.balances : null
|
||||
isLoading: RootStore.tokensLoading
|
||||
errorTooltipText: token && token.balances ? networkConnectionStore.getNetworkDownTextForToken(token.balances): ""
|
||||
getNetworkColor: function(chainId){
|
||||
return RootStore.getNetworkColor(chainId)
|
||||
}
|
||||
|
@ -274,17 +277,20 @@ Item {
|
|||
InformationTile {
|
||||
maxWidth: parent.width
|
||||
primaryText: qsTr("Market Cap")
|
||||
secondaryText: token && token.marketCap ? LocaleUtils.currencyAmountToLocaleString(token.marketCap) : "---"
|
||||
secondaryText: token && token.marketCap ? LocaleUtils.currencyAmountToLocaleString(token.marketCap) : Constants.dummyText
|
||||
isLoading: RootStore.tokensLoading
|
||||
}
|
||||
InformationTile {
|
||||
maxWidth: parent.width
|
||||
primaryText: qsTr("Day Low")
|
||||
secondaryText: token && token.lowDay ? LocaleUtils.currencyAmountToLocaleString(token.lowDay) : "---"
|
||||
secondaryText: token && token.lowDay ? LocaleUtils.currencyAmountToLocaleString(token.lowDay) : Constants.dummyText
|
||||
isLoading: RootStore.tokensLoading
|
||||
}
|
||||
InformationTile {
|
||||
maxWidth: parent.width
|
||||
primaryText: qsTr("Day High")
|
||||
secondaryText: token && token.highDay ? LocaleUtils.currencyAmountToLocaleString(token.highDay) : "---"
|
||||
secondaryText: token && token.highDay ? LocaleUtils.currencyAmountToLocaleString(token.highDay) : Constants.dummyText
|
||||
isLoading: RootStore.tokensLoading
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
|
@ -293,28 +299,31 @@ Item {
|
|||
readonly property double changePctHour: token.changePctHour ?? 0
|
||||
maxWidth: parent.width
|
||||
primaryText: qsTr("Hour")
|
||||
secondaryText: changePctHour ? "%1%".arg(LocaleUtils.numberToLocaleString(changePctHour, 2)) : "---"
|
||||
secondaryLabel.color: Math.sign(changePctHour) === 0 ? Theme.palette.directColor1 :
|
||||
Math.sign(changePctHour) === -1 ? Theme.palette.dangerColor1 :
|
||||
Theme.palette.successColor1
|
||||
secondaryText: changePctHour ? "%1%".arg(LocaleUtils.numberToLocaleString(changePctHour, 2)) : Constants.dummyText
|
||||
secondaryLabel.customColor: changePctHour === 0 ? Theme.palette.directColor1 :
|
||||
changePctHour < 0 ? Theme.palette.dangerColor1 :
|
||||
Theme.palette.successColor1
|
||||
isLoading: RootStore.tokensLoading
|
||||
}
|
||||
InformationTile {
|
||||
readonly property double changePctDay: token.changePctDay ?? 0
|
||||
maxWidth: parent.width
|
||||
primaryText: qsTr("Day")
|
||||
secondaryText: changePctDay ? "%1%".arg(LocaleUtils.numberToLocaleString(changePctDay, 2)) : "---"
|
||||
secondaryLabel.color: Math.sign(changePctDay) === 0 ? Theme.palette.directColor1 :
|
||||
Math.sign(changePctDay) === -1 ? Theme.palette.dangerColor1 :
|
||||
Theme.palette.successColor1
|
||||
secondaryText: changePctDay ? "%1%".arg(LocaleUtils.numberToLocaleString(changePctDay, 2)) : Constants.dummyText
|
||||
secondaryLabel.customColor: changePctDay === 0 ? Theme.palette.directColor1 :
|
||||
changePctDay < 0 ? Theme.palette.dangerColor1 :
|
||||
Theme.palette.successColor1
|
||||
isLoading: RootStore.tokensLoading
|
||||
}
|
||||
InformationTile {
|
||||
readonly property double changePct24hour: token.changePct24hour ?? 0
|
||||
maxWidth: parent.width
|
||||
primaryText: qsTr("24 Hours")
|
||||
secondaryText: changePct24hour ? "%1%".arg(LocaleUtils.numberToLocaleString(changePct24hour, 2)) : "---"
|
||||
secondaryLabel.color: Math.sign(changePct24hour) === 0 ? Theme.palette.directColor1 :
|
||||
Math.sign(changePct24hour) === -1 ? Theme.palette.dangerColor1 :
|
||||
Theme.palette.successColor1
|
||||
secondaryText: changePct24hour ? "%1%".arg(LocaleUtils.numberToLocaleString(changePct24hour, 2)) : Constants.dummyText
|
||||
secondaryLabel.customColor: changePct24hour === 0 ? Theme.palette.directColor1 :
|
||||
changePct24hour < 0 ? Theme.palette.dangerColor1 :
|
||||
Theme.palette.successColor1
|
||||
isLoading: RootStore.tokensLoading
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,18 +357,19 @@ Item {
|
|||
spacing: 24
|
||||
|
||||
width: scrollView.availableWidth
|
||||
StatusBaseText {
|
||||
StatusTextWithLoadingState {
|
||||
id: tokenDescriptionText
|
||||
width: Math.max(536 , scrollView.availableWidth - tagsLayout.width - 24)
|
||||
|
||||
font.pixelSize: 15
|
||||
lineHeight: 22
|
||||
lineHeightMode: Text.FixedHeight
|
||||
text: token.description ?? ""
|
||||
color: Theme.palette.directColor1
|
||||
text: token.description ?? Constants.dummyText
|
||||
customColor: Theme.palette.directColor1
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.Wrap
|
||||
textFormat: Qt.RichText
|
||||
loading: RootStore.tokensLoading
|
||||
}
|
||||
ColumnLayout {
|
||||
id: tagsLayout
|
||||
|
|
|
@ -14,6 +14,7 @@ import shared 1.0
|
|||
import shared.panels 1.0
|
||||
import shared.controls 1.0
|
||||
import shared.popups.keycard 1.0
|
||||
import shared.stores 1.0
|
||||
|
||||
import "../controls"
|
||||
import "../popups"
|
||||
|
@ -22,6 +23,7 @@ import "../stores"
|
|||
Rectangle {
|
||||
id: root
|
||||
|
||||
readonly property NetworkConnectionStore networkConnectionStore: NetworkConnectionStore {}
|
||||
property var changeSelectedAccount: function(){}
|
||||
property bool showSavedAddresses: false
|
||||
onShowSavedAddressesChanged: {
|
||||
|
@ -117,6 +119,20 @@ Rectangle {
|
|||
font.weight: Font.Medium
|
||||
font.pixelSize: 22
|
||||
loading: RootStore.tokensLoading
|
||||
visible: !networkConnectionStore.tokenBalanceNotAvailable
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: errorIcon
|
||||
width: 14
|
||||
height: visible ? 14 : 0
|
||||
icon.width: 14
|
||||
icon.height: 14
|
||||
icon.name: "tiny/warning"
|
||||
icon.color: Theme.palette.dangerColor1
|
||||
tooltip.text: networkConnectionStore.tokenBalanceNotAvailableText
|
||||
tooltip.maxWidth: 200
|
||||
visible: networkConnectionStore.tokenBalanceNotAvailable
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
|
@ -162,6 +178,9 @@ Rectangle {
|
|||
statusListItemTitle.font.weight: Font.Medium
|
||||
color: sensor.containsMouse || highlighted ? Theme.palette.baseColor3 : "transparent"
|
||||
statusListItemSubTitle.loading: RootStore.tokensLoading
|
||||
errorMode: networkConnectionStore.tokenBalanceNotAvailable
|
||||
errorIcon.tooltip.maxWidth: 300
|
||||
errorIcon.tooltip.text: networkConnectionStore.tokenBalanceNotAvailableText
|
||||
onClicked: {
|
||||
changeSelectedAccount(index)
|
||||
showSavedAddresses = false
|
||||
|
|
|
@ -6,6 +6,7 @@ import StatusQ.Controls 0.1
|
|||
|
||||
import utils 1.0
|
||||
import shared.views 1.0
|
||||
import shared.stores 1.0
|
||||
|
||||
import "./"
|
||||
import "../stores"
|
||||
|
@ -19,6 +20,7 @@ Item {
|
|||
property var store
|
||||
property var contactsStore
|
||||
property var sendModal
|
||||
readonly property NetworkConnectionStore networkConnectionStore: NetworkConnectionStore {}
|
||||
|
||||
function resetStack() {
|
||||
stack.currentIndex = 0;
|
||||
|
@ -58,6 +60,7 @@ Item {
|
|||
currentAccount: RootStore.currentAccount
|
||||
store: root.store
|
||||
walletStore: RootStore
|
||||
networkConnectionStore: root.networkConnectionStore
|
||||
}
|
||||
StatusTabBar {
|
||||
id: walletTabBar
|
||||
|
@ -90,6 +93,7 @@ Item {
|
|||
|
||||
AssetsView {
|
||||
account: RootStore.currentAccount
|
||||
networkConnectionStore: root.networkConnectionStore
|
||||
assetDetailsLaunched: stack.currentIndex === 2
|
||||
onAssetClicked: {
|
||||
assetDetailView.token = token
|
||||
|
@ -124,6 +128,7 @@ Item {
|
|||
visible: (stack.currentIndex === 2)
|
||||
|
||||
address: RootStore.currentAccount.mixedcaseAddress
|
||||
networkConnectionStore: root.networkConnectionStore
|
||||
}
|
||||
TransactionDetailView {
|
||||
id: transactionDetailView
|
||||
|
@ -142,6 +147,7 @@ Item {
|
|||
Layout.rightMargin: !!root.StackView ? -root.StackView.view.anchors.rightMargin : 0
|
||||
sendModal: root.sendModal
|
||||
walletStore: RootStore
|
||||
networkConnectionStore: root.networkConnectionStore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,29 +156,4 @@ QtObject {
|
|||
function resolveENS(value) {
|
||||
mainModuleInst.resolveENS(value, "")
|
||||
}
|
||||
|
||||
property var networkConnectionModuleInst: networkConnectionModule
|
||||
|
||||
function getChainIdsJointString(chainIdsDown) {
|
||||
let jointChainIdString = ""
|
||||
for (const chain of chainIdsDown) {
|
||||
jointChainIdString = (!!jointChainIdString) ? jointChainIdString + " & " : jointChainIdString
|
||||
jointChainIdString += allNetworks.getNetworkFullName(parseInt(chain))
|
||||
}
|
||||
return jointChainIdString
|
||||
}
|
||||
|
||||
function retryConnection(websiteDown) {
|
||||
switch(websiteDown) {
|
||||
case Constants.walletConnections.blockchains:
|
||||
networkConnectionModule.refreshBlockchainValues()
|
||||
break
|
||||
case Constants.walletConnections.market:
|
||||
networkConnectionModule.refreshMarketValues()
|
||||
break
|
||||
case Constants.walletConnections.collectibles:
|
||||
networkConnectionModule.refreshCollectiblesValues()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -680,7 +680,6 @@ Item {
|
|||
ConnectionWarnings {
|
||||
id: walletBlockchainConnectionBanner
|
||||
objectName: "walletBlockchainConnectionBanner"
|
||||
readonly property string jointChainIdString: appMain.rootStore.getChainIdsJointString(chainIdsDown)
|
||||
Layout.fillWidth: true
|
||||
websiteDown: Constants.walletConnections.blockchains
|
||||
text: {
|
||||
|
@ -723,6 +722,7 @@ Item {
|
|||
StatusToolTip {
|
||||
id: toolTip
|
||||
orientation: StatusToolTip.Orientation.Bottom
|
||||
maxWidth: 300
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ Control {
|
|||
property alias secondaryText: cryptoBalance.text
|
||||
property alias tertiaryText: fiatBalance.text
|
||||
property var balances
|
||||
property bool isLoading: false
|
||||
property string errorTooltipText
|
||||
property StatusAssetSettings asset: StatusAssetSettings {
|
||||
width: 40
|
||||
height: 40
|
||||
|
@ -34,8 +36,9 @@ Control {
|
|||
id: identiconLoader
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
asset: root.asset
|
||||
loading: root.isLoading
|
||||
}
|
||||
StatusBaseText {
|
||||
StatusTextWithLoadingState {
|
||||
id: tokenName
|
||||
width: Math.min(root.width - identiconLoader.width - cryptoBalance.width - fiatBalance.width - 24, implicitWidth)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
@ -43,15 +46,17 @@ Control {
|
|||
lineHeight: 30
|
||||
lineHeightMode: Text.FixedHeight
|
||||
elide: Text.ElideRight
|
||||
color: Theme.palette.directColor1
|
||||
customColor: Theme.palette.directColor1
|
||||
loading: root.isLoading
|
||||
}
|
||||
StatusBaseText {
|
||||
StatusTextWithLoadingState {
|
||||
id: cryptoBalance
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 22
|
||||
lineHeight: 30
|
||||
lineHeightMode: Text.FixedHeight
|
||||
color: Theme.palette.baseColor1
|
||||
customColor: Theme.palette.baseColor1
|
||||
loading: root.isLoading
|
||||
}
|
||||
StatusBaseText {
|
||||
id: dotSeparator
|
||||
|
@ -61,13 +66,14 @@ Control {
|
|||
color: Theme.palette.baseColor1
|
||||
text: "."
|
||||
}
|
||||
StatusBaseText {
|
||||
StatusTextWithLoadingState {
|
||||
id: fiatBalance
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 22
|
||||
lineHeight: 30
|
||||
lineHeightMode: Text.FixedHeight
|
||||
color: Theme.palette.baseColor1
|
||||
customColor: Theme.palette.baseColor1
|
||||
loading: root.isLoading
|
||||
}
|
||||
}
|
||||
Row {
|
||||
|
@ -81,6 +87,17 @@ Control {
|
|||
tagPrimaryLabel.text: root.formatBalance(model.balance)
|
||||
tagPrimaryLabel.color: root.getNetworkColor(model.chainId)
|
||||
image.source: Style.svg("tiny/%1".arg(root.getNetworkIcon(model.chainId)))
|
||||
loading: root.isLoading
|
||||
rightComponent: StatusFlatRoundButton {
|
||||
width: 14
|
||||
height: visible ? 14 : 0
|
||||
icon.width: 14
|
||||
icon.height: 14
|
||||
icon.name: "tiny/warning"
|
||||
icon.color: Theme.palette.dangerColor1
|
||||
tooltip.text: root.errorTooltipText
|
||||
visible: !!root.errorTooltipText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ Rectangle {
|
|||
property alias tagsDelegate: tags.delegate
|
||||
property int maxWidth: 0
|
||||
property bool copy: false
|
||||
property bool isLoading: false
|
||||
|
||||
signal copyClicked(string textToCopy)
|
||||
|
||||
|
@ -43,13 +44,14 @@ Rectangle {
|
|||
}
|
||||
RowLayout {
|
||||
width: 100
|
||||
StatusBaseText {
|
||||
StatusTextWithLoadingState {
|
||||
id: secondaryText
|
||||
Layout.maximumWidth: root.maxWidth - Style.current.xlPadding - (root.copy ? 50 : 0)
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.directColor1
|
||||
customColor: Theme.palette.directColor1
|
||||
visible: text
|
||||
elide: Text.ElideRight
|
||||
loading: root.isLoading
|
||||
}
|
||||
CopyToClipBoardButton {
|
||||
visible: root.copy
|
||||
|
|
|
@ -21,24 +21,52 @@ StatusListItem {
|
|||
Math.sign(changePct24hour) === 0 ? Theme.palette.baseColor1 :
|
||||
Math.sign(changePct24hour) === -1 ? Theme.palette.dangerColor1 :
|
||||
Theme.palette.successColor1
|
||||
property string errorTooltipText_1
|
||||
property string errorTooltipText_2
|
||||
|
||||
title: name
|
||||
subTitle: LocaleUtils.currencyAmountToLocaleString(enabledNetworkBalance)
|
||||
asset.name: symbol ? Style.png("tokens/" + symbol) : ""
|
||||
asset.isImage: true
|
||||
|
||||
statusListItemTitleIcons.sourceComponent: StatusFlatRoundButton {
|
||||
width: 14
|
||||
height: visible ? 14 : 0
|
||||
icon.width: 14
|
||||
icon.height: 14
|
||||
icon.name: "tiny/warning"
|
||||
icon.color: Theme.palette.dangerColor1
|
||||
tooltip.text: root.errorTooltipText_1
|
||||
tooltip.maxWidth: 300
|
||||
visible: !!tooltip.text
|
||||
}
|
||||
|
||||
components: [
|
||||
Column {
|
||||
id: valueColumn
|
||||
StatusFlatRoundButton {
|
||||
id: errorIcon
|
||||
width: 14
|
||||
height: visible ? 14 : 0
|
||||
icon.width: 14
|
||||
icon.height: 14
|
||||
icon.name: "tiny/warning"
|
||||
icon.color: Theme.palette.dangerColor1
|
||||
tooltip.text: root.errorTooltipText_2
|
||||
tooltip.maxWidth: 200
|
||||
visible: !!tooltip.text
|
||||
}
|
||||
StatusTextWithLoadingState {
|
||||
id: localeCurrencyBalance
|
||||
anchors.right: parent.right
|
||||
font.pixelSize: 15
|
||||
text: LocaleUtils.currencyAmountToLocaleString(enabledNetworkCurrencyBalance)
|
||||
visible: !errorIcon.visible
|
||||
}
|
||||
Row {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: 8
|
||||
visible: !errorIcon.visible
|
||||
StatusTextWithLoadingState {
|
||||
id: change24HourText
|
||||
font.pixelSize: 15
|
||||
|
|
|
@ -3,10 +3,13 @@ import QtQuick 2.14
|
|||
import StatusQ.Core 0.1
|
||||
|
||||
import utils 1.0
|
||||
import shared.stores 1.0
|
||||
|
||||
ModuleWarning {
|
||||
id: root
|
||||
|
||||
readonly property NetworkConnectionStore networkConnectionStore: NetworkConnectionStore {}
|
||||
readonly property string jointChainIdString: networkConnectionStore.getChainIdsJointString(chainIdsDown)
|
||||
property string websiteDown
|
||||
property int connectionState: -1
|
||||
property int autoTryTimerInSecs: 0
|
||||
|
@ -37,11 +40,11 @@ ModuleWarning {
|
|||
type: connectionState === Constants.ConnectionStatus.Success ? ModuleWarning.Success : ModuleWarning.Danger
|
||||
buttonText: connectionState === Constants.ConnectionStatus.Failure ? qsTr("Retry now") : ""
|
||||
|
||||
onClicked: appMain.rootStore.retryConnection(websiteDown)
|
||||
onClicked: networkConnectionStore.retryConnection(websiteDown)
|
||||
onCloseClicked: hide()
|
||||
|
||||
Connections {
|
||||
target: appMain.rootStore.networkConnectionModuleInst
|
||||
target: networkConnectionStore.networkConnectionModuleInst
|
||||
function onNetworkConnectionStatusUpdate(website: string, completelyDown: bool, connectionState: int, chainIds: string, lastCheckedAt: int, timeToAutoRetryInSecs: int, withCache: bool) {
|
||||
if (website === websiteDown) {
|
||||
root.connectionState = connectionState
|
||||
|
|
|
@ -120,6 +120,7 @@ StatusDialog {
|
|||
popup.recalculateRoutesAndFees()
|
||||
}
|
||||
}
|
||||
readonly property NetworkConnectionStore networkConnectionStore: NetworkConnectionStore {}
|
||||
|
||||
onErrorTypeChanged: {
|
||||
if(errorType === Constants.SendAmountExceedsBalance)
|
||||
|
@ -166,6 +167,13 @@ StatusDialog {
|
|||
recipientSelector.input.text = popup.selectedAccount.address
|
||||
d.waitTimer.restart()
|
||||
}
|
||||
|
||||
// add networks that are down to disabled list
|
||||
if(!!d.networkConnectionStore.blockchainNetworksDown) {
|
||||
for(let i in d.networkConnectionStore.blockchainNetworksDown) {
|
||||
store.addRemoveDisabledToChain(parseInt(d.networkConnectionStore.blockchainNetworksDown[i]), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClosed: popup.store.resetTxStoreProperties()
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
import QtQuick 2.13
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
|
||||
import utils 1.0
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
readonly property var networkConnectionModuleInst: networkConnectionModule
|
||||
|
||||
readonly property var blockchainNetworksDown: networkConnectionModule.blockchainNetworkConnection.chainIds.split(";")
|
||||
readonly property bool atleastOneBlockchainNetworkAvailable: blockchainNetworksDown.length < networksModule.all.count
|
||||
readonly property bool noBlockchainConnWithoutCache: (!mainModule.isOnline || networkConnectionModule.blockchainNetworkConnection.completelyDown) &&
|
||||
!walletSection.tokensLoading && walletSectionCurrent.assets.count === 0
|
||||
|
||||
readonly property bool sendBuyBridgeEnabled: localAppSettings.testEnvironment || (mainModule.isOnline &&
|
||||
(!networkConnectionModule.blockchainNetworkConnection.completelyDown && atleastOneBlockchainNetworkAvailable) &&
|
||||
!networkConnectionModule.marketValuesNetworkConnection.completelyDown)
|
||||
readonly property string sendBuyBridgeToolTipText: !mainModule.isOnline ?
|
||||
qsTr("Requires internet connection") :
|
||||
networkConnectionModule.blockchainNetworkConnection.completelyDown ||
|
||||
(!networkConnectionModule.blockchainNetworkConnection.completelyDown &&
|
||||
!atleastOneBlockchainNetworkAvailable) ?
|
||||
qsTr("Requires Pocket Network(POKT) or Infura, both of which are currently unavailable") :
|
||||
networkConnectionModule.marketValuesNetworkConnection.completelyDown ?
|
||||
qsTr("Requires CryptoCompare or CoinGecko, both of which are currently unavailable"):
|
||||
qsTr("Requires POKT/ Infura and CryptoCompare/CoinGecko, which are all currently unavailable")
|
||||
|
||||
|
||||
readonly property bool tokenBalanceNotAvailable: ((!mainModule.isOnline || networkConnectionModule.blockchainNetworkConnection.completelyDown) &&
|
||||
!walletSection.tokensLoading && walletSectionCurrent.assets.count === 0) ||
|
||||
(networkConnectionModule.marketValuesNetworkConnection.completelyDown &&
|
||||
!networkConnectionModule.marketValuesNetworkConnection.withCache)
|
||||
readonly property string tokenBalanceNotAvailableText: !mainModule.isOnline ?
|
||||
qsTr("Internet connection lost. Data could not be retrieved.") :
|
||||
networkConnectionModule.blockchainNetworkConnection.completelyDown ?
|
||||
qsTr("Token balances are fetched from Pocket Network (POKT) and Infura which are both curently unavailable") :
|
||||
networkConnectionModule.marketValuesNetworkConnection.completelyDown ?
|
||||
qsTr("Market values are fetched from CryptoCompare and CoinGecko which are both currently unavailable") :
|
||||
qsTr("Market values and token balances use CryptoCompare/CoinGecko and POKT/Infura which are all currently unavailable.")
|
||||
|
||||
function getBlockchainNetworkDownTextForToken(balances) {
|
||||
if(!!balances && !networkConnectionModule.blockchainNetworkConnection.completelyDown) {
|
||||
let chainIdsDown = []
|
||||
for (var i =0; i<balances.count; i++) {
|
||||
let chainId = balances.rowData(i, "chainId")
|
||||
if(blockchainNetworksDown.includes(chainId))
|
||||
chainIdsDown.push(chainId)
|
||||
}
|
||||
if(chainIdsDown.length > 0) {
|
||||
return qsTr("Pocket Network (POKT) & Infura are currently both unavailable for %1. %1 balances are as of %2.")
|
||||
.arg(getChainIdsJointString(chainIdsDown))
|
||||
.arg(LocaleUtils.formatDateTime(new Date(networkConnectionModule.blockchainNetworkConnection.lastCheckedAt*1000)))
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
function getMarketNetworkDownText() {
|
||||
if(networkConnectionModule.blockchainNetworkConnection.completelyDown &&
|
||||
!walletSection.tokensLoading && walletSectionCurrent.assets.count === 0 &&
|
||||
networkConnectionModule.marketValuesNetworkConnection.completelyDown &&
|
||||
!networkConnectionModule.marketValuesNetworkConnection.withCache)
|
||||
return qsTr("Market values and token balances use CryptoCompare/CoinGecko and POKT/Infura which are all currently unavailable.")
|
||||
else if(networkConnectionModule.marketValuesNetworkConnection.completelyDown &&
|
||||
!networkConnectionModule.marketValuesNetworkConnection.withCache)
|
||||
return qsTr("Market values are fetched from CryptoCompare and CoinGecko which are both currently unavailable")
|
||||
else
|
||||
return ""
|
||||
}
|
||||
|
||||
function getChainIdsJointString(chainIdsDown) {
|
||||
let jointChainIdString = ""
|
||||
for (const chain of chainIdsDown) {
|
||||
jointChainIdString = (!!jointChainIdString) ? jointChainIdString + " & " : jointChainIdString
|
||||
jointChainIdString += networksModule.all.getNetworkFullName(parseInt(chain))
|
||||
}
|
||||
return jointChainIdString
|
||||
}
|
||||
|
||||
function retryConnection(websiteDown) {
|
||||
switch(websiteDown) {
|
||||
case Constants.walletConnections.blockchains:
|
||||
networkConnectionModule.refreshBlockchainValues()
|
||||
break
|
||||
case Constants.walletConnections.market:
|
||||
networkConnectionModule.refreshMarketValues()
|
||||
break
|
||||
case Constants.walletConnections.collectibles:
|
||||
networkConnectionModule.refreshCollectiblesValues()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,3 +5,4 @@ BIP39_en 1.0 BIP39_en.qml
|
|||
ChartStoreBase 1.0 ChartStoreBase.qml
|
||||
TokenBalanceHistoryStore 1.0 TokenBalanceHistoryStore.qml
|
||||
TokenMarketValuesStore 1.0 TokenMarketValuesStore.qml
|
||||
NetworkConnectionStore 1.0 NetworkConnectionStore.qml
|
||||
|
|
|
@ -17,6 +17,7 @@ Item {
|
|||
id: root
|
||||
|
||||
property var account
|
||||
property var networkConnectionStore
|
||||
property bool assetDetailsLaunched: false
|
||||
|
||||
signal assetClicked(var token)
|
||||
|
@ -32,8 +33,9 @@ Item {
|
|||
id: assetListView
|
||||
objectName: "assetViewStatusListView"
|
||||
anchors.fill: parent
|
||||
model: RootStore.tokensLoading ? Constants.dummyModelItems : filteredModel
|
||||
delegate: RootStore.tokensLoading ? loadingTokenDelegate : tokenDelegate
|
||||
// To-do: will try to move the loading tokens to the nim side under this task https://github.com/status-im/status-desktop/issues/9648
|
||||
model: RootStore.tokensLoading || networkConnectionStore.noBlockchainConnWithoutCache ? Constants.dummyModelItems : filteredModel
|
||||
delegate: RootStore.tokensLoading || networkConnectionStore.noBlockchainConnWithoutCache ? loadingTokenDelegate : tokenDelegate
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
|
@ -49,6 +51,7 @@ Item {
|
|||
Component {
|
||||
id: loadingTokenDelegate
|
||||
LoadingTokenDelegate {
|
||||
objectName: "AssetView_LoadingTokenDelegate_" + index
|
||||
width: ListView.view.width
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +61,8 @@ Item {
|
|||
TokenDelegate {
|
||||
objectName: "AssetView_TokenListItem_" + symbol
|
||||
readonly property string balance: "%1".arg(enabledNetworkBalance.amount) // Needed for the tests
|
||||
errorTooltipText_1: networkConnectionStore.getBlockchainNetworkDownTextForToken(balances)
|
||||
errorTooltipText_2: networkConnectionStore.getMarketNetworkDownText()
|
||||
width: ListView.view.width
|
||||
onClicked: {
|
||||
RootStore.getHistoricalDataForToken(symbol, RootStore.currencyStore.currentCurrency)
|
||||
|
|
Loading…
Reference in New Issue