feat: list, toggle and remove custom tokens
This commit is contained in:
parent
f3f27a5e59
commit
27abf30fc8
|
@ -17,6 +17,7 @@ QtObject:
|
||||||
focusedAccount: AccountItemView
|
focusedAccount: AccountItemView
|
||||||
currentTransactions: TransactionList
|
currentTransactions: TransactionList
|
||||||
defaultTokenList: TokenList
|
defaultTokenList: TokenList
|
||||||
|
customTokenList: TokenList
|
||||||
status: Status
|
status: Status
|
||||||
totalFiatBalance: string
|
totalFiatBalance: string
|
||||||
etherscanLink: string
|
etherscanLink: string
|
||||||
|
@ -35,6 +36,7 @@ QtObject:
|
||||||
self.focusedAccount.delete
|
self.focusedAccount.delete
|
||||||
self.currentTransactions.delete
|
self.currentTransactions.delete
|
||||||
self.defaultTokenList.delete
|
self.defaultTokenList.delete
|
||||||
|
self.customTokenList.delete
|
||||||
self.QAbstractListModel.delete
|
self.QAbstractListModel.delete
|
||||||
|
|
||||||
proc setup(self: WalletView) =
|
proc setup(self: WalletView) =
|
||||||
|
@ -50,6 +52,7 @@ QtObject:
|
||||||
result.currentTransactions = newTransactionList()
|
result.currentTransactions = newTransactionList()
|
||||||
result.currentCollectiblesLists = newCollectiblesList()
|
result.currentCollectiblesLists = newCollectiblesList()
|
||||||
result.defaultTokenList = newTokenList()
|
result.defaultTokenList = newTokenList()
|
||||||
|
result.customTokenList = newTokenList()
|
||||||
result.totalFiatBalance = ""
|
result.totalFiatBalance = ""
|
||||||
result.etherscanLink = ""
|
result.etherscanLink = ""
|
||||||
result.safeLowGasPrice = "0"
|
result.safeLowGasPrice = "0"
|
||||||
|
@ -295,6 +298,20 @@ QtObject:
|
||||||
self.accountListChanged()
|
self.accountListChanged()
|
||||||
self.currentAccountChanged()
|
self.currentAccountChanged()
|
||||||
|
|
||||||
|
proc removeCustomToken*(self: WalletView, tokenAddress: string) {.slot.} =
|
||||||
|
let t = getTokenByAddress(getCustomTokens(), tokenAddress)
|
||||||
|
if t.kind == JNull: return
|
||||||
|
self.status.wallet.hideAsset(t["symbol"].getStr)
|
||||||
|
removeCustomToken(tokenAddress)
|
||||||
|
self.customTokenList.loadCustomTokens()
|
||||||
|
for account in self.status.wallet.accounts:
|
||||||
|
if account.address == self.currentAccount.address:
|
||||||
|
self.currentAccount.setAccountItem(account)
|
||||||
|
else:
|
||||||
|
self.accounts.updateAssetsInList(account.address, account.assetList)
|
||||||
|
self.accountListChanged()
|
||||||
|
self.currentAccountChanged()
|
||||||
|
|
||||||
proc updateView*(self: WalletView) =
|
proc updateView*(self: WalletView) =
|
||||||
self.totalFiatBalanceChanged()
|
self.totalFiatBalanceChanged()
|
||||||
self.currentAccountChanged()
|
self.currentAccountChanged()
|
||||||
|
@ -456,11 +473,21 @@ QtObject:
|
||||||
result = $status_wallet.getWalletAccounts()[0].address
|
result = $status_wallet.getWalletAccounts()[0].address
|
||||||
|
|
||||||
proc getDefaultTokenList(self: WalletView): QVariant {.slot.} =
|
proc getDefaultTokenList(self: WalletView): QVariant {.slot.} =
|
||||||
self.defaultTokenList.setupTokens()
|
self.defaultTokenList.loadDefaultTokens()
|
||||||
result = newQVariant(self.defaultTokenList)
|
result = newQVariant(self.defaultTokenList)
|
||||||
|
|
||||||
QtProperty[QVariant] defaultTokenList:
|
QtProperty[QVariant] defaultTokenList:
|
||||||
read = getDefaultTokenList
|
read = getDefaultTokenList
|
||||||
|
|
||||||
|
proc loadCustomTokens(self: WalletView) {.slot.} =
|
||||||
|
self.customTokenList.loadCustomTokens()
|
||||||
|
|
||||||
|
proc getCustomTokenList(self: WalletView): QVariant {.slot.} =
|
||||||
|
result = newQVariant(self.customTokenList)
|
||||||
|
|
||||||
|
QtProperty[QVariant] customTokenList:
|
||||||
|
read = getCustomTokenList
|
||||||
|
|
||||||
proc historyWasFetched*(self: WalletView) {.signal.}
|
proc historyWasFetched*(self: WalletView) {.signal.}
|
||||||
|
|
||||||
proc setHistoryFetchState*(self: WalletView, accounts: seq[string], isFetching: bool) =
|
proc setHistoryFetchState*(self: WalletView, accounts: seq[string], isFetching: bool) =
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import NimQml, tables, json
|
import NimQml, tables, json
|
||||||
import ../../../status/libstatus/default_tokens
|
import ../../../status/libstatus/default_tokens
|
||||||
|
import ../../../status/libstatus/tokens
|
||||||
|
|
||||||
type
|
type
|
||||||
TokenRoles {.pure.} = enum
|
TokenRoles {.pure.} = enum
|
||||||
Name = UserRole + 1,
|
Name = UserRole + 1,
|
||||||
Symbol = UserRole + 2,
|
Symbol = UserRole + 2,
|
||||||
HasIcon = UserRole + 3
|
HasIcon = UserRole + 3,
|
||||||
|
Address = UserRole + 4
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type TokenList* = ref object of QAbstractListModel
|
type TokenList* = ref object of QAbstractListModel
|
||||||
|
@ -18,10 +20,16 @@ QtObject:
|
||||||
self.tokens = @[]
|
self.tokens = @[]
|
||||||
self.QAbstractListModel.delete
|
self.QAbstractListModel.delete
|
||||||
|
|
||||||
proc setupTokens*(self:TokenList) =
|
proc loadDefaultTokens*(self:TokenList) =
|
||||||
if self.tokens.len == 0:
|
if self.tokens.len == 0:
|
||||||
self.tokens = getDefaultTokens().getElems()
|
self.tokens = getDefaultTokens().getElems()
|
||||||
|
|
||||||
|
proc loadCustomTokens*(self: TokenList) =
|
||||||
|
self.beginResetModel()
|
||||||
|
self.tokens = getCustomTokens().getElems()
|
||||||
|
echo $self.tokens
|
||||||
|
self.endResetModel()
|
||||||
|
|
||||||
proc newTokenList*(): TokenList =
|
proc newTokenList*(): TokenList =
|
||||||
new(result, delete)
|
new(result, delete)
|
||||||
result.tokens = @[]
|
result.tokens = @[]
|
||||||
|
@ -40,13 +48,12 @@ QtObject:
|
||||||
case tokenRole:
|
case tokenRole:
|
||||||
of TokenRoles.Name: result = newQVariant(token["name"].getStr)
|
of TokenRoles.Name: result = newQVariant(token["name"].getStr)
|
||||||
of TokenRoles.Symbol: result = newQVariant(token["symbol"].getStr)
|
of TokenRoles.Symbol: result = newQVariant(token["symbol"].getStr)
|
||||||
of TokenRoles.HasIcon: result = newQVariant(token["hasIcon"].getBool)
|
of TokenRoles.HasIcon: result = newQVariant(token{"hasIcon"}.getBool)
|
||||||
|
of TokenRoles.Address: result = newQVariant(token["address"].getStr)
|
||||||
|
|
||||||
method roleNames(self: TokenList): Table[int, string] =
|
method roleNames(self: TokenList): Table[int, string] =
|
||||||
{TokenRoles.Name.int:"name",
|
{TokenRoles.Name.int:"name",
|
||||||
TokenRoles.Symbol.int:"symbol",
|
TokenRoles.Symbol.int:"symbol",
|
||||||
TokenRoles.HasIcon.int:"hasIcon"}.toTable
|
TokenRoles.HasIcon.int:"hasIcon",
|
||||||
|
TokenRoles.Address.int:"address"}.toTable
|
||||||
|
|
||||||
proc forceUpdate*(self: TokenList) =
|
|
||||||
self.beginResetModel()
|
|
||||||
self.endResetModel()
|
|
||||||
|
|
|
@ -1152,15 +1152,3 @@ proc getDefaultTokens*(): JsonNode =
|
||||||
"hasIcon": true
|
"hasIcon": true
|
||||||
})
|
})
|
||||||
|
|
||||||
proc getTokenBySymbol*(symbol: string): JsonNode =
|
|
||||||
for defToken in getDefaultTokens().getElems():
|
|
||||||
if defToken["symbol"].getStr == symbol:
|
|
||||||
return defToken
|
|
||||||
return newJNull()
|
|
||||||
|
|
||||||
proc getTokenByAddress*(address: string): JsonNode =
|
|
||||||
for defToken in getDefaultTokens().getElems():
|
|
||||||
if defToken["address"].getStr == address:
|
|
||||||
return defToken
|
|
||||||
|
|
||||||
return newJNull()
|
|
|
@ -7,22 +7,45 @@ import settings
|
||||||
from types import Setting, Network
|
from types import Setting, Network
|
||||||
import default_tokens
|
import default_tokens
|
||||||
import strutils
|
import strutils
|
||||||
|
import locks
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "wallet"
|
topics = "wallet"
|
||||||
|
|
||||||
proc getCustomTokens*(): JsonNode =
|
var customTokensLock: Lock
|
||||||
let payload = %* []
|
initLock(customTokensLock)
|
||||||
let response = callPrivateRPC("wallet_getCustomTokens", payload).parseJson
|
|
||||||
if response["result"].kind == JNull:
|
var customTokens {.guard: customTokensLock.} = %*{}
|
||||||
return %* []
|
var dirty {.guard: customTokensLock.} = true
|
||||||
return response["result"]
|
|
||||||
|
proc getCustomTokens*(useCached: bool = true): JsonNode =
|
||||||
|
{.gcsafe.}:
|
||||||
|
withLock customTokensLock:
|
||||||
|
if useCached and not dirty:
|
||||||
|
result = customTokens
|
||||||
|
else:
|
||||||
|
let payload = %* []
|
||||||
|
result = callPrivateRPC("wallet_getCustomTokens", payload).parseJSON()["result"]
|
||||||
|
if result.kind == JNull: result = %* []
|
||||||
|
dirty = false
|
||||||
|
customTokens = result
|
||||||
|
|
||||||
|
proc getTokenBySymbol*(tokenList: JsonNode, symbol: string): JsonNode =
|
||||||
|
for defToken in tokenList.getElems():
|
||||||
|
if defToken["symbol"].getStr == symbol:
|
||||||
|
return defToken
|
||||||
|
return newJNull()
|
||||||
|
|
||||||
|
proc getTokenByAddress*(tokenList: JsonNode, address: string): JsonNode =
|
||||||
|
for defToken in tokenList.getElems():
|
||||||
|
if defToken["address"].getStr == address:
|
||||||
|
return defToken
|
||||||
|
return newJNull()
|
||||||
|
|
||||||
proc visibleTokensSNTDefault(): JsonNode =
|
proc visibleTokensSNTDefault(): JsonNode =
|
||||||
let currentNetwork = getSetting[string](Setting.Networks_CurrentNetwork)
|
let currentNetwork = getSetting[string](Setting.Networks_CurrentNetwork)
|
||||||
let SNT = if getCurrentNetwork() == Network.Testnet: "STT" else: "SNT"
|
let SNT = if getCurrentNetwork() == Network.Testnet: "STT" else: "SNT"
|
||||||
let response = getSetting[string](Setting.VisibleTokens, "{\"" & currentNetwork & "\": [\"" & SNT & "\"]}")
|
let response = getSetting[string](Setting.VisibleTokens, "{\"" & currentNetwork & "\": [\"" & SNT & "\"]}")
|
||||||
echo response
|
|
||||||
result = response.parseJson
|
result = response.parseJson
|
||||||
|
|
||||||
proc toggleAsset*(symbol: string) =
|
proc toggleAsset*(symbol: string) =
|
||||||
|
@ -38,6 +61,17 @@ proc toggleAsset*(symbol: string) =
|
||||||
visibleTokens[currentNetwork] = %* visibleTokenList
|
visibleTokens[currentNetwork] = %* visibleTokenList
|
||||||
discard saveSetting(Setting.VisibleTokens, $visibleTokens)
|
discard saveSetting(Setting.VisibleTokens, $visibleTokens)
|
||||||
|
|
||||||
|
proc hideAsset*(symbol: string) =
|
||||||
|
let currentNetwork = getSetting[string](Setting.Networks_CurrentNetwork)
|
||||||
|
let visibleTokens = visibleTokensSNTDefault()
|
||||||
|
var visibleTokenList = visibleTokens[currentNetwork].to(seq[string])
|
||||||
|
var symbolIdx = visibleTokenList.find(symbol)
|
||||||
|
if symbolIdx > -1:
|
||||||
|
visibleTokenList.del(symbolIdx)
|
||||||
|
visibleTokens[currentNetwork] = newJArray()
|
||||||
|
visibleTokens[currentNetwork] = %* visibleTokenList
|
||||||
|
discard saveSetting(Setting.VisibleTokens, $visibleTokens)
|
||||||
|
|
||||||
proc getVisibleTokens*(): JsonNode =
|
proc getVisibleTokens*(): JsonNode =
|
||||||
let currentNetwork = getSetting[string](Setting.Networks_CurrentNetwork)
|
let currentNetwork = getSetting[string](Setting.Networks_CurrentNetwork)
|
||||||
let visibleTokens = visibleTokensSNTDefault()
|
let visibleTokens = visibleTokensSNTDefault()
|
||||||
|
@ -45,24 +79,23 @@ proc getVisibleTokens*(): JsonNode =
|
||||||
let customTokens = getCustomTokens()
|
let customTokens = getCustomTokens()
|
||||||
|
|
||||||
result = newJArray()
|
result = newJArray()
|
||||||
|
|
||||||
for v in visibleTokenList:
|
for v in visibleTokenList:
|
||||||
let t = getTokenBySymbol(v)
|
let t = getTokenBySymbol(getDefaultTokens(), v)
|
||||||
if t.kind != JNull: result.elems.add(t)
|
if t.kind != JNull: result.elems.add(t)
|
||||||
|
let ct = getTokenBySymbol(getCustomTokens(), v)
|
||||||
for custToken in customTokens.getElems():
|
if ct.kind != JNull: result.elems.add(ct)
|
||||||
for v in visibleTokenList:
|
|
||||||
if custToken["symbol"].getStr == v:
|
|
||||||
result.elems.add(custToken)
|
|
||||||
break
|
|
||||||
|
|
||||||
proc addCustomToken*(address: string, name: string, symbol: string, decimals: int, color: string) =
|
proc addCustomToken*(address: string, name: string, symbol: string, decimals: int, color: string) =
|
||||||
let payload = %* [{"address": address, "name": name, "symbol": symbol, "decimals": decimals, "color": color}]
|
let payload = %* [{"address": address, "name": name, "symbol": symbol, "decimals": decimals, "color": color}]
|
||||||
discard callPrivateRPC("wallet_addCustomToken", payload)
|
discard callPrivateRPC("wallet_addCustomToken", payload)
|
||||||
|
withLock customTokensLock:
|
||||||
|
dirty = true
|
||||||
|
|
||||||
proc removeCustomToken*(address: string) =
|
proc removeCustomToken*(address: string) =
|
||||||
let payload = %* [address]
|
let payload = %* [address]
|
||||||
discard callPrivateRPC("wallet_deleteCustomToken", payload)
|
echo callPrivateRPC("wallet_deleteCustomToken", payload)
|
||||||
|
withLock customTokensLock:
|
||||||
|
dirty = true
|
||||||
|
|
||||||
proc getTokensBalances*(accounts: openArray[string], tokens: openArray[string]): JsonNode =
|
proc getTokensBalances*(accounts: openArray[string], tokens: openArray[string]): JsonNode =
|
||||||
let payload = %* [accounts, tokens]
|
let payload = %* [accounts, tokens]
|
||||||
|
@ -80,9 +113,14 @@ proc getTokenBalance*(tokenAddress: string, account: string): string =
|
||||||
let response = callPrivateRPC("eth_call", payload)
|
let response = callPrivateRPC("eth_call", payload)
|
||||||
let balance = response.parseJson["result"].getStr
|
let balance = response.parseJson["result"].getStr
|
||||||
|
|
||||||
let t = getTokenByAddress(tokenAddress)
|
|
||||||
var decimals = 18
|
var decimals = 18
|
||||||
if t.kind != JNull: decimals = t["decimals"].getInt
|
let t = getTokenByAddress(getDefaultTokens(), tokenAddress)
|
||||||
|
let ct = getTokenByAddress(getCustomTokens(), tokenAddress)
|
||||||
|
if t.kind != JNull:
|
||||||
|
decimals = t["decimals"].getInt
|
||||||
|
elif ct.kind != JNull:
|
||||||
|
decimals = ct["decimals"].getInt
|
||||||
|
|
||||||
result = $hex2Token(balance, decimals)
|
result = $hex2Token(balance, decimals)
|
||||||
|
|
||||||
proc getSNTAddress*(): string =
|
proc getSNTAddress*(): string =
|
||||||
|
@ -92,10 +130,3 @@ proc getSNTAddress*(): string =
|
||||||
proc getSNTBalance*(account: string): string =
|
proc getSNTBalance*(account: string): string =
|
||||||
let snt = contracts.getContract("snt")
|
let snt = contracts.getContract("snt")
|
||||||
result = getTokenBalance("0x" & $snt.address, account)
|
result = getTokenBalance("0x" & $snt.address, account)
|
||||||
|
|
||||||
proc addOrRemoveToken*(enable: bool, address: string, name: string, symbol: string, decimals: int, color: string): JsonNode =
|
|
||||||
if enable:
|
|
||||||
addCustomToken(address, name, symbol, decimals, color)
|
|
||||||
else:
|
|
||||||
removeCustomToken(address)
|
|
||||||
getCustomTokens()
|
|
||||||
|
|
|
@ -198,6 +198,7 @@ proc addWatchOnlyAccount*(self: WalletModel, address: string, accountName: strin
|
||||||
return self.addNewGeneratedAccount(account, "", accountName, color, constants.WATCH, false)
|
return self.addNewGeneratedAccount(account, "", accountName, color, constants.WATCH, false)
|
||||||
|
|
||||||
proc hasAsset*(self: WalletModel, account: string, symbol: string): bool =
|
proc hasAsset*(self: WalletModel, account: string, symbol: string): bool =
|
||||||
|
self.tokens = status_tokens.getVisibleTokens()
|
||||||
self.tokens.anyIt(it["symbol"].getStr == symbol)
|
self.tokens.anyIt(it["symbol"].getStr == symbol)
|
||||||
|
|
||||||
proc changeAccountSettings*(self: WalletModel, address: string, accountName: string, color: string): string =
|
proc changeAccountSettings*(self: WalletModel, address: string, accountName: string, color: string): string =
|
||||||
|
@ -224,6 +225,14 @@ proc toggleAsset*(self: WalletModel, symbol: string) =
|
||||||
updateBalance(account, self.getDefaultCurrency())
|
updateBalance(account, self.getDefaultCurrency())
|
||||||
self.events.emit("assetChanged", Args())
|
self.events.emit("assetChanged", Args())
|
||||||
|
|
||||||
|
proc hideAsset*(self: WalletModel, symbol: string) =
|
||||||
|
status_tokens.hideAsset(symbol)
|
||||||
|
self.tokens = status_tokens.getVisibleTokens()
|
||||||
|
for account in self.accounts:
|
||||||
|
account.assetList = self.generateAccountConfiguredAssets(account.address)
|
||||||
|
updateBalance(account, self.getDefaultCurrency())
|
||||||
|
self.events.emit("assetChanged", Args())
|
||||||
|
|
||||||
proc addCustomToken*(self: WalletModel, symbol: string, enable: bool, address: string, name: string, decimals: int, color: string) =
|
proc addCustomToken*(self: WalletModel, symbol: string, enable: bool, address: string, name: string, decimals: int, color: string) =
|
||||||
addCustomToken(address, name, symbol, decimals, color)
|
addCustomToken(address, name, symbol, decimals, color)
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,8 @@ ModalPopup {
|
||||||
changeError.open()
|
changeError.open()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
walletModel.loadCustomTokens()
|
||||||
popup.close();
|
popup.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,7 @@ ModalPopup {
|
||||||
//% "Add custom token"
|
//% "Add custom token"
|
||||||
label: qsTrId("add-custom-token")
|
label: qsTrId("add-custom-token")
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
onClicked: {
|
onClicked: addCustomTokenModal.open()
|
||||||
popup.close()
|
|
||||||
addCustomTokenModal.open()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,6 +158,7 @@ Item {
|
||||||
icon.source: "../../img/add_remove_token.svg"
|
icon.source: "../../img/add_remove_token.svg"
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
tokenSettingsModal.open()
|
tokenSettingsModal.open()
|
||||||
|
walletModel.loadCustomTokens()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Action {
|
Action {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
import QtQuick.Controls 2.13
|
import QtQuick.Controls 2.13
|
||||||
|
import QtQuick.Layouts 1.13
|
||||||
|
|
||||||
import "../../../../imports"
|
import "../../../../imports"
|
||||||
import "../../../../shared"
|
import "../../../../shared"
|
||||||
import "../../Chat/ContactsColumn"
|
import "../../Chat/ContactsColumn"
|
||||||
|
@ -16,70 +18,139 @@ Item {
|
||||||
anchors.top: modalBody.top
|
anchors.top: modalBody.top
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView {
|
Component {
|
||||||
id: tokenListView
|
id: tokenComponent
|
||||||
spacing: 0
|
Item {
|
||||||
|
id: tokenContainer
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Style.current.smallPadding
|
||||||
|
width: 300
|
||||||
|
property bool isVisible: symbol && (searchBox.text == "" || name.toLowerCase().includes(searchBox.text.toLowerCase()) || symbol.toLowerCase().includes(searchBox.text.toLowerCase()))
|
||||||
|
|
||||||
|
visible: isVisible
|
||||||
|
height: isVisible ? 40 + Style.current.smallPadding : 0
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: assetInfoImage
|
||||||
|
width: 36
|
||||||
|
height: tokenContainer.isVisible !== "" ? 36 : 0
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 0
|
||||||
|
source: hasIcon ? "../../../img/tokens/" + symbol + ".png" : "../../../img/tokens/0-native.png"
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 0
|
||||||
|
}
|
||||||
|
StyledText {
|
||||||
|
id: assetSymbol
|
||||||
|
text: symbol
|
||||||
|
anchors.left: assetInfoImage.right
|
||||||
|
anchors.leftMargin: Style.current.smallPadding
|
||||||
|
anchors.top: assetInfoImage.top
|
||||||
|
anchors.topMargin: 0
|
||||||
|
font.pixelSize: 15
|
||||||
|
}
|
||||||
|
StyledText {
|
||||||
|
id: assetFullTokenName
|
||||||
|
text: name || ""
|
||||||
|
anchors.bottom: assetInfoImage.bottom
|
||||||
|
anchors.bottomMargin: 0
|
||||||
|
anchors.left: assetInfoImage.right
|
||||||
|
anchors.leftMargin: Style.current.smallPadding
|
||||||
|
color: Style.current.darkGrey
|
||||||
|
font.pixelSize: 15
|
||||||
|
width: 330
|
||||||
|
}
|
||||||
|
CheckBox {
|
||||||
|
id: assetCheck
|
||||||
|
checked: walletModel.hasAsset("0x123", symbol)
|
||||||
|
anchors.left: assetFullTokenName.right
|
||||||
|
anchors.leftMargin: Style.current.smallPadding
|
||||||
|
onClicked: walletModel.toggleAsset(symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: contextMenu.popup(assetSymbol.x - 100, assetSymbol.y + 25)
|
||||||
|
PopupMenu {
|
||||||
|
id: contextMenu
|
||||||
|
Action {
|
||||||
|
icon.source: "../../../img/make-admin.svg"
|
||||||
|
text: qsTr("Token details")
|
||||||
|
onTriggered: {
|
||||||
|
console.log("TODO")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Action {
|
||||||
|
icon.source: "../../../img/remove-from-group.svg"
|
||||||
|
icon.color: Style.current.red
|
||||||
|
text: qsTr("Remove token")
|
||||||
|
onTriggered: walletModel.removeCustomToken(address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
id: sview
|
||||||
clip: true
|
clip: true
|
||||||
|
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||||
|
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
||||||
|
|
||||||
|
contentHeight: tokenList.height
|
||||||
|
|
||||||
anchors.top: searchBox.bottom
|
anchors.top: searchBox.bottom
|
||||||
anchors.topMargin: Style.current.smallPadding
|
anchors.topMargin: Style.current.smallPadding
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
model: walletModel.defaultTokenList
|
|
||||||
ScrollBar.vertical: ScrollBar { active: true }
|
|
||||||
|
|
||||||
delegate: Component {
|
|
||||||
id: component
|
|
||||||
Item {
|
|
||||||
id: tokenContainer
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: Style.current.smallPadding
|
|
||||||
width: parent.width
|
|
||||||
property bool isVisible: symbol && (searchBox.text == "" || name.toLowerCase().includes(searchBox.text.toLowerCase()) || symbol.toLowerCase().includes(searchBox.text.toLowerCase()))
|
|
||||||
|
|
||||||
visible: isVisible
|
Item {
|
||||||
height: isVisible ? 40 + Style.current.smallPadding : 0
|
id: tokenList
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: customTokens
|
||||||
|
|
||||||
Image {
|
|
||||||
id: assetInfoImage
|
|
||||||
width: 36
|
|
||||||
height: tokenContainer.isVisible !== "" ? 36 : 0
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 0
|
|
||||||
source: hasIcon ? "../../../img/tokens/" + symbol + ".png" : "../../../img/tokens/0-native.png"
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 0
|
|
||||||
}
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: assetSymbol
|
id: customLbl
|
||||||
text: symbol
|
text: qsTr("Custom")
|
||||||
anchors.left: assetInfoImage.right
|
font.pixelSize: 13
|
||||||
anchors.leftMargin: Style.current.smallPadding
|
color: Style.current.secondaryText
|
||||||
anchors.top: assetInfoImage.top
|
height: 20
|
||||||
anchors.topMargin: 0
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: walletModel.customTokenList
|
||||||
|
delegate: tokenComponent
|
||||||
|
anchors.top: customLbl.bottom
|
||||||
|
anchors.topMargin: Style.current.smallPadding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.top: customTokens.bottom
|
||||||
|
anchors.topMargin: Style.current.smallPadding
|
||||||
|
id: defaultTokens
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: assetFullTokenName
|
id: defaultLbl
|
||||||
text: name || ""
|
text: qsTr("Default")
|
||||||
anchors.bottom: assetInfoImage.bottom
|
font.pixelSize: 13
|
||||||
anchors.bottomMargin: 0
|
color: Style.current.secondaryText
|
||||||
anchors.left: assetInfoImage.right
|
height: 20
|
||||||
anchors.leftMargin: Style.current.smallPadding
|
|
||||||
color: Style.current.darkGrey
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
}
|
||||||
CheckBox {
|
|
||||||
id: assetCheck
|
Repeater {
|
||||||
checked: walletModel.hasAsset("0x123", symbol)
|
model: walletModel.defaultTokenList
|
||||||
anchors.right: parent.right
|
delegate: tokenComponent
|
||||||
anchors.rightMargin: Style.current.smallPadding
|
anchors.top: defaultLbl.bottom
|
||||||
onClicked: walletModel.toggleAsset(symbol)
|
anchors.topMargin: Style.current.smallPadding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
highlightFollowsCurrentItem: true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue