parent
41694a6e09
commit
0515152bd7
|
@ -50,6 +50,16 @@ proc setAssets(self: Module, tokens: seq[WalletTokenDto]) =
|
||||||
t.enabledNetworkBalance.currencybalance,
|
t.enabledNetworkBalance.currencybalance,
|
||||||
t.visible,
|
t.visible,
|
||||||
toSeq(t.balancesPerChain.values),
|
toSeq(t.balancesPerChain.values),
|
||||||
|
t.description,
|
||||||
|
t.assetWebsiteUrl,
|
||||||
|
t.builtOn,
|
||||||
|
t.smartContractAddress,
|
||||||
|
t.marketCap,
|
||||||
|
t.highDay,
|
||||||
|
t.lowDay,
|
||||||
|
t.changePctHour,
|
||||||
|
t.changePctDay,
|
||||||
|
t.changePct24hour,
|
||||||
)
|
)
|
||||||
items.add(item)
|
items.add(item)
|
||||||
|
|
||||||
|
@ -91,4 +101,4 @@ proc onTokensRebuilt(self: Module, accountsTokens: OrderedTable[string, seq[Wall
|
||||||
let walletAccount = self.controller.getWalletAccount(self.currentAccountIndex)
|
let walletAccount = self.controller.getWalletAccount(self.currentAccountIndex)
|
||||||
if not accountsTokens.contains(walletAccount.address):
|
if not accountsTokens.contains(walletAccount.address):
|
||||||
return
|
return
|
||||||
self.setAssets(accountsTokens[walletAccount.address])
|
self.setAssets(accountsTokens[walletAccount.address])
|
||||||
|
|
|
@ -114,3 +114,27 @@ QtObject:
|
||||||
self.items = items
|
self.items = items
|
||||||
self.endResetModel()
|
self.endResetModel()
|
||||||
self.countChanged()
|
self.countChanged()
|
||||||
|
|
||||||
|
proc getChainColor*(self: Model, chainId: int): string {.slot.} =
|
||||||
|
for item in self.items:
|
||||||
|
if(item.getChainId() == chainId):
|
||||||
|
return item.getChainColor()
|
||||||
|
return ""
|
||||||
|
|
||||||
|
proc getIconUrl*(self: Model, chainId: int): string {.slot.} =
|
||||||
|
for item in self.items:
|
||||||
|
if(item.getChainId() == chainId):
|
||||||
|
return item.getIconURL()
|
||||||
|
return ""
|
||||||
|
|
||||||
|
proc getNetworkIconUrl*(self: Model, shortName: string): string {.slot.} =
|
||||||
|
for item in self.items:
|
||||||
|
if(item.getShortName() == toLowerAscii(shortName)):
|
||||||
|
return item.getIconURL()
|
||||||
|
return ""
|
||||||
|
|
||||||
|
proc getNetworkName*(self: Model, shortName: string): string {.slot.} =
|
||||||
|
for item in self.items:
|
||||||
|
if(item.getShortName() == toLowerAscii(shortName)):
|
||||||
|
return item.getChainName()
|
||||||
|
return ""
|
||||||
|
|
|
@ -54,6 +54,16 @@ method refreshWalletAccounts*(self: Module) =
|
||||||
t.enabledNetworkBalance.currencyBalance,
|
t.enabledNetworkBalance.currencyBalance,
|
||||||
t.visible,
|
t.visible,
|
||||||
toSeq(t.balancesPerChain.values),
|
toSeq(t.balancesPerChain.values),
|
||||||
|
t.description,
|
||||||
|
t.assetWebsiteUrl,
|
||||||
|
t.builtOn,
|
||||||
|
t.smartContractAddress,
|
||||||
|
t.marketCap,
|
||||||
|
t.highDay,
|
||||||
|
t.lowDay,
|
||||||
|
t.changePctHour,
|
||||||
|
t.changePctDay,
|
||||||
|
t.changePct24hour,
|
||||||
))
|
))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,16 @@ proc setAssetsAndBalance(self: Module, tokens: seq[WalletTokenDto]) =
|
||||||
t.enabledNetworkBalance.currencybalance,
|
t.enabledNetworkBalance.currencybalance,
|
||||||
t.visible,
|
t.visible,
|
||||||
toSeq(t.balancesPerChain.values),
|
toSeq(t.balancesPerChain.values),
|
||||||
|
t.description,
|
||||||
|
t.assetWebsiteUrl,
|
||||||
|
t.builtOn,
|
||||||
|
t.smartContractAddress,
|
||||||
|
t.marketCap,
|
||||||
|
t.highDay,
|
||||||
|
t.lowDay,
|
||||||
|
t.changePctHour,
|
||||||
|
t.changePctDay,
|
||||||
|
t.changePct24hour,
|
||||||
)
|
)
|
||||||
items.add(item)
|
items.add(item)
|
||||||
totalCurrencyBalanceForAllAssets += t.enabledNetworkBalance.currencybalance
|
totalCurrencyBalanceForAllAssets += t.enabledNetworkBalance.currencybalance
|
||||||
|
|
|
@ -13,6 +13,16 @@ type
|
||||||
enabledNetworkBalance: float
|
enabledNetworkBalance: float
|
||||||
networkVisible: bool
|
networkVisible: bool
|
||||||
balances: balance_model.BalanceModel
|
balances: balance_model.BalanceModel
|
||||||
|
description: string
|
||||||
|
assetWebsiteUrl: string
|
||||||
|
builtOn: string
|
||||||
|
smartContractAddress: string
|
||||||
|
marketCap: string
|
||||||
|
highDay: string
|
||||||
|
lowDay: string
|
||||||
|
changePctHour: string
|
||||||
|
changePctDay: string
|
||||||
|
changePct24hour: string
|
||||||
|
|
||||||
proc initItem*(
|
proc initItem*(
|
||||||
name, symbol: string,
|
name, symbol: string,
|
||||||
|
@ -21,7 +31,17 @@ proc initItem*(
|
||||||
enabledNetworkBalance: float,
|
enabledNetworkBalance: float,
|
||||||
enabledNetworkCurrencyBalance: float,
|
enabledNetworkCurrencyBalance: float,
|
||||||
networkVisible: bool,
|
networkVisible: bool,
|
||||||
balances: seq[BalanceDto]
|
balances: seq[BalanceDto],
|
||||||
|
description: string,
|
||||||
|
assetWebsiteUrl: string,
|
||||||
|
builtOn: string,
|
||||||
|
smartContractAddress: string,
|
||||||
|
marketCap: string,
|
||||||
|
highDay: string,
|
||||||
|
lowDay: string,
|
||||||
|
changePctHour: string,
|
||||||
|
changePctDay: string,
|
||||||
|
changePct24hour: string,
|
||||||
): Item =
|
): Item =
|
||||||
result.name = name
|
result.name = name
|
||||||
result.symbol = symbol
|
result.symbol = symbol
|
||||||
|
@ -32,6 +52,16 @@ proc initItem*(
|
||||||
result.networkVisible = networkVisible
|
result.networkVisible = networkVisible
|
||||||
result.balances = balance_model.newModel()
|
result.balances = balance_model.newModel()
|
||||||
result.balances.setItems(balances)
|
result.balances.setItems(balances)
|
||||||
|
result.description = description
|
||||||
|
result.assetWebsiteUrl = assetWebsiteUrl
|
||||||
|
result.builtOn = builtOn
|
||||||
|
result.smartContractAddress = smartContractAddress
|
||||||
|
result.marketCap = marketCap
|
||||||
|
result.highDay = highDay
|
||||||
|
result.lowDay = lowDay
|
||||||
|
result.changePctHour = changePctHour
|
||||||
|
result.changePctDay = changePctDay
|
||||||
|
result.changePct24hour = changePct24hour
|
||||||
|
|
||||||
proc `$`*(self: Item): string =
|
proc `$`*(self: Item): string =
|
||||||
result = fmt"""AllTokensItem(
|
result = fmt"""AllTokensItem(
|
||||||
|
@ -42,6 +72,16 @@ proc `$`*(self: Item): string =
|
||||||
enabledNetworkBalance: {self.enabledNetworkBalance},
|
enabledNetworkBalance: {self.enabledNetworkBalance},
|
||||||
enabledNetworkCurrencyBalance: {self.enabledNetworkCurrencyBalance},
|
enabledNetworkCurrencyBalance: {self.enabledNetworkCurrencyBalance},
|
||||||
networkVisible: {self.networkVisible},
|
networkVisible: {self.networkVisible},
|
||||||
|
description: {self.description},
|
||||||
|
assetWebsiteUrl: {self.assetWebsiteUrl}
|
||||||
|
builtOn: {self.builtOn}
|
||||||
|
smartContractAddress: {self.smartContractAddress}
|
||||||
|
marketCap: {self.marketCap},
|
||||||
|
highDay: {self.highDay},
|
||||||
|
lowDay: {self.lowDay},
|
||||||
|
changePctHour: {self.changePctHour},
|
||||||
|
changePctDay: {self.changePctDay},
|
||||||
|
changePct24hour: {self.changePct24hour},
|
||||||
]"""
|
]"""
|
||||||
|
|
||||||
proc getName*(self: Item): string =
|
proc getName*(self: Item): string =
|
||||||
|
@ -66,4 +106,34 @@ proc getNetworkVisible*(self: Item): bool =
|
||||||
return self.networkVisible
|
return self.networkVisible
|
||||||
|
|
||||||
proc getBalances*(self: Item): balance_model.BalanceModel =
|
proc getBalances*(self: Item): balance_model.BalanceModel =
|
||||||
return self.balances
|
return self.balances
|
||||||
|
|
||||||
|
proc getDescription*(self: Item): string =
|
||||||
|
return self.description
|
||||||
|
|
||||||
|
proc getAssetWebsiteUrl*(self: Item): string =
|
||||||
|
return self.assetWebsiteUrl
|
||||||
|
|
||||||
|
proc getBuiltOn*(self: Item): string =
|
||||||
|
return self.builtOn
|
||||||
|
|
||||||
|
proc getSmartContractAddress*(self: Item): string =
|
||||||
|
return self.smartContractAddress
|
||||||
|
|
||||||
|
proc getMarketCap*(self: Item): string =
|
||||||
|
return self.marketCap
|
||||||
|
|
||||||
|
proc getHighDay*(self: Item): string =
|
||||||
|
return self.highDay
|
||||||
|
|
||||||
|
proc getLowDay*(self: Item): string =
|
||||||
|
return self.lowDay
|
||||||
|
|
||||||
|
proc getChangePctHour*(self: Item): string =
|
||||||
|
return self.changePctHour
|
||||||
|
|
||||||
|
proc getChangePctDay*(self: Item): string =
|
||||||
|
return self.changePctDay
|
||||||
|
|
||||||
|
proc getChangePct24hour*(self: Item): string =
|
||||||
|
return self.changePct24hour
|
||||||
|
|
|
@ -12,6 +12,16 @@ type
|
||||||
EnabledNetworkBalance
|
EnabledNetworkBalance
|
||||||
NetworkVisible
|
NetworkVisible
|
||||||
Balances
|
Balances
|
||||||
|
Description
|
||||||
|
AssetWebsiteUrl
|
||||||
|
BuiltOn
|
||||||
|
SmartContractAddress
|
||||||
|
MarketCap
|
||||||
|
HighDay
|
||||||
|
LowDay
|
||||||
|
ChangePctHour
|
||||||
|
ChangePctDay
|
||||||
|
ChangePct24hour
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
|
@ -55,6 +65,16 @@ QtObject:
|
||||||
ModelRole.EnabledNetworkBalance.int:"enabledNetworkBalance",
|
ModelRole.EnabledNetworkBalance.int:"enabledNetworkBalance",
|
||||||
ModelRole.NetworkVisible.int:"networkVisible",
|
ModelRole.NetworkVisible.int:"networkVisible",
|
||||||
ModelRole.Balances.int:"balances",
|
ModelRole.Balances.int:"balances",
|
||||||
|
ModelRole.Description.int:"description",
|
||||||
|
ModelRole.AssetWebsiteUrl.int:"assetWebsiteUrl",
|
||||||
|
ModelRole.BuiltOn.int:"builtOn",
|
||||||
|
ModelRole.SmartContractAddress.int:"smartContractAddress",
|
||||||
|
ModelRole.MarketCap.int:"marketCap",
|
||||||
|
ModelRole.HighDay.int:"highDay",
|
||||||
|
ModelRole.LowDay.int:"lowDay",
|
||||||
|
ModelRole.ChangePctHour.int:"changePctHour",
|
||||||
|
ModelRole.ChangePctDay.int:"changePctDay",
|
||||||
|
ModelRole.ChangePct24hour.int:"changePct24hour",
|
||||||
}.toTable
|
}.toTable
|
||||||
|
|
||||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||||
|
@ -84,6 +104,27 @@ QtObject:
|
||||||
result = newQVariant(item.getNetworkVisible())
|
result = newQVariant(item.getNetworkVisible())
|
||||||
of ModelRole.Balances:
|
of ModelRole.Balances:
|
||||||
result = newQVariant(item.getBalances())
|
result = newQVariant(item.getBalances())
|
||||||
|
of ModelRole.Description:
|
||||||
|
result = newQVariant(item.getDescription())
|
||||||
|
of ModelRole.AssetWebsiteUrl:
|
||||||
|
result = newQVariant(item.getAssetWebsiteUrl())
|
||||||
|
of ModelRole.BuiltOn:
|
||||||
|
result = newQVariant(item.getBuiltOn())
|
||||||
|
of ModelRole.SmartContractAddress:
|
||||||
|
result = newQVariant(item.getSmartContractAddress())
|
||||||
|
of ModelRole.MarketCap:
|
||||||
|
result = newQVariant(item.getMarketCap())
|
||||||
|
of ModelRole.HighDay:
|
||||||
|
result = newQVariant(item.getHighDay())
|
||||||
|
of ModelRole.LowDay:
|
||||||
|
result = newQVariant(item.getLowDay())
|
||||||
|
of ModelRole.ChangePctHour:
|
||||||
|
result = newQVariant(item.getChangePctHour())
|
||||||
|
of ModelRole.ChangePctDay:
|
||||||
|
result = newQVariant(item.getChangePctDay())
|
||||||
|
of ModelRole.ChangePct24hour:
|
||||||
|
result = newQVariant(item.getChangePct24hour())
|
||||||
|
|
||||||
|
|
||||||
proc rowData(self: Model, index: int, column: string): string {.slot.} =
|
proc rowData(self: Model, index: int, column: string): string {.slot.} =
|
||||||
if (index >= self.items.len):
|
if (index >= self.items.len):
|
||||||
|
@ -97,6 +138,17 @@ QtObject:
|
||||||
of "enabledNetworkCurrencyBalance": result = $item.getEnabledNetworkCurrencyBalance()
|
of "enabledNetworkCurrencyBalance": result = $item.getEnabledNetworkCurrencyBalance()
|
||||||
of "enabledNetworkBalance": result = $item.getEnabledNetworkBalance()
|
of "enabledNetworkBalance": result = $item.getEnabledNetworkBalance()
|
||||||
of "networkVisible": result = $item.getNetworkVisible()
|
of "networkVisible": result = $item.getNetworkVisible()
|
||||||
|
of "description": result = $item.getDescription()
|
||||||
|
of "assetWebsiteUrl": result = $item.getAssetWebsiteUrl()
|
||||||
|
of "builtOn": result = $item.getBuiltOn()
|
||||||
|
of "smartContractAddress": result = $item.getSmartContractAddress()
|
||||||
|
of "marketCap": result = $item.getMarketCap()
|
||||||
|
of "highDay": result = $item.getHighDay()
|
||||||
|
of "lowDay": result = $item.getLowDay()
|
||||||
|
of "changePctHour": result = $item.getChangePctHour()
|
||||||
|
of "changePctDay": result = $item.getChangePctDay()
|
||||||
|
of "changePct24hour": result = $item.getChangePct24hour()
|
||||||
|
|
||||||
|
|
||||||
proc setItems*(self: Model, items: seq[Item]) =
|
proc setItems*(self: Model, items: seq[Item]) =
|
||||||
self.beginResetModel()
|
self.beginResetModel()
|
||||||
|
|
|
@ -30,7 +30,7 @@ let DEFAULT_TORRENT_CONFIG_TORRENTDIR* = joinPath(main_constants.defaultDataDir(
|
||||||
let NETWORKS* = %* [
|
let NETWORKS* = %* [
|
||||||
{
|
{
|
||||||
"chainId": 1,
|
"chainId": 1,
|
||||||
"chainName": "Mainnet",
|
"chainName": "Ethereum Mainnet",
|
||||||
"rpcUrl": "https://mainnet.infura.io/v3/" & INFURA_TOKEN_RESOLVED,
|
"rpcUrl": "https://mainnet.infura.io/v3/" & INFURA_TOKEN_RESOLVED,
|
||||||
"blockExplorerUrl": "https://etherscan.io/",
|
"blockExplorerUrl": "https://etherscan.io/",
|
||||||
"iconUrl": "network/Network=Ethereum",
|
"iconUrl": "network/Network=Ethereum",
|
||||||
|
|
|
@ -17,12 +17,54 @@ type
|
||||||
color*: string
|
color*: string
|
||||||
isCustom* {.dontSerialize.}: bool
|
isCustom* {.dontSerialize.}: bool
|
||||||
isVisible* {.dontSerialize.}: bool
|
isVisible* {.dontSerialize.}: bool
|
||||||
|
description* :string
|
||||||
|
assetWebsiteUrl*: string
|
||||||
|
builtOn*: string
|
||||||
|
smartContractAddress*: string
|
||||||
|
marketCap*: string
|
||||||
|
highDay*: string
|
||||||
|
lowDay*: string
|
||||||
|
changePctHour*: string
|
||||||
|
changePctDay*: string
|
||||||
|
changePct24hour*: string
|
||||||
|
|
||||||
proc newTokenDto*(
|
proc newTokenDto*(
|
||||||
name: string, chainId: int, address: Address, symbol: string, decimals: int, hasIcon: bool, isCustom: bool = false
|
name: string,
|
||||||
|
chainId: int,
|
||||||
|
address: Address,
|
||||||
|
symbol: string,
|
||||||
|
decimals: int,
|
||||||
|
hasIcon: bool,
|
||||||
|
isCustom: bool = false,
|
||||||
|
description: string = "",
|
||||||
|
assetWebsiteUrl: string = "",
|
||||||
|
builtOn: string = "",
|
||||||
|
smartContractAddress: string = "",
|
||||||
|
marketCap: string = "",
|
||||||
|
highDay: string = "",
|
||||||
|
lowDay: string = "",
|
||||||
|
changePctHour: string = "",
|
||||||
|
changePctDay: string = "",
|
||||||
|
changePct24hour: string = "",
|
||||||
): TokenDto =
|
): TokenDto =
|
||||||
return TokenDto(
|
return TokenDto(
|
||||||
name: name, chainId: chainId, address: address, symbol: symbol, decimals: decimals, hasIcon: hasIcon, isCustom: isCustom
|
name: name,
|
||||||
|
chainId: chainId,
|
||||||
|
address: address,
|
||||||
|
symbol: symbol,
|
||||||
|
decimals: decimals,
|
||||||
|
hasIcon: hasIcon,
|
||||||
|
isCustom: isCustom,
|
||||||
|
description: description,
|
||||||
|
assetWebsiteUrl: assetWebsiteUrl,
|
||||||
|
builtOn: builtOn,
|
||||||
|
smartContractAddress: smartContractAddress,
|
||||||
|
marketCap: marketCap,
|
||||||
|
highDay: highDay,
|
||||||
|
lowDay: lowDay,
|
||||||
|
changePctHour: changePctHour,
|
||||||
|
changePctDay: changePctDay,
|
||||||
|
changePct24hour: changePct24hour,
|
||||||
)
|
)
|
||||||
|
|
||||||
proc toTokenDto*(jsonObj: JsonNode, isVisible: bool, hasIcon: bool = false, isCustom: bool = true): TokenDto =
|
proc toTokenDto*(jsonObj: JsonNode, isVisible: bool, hasIcon: bool = false, isCustom: bool = true): TokenDto =
|
||||||
|
@ -36,8 +78,18 @@ proc toTokenDto*(jsonObj: JsonNode, isVisible: bool, hasIcon: bool = false, isCu
|
||||||
discard jsonObj.getProp("symbol", result.symbol)
|
discard jsonObj.getProp("symbol", result.symbol)
|
||||||
discard jsonObj.getProp("decimals", result.decimals)
|
discard jsonObj.getProp("decimals", result.decimals)
|
||||||
discard jsonObj.getProp("color", result.color)
|
discard jsonObj.getProp("color", result.color)
|
||||||
|
discard jsonObj.getProp("description", result.description)
|
||||||
|
discard jsonObj.getProp("assetWebsiteUrl", result.assetWebsiteUrl)
|
||||||
|
discard jsonObj.getProp("builtOn", result.builtOn)
|
||||||
|
discard jsonObj.getProp("smartContractAddress", result.smartContractAddress)
|
||||||
|
discard jsonObj.getProp("marketCap", result.marketCap)
|
||||||
|
discard jsonObj.getProp("highDay", result.highDay)
|
||||||
|
discard jsonObj.getProp("lowDay", result.lowDay)
|
||||||
|
discard jsonObj.getProp("changePctHour", result.changePctHour)
|
||||||
|
discard jsonObj.getProp("changePctDay", result.changePctDay)
|
||||||
|
discard jsonObj.getProp("changePct24hour", result.changePct24hour)
|
||||||
|
|
||||||
result.isVisible = isVisible
|
result.isVisible = isVisible
|
||||||
|
|
||||||
proc addressAsString*(self: TokenDto): string =
|
proc addressAsString*(self: TokenDto): string =
|
||||||
return $self.address
|
return $self.address
|
||||||
|
|
|
@ -169,6 +169,38 @@ proc fetchPrices(networkSymbols: seq[string], allTokens: seq[TokenDto], currency
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error fetching prices: ", message = e.msg
|
error "error fetching prices: ", message = e.msg
|
||||||
|
|
||||||
|
proc getMarketValues(networkSymbols: seq[string], allTokens: seq[TokenDto], currency: string): Table[string, Table[string, string]] =
|
||||||
|
let allSymbols = prepareSymbols(networkSymbols, allTokens)
|
||||||
|
for symbols in allSymbols:
|
||||||
|
if symbols.len == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
let response = backend.fetchMarketValues(symbols, currency)
|
||||||
|
for (symbol, marketValue) in response.result.pairs:
|
||||||
|
var marketValues: Table[string, string] = initTable[string, string]()
|
||||||
|
for (key, value) in marketValue.pairs:
|
||||||
|
marketValues[key] = value.getStr()
|
||||||
|
result[symbol] = marketValues
|
||||||
|
except Exception as e:
|
||||||
|
error "error fetching markey values: ", message = e.msg
|
||||||
|
|
||||||
|
proc getTokenDetails(networkSymbols: seq[string], allTokens: seq[TokenDto]): Table[string, Table[string, string]] =
|
||||||
|
let allSymbols = prepareSymbols(networkSymbols, allTokens)
|
||||||
|
for symbols in allSymbols:
|
||||||
|
if symbols.len == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
let response = backend.fetchTokenDetails(symbols)
|
||||||
|
for (symbol, tokenDetail) in response.result.pairs:
|
||||||
|
var tokenDetails: Table[string, string] = initTable[string, string]()
|
||||||
|
for (key, value) in tokenDetail.pairs:
|
||||||
|
tokenDetails[key] = value.getStr()
|
||||||
|
result[symbol] = tokenDetails
|
||||||
|
except Exception as e:
|
||||||
|
error "error fetching markey values: ", message = e.msg
|
||||||
|
|
||||||
proc getTokensBalances(walletAddresses: seq[string], allTokens: seq[TokenDto]): JsonNode =
|
proc getTokensBalances(walletAddresses: seq[string], allTokens: seq[TokenDto]): JsonNode =
|
||||||
try:
|
try:
|
||||||
result = newJObject()
|
result = newJObject()
|
||||||
|
@ -218,6 +250,8 @@ const prepareTokensTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
allTokens = deduplicate(allTokens)
|
allTokens = deduplicate(allTokens)
|
||||||
|
|
||||||
var prices = fetchPrices(networkSymbols, allTokens, arg.currency)
|
var prices = fetchPrices(networkSymbols, allTokens, arg.currency)
|
||||||
|
var marketValues = getMarketValues(networkSymbols, allTokens, arg.currency)
|
||||||
|
var tokenDetails = getTokenDetails(networkSymbols, allTokens)
|
||||||
let tokenBalances = getTokensBalances(arg.walletAddresses, allTokens)
|
let tokenBalances = getTokensBalances(arg.walletAddresses, allTokens)
|
||||||
|
|
||||||
var builtTokensPerAccount = %*{ }
|
var builtTokensPerAccount = %*{ }
|
||||||
|
@ -252,6 +286,21 @@ const prepareTokensTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
var totalTokenBalance: BalanceDto
|
var totalTokenBalance: BalanceDto
|
||||||
totalTokenBalance.balance = toSeq(balancesPerChain.values).map(x => x.balance).foldl(a + b)
|
totalTokenBalance.balance = toSeq(balancesPerChain.values).map(x => x.balance).foldl(a + b)
|
||||||
totalTokenBalance.currencyBalance = totalTokenBalance.balance * prices[networkDto.nativeCurrencySymbol]
|
totalTokenBalance.currencyBalance = totalTokenBalance.balance * prices[networkDto.nativeCurrencySymbol]
|
||||||
|
var marketCap: string = ""
|
||||||
|
var highDay: string = ""
|
||||||
|
var lowDay: string = ""
|
||||||
|
var changePctHour: string = ""
|
||||||
|
var changePctDay: string = ""
|
||||||
|
var changePct24hour: string = ""
|
||||||
|
|
||||||
|
if(marketValues.hasKey(networkDto.nativeCurrencySymbol)):
|
||||||
|
marketCap = marketValues[networkDto.nativeCurrencySymbol]["MKTCAP"]
|
||||||
|
highDay = marketValues[networkDto.nativeCurrencySymbol]["HIGHDAY"]
|
||||||
|
lowDay = marketValues[networkDto.nativeCurrencySymbol]["LOWDAY"]
|
||||||
|
changePctHour = marketValues[networkDto.nativeCurrencySymbol]["CHANGEPCTHOUR"]
|
||||||
|
changePctDay = marketValues[networkDto.nativeCurrencySymbol]["CHANGEPCTDAY"]
|
||||||
|
changePct24hour = marketValues[networkDto.nativeCurrencySymbol]["CHANGEPCT24HOUR"]
|
||||||
|
|
||||||
builtTokens.add(WalletTokenDto(
|
builtTokens.add(WalletTokenDto(
|
||||||
name: networkDto.nativeCurrencyName,
|
name: networkDto.nativeCurrencyName,
|
||||||
symbol: networkDto.nativeCurrencySymbol,
|
symbol: networkDto.nativeCurrencySymbol,
|
||||||
|
@ -263,6 +312,16 @@ const prepareTokensTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
enabledNetworkBalance: enabledNetworkBalance,
|
enabledNetworkBalance: enabledNetworkBalance,
|
||||||
balancesPerChain: balancesPerChain,
|
balancesPerChain: balancesPerChain,
|
||||||
visible: networkDto.enabled,
|
visible: networkDto.enabled,
|
||||||
|
description: "Ethereum is a decentralized platform that runs smart contracts (applications that run exactly as programmed without any possibility of downtime, censorship, fraud or third party interference). In the Ethereum protocol and blockchain, there is a price for each operation. In order to have anything transferred or executed by the network, you have to consume or burn Gas. Ethereum’s native cryptocurrency is Ether (ETH) and it is used to pay for computation time and transaction fees.The introductory whitepaper was originally published in 2013 by Vitalik Buterin, the founder of Ethereum, the project was crowdfunded during August 2014 by fans all around the world and launched in 2015. Ethereum is developed and maintained by ETHDEV with contributions from minds across the globe. There is an Ecosystem Support Program which is a branch of the Ethereum Foundation focused on supporting projects and entities within the greater Ethereum community to promote the success and growth of the ecosystem. Multiple startups work with the Ethereum blockchain covering areas in: DeFi, NFTs, Ethereum Name Service, Wallets, Scaling, etc.The launch of Ethereum is a process divided into 4 main phases: Frontier, Homestead, Metropolis and Serenity.Ethereum 2.0, also known as Serenity, is the final phase of Ethereum, it aims to solve the decentralized scaling challenge. A naive way to solve Ethereum's problems would be to make it more centralized. But decentralization is too important, as it gives Ethereum censorship resistance, openness, data privacy and near-unbreakable security.The Eth2 upgrades will make Ethereum scalable, secure, and decentralized. Sharding will make Ethereum more scalable by increasing transactions per second while decreasing the power needed to run a node and validate the chain. The beacon chain will make Ethereum secure by coordinating validators across shards. And staking will lower the barrier to participation, creating a larger – more decentralized – network.The beacon chain will also introduce proof-of-stake to Ethereum. Ethereum is moving to the proof-of-stake (PoS) consensus mechanism from proof-of-work (PoW). This was always the plan as it's a key part of the community's strategy to scale Ethereum via the Eth2 upgrades. However, getting PoS right is a big technical challenge and not as straightforward as using PoW to reach consensus across the networkKeep up with Ethereum upgradesFor ETH holders and Dapp users, this has no impact whatsoever, however, for users wishing to get involved, there are ways to participate in Ethereum and future Eth2-related efforts. Get involved in Eth 2.0Blockchain data provided by: Etherchain (Main Source), Blockchair (Backup), and Etherscan (Total Supply only).",
|
||||||
|
assetWebsiteUrl: "https://www.ethereum.org/",
|
||||||
|
builtOn: "",
|
||||||
|
smartContractAddress: "",
|
||||||
|
marketCap: marketCap,
|
||||||
|
highDay: highDay,
|
||||||
|
lowDay: lowDay,
|
||||||
|
changePctHour: changePctHour,
|
||||||
|
changePctDay: changePctDay,
|
||||||
|
changePct24hour: changePct24hour,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -294,6 +353,32 @@ const prepareTokensTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
var totalTokenBalance: BalanceDto
|
var totalTokenBalance: BalanceDto
|
||||||
totalTokenBalance.balance = toSeq(balancesPerChain.values).map(x => x.balance).foldl(a + b)
|
totalTokenBalance.balance = toSeq(balancesPerChain.values).map(x => x.balance).foldl(a + b)
|
||||||
totalTokenBalance.currencyBalance = totalTokenBalance.balance * prices[tokenDto.symbol]
|
totalTokenBalance.currencyBalance = totalTokenBalance.balance * prices[tokenDto.symbol]
|
||||||
|
var marketCap: string = ""
|
||||||
|
var highDay: string = ""
|
||||||
|
var lowDay: string = ""
|
||||||
|
var changePctHour: string = ""
|
||||||
|
var changePctDay: string = ""
|
||||||
|
var changePct24hour: string = ""
|
||||||
|
var description: string = ""
|
||||||
|
var assetWebsiteUrl: string = ""
|
||||||
|
var builtOn: string = ""
|
||||||
|
var smartContractAddress: string = ""
|
||||||
|
|
||||||
|
if(tokenDetails.hasKey(tokenDto.symbol)):
|
||||||
|
description = tokenDetails[tokenDto.symbol]["Description"]
|
||||||
|
assetWebsiteUrl = tokenDetails[tokenDto.symbol]["AssetWebsiteUrl"]
|
||||||
|
builtOn = tokenDetails[tokenDto.symbol]["BuiltOn"]
|
||||||
|
smartContractAddress = tokenDetails[tokenDto.symbol]["SmartContractAddress"]
|
||||||
|
|
||||||
|
if(marketValues.hasKey(tokenDto.symbol)):
|
||||||
|
marketCap = marketValues[tokenDto.symbol]["MKTCAP"]
|
||||||
|
highDay = marketValues[tokenDto.symbol]["HIGHDAY"]
|
||||||
|
lowDay = marketValues[tokenDto.symbol]["LOWDAY"]
|
||||||
|
changePctHour = marketValues[tokenDto.symbol]["CHANGEPCTHOUR"]
|
||||||
|
changePctDay = marketValues[tokenDto.symbol]["CHANGEPCTDAY"]
|
||||||
|
changePct24hour = marketValues[tokenDto.symbol]["CHANGEPCT24HOUR"]
|
||||||
|
|
||||||
|
let tokenDescription = description.multiReplace([("|", ""),("Facebook",""),("Telegram",""),("Discord",""),("Youtube",""),("YouTube",""),("Instagram",""),("Reddit",""),("Github",""),("GitHub",""),("Whitepaper",""),("Medium",""),("Weibo",""),("LinkedIn",""),("Litepaper",""),("KakaoTalk",""),("BitcoinTalk",""),("Slack",""),("Docs",""),("Kakao",""),("Gitter","")])
|
||||||
builtTokens.add(WalletTokenDto(
|
builtTokens.add(WalletTokenDto(
|
||||||
name: tokenDto.name,
|
name: tokenDto.name,
|
||||||
symbol: tokenDto.symbol,
|
symbol: tokenDto.symbol,
|
||||||
|
@ -304,7 +389,17 @@ const prepareTokensTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
totalBalance: totalTokenBalance,
|
totalBalance: totalTokenBalance,
|
||||||
balancesPerChain: balancesPerChain,
|
balancesPerChain: balancesPerChain,
|
||||||
enabledNetworkBalance: enabledNetworkBalance,
|
enabledNetworkBalance: enabledNetworkBalance,
|
||||||
visible: visible
|
visible: visible,
|
||||||
|
description: tokenDescription,
|
||||||
|
assetWebsiteUrl: assetWebsiteUrl,
|
||||||
|
builtOn: builtOn,
|
||||||
|
smartContractAddress: smartContractAddress,
|
||||||
|
marketCap: marketCap,
|
||||||
|
highDay: highDay,
|
||||||
|
lowDay: lowDay,
|
||||||
|
changePctHour: changePctHour,
|
||||||
|
changePctDay: changePctDay,
|
||||||
|
changePct24hour: changePct24hour
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,16 @@ type
|
||||||
enabledNetworkBalance*: BalanceDto
|
enabledNetworkBalance*: BalanceDto
|
||||||
balancesPerChain*: Table[int, BalanceDto]
|
balancesPerChain*: Table[int, BalanceDto]
|
||||||
visible*: bool
|
visible*: bool
|
||||||
|
description*: string
|
||||||
|
assetWebsiteUrl*: string
|
||||||
|
builtOn*: string
|
||||||
|
smartContractAddress*: string
|
||||||
|
marketCap*: string
|
||||||
|
highDay*: string
|
||||||
|
lowDay*: string
|
||||||
|
changePctHour*: string
|
||||||
|
changePctDay*: string
|
||||||
|
changePct24hour*: string
|
||||||
|
|
||||||
type
|
type
|
||||||
WalletAccountDto* = ref object of RootObj
|
WalletAccountDto* = ref object of RootObj
|
||||||
|
@ -97,6 +107,16 @@ proc toWalletTokenDto*(jsonObj: JsonNode): WalletTokenDto =
|
||||||
discard jsonObj.getProp("color", result.color)
|
discard jsonObj.getProp("color", result.color)
|
||||||
discard jsonObj.getProp("isCustom", result.isCustom)
|
discard jsonObj.getProp("isCustom", result.isCustom)
|
||||||
discard jsonObj.getProp("visible", result.visible)
|
discard jsonObj.getProp("visible", result.visible)
|
||||||
|
discard jsonObj.getProp("description", result.description)
|
||||||
|
discard jsonObj.getProp("assetWebsiteUrl", result.assetWebsiteUrl)
|
||||||
|
discard jsonObj.getProp("builtOn", result.builtOn)
|
||||||
|
discard jsonObj.getProp("smartContractAddress", result.smartContractAddress)
|
||||||
|
discard jsonObj.getProp("marketCap", result.marketCap)
|
||||||
|
discard jsonObj.getProp("highDay", result.highDay)
|
||||||
|
discard jsonObj.getProp("lowDay", result.lowDay)
|
||||||
|
discard jsonObj.getProp("changePctHour", result.changePctHour)
|
||||||
|
discard jsonObj.getProp("changePctDay", result.changePctDay)
|
||||||
|
discard jsonObj.getProp("changePct24hour", result.changePct24hour)
|
||||||
|
|
||||||
var totalBalanceObj: JsonNode
|
var totalBalanceObj: JsonNode
|
||||||
if(jsonObj.getProp("totalBalance", totalBalanceObj)):
|
if(jsonObj.getProp("totalBalance", totalBalanceObj)):
|
||||||
|
@ -126,5 +146,15 @@ proc walletTokenDtoToJson*(dto: WalletTokenDto): JsonNode =
|
||||||
"totalBalance": %* dto.totalBalance,
|
"totalBalance": %* dto.totalBalance,
|
||||||
"enabledNetworkBalance": %* dto.enabledNetworkBalance,
|
"enabledNetworkBalance": %* dto.enabledNetworkBalance,
|
||||||
"balancesPerChain": balancesPerChainJsonObj,
|
"balancesPerChain": balancesPerChainJsonObj,
|
||||||
"visible": dto.visible
|
"visible": dto.visible,
|
||||||
|
"description": dto.description,
|
||||||
|
"assetWebsiteUrl": dto.assetWebsiteUrl,
|
||||||
|
"builtOn": dto.builtOn,
|
||||||
|
"smartContractAddress": dto.smartContractAddress,
|
||||||
|
"marketCap": dto.marketCap,
|
||||||
|
"highDay": dto.highDay,
|
||||||
|
"lowDay": dto.lowDay,
|
||||||
|
"changePctHour": dto.changePctHour,
|
||||||
|
"changePctDay": dto.changePctDay,
|
||||||
|
"changePct24hour": dto.changePct24hour
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,3 +203,10 @@ rpc(addDappPermissions, "permissions"):
|
||||||
rpc(deleteDappPermissionsByNameAndAddress, "permissions"):
|
rpc(deleteDappPermissionsByNameAndAddress, "permissions"):
|
||||||
dapp: string
|
dapp: string
|
||||||
address: string
|
address: string
|
||||||
|
|
||||||
|
rpc(fetchMarketValues, "wallet"):
|
||||||
|
symbols: seq[string]
|
||||||
|
currency: string
|
||||||
|
|
||||||
|
rpc(fetchTokenDetails, "wallet"):
|
||||||
|
symbols: seq[string]
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
import QtQuick.Controls 2.14
|
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
|
@ -7,6 +6,7 @@ import StatusQ.Components 0.1
|
||||||
|
|
||||||
import shared 1.0
|
import shared 1.0
|
||||||
import shared.panels 1.0
|
import shared.panels 1.0
|
||||||
|
import shared.controls 1.0
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
import "../popups"
|
import "../popups"
|
||||||
|
@ -60,35 +60,10 @@ Item {
|
||||||
Repeater {
|
Repeater {
|
||||||
id: chainRepeater
|
id: chainRepeater
|
||||||
model: store.enabledNetworks
|
model: store.enabledNetworks
|
||||||
delegate: Control {
|
delegate: InformationTag {
|
||||||
horizontalPadding: Style.current.halfPadding
|
tagPrimaryLabel.text: model.shortName
|
||||||
verticalPadding: 5
|
tagPrimaryLabel.color: model.chainColor
|
||||||
background: Rectangle {
|
image.source: Style.svg("tiny/" + model.iconUrl)
|
||||||
implicitWidth: 66
|
|
||||||
implicitHeight: 32
|
|
||||||
color: "transparent"
|
|
||||||
border.width: 1
|
|
||||||
border.color: Theme.palette.baseColor2
|
|
||||||
radius: 36
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: Row {
|
|
||||||
spacing: 4
|
|
||||||
// FIXME this could be StatusIcon but it can't load images from an arbitrary URL
|
|
||||||
Image {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
width: 22
|
|
||||||
height: 22
|
|
||||||
source: Style.svg("tiny/" + model.iconUrl)
|
|
||||||
}
|
|
||||||
StatusBaseText {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
text: model.shortName
|
|
||||||
color: model.chainColor
|
|
||||||
font.pixelSize: Style.current.primaryTextFontSize
|
|
||||||
font.weight: Font.Medium
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
import QtQuick.Controls 2.13
|
|
||||||
import QtGraphicalEffects 1.13
|
import QtGraphicalEffects 1.13
|
||||||
import QtQuick.Layouts 1.13
|
import QtQuick.Layouts 1.13
|
||||||
|
|
||||||
|
@ -138,36 +137,10 @@ StatusModal {
|
||||||
spacing: 5
|
spacing: 5
|
||||||
Repeater {
|
Repeater {
|
||||||
model: RootStore.enabledNetworks
|
model: RootStore.enabledNetworks
|
||||||
delegate: Control {
|
delegate: InformationTag {
|
||||||
horizontalPadding: Style.current.halfPadding
|
tagPrimaryLabel.text: model.shortName
|
||||||
verticalPadding: 5
|
tagPrimaryLabel.color: model.chainColor
|
||||||
background: Rectangle {
|
image.source: Style.svg("tiny/" + model.iconUrl)
|
||||||
implicitWidth: 66
|
|
||||||
implicitHeight: 32
|
|
||||||
color: "transparent"
|
|
||||||
border.width: 1
|
|
||||||
border.color: Theme.palette.baseColor2
|
|
||||||
radius: 36
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: Row {
|
|
||||||
spacing: 4
|
|
||||||
// FIXME this could be StatusIcon but it can't load images from an arbitrary URL
|
|
||||||
Image {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
width: 24
|
|
||||||
height: 24
|
|
||||||
source: Style.svg("tiny/" + model.iconUrl)
|
|
||||||
}
|
|
||||||
StatusBaseText {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
text: model.shortName
|
|
||||||
color: model.chainColor
|
|
||||||
font.pixelSize: Style.current.primaryTextFontSize
|
|
||||||
font.weight: Font.Medium
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
|
@ -67,6 +67,11 @@ Item {
|
||||||
|
|
||||||
AssetsView {
|
AssetsView {
|
||||||
account: RootStore.currentAccount
|
account: RootStore.currentAccount
|
||||||
|
assetDetailsLaunched: stack.currentIndex === 2
|
||||||
|
onAssetClicked: {
|
||||||
|
assetDetailView.token = token
|
||||||
|
stack.currentIndex = 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CollectiblesView {
|
CollectiblesView {
|
||||||
onCollectibleClicked: {
|
onCollectibleClicked: {
|
||||||
|
@ -79,7 +84,14 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CollectibleDetailView {
|
CollectibleDetailView {
|
||||||
anchors.fill: parent
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
onGoBack: stack.currentIndex = 0
|
||||||
|
}
|
||||||
|
AssetsDetailView {
|
||||||
|
id: assetDetailView
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
onGoBack: stack.currentIndex = 0
|
onGoBack: stack.currentIndex = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import StatusQ.Core.Theme 0.1
|
||||||
import shared.panels 1.0
|
import shared.panels 1.0
|
||||||
|
|
||||||
import "../../stores"
|
import "../../stores"
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
import QtQuick.Controls 2.14
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
import shared.controls 1.0
|
||||||
|
|
||||||
|
import StatusQ.Components 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
|
||||||
|
Control {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias primaryText: tokenName.text
|
||||||
|
property alias secondaryText: cryptoBalance.text
|
||||||
|
property alias tertiaryText: fiatBalance.text
|
||||||
|
property var balances
|
||||||
|
property StatusImageSettings image: StatusImageSettings {
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
}
|
||||||
|
property var getNetworkColor: function(chainId){}
|
||||||
|
property var getNetworkIcon: function(chainId){}
|
||||||
|
|
||||||
|
topPadding: Style.current.padding
|
||||||
|
|
||||||
|
contentItem: Column {
|
||||||
|
spacing: 4
|
||||||
|
Row {
|
||||||
|
spacing: 8
|
||||||
|
StatusSmartIdenticon {
|
||||||
|
id: identiconLoader
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
image: root.image
|
||||||
|
}
|
||||||
|
StatusBaseText {
|
||||||
|
id: tokenName
|
||||||
|
width: Math.min(root.width - identiconLoader.width - cryptoBalance.width - fiatBalance.width - 24, implicitWidth)
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
font.pixelSize: 22
|
||||||
|
lineHeight: 30
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
elide: Text.ElideRight
|
||||||
|
color: Theme.palette.directColor1
|
||||||
|
}
|
||||||
|
StatusBaseText {
|
||||||
|
id: cryptoBalance
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
font.pixelSize: 22
|
||||||
|
lineHeight: 30
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
}
|
||||||
|
StatusBaseText {
|
||||||
|
id: dotSeparator
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.verticalCenterOffset: -15
|
||||||
|
font.pixelSize: 50
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
text: "."
|
||||||
|
}
|
||||||
|
StatusBaseText {
|
||||||
|
id: fiatBalance
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
font.pixelSize: 22
|
||||||
|
lineHeight: 30
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Row {
|
||||||
|
spacing: Style.current.smallPadding
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: identiconLoader.width
|
||||||
|
Repeater {
|
||||||
|
id: chainRepeater
|
||||||
|
model: balances ? balances : null
|
||||||
|
delegate: InformationTag {
|
||||||
|
tagPrimaryLabel.text: model.balance
|
||||||
|
tagPrimaryLabel.color: root.getNetworkColor(model.chainId)
|
||||||
|
image.source: Style.svg("tiny/%1".arg(root.getNetworkIcon(model.chainId)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
import QtQuick.Layouts 1.13
|
||||||
|
import QtQuick.Controls 2.14
|
||||||
|
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
Control {
|
||||||
|
property alias image : image
|
||||||
|
property alias iconAsset : iconAsset
|
||||||
|
property alias tagPrimaryLabel: tagPrimaryLabel
|
||||||
|
property alias tagSecondaryLabel: tagSecondaryLabel
|
||||||
|
property alias controlBackground: controlBackground
|
||||||
|
|
||||||
|
horizontalPadding: Style.current.halfPadding
|
||||||
|
verticalPadding: 5
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
id: controlBackground
|
||||||
|
implicitWidth: 66
|
||||||
|
implicitHeight: 32
|
||||||
|
color: "transparent"
|
||||||
|
border.width: 1
|
||||||
|
border.color: Theme.palette.baseColor2
|
||||||
|
radius: 36
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: RowLayout {
|
||||||
|
spacing: 4
|
||||||
|
// FIXME this could be StatusIcon but it can't load images from an arbitrary URL
|
||||||
|
Image {
|
||||||
|
id: image
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.maximumWidth: visible ? 22 : 0
|
||||||
|
Layout.maximumHeight: visible ? 22 : 0
|
||||||
|
visible: image.source !== ""
|
||||||
|
}
|
||||||
|
StatusIcon {
|
||||||
|
id: iconAsset
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.maximumWidth: visible ? 22 : 0
|
||||||
|
Layout.maximumHeight: visible ? 22 : 0
|
||||||
|
visible: iconAsset.icon !== ""
|
||||||
|
}
|
||||||
|
StatusBaseText {
|
||||||
|
id: tagPrimaryLabel
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
font.pixelSize: Style.current.primaryTextFontSize
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.palette.directColor1
|
||||||
|
visible: text !== ""
|
||||||
|
}
|
||||||
|
StatusBaseText {
|
||||||
|
id: tagSecondaryLabel
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.maximumWidth: 100
|
||||||
|
font.pixelSize: Style.current.primaryTextFontSize
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
visible: text !== ""
|
||||||
|
elide: Text.ElideMiddle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,8 @@ Rectangle {
|
||||||
|
|
||||||
property alias primaryText: primaryText.text
|
property alias primaryText: primaryText.text
|
||||||
property alias secondaryText: secondaryText.text
|
property alias secondaryText: secondaryText.text
|
||||||
|
property alias primaryLabel: primaryText
|
||||||
|
property alias secondaryLabel: secondaryText
|
||||||
property alias tagsModel: tags.model
|
property alias tagsModel: tags.model
|
||||||
property alias tagsDelegate: tags.delegate
|
property alias tagsDelegate: tags.delegate
|
||||||
property int maxWidth: 0
|
property int maxWidth: 0
|
||||||
|
|
|
@ -26,3 +26,5 @@ TransactionFormGroup 1.0 TransactionFormGroup.qml
|
||||||
EmojiHash 1.0 EmojiHash.qml
|
EmojiHash 1.0 EmojiHash.qml
|
||||||
InformationTile 1.0 InformationTile.qml
|
InformationTile 1.0 InformationTile.qml
|
||||||
SocialLinkPreview 1.0 SocialLinkPreview.qml
|
SocialLinkPreview 1.0 SocialLinkPreview.qml
|
||||||
|
AssetsDetailsHeader 1.0 AssetsDetailsHeader.qml
|
||||||
|
InformationTag 1.0 InformationTag.qml
|
||||||
|
|
|
@ -40,6 +40,23 @@ QtObject {
|
||||||
|
|
||||||
property var walletTokensModule: walletSectionAllTokens
|
property var walletTokensModule: walletSectionAllTokens
|
||||||
property var tokens: walletSectionAllTokens.all
|
property var tokens: walletSectionAllTokens.all
|
||||||
|
property var accounts: walletSectionAccounts.model
|
||||||
|
|
||||||
|
function getNetworkColor(chainId) {
|
||||||
|
return networksModule.all.getChainColor(chainId)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNetworkIcon(chainId) {
|
||||||
|
return networksModule.all.getIconUrl(chainId)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNetworkIconUrl(symbol) {
|
||||||
|
return networksModule.all.getNetworkIconUrl(symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNetworkName(symbol) {
|
||||||
|
return networksModule.all.getNetworkName(symbol)
|
||||||
|
}
|
||||||
|
|
||||||
readonly property var formationChars: (["*", "`", "~"])
|
readonly property var formationChars: (["*", "`", "~"])
|
||||||
function getSelectedTextWithFormationChars(messageInputField) {
|
function getSelectedTextWithFormationChars(messageInputField) {
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
import QtQuick.Layouts 1.13
|
||||||
|
import QtQuick.Controls 2.14
|
||||||
|
import QtQuick.Window 2.12
|
||||||
|
|
||||||
|
import StatusQ.Components 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
import shared.controls 1.0
|
||||||
|
|
||||||
|
import "../stores"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var token
|
||||||
|
|
||||||
|
signal goBack()
|
||||||
|
|
||||||
|
StatusFlatButton {
|
||||||
|
id: backButton
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.topMargin: -Style.current.xlPadding
|
||||||
|
anchors.leftMargin: -Style.current.xlPadding
|
||||||
|
icon.name: "arrow-left"
|
||||||
|
icon.width: 20
|
||||||
|
icon.height: 20
|
||||||
|
text: qsTr("Assets")
|
||||||
|
size: StatusBaseButton.Size.Large
|
||||||
|
onClicked: root.goBack()
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetsDetailsHeader {
|
||||||
|
id: tokenDetailsHeader
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
width: parent.width
|
||||||
|
image.source: token && token.symbol ? Style.png("tokens/%1".arg(token.symbol)) : ""
|
||||||
|
primaryText: token ? token.name : ""
|
||||||
|
secondaryText: token ? qsTr("%1 %2").arg(Utils.toLocaleString(token.totalBalance, RootStore.locale, {"currency": true})).arg(token.symbol) : ""
|
||||||
|
tertiaryText: token ? "%1 %2".arg(Utils.toLocaleString(token.totalCurrencyBalance.toFixed(2), RootStore.locale, {"currency": true})).arg(RootStore.currencyStore.currentCurrency.toUpperCase()) : ""
|
||||||
|
balances: token && token.balances ? token.balances : null
|
||||||
|
getNetworkColor: function(chainId){
|
||||||
|
return RootStore.getNetworkColor(chainId)
|
||||||
|
}
|
||||||
|
getNetworkIcon: function(chainId){
|
||||||
|
return RootStore.getNetworkIcon(chainId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.top: tokenDetailsHeader.bottom
|
||||||
|
anchors.topMargin: 24
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
spacing: Style.current.padding
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
InformationTile {
|
||||||
|
maxWidth: parent.width
|
||||||
|
primaryText: qsTr("Market Cap")
|
||||||
|
secondaryText: token && token.marketCap !== "" ? token.marketCap : "---"
|
||||||
|
}
|
||||||
|
InformationTile {
|
||||||
|
maxWidth: parent.width
|
||||||
|
primaryText: qsTr("Day Low")
|
||||||
|
secondaryText: token && token.lowDay !== "" ? token.lowDay : "---"
|
||||||
|
}
|
||||||
|
InformationTile {
|
||||||
|
maxWidth: parent.width
|
||||||
|
primaryText: qsTr("Day High")
|
||||||
|
secondaryText: token && token.highDay ? token.highDay : "---"
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
InformationTile {
|
||||||
|
readonly property string changePctHour: token ? token.changePctHour : ""
|
||||||
|
maxWidth: parent.width
|
||||||
|
primaryText: qsTr("Hour")
|
||||||
|
secondaryText: changePctHour ? "%1%".arg(changePctHour) : "---"
|
||||||
|
secondaryLabel.color: Math.sign(Number(changePctHour)) === 0 ? Theme.palette.directColor1 :
|
||||||
|
Math.sign(Number(changePctHour)) === -1 ? Theme.palette.dangerColor1 :
|
||||||
|
Theme.palette.successColor1
|
||||||
|
}
|
||||||
|
InformationTile {
|
||||||
|
readonly property string changePctDay: token ? token.changePctDay : ""
|
||||||
|
maxWidth: parent.width
|
||||||
|
primaryText: qsTr("Day")
|
||||||
|
secondaryText: changePctDay ? "%1%".arg(changePctDay) : "---"
|
||||||
|
secondaryLabel.color: Math.sign(Number(changePctDay)) === 0 ? Theme.palette.directColor1 :
|
||||||
|
Math.sign(Number(changePctDay)) === -1 ? Theme.palette.dangerColor1 :
|
||||||
|
Theme.palette.successColor1
|
||||||
|
}
|
||||||
|
InformationTile {
|
||||||
|
readonly property string changePct24hour: token ? token.changePct24hour : ""
|
||||||
|
maxWidth: parent.width
|
||||||
|
primaryText: qsTr("24 Hours")
|
||||||
|
secondaryText: changePct24hour ? "%1%".arg(changePct24hour) : "---"
|
||||||
|
secondaryLabel.color: Math.sign(Number(changePct24hour)) === 0 ? Theme.palette.directColor1 :
|
||||||
|
Math.sign(Number(changePct24hour)) === -1 ? Theme.palette.dangerColor1 :
|
||||||
|
Theme.palette.successColor1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusTabBar {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.current.xlPadding
|
||||||
|
|
||||||
|
StatusTabButton {
|
||||||
|
leftPadding: 0
|
||||||
|
width: implicitWidth
|
||||||
|
text: qsTr("Overview")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StackLayout {
|
||||||
|
id: stack
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
StatusScrollView {
|
||||||
|
id: scrollView
|
||||||
|
Layout.preferredWidth: parent.width
|
||||||
|
Layout.preferredHeight: parent.height
|
||||||
|
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
|
||||||
|
topPadding: 8
|
||||||
|
bottomPadding: 8
|
||||||
|
Flow {
|
||||||
|
id: detailsFlow
|
||||||
|
|
||||||
|
readonly property bool isOverflowing: detailsFlow.width - tagsLayout.width - tokenDescriptionText.width < 24
|
||||||
|
|
||||||
|
spacing: 24
|
||||||
|
|
||||||
|
width: scrollView.availableWidth
|
||||||
|
StatusBaseText {
|
||||||
|
id: tokenDescriptionText
|
||||||
|
width: Math.max(536 , scrollView.availableWidth - tagsLayout.width - 24)
|
||||||
|
|
||||||
|
font.pixelSize: 15
|
||||||
|
lineHeight: 22
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
text: token ? token.description : ""
|
||||||
|
color: Theme.palette.directColor1
|
||||||
|
elide: Text.ElideRight
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
textFormat: Qt.RichText
|
||||||
|
}
|
||||||
|
ColumnLayout {
|
||||||
|
id: tagsLayout
|
||||||
|
spacing: 10
|
||||||
|
InformationTag {
|
||||||
|
id: website
|
||||||
|
Layout.alignment: detailsFlow.isOverflowing ? Qt.AlignLeft : Qt.AlignRight
|
||||||
|
iconAsset.icon: "browser"
|
||||||
|
tagPrimaryLabel.text: qsTr("Website")
|
||||||
|
controlBackground.color: Theme.palette.baseColor2
|
||||||
|
controlBackground.border.color: "transparent"
|
||||||
|
visible: token && token.assetWebsiteUrl !== ""
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: Global.openLink(token.assetWebsiteUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InformationTag {
|
||||||
|
id: smartContractAddress
|
||||||
|
Layout.alignment: detailsFlow.isOverflowing ? Qt.AlignLeft : Qt.AlignRight
|
||||||
|
|
||||||
|
image.source: token && token.builtOn !== "" ? Style.svg("tiny/" + RootStore.getNetworkIconUrl(token.builtOn)) : ""
|
||||||
|
tagPrimaryLabel.text: token && token.builtOn !== "" ? RootStore.getNetworkName(token.builtOn) : "---"
|
||||||
|
tagSecondaryLabel.text: token && token.smartContractAddress !== "" ? token.smartContractAddress : "---"
|
||||||
|
controlBackground.color: Theme.palette.baseColor2
|
||||||
|
controlBackground.border.color: "transparent"
|
||||||
|
visible: token && token.builtOn !== "" && token.smartContractAddress !== ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,32 +1,66 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
import QtQuick.Layouts 1.3
|
|
||||||
import QtQuick.Controls 2.14
|
import QtQuick.Controls 2.14
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
import StatusQ.Components 0.1
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
import shared 1.0
|
|
||||||
import "../stores"
|
import "../stores"
|
||||||
import "../controls"
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
property var account
|
property var account
|
||||||
|
property bool assetDetailsLaunched: false
|
||||||
|
|
||||||
|
signal assetClicked(var token)
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
readonly property var alwaysVisible : ["ETH", "SNT", "DAI", "STT"]
|
||||||
|
property int selectedAssetIndex: -1
|
||||||
|
}
|
||||||
|
|
||||||
height: assetListView.height
|
height: assetListView.height
|
||||||
|
|
||||||
StatusListView {
|
StatusListView {
|
||||||
id: assetListView
|
id: assetListView
|
||||||
anchors.fill: parent
|
|
||||||
model: account.assets
|
|
||||||
objectName: "assetViewStatusListView"
|
objectName: "assetViewStatusListView"
|
||||||
delegate: AssetDelegate {
|
anchors.fill: parent
|
||||||
locale: RootStore.locale
|
model: SortFilterProxyModel {
|
||||||
currency: RootStore.currentCurrency
|
sourceModel: account.assets
|
||||||
currencySymbol: RootStore.currencyStore.currentCurrencySymbol
|
filters: [
|
||||||
|
ExpressionFilter {
|
||||||
|
expression: d.alwaysVisible.includes(symbol) || (networkVisible && enabledNetworkBalance > 0)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
delegate: StatusListItem {
|
||||||
|
width: parent.width
|
||||||
|
title: name
|
||||||
|
subTitle: qsTr("%1 %2").arg(Utils.toLocaleString(enabledNetworkBalance, RootStore.locale, {"currency": true})).arg(symbol)
|
||||||
|
image.source: symbol ? Style.png("tokens/" + symbol) : ""
|
||||||
|
components: [
|
||||||
|
StatusBaseText {
|
||||||
|
font.pixelSize: 15
|
||||||
|
font.strikeout: false
|
||||||
|
text: enabledNetworkCurrencyBalance.toLocaleCurrencyString(Qt.locale(), RootStore.currencyStore.currentCurrencySymbol)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
onClicked: {
|
||||||
|
d.selectedAssetIndex = index
|
||||||
|
assetClicked(model)
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
// on Model reset if the detail view is shown, update the data in background.
|
||||||
|
if(root.assetDetailsLaunched && index === d.selectedAssetIndex)
|
||||||
|
assetClicked(model)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded }
|
ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded }
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,3 +10,4 @@ PasswordView 1.0 PasswordView.qml
|
||||||
ProfileView 1.0 ProfileView.qml
|
ProfileView 1.0 ProfileView.qml
|
||||||
AssetsView 1.0 AssetsView.qml
|
AssetsView 1.0 AssetsView.qml
|
||||||
HistoryView 1.0 HistoryView.qml
|
HistoryView 1.0 HistoryView.qml
|
||||||
|
AssetsDetailView 1.0 AssetsDetailView.qml
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit e6a3f63ec7f2fa691878ed35f921413dc8acfc66
|
Subproject commit 25a80cf20b2fd6153eccdb3cd154126181b86561
|
Loading…
Reference in New Issue