chore(Wallet): AssetView replaced with the refactored version
Closes: #14704 Closes: #14939
This commit is contained in:
parent
38914df0f0
commit
d700a1ad53
|
@ -1,271 +0,0 @@
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Controls 2.15
|
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
|
|
||||||
import shared.views 1.0
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
import Storybook 1.0
|
|
||||||
|
|
||||||
import Qt.labs.settings 1.1
|
|
||||||
|
|
||||||
SplitView {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: assetsModel
|
|
||||||
|
|
||||||
function format(amount, symbol) {
|
|
||||||
return `${amount.toLocaleString(Qt.locale())} ${symbol}`
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
const data = [
|
|
||||||
{
|
|
||||||
key: "key_ETH",
|
|
||||||
symbol: "ETH",
|
|
||||||
name: "Ether",
|
|
||||||
icon: Constants.tokenIcon("ETH", false),
|
|
||||||
balance: 10.0,
|
|
||||||
balanceText: format(10.0, "ETH"),
|
|
||||||
error: "",
|
|
||||||
|
|
||||||
marketDetailsAvailable: true,
|
|
||||||
marketDetailsLoading: true,
|
|
||||||
marketPrice: 0,
|
|
||||||
marketChangePct24hour: 0,
|
|
||||||
|
|
||||||
communityId: "",
|
|
||||||
communityName: "",
|
|
||||||
communityIcon: Qt.resolvedUrl(""),
|
|
||||||
|
|
||||||
position: 2,
|
|
||||||
canBeHidden: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "key_SNT",
|
|
||||||
symbol: "SNT",
|
|
||||||
name: "Status",
|
|
||||||
icon: Constants.tokenIcon("SNT", false),
|
|
||||||
balance: 20023.0,
|
|
||||||
balanceText: format(20023.0, "SNT"),
|
|
||||||
error: "",
|
|
||||||
|
|
||||||
marketDetailsAvailable: true,
|
|
||||||
marketDetailsLoading: false,
|
|
||||||
marketPrice: 50.23,
|
|
||||||
marketChangePct24hour: 12,
|
|
||||||
|
|
||||||
communityId: "",
|
|
||||||
communityName: "",
|
|
||||||
communityIcon: Qt.resolvedUrl(""),
|
|
||||||
|
|
||||||
position: 1,
|
|
||||||
canBeHidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "key_MCT",
|
|
||||||
symbol: "MCT",
|
|
||||||
name: "My custom token",
|
|
||||||
icon: Constants.tokenIcon("ZRX", false),
|
|
||||||
balance: 102.4,
|
|
||||||
balanceText: format(102.4, "MCT"),
|
|
||||||
error: "",
|
|
||||||
|
|
||||||
marketDetailsAvailable: false,
|
|
||||||
marketDetailsLoading: false,
|
|
||||||
marketPrice: 0,
|
|
||||||
marketChangePct24hour: 0,
|
|
||||||
|
|
||||||
communityId: "34",
|
|
||||||
communityName: "Crypto Kitties",
|
|
||||||
communityIcon: Constants.tokenIcon("DAI", false),
|
|
||||||
|
|
||||||
position: 4,
|
|
||||||
canBeHidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "key_DAI",
|
|
||||||
symbol: "DAI",
|
|
||||||
name: "Dai",
|
|
||||||
icon: Constants.tokenIcon("DAI", false),
|
|
||||||
balance: 123.24,
|
|
||||||
balanceText: format(123.24, "DAI"),
|
|
||||||
error: "",
|
|
||||||
|
|
||||||
marketDetailsAvailable: true,
|
|
||||||
marketDetailsLoading: false,
|
|
||||||
marketPrice: 23.23,
|
|
||||||
marketChangePct24hour: 2.3,
|
|
||||||
|
|
||||||
communityId: "",
|
|
||||||
communityName: "",
|
|
||||||
communityIcon: Qt.resolvedUrl(""),
|
|
||||||
|
|
||||||
position: 3,
|
|
||||||
canBeHidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "key_USDT",
|
|
||||||
symbol: "USDT",
|
|
||||||
name: "USDT",
|
|
||||||
icon: Constants.tokenIcon("USDT", false),
|
|
||||||
balance: 15.24,
|
|
||||||
balanceText: format(15.24, "USDT"),
|
|
||||||
error: "",
|
|
||||||
|
|
||||||
marketDetailsAvailable: true,
|
|
||||||
marketDetailsLoading: false,
|
|
||||||
marketPrice: 0.99,
|
|
||||||
marketChangePct24hour: 0,
|
|
||||||
|
|
||||||
communityId: "",
|
|
||||||
communityName: "",
|
|
||||||
communityIcon: Qt.resolvedUrl(""),
|
|
||||||
|
|
||||||
position: 5,
|
|
||||||
canBeHidden: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "key_TBT",
|
|
||||||
symbol: "TBT",
|
|
||||||
name: "The best token",
|
|
||||||
icon: Constants.tokenIcon("UNI", false),
|
|
||||||
balance: 102,
|
|
||||||
balanceText: format(102, "TBT"),
|
|
||||||
error: "Pocket Network (POKT) & Infura are currently both "
|
|
||||||
+ "unavailable for %1. %1 balances are as of %2."
|
|
||||||
.arg("TBT").arg("10/06/2024"),
|
|
||||||
|
|
||||||
marketDetailsAvailable: false,
|
|
||||||
marketDetailsLoading: false,
|
|
||||||
marketPrice: 0,
|
|
||||||
marketChangePct24hour: 0,
|
|
||||||
|
|
||||||
communityId: "3423",
|
|
||||||
communityName: "Best tokens",
|
|
||||||
communityIcon: Constants.tokenIcon("UNI", false),
|
|
||||||
|
|
||||||
position: 6,
|
|
||||||
canBeHidden: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
append(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SplitView {
|
|
||||||
SplitView.fillWidth: true
|
|
||||||
SplitView.fillHeight: true
|
|
||||||
|
|
||||||
orientation: Qt.Vertical
|
|
||||||
|
|
||||||
Pane {
|
|
||||||
SplitView.fillWidth: true
|
|
||||||
SplitView.fillHeight: true
|
|
||||||
|
|
||||||
AssetsViewNew {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
loading: loadingCheckBox.checked
|
|
||||||
sorterVisible: sorterVisibleCheckBox.checked
|
|
||||||
customOrderAvailable: customOrderAvailableCheckBox.checked
|
|
||||||
|
|
||||||
sendEnabled: sendEnabledCheckBox.checked
|
|
||||||
swapEnabled: swapEnabledCheckBox.checked
|
|
||||||
swapVisible: swapVisibleCheckBox.checked
|
|
||||||
|
|
||||||
balanceError: balanceErrorCheckBox.checked
|
|
||||||
? "Balance error!" : ""
|
|
||||||
|
|
||||||
marketDataError: marketDataErrorCheckBox.checked
|
|
||||||
? "Market data error!" : ""
|
|
||||||
|
|
||||||
model: assetsModel
|
|
||||||
|
|
||||||
onSendRequested: logs.logEvent(`send requested: ${key}`)
|
|
||||||
onReceiveRequested: logs.logEvent(`receive requested: ${key}`)
|
|
||||||
onSwapRequested: logs.logEvent(`swap requested: ${key}`)
|
|
||||||
onAssetClicked: logs.logEvent(`asset clicked: ${key}`)
|
|
||||||
|
|
||||||
onHideRequested: logs.logEvent(`hide requested: ${key}`)
|
|
||||||
onHideCommunityAssets: logs.logEvent(`hide community assets requested: ${communityKey}`)
|
|
||||||
onManageTokensRequested: logs.logEvent(`manage tokens requested`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Logs {
|
|
||||||
id: logs
|
|
||||||
}
|
|
||||||
|
|
||||||
LogsView {
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
SplitView.preferredHeight: 150
|
|
||||||
SplitView.fillWidth: true
|
|
||||||
|
|
||||||
logText: logs.logText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Pane {
|
|
||||||
SplitView.preferredWidth: 300
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
CheckBox {
|
|
||||||
id: loadingCheckBox
|
|
||||||
|
|
||||||
text: "loading"
|
|
||||||
}
|
|
||||||
CheckBox {
|
|
||||||
id: sorterVisibleCheckBox
|
|
||||||
|
|
||||||
text: "sorter visible"
|
|
||||||
}
|
|
||||||
CheckBox {
|
|
||||||
id: customOrderAvailableCheckBox
|
|
||||||
|
|
||||||
text: "custom order available"
|
|
||||||
}
|
|
||||||
CheckBox {
|
|
||||||
id: sendEnabledCheckBox
|
|
||||||
|
|
||||||
text: "send enabled"
|
|
||||||
}
|
|
||||||
CheckBox {
|
|
||||||
id: swapEnabledCheckBox
|
|
||||||
|
|
||||||
text: "swap enabled"
|
|
||||||
}
|
|
||||||
CheckBox {
|
|
||||||
id: swapVisibleCheckBox
|
|
||||||
|
|
||||||
text: "swap visible"
|
|
||||||
}
|
|
||||||
CheckBox {
|
|
||||||
id: balanceErrorCheckBox
|
|
||||||
|
|
||||||
text: "balance error"
|
|
||||||
}
|
|
||||||
CheckBox {
|
|
||||||
id: marketDataErrorCheckBox
|
|
||||||
|
|
||||||
text: "market data error"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings {
|
|
||||||
property alias loading: loadingCheckBox.checked
|
|
||||||
property alias filterVisible: sorterVisibleCheckBox.checked
|
|
||||||
property alias customOrderAvailable: customOrderAvailableCheckBox.checked
|
|
||||||
property alias sendEnabled: sendEnabledCheckBox.checked
|
|
||||||
property alias swapEnabled: swapEnabledCheckBox.checked
|
|
||||||
property alias swapVisible: swapVisibleCheckBox.checked
|
|
||||||
property alias balanceError: balanceErrorCheckBox.checked
|
|
||||||
property alias marketDataError: marketDataErrorCheckBox.checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// category: Views
|
|
|
@ -1,248 +1,271 @@
|
||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import Qt.labs.settings 1.0
|
import shared.views 1.0
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
|
||||||
|
|
||||||
import StatusQ 0.1
|
|
||||||
import StatusQ.Models 0.1
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
|
||||||
|
|
||||||
import mainui 1.0
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
import shared.controls 1.0
|
|
||||||
import shared.views 1.0
|
|
||||||
import shared.stores 1.0
|
|
||||||
|
|
||||||
import Storybook 1.0
|
import Storybook 1.0
|
||||||
import Models 1.0
|
|
||||||
|
|
||||||
import AppLayouts.Wallet.views 1.0
|
|
||||||
import AppLayouts.Wallet.stores 1.0
|
|
||||||
|
|
||||||
|
import Qt.labs.settings 1.1
|
||||||
|
|
||||||
SplitView {
|
SplitView {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
Logs { id: logs }
|
ListModel {
|
||||||
|
id: assetsModel
|
||||||
|
|
||||||
orientation: Qt.Horizontal
|
function format(amount, symbol) {
|
||||||
|
return `${amount.toLocaleString(Qt.locale())} ${symbol}`
|
||||||
QtObject {
|
|
||||||
id: d
|
|
||||||
|
|
||||||
readonly property string networksChainsCurrentlySelected: {
|
|
||||||
let supportedNwChains = []
|
|
||||||
for (let i = 0; i< networksRepeater.count; i++) {
|
|
||||||
if (networksRepeater.itemAt(i).checked && networksRepeater.itemAt(i).visible)
|
|
||||||
supportedNwChains.push(networksRepeater.itemAt(i).chainID)
|
|
||||||
}
|
|
||||||
return supportedNwChains.join(":")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property string addressesSelected: {
|
Component.onCompleted: {
|
||||||
let supportedAddresses = []
|
const data = [
|
||||||
for (let i = 0; i< accountsRepeater.count; i++) {
|
{
|
||||||
if (accountsRepeater.itemAt(i).checked && accountsRepeater.itemAt(i).visible)
|
key: "key_ETH",
|
||||||
supportedAddresses.push(accountsRepeater.itemAt(i).address)
|
symbol: "ETH",
|
||||||
}
|
name: "Ether",
|
||||||
return supportedAddresses.join(":")
|
icon: Constants.tokenIcon("ETH", false),
|
||||||
}
|
balance: 10.0,
|
||||||
|
balanceText: format(10.0, "ETH"),
|
||||||
|
error: "",
|
||||||
|
|
||||||
readonly property var currencyStore: CurrenciesStore {}
|
marketDetailsAvailable: true,
|
||||||
|
marketDetailsLoading: true,
|
||||||
|
marketPrice: 0,
|
||||||
|
marketChangePct24hour: 0,
|
||||||
|
|
||||||
property WalletAssetsStore walletAssetStore: WalletAssetsStore {
|
communityId: "",
|
||||||
assetsWithFilteredBalances: d.assetsWithFilteredBalances
|
communityName: "",
|
||||||
assetsController: assetsView.controller
|
communityIcon: Qt.resolvedUrl(""),
|
||||||
}
|
|
||||||
|
|
||||||
// Added this here simply because the network and address filtering wont work in Storybook applied in AssetsView
|
position: 2,
|
||||||
readonly property SubmodelProxyModel assetsWithFilteredBalances: SubmodelProxyModel {
|
canBeHidden: false
|
||||||
sourceModel: d.walletAssetStore.groupedAccountsAssetsModel
|
},
|
||||||
submodelRoleName: "balances"
|
{
|
||||||
delegateModel: SortFilterProxyModel {
|
key: "key_SNT",
|
||||||
sourceModel: submodel
|
symbol: "SNT",
|
||||||
filters: FastExpressionFilter {
|
name: "Status",
|
||||||
expression: {
|
icon: Constants.tokenIcon("SNT", false),
|
||||||
d.networksChainsCurrentlySelected
|
balance: 20023.0,
|
||||||
return d.networksChainsCurrentlySelected.split(":").includes(model.chainId+"")
|
balanceText: format(20023.0, "SNT"),
|
||||||
}
|
error: "",
|
||||||
expectedRoles: ["chainId"]
|
|
||||||
}
|
marketDetailsAvailable: true,
|
||||||
|
marketDetailsLoading: false,
|
||||||
|
marketPrice: 50.23,
|
||||||
|
marketChangePct24hour: 12,
|
||||||
|
|
||||||
|
communityId: "",
|
||||||
|
communityName: "",
|
||||||
|
communityIcon: Qt.resolvedUrl(""),
|
||||||
|
|
||||||
|
position: 1,
|
||||||
|
canBeHidden: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "key_MCT",
|
||||||
|
symbol: "MCT",
|
||||||
|
name: "My custom token",
|
||||||
|
icon: Constants.tokenIcon("ZRX", false),
|
||||||
|
balance: 102.4,
|
||||||
|
balanceText: format(102.4, "MCT"),
|
||||||
|
error: "",
|
||||||
|
|
||||||
|
marketDetailsAvailable: false,
|
||||||
|
marketDetailsLoading: false,
|
||||||
|
marketPrice: 0,
|
||||||
|
marketChangePct24hour: 0,
|
||||||
|
|
||||||
|
communityId: "34",
|
||||||
|
communityName: "Crypto Kitties",
|
||||||
|
communityIcon: Constants.tokenIcon("DAI", false),
|
||||||
|
|
||||||
|
position: 4,
|
||||||
|
canBeHidden: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "key_DAI",
|
||||||
|
symbol: "DAI",
|
||||||
|
name: "Dai",
|
||||||
|
icon: Constants.tokenIcon("DAI", false),
|
||||||
|
balance: 123.24,
|
||||||
|
balanceText: format(123.24, "DAI"),
|
||||||
|
error: "",
|
||||||
|
|
||||||
|
marketDetailsAvailable: true,
|
||||||
|
marketDetailsLoading: false,
|
||||||
|
marketPrice: 23.23,
|
||||||
|
marketChangePct24hour: 2.3,
|
||||||
|
|
||||||
|
communityId: "",
|
||||||
|
communityName: "",
|
||||||
|
communityIcon: Qt.resolvedUrl(""),
|
||||||
|
|
||||||
|
position: 3,
|
||||||
|
canBeHidden: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "key_USDT",
|
||||||
|
symbol: "USDT",
|
||||||
|
name: "USDT",
|
||||||
|
icon: Constants.tokenIcon("USDT", false),
|
||||||
|
balance: 15.24,
|
||||||
|
balanceText: format(15.24, "USDT"),
|
||||||
|
error: "",
|
||||||
|
|
||||||
|
marketDetailsAvailable: true,
|
||||||
|
marketDetailsLoading: false,
|
||||||
|
marketPrice: 0.99,
|
||||||
|
marketChangePct24hour: 0,
|
||||||
|
|
||||||
|
communityId: "",
|
||||||
|
communityName: "",
|
||||||
|
communityIcon: Qt.resolvedUrl(""),
|
||||||
|
|
||||||
|
position: 5,
|
||||||
|
canBeHidden: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "key_TBT",
|
||||||
|
symbol: "TBT",
|
||||||
|
name: "The best token",
|
||||||
|
icon: Constants.tokenIcon("UNI", false),
|
||||||
|
balance: 102,
|
||||||
|
balanceText: format(102, "TBT"),
|
||||||
|
error: "Pocket Network (POKT) & Infura are currently both "
|
||||||
|
+ "unavailable for %1. %1 balances are as of %2."
|
||||||
|
.arg("TBT").arg("10/06/2024"),
|
||||||
|
|
||||||
|
marketDetailsAvailable: false,
|
||||||
|
marketDetailsLoading: false,
|
||||||
|
marketPrice: 0,
|
||||||
|
marketChangePct24hour: 0,
|
||||||
|
|
||||||
|
communityId: "3423",
|
||||||
|
communityName: "Best tokens",
|
||||||
|
communityIcon: Constants.tokenIcon("UNI", false),
|
||||||
|
|
||||||
|
position: 6,
|
||||||
|
canBeHidden: true
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
append(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Popups {
|
SplitView {
|
||||||
popupParent: root
|
|
||||||
rootStore: QtObject {}
|
|
||||||
communityTokensStore: QtObject {}
|
|
||||||
walletAssetsStore: d.walletAssetStore
|
|
||||||
}
|
|
||||||
|
|
||||||
StackLayout {
|
|
||||||
id: stack
|
|
||||||
SplitView.fillWidth: true
|
SplitView.fillWidth: true
|
||||||
SplitView.fillHeight: true
|
SplitView.fillHeight: true
|
||||||
|
|
||||||
currentIndex: 0
|
orientation: Qt.Vertical
|
||||||
|
|
||||||
|
Pane {
|
||||||
|
SplitView.fillWidth: true
|
||||||
|
SplitView.fillHeight: true
|
||||||
|
|
||||||
AssetsView {
|
AssetsView {
|
||||||
id: assetsView
|
anchors.fill: parent
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
areAssetsLoading: loadingCheckbox.checked
|
|
||||||
controller: ManageTokensController {
|
|
||||||
sourceModel: d.walletAssetStore.groupedAccountAssetsModel
|
|
||||||
settingsKey: "WalletAssets"
|
|
||||||
serializeAsCollectibles: false
|
|
||||||
|
|
||||||
onRequestSaveSettings: (jsonData) => {
|
loading: loadingCheckBox.checked
|
||||||
savingStarted()
|
sorterVisible: sorterVisibleCheckBox.checked
|
||||||
settingsStore.setValue(settingsKey, jsonData)
|
customOrderAvailable: customOrderAvailableCheckBox.checked
|
||||||
savingFinished()
|
|
||||||
}
|
|
||||||
onRequestLoadSettings: {
|
|
||||||
loadingStarted()
|
|
||||||
const jsonData = settingsStore.value(settingsKey, null)
|
|
||||||
loadingFinished(jsonData)
|
|
||||||
}
|
|
||||||
onRequestClearSettings: {
|
|
||||||
settingsStore.setValue(settingsKey, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
onTokenHidden: (symbol, name) => Global.displayToastMessage(
|
sendEnabled: sendEnabledCheckBox.checked
|
||||||
qsTr("%1 (%2) was successfully hidden").arg(name).arg(symbol), "", "checkmark-circle",
|
swapEnabled: swapEnabledCheckBox.checked
|
||||||
false, Constants.ephemeralNotificationType.success, "")
|
swapVisible: swapVisibleCheckBox.checked
|
||||||
onCommunityTokenGroupHidden: (communityName) => Global.displayToastMessage(
|
|
||||||
qsTr("%1 community assets successfully hidden").arg(communityName), "", "checkmark-circle",
|
|
||||||
false, Constants.ephemeralNotificationType.success, "")
|
|
||||||
onTokenShown: (symbol, name) => Global.displayToastMessage(qsTr("%1 is now visible").arg(name), "", "checkmark-circle",
|
|
||||||
false, Constants.ephemeralNotificationType.success, "")
|
|
||||||
onCommunityTokenGroupShown: (communityName) => Global.displayToastMessage(
|
|
||||||
qsTr("%1 community assets are now visible").arg(communityName), "", "checkmark-circle",
|
|
||||||
false, Constants.ephemeralNotificationType.success, "")
|
|
||||||
}
|
|
||||||
filterVisible: ctrlFilterVisible.checked
|
|
||||||
currencyStore: d.currencyStore
|
|
||||||
tokensStore: TokensStore {
|
|
||||||
displayAssetsBelowBalance: ctrlBalanceThresholdSwitch.checked
|
|
||||||
getDisplayAssetsBelowBalanceThresholdDisplayAmount: () => ctrlBalanceThreshold.value
|
|
||||||
}
|
|
||||||
networkFilters: d.networksChainsCurrentlySelected
|
|
||||||
addressFilters: d.addressesSelected
|
|
||||||
onAssetClicked: {
|
|
||||||
stack.currentIndex = 1
|
|
||||||
detailsView.token = token
|
|
||||||
logs.logEvent("onAssetClicked", ["token"], [token.symbol, token.communityId])
|
|
||||||
}
|
|
||||||
onSendRequested: logs.logEvent("onSendRequested", ["symbol"], arguments)
|
|
||||||
onReceiveRequested: logs.logEvent("onReceiveRequested", ["symbol"], arguments)
|
|
||||||
onSwitchToCommunityRequested: logs.logEvent("onSwitchToCommunityRequested", ["communityId"], arguments)
|
|
||||||
onManageTokensRequested: logs.logEvent("onManageTokensRequested")
|
|
||||||
|
|
||||||
Settings {
|
balanceError: balanceErrorCheckBox.checked
|
||||||
id: settingsStore
|
? "Balance error!" : ""
|
||||||
category: "ManageTokens-" + assetsView.controller.settingsKey
|
|
||||||
|
marketDataError: marketDataErrorCheckBox.checked
|
||||||
|
? "Market data error!" : ""
|
||||||
|
|
||||||
|
model: assetsModel
|
||||||
|
|
||||||
|
onSendRequested: logs.logEvent(`send requested: ${key}`)
|
||||||
|
onReceiveRequested: logs.logEvent(`receive requested: ${key}`)
|
||||||
|
onSwapRequested: logs.logEvent(`swap requested: ${key}`)
|
||||||
|
onAssetClicked: logs.logEvent(`asset clicked: ${key}`)
|
||||||
|
|
||||||
|
onHideRequested: logs.logEvent(`hide requested: ${key}`)
|
||||||
|
onHideCommunityAssets: logs.logEvent(`hide community assets requested: ${communityKey}`)
|
||||||
|
onManageTokensRequested: logs.logEvent(`manage tokens requested`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
Logs {
|
||||||
Layout.fillHeight: true
|
id: logs
|
||||||
Layout.fillWidth: true
|
|
||||||
Button {
|
|
||||||
text: "go back"
|
|
||||||
onClicked: stack.currentIndex = 0
|
|
||||||
}
|
|
||||||
AssetsDetailView {
|
|
||||||
id: detailsView
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
currencyStore: d.currencyStore
|
|
||||||
allNetworksModel: NetworksModel.flatNetworks
|
|
||||||
networkFilters: d.networksChainsCurrentlySelected
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogsView {
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
SplitView.preferredHeight: 150
|
||||||
|
SplitView.fillWidth: true
|
||||||
|
|
||||||
|
logText: logs.logText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pane {
|
Pane {
|
||||||
SplitView.preferredWidth: 250
|
SplitView.preferredWidth: 300
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 12
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
Switch {
|
|
||||||
id: ctrlFilterVisible
|
|
||||||
text: "Filter visible"
|
|
||||||
checked: true
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckBox {
|
CheckBox {
|
||||||
id: loadingCheckbox
|
id: loadingCheckBox
|
||||||
checked: false
|
|
||||||
text: "loading"
|
text: "loading"
|
||||||
}
|
}
|
||||||
|
CheckBox {
|
||||||
|
id: sorterVisibleCheckBox
|
||||||
|
|
||||||
ColumnLayout {
|
text: "sorter visible"
|
||||||
Layout.fillWidth: true
|
|
||||||
Text {
|
|
||||||
text: "select supported network(s)"
|
|
||||||
}
|
}
|
||||||
Repeater {
|
CheckBox {
|
||||||
id: networksRepeater
|
id: customOrderAvailableCheckBox
|
||||||
model: NetworksModel.flatNetworks
|
|
||||||
delegate: CheckBox {
|
text: "custom order available"
|
||||||
readonly property int chainID: chainId
|
|
||||||
width: parent.width
|
|
||||||
text: chainName
|
|
||||||
visible: isTest
|
|
||||||
checked: true
|
|
||||||
onToggled: {
|
|
||||||
isEnabled = checked
|
|
||||||
}
|
}
|
||||||
|
CheckBox {
|
||||||
|
id: sendEnabledCheckBox
|
||||||
|
|
||||||
|
text: "send enabled"
|
||||||
|
}
|
||||||
|
CheckBox {
|
||||||
|
id: swapEnabledCheckBox
|
||||||
|
|
||||||
|
text: "swap enabled"
|
||||||
|
}
|
||||||
|
CheckBox {
|
||||||
|
id: swapVisibleCheckBox
|
||||||
|
|
||||||
|
text: "swap visible"
|
||||||
|
}
|
||||||
|
CheckBox {
|
||||||
|
id: balanceErrorCheckBox
|
||||||
|
|
||||||
|
text: "balance error"
|
||||||
|
}
|
||||||
|
CheckBox {
|
||||||
|
id: marketDataErrorCheckBox
|
||||||
|
|
||||||
|
text: "market data error"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
Settings {
|
||||||
Layout.fillWidth: true
|
property alias loading: loadingCheckBox.checked
|
||||||
Text {
|
property alias filterVisible: sorterVisibleCheckBox.checked
|
||||||
text: "select account(s)"
|
property alias customOrderAvailable: customOrderAvailableCheckBox.checked
|
||||||
}
|
property alias sendEnabled: sendEnabledCheckBox.checked
|
||||||
Repeater {
|
property alias swapEnabled: swapEnabledCheckBox.checked
|
||||||
id: accountsRepeater
|
property alias swapVisible: swapVisibleCheckBox.checked
|
||||||
model: WalletAccountsModel {}
|
property alias balanceError: balanceErrorCheckBox.checked
|
||||||
delegate: CheckBox {
|
property alias marketDataError: marketDataErrorCheckBox.checked
|
||||||
readonly property string address: model.address
|
|
||||||
checked: true
|
|
||||||
visible: index<2
|
|
||||||
width: parent.width
|
|
||||||
text: name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Switch {
|
|
||||||
id: ctrlBalanceThresholdSwitch
|
|
||||||
text: qsTr("Currency balance threshold")
|
|
||||||
checked: false
|
|
||||||
}
|
|
||||||
CurrencyAmountInput {
|
|
||||||
id: ctrlBalanceThreshold
|
|
||||||
value: 10.1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// category: Views
|
// category: Views
|
||||||
// https://www.figma.com/file/FkFClTCYKf83RJWoifWgoX/Wallet-v2?type=design&node-id=17159-67977&mode=design&t=s5EXsh6Vi4nTNYUh-0
|
|
||||||
// https://www.figma.com/file/FkFClTCYKf83RJWoifWgoX/Wallet-v2?type=design&node-id=17171-285559&mode=design&t=s5EXsh6Vi4nTNYUh-0
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ SplitView {
|
||||||
SplitView.fillWidth: true
|
SplitView.fillWidth: true
|
||||||
SplitView.fillHeight: true
|
SplitView.fillHeight: true
|
||||||
|
|
||||||
TokenDelegateNew {
|
TokenDelegate {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
name: nameTextFiled.text
|
name: nameTextFiled.text
|
||||||
|
|
|
@ -206,12 +206,14 @@ Dialog {
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
currentIndex: walletTabBar.currentIndex
|
currentIndex: walletTabBar.currentIndex
|
||||||
|
|
||||||
AssetsView {
|
// Disable because the refactored version of AssetView requires specific
|
||||||
id: assetsTab
|
// integration but the old version was not working properly neither.
|
||||||
controller: popup.assetsStore.assetsController
|
//AssetsView {
|
||||||
currencyStore: popup.currencyStore
|
// id: assetsTab
|
||||||
tokensStore: popup.tokensStore
|
// controller: popup.assetsStore.assetsController
|
||||||
}
|
// currencyStore: popup.currencyStore
|
||||||
|
// tokensStore: popup.tokensStore
|
||||||
|
//}
|
||||||
HistoryView {
|
HistoryView {
|
||||||
id: historyTab
|
id: historyTab
|
||||||
overview: WalletStore.dappBrowserAccount
|
overview: WalletStore.dappBrowserAccount
|
||||||
|
|
|
@ -143,8 +143,7 @@ RightTabBaseView {
|
||||||
Component {
|
Component {
|
||||||
id: assetsView
|
id: assetsView
|
||||||
|
|
||||||
AssetsViewNew {
|
AssetsView {
|
||||||
|
|
||||||
AssetsViewAdaptor {
|
AssetsViewAdaptor {
|
||||||
id: assetsViewAdaptor
|
id: assetsViewAdaptor
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,16 @@
|
||||||
import QtQuick 2.15
|
|
||||||
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
TokenDelegate {
|
TokenDelegate {
|
||||||
id: root
|
|
||||||
|
|
||||||
title: Constants.dummyText
|
title: Constants.dummyText
|
||||||
subTitle: Constants.dummyText
|
subTitle: Constants.dummyText
|
||||||
asset.name: Constants.dummyText
|
asset.name: Constants.dummyText
|
||||||
|
|
||||||
currencyBalance.text: Constants.dummyText
|
|
||||||
currencyBalance.loading: true
|
|
||||||
change24HourPercentage.text: Constants.dummyText
|
|
||||||
change24HourPercentage.loading: true
|
|
||||||
currencyPrice.text: Constants.dummyText
|
|
||||||
currencyPrice.loading: true
|
|
||||||
|
|
||||||
statusListItemSubTitle.loading: true
|
statusListItemSubTitle.loading: true
|
||||||
statusListItemTitle.loading: true
|
statusListItemTitle.loading: true
|
||||||
statusListItemIcon.loading: true
|
statusListItemIcon.loading: true
|
||||||
|
|
||||||
textColor: Theme.palette.baseColor1
|
marketDetailsAvailable: true
|
||||||
|
marketDetailsLoading: true
|
||||||
|
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
TokenDelegateNew {
|
|
||||||
title: Constants.dummyText
|
|
||||||
subTitle: Constants.dummyText
|
|
||||||
asset.name: Constants.dummyText
|
|
||||||
|
|
||||||
statusListItemSubTitle.loading: true
|
|
||||||
statusListItemTitle.loading: true
|
|
||||||
statusListItemIcon.loading: true
|
|
||||||
|
|
||||||
marketDetailsAvailable: true
|
|
||||||
marketDetailsLoading: true
|
|
||||||
|
|
||||||
enabled: false
|
|
||||||
}
|
|
|
@ -7,67 +7,63 @@ import StatusQ.Core 0.1
|
||||||
import StatusQ.Controls 0.1
|
import StatusQ.Controls 0.1
|
||||||
|
|
||||||
import AppLayouts.Wallet.controls 1.0
|
import AppLayouts.Wallet.controls 1.0
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
StatusListItem {
|
StatusListItem {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
// expected roles: name, symbol, currencyPrice, changePct24hour, communityId, communityName, communityImage
|
property string name
|
||||||
|
property url icon
|
||||||
|
property string balance
|
||||||
|
|
||||||
property alias currencyBalance: currencyBalance
|
property bool marketDetailsAvailable: false
|
||||||
property alias change24HourPercentage: change24HourPercentageText
|
property string marketBalance
|
||||||
property alias currencyPrice: currencyPrice
|
property bool marketDetailsLoading: false
|
||||||
|
property string marketCurrencyPrice
|
||||||
|
property real marketChangePct24hour
|
||||||
|
|
||||||
property string currentCurrencySymbol
|
property string communityId
|
||||||
property string textColor: {
|
property string communityName
|
||||||
if (!modelData || !modelData.marketDetails) {
|
property url communityIcon
|
||||||
return Theme.palette.successColor1
|
|
||||||
}
|
|
||||||
return modelData.marketDetails.changePct24hour === undefined ?
|
|
||||||
Theme.palette.baseColor1 :
|
|
||||||
modelData.marketDetails.changePct24hour === 0 ?
|
|
||||||
Theme.palette.baseColor1 :
|
|
||||||
modelData.marketDetails.changePct24hour < 0 ?
|
|
||||||
Theme.palette.dangerColor1 :
|
|
||||||
Theme.palette.successColor1
|
|
||||||
}
|
|
||||||
|
|
||||||
property string errorTooltipText_1
|
property string errorTooltipText_1
|
||||||
property string errorTooltipText_2
|
property string errorTooltipText_2
|
||||||
|
|
||||||
readonly property bool isCommunityToken: !!modelData && !!modelData.communityId
|
signal communityClicked(string communityId)
|
||||||
readonly property string symbolUrl: {
|
|
||||||
if (!modelData)
|
QtObject {
|
||||||
return ""
|
id: d
|
||||||
if (modelData.image)
|
|
||||||
return modelData.image
|
readonly property bool isCommunityToken: !!root.communityId
|
||||||
if (modelData.symbol)
|
|
||||||
return Constants.tokenIcon(modelData.symbol, false)
|
readonly property string textColor: {
|
||||||
return ""
|
if (!root.marketDetailsAvailable)
|
||||||
|
return Theme.palette.successColor1
|
||||||
|
|
||||||
|
if (root.marketChangePct24hour === 0)
|
||||||
|
return Theme.palette.baseColor1
|
||||||
|
|
||||||
|
return root.marketChangePct24hour < 0
|
||||||
|
? Theme.palette.dangerColor1
|
||||||
|
: Theme.palette.successColor1
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property string upDownTriangle: {
|
readonly property string upDownTriangle: {
|
||||||
if (!modelData || !modelData.marketDetails)
|
if (root.marketChangePct24hour === 0)
|
||||||
return ""
|
|
||||||
if (modelData.marketDetails.changePct24hour < 0)
|
|
||||||
return "▾"
|
|
||||||
if (modelData.marketDetails.changePct24hour > 0)
|
|
||||||
return "▴"
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
return root.marketChangePct24hour < 0 ? "▾" : "▴"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
readonly property bool isUndefined: modelData && !modelData.marketDetailsLoading && title === ""
|
|
||||||
|
|
||||||
signal switchToCommunityRequested(string communityId)
|
title: root.name
|
||||||
|
subTitle: root.balance
|
||||||
title: modelData ? modelData.name : ""
|
asset.name: root.icon
|
||||||
subTitle: LocaleUtils.currencyAmountToLocaleString(modelData.enabledNetworkBalance)
|
|
||||||
asset.name: symbolUrl
|
|
||||||
asset.isImage: true
|
asset.isImage: true
|
||||||
asset.width: 32
|
asset.width: 32
|
||||||
asset.height: 32
|
asset.height: 32
|
||||||
errorIcon.tooltip.maxWidth: 300
|
errorIcon.tooltip.maxWidth: 300
|
||||||
height: isUndefined ? 0 : implicitHeight
|
height: implicitHeight
|
||||||
visible: !isUndefined
|
|
||||||
|
|
||||||
statusListItemTitleIcons.sourceComponent: StatusFlatRoundButton {
|
statusListItemTitleIcons.sourceComponent: StatusFlatRoundButton {
|
||||||
width: 14
|
width: 14
|
||||||
|
@ -94,26 +90,32 @@ StatusListItem {
|
||||||
icon.color: Theme.palette.dangerColor1
|
icon.color: Theme.palette.dangerColor1
|
||||||
tooltip.text: root.errorTooltipText_2
|
tooltip.text: root.errorTooltipText_2
|
||||||
tooltip.maxWidth: 200
|
tooltip.maxWidth: 200
|
||||||
visible: !!tooltip.text
|
visible: root.marketDetailsAvailable && !!tooltip.text
|
||||||
}
|
}
|
||||||
StatusTextWithLoadingState {
|
StatusTextWithLoadingState {
|
||||||
id: currencyBalance
|
id: currencyBalance
|
||||||
|
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
loading: modelData && modelData.marketDetailsLoading
|
visible: !errorIcon.visible && root.marketDetailsAvailable
|
||||||
visible: !errorIcon.visible && !root.isCommunityToken
|
|
||||||
|
loading: root.marketDetailsLoading
|
||||||
|
text: loading ? Constants.dummyText : root.marketBalance
|
||||||
}
|
}
|
||||||
Row {
|
Row {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
spacing: 6
|
spacing: 6
|
||||||
visible: !errorIcon.visible && !root.isCommunityToken
|
visible: !errorIcon.visible && root.marketDetailsAvailable
|
||||||
|
|
||||||
StatusTextWithLoadingState {
|
StatusTextWithLoadingState {
|
||||||
id: change24HourPercentageText
|
id: change24HourPercentageText
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
customColor: root.textColor
|
customColor: d.textColor
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
loading: modelData && modelData.marketDetailsLoading
|
loading: root.marketDetailsLoading
|
||||||
text: modelData && modelData.marketDetails && modelData.marketDetails.changePct24hour !== undefined ? "%1 %2%".arg(root.upDownTriangle).arg(LocaleUtils.numberToLocaleString(modelData.marketDetails.changePct24hour, 2))
|
|
||||||
: "---"
|
text: qsTr("%1 %2%", "[up/down/none character depending on value sign] [localized percentage value]%")
|
||||||
|
.arg(d.upDownTriangle).arg(LocaleUtils.numberToLocaleString(root.marketChangePct24hour, 2))
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
@ -123,39 +125,45 @@ StatusListItem {
|
||||||
}
|
}
|
||||||
StatusTextWithLoadingState {
|
StatusTextWithLoadingState {
|
||||||
id: currencyPrice
|
id: currencyPrice
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
customColor: root.textColor
|
customColor: d.textColor
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
loading: modelData && modelData.marketDetailsLoading
|
loading: root.marketDetailsLoading
|
||||||
text: modelData && modelData.marketDetails ? LocaleUtils.currencyAmountToLocaleString(modelData.marketDetails.currencyPrice) : ""
|
text: loading ? Constants.dummyText : root.marketCurrencyPrice
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ManageTokensCommunityTag {
|
|
||||||
|
Loader {
|
||||||
|
active: d.isCommunityToken
|
||||||
|
|
||||||
|
sourceComponent: ManageTokensCommunityTag {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
communityImage: !!modelData ? modelData.communityImage : ""
|
|
||||||
communityName: !!modelData && !!modelData.communityName ? modelData.communityName: ""
|
communityImage: root.communityIcon
|
||||||
communityId: !!modelData && !!modelData.communityId ? modelData.communityId : ""
|
communityName: root.communityName
|
||||||
|
communityId: root.communityId
|
||||||
|
|
||||||
asset.letterSize: 12
|
asset.letterSize: 12
|
||||||
visible: root.isCommunityToken
|
|
||||||
|
|
||||||
TapHandler {
|
TapHandler {
|
||||||
acceptedButtons: Qt.LeftButton
|
acceptedButtons: Qt.LeftButton
|
||||||
onSingleTapped: root.switchToCommunityRequested(modelData.communityId)
|
onSingleTapped: root.communityClicked(root.communityId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
states: [
|
states: State {
|
||||||
State {
|
|
||||||
name: "unknownToken"
|
name: "unknownToken"
|
||||||
when: !root.symbolUrl
|
when: !root.icon.toString()
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: root.asset
|
target: root.asset
|
||||||
isLetterIdenticon: true
|
isLetterIdenticon: true
|
||||||
color: Theme.palette.miscColor5
|
color: Theme.palette.miscColor5
|
||||||
name: !!modelData && modelData.symbol ? modelData.symbol : ""
|
name: root.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,169 +0,0 @@
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Controls 2.15
|
|
||||||
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
import StatusQ.Components 0.1
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
|
|
||||||
import AppLayouts.Wallet.controls 1.0
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
StatusListItem {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string name
|
|
||||||
property url icon
|
|
||||||
property string balance
|
|
||||||
|
|
||||||
property bool marketDetailsAvailable: false
|
|
||||||
property string marketBalance
|
|
||||||
property bool marketDetailsLoading: false
|
|
||||||
property string marketCurrencyPrice
|
|
||||||
property real marketChangePct24hour
|
|
||||||
|
|
||||||
property string communityId
|
|
||||||
property string communityName
|
|
||||||
property url communityIcon
|
|
||||||
|
|
||||||
property string errorTooltipText_1
|
|
||||||
property string errorTooltipText_2
|
|
||||||
|
|
||||||
signal communityClicked(string communityId)
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: d
|
|
||||||
|
|
||||||
readonly property bool isCommunityToken: !!root.communityId
|
|
||||||
|
|
||||||
readonly property string textColor: {
|
|
||||||
if (!root.marketDetailsAvailable)
|
|
||||||
return Theme.palette.successColor1
|
|
||||||
|
|
||||||
if (root.marketChangePct24hour === 0)
|
|
||||||
return Theme.palette.baseColor1
|
|
||||||
|
|
||||||
return root.marketChangePct24hour < 0
|
|
||||||
? Theme.palette.dangerColor1
|
|
||||||
: Theme.palette.successColor1
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property string upDownTriangle: {
|
|
||||||
if (root.marketChangePct24hour === 0)
|
|
||||||
return ""
|
|
||||||
|
|
||||||
return root.marketChangePct24hour < 0 ? "▾" : "▴"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
title: root.name
|
|
||||||
subTitle: root.balance
|
|
||||||
asset.name: root.icon
|
|
||||||
asset.isImage: true
|
|
||||||
asset.width: 32
|
|
||||||
asset.height: 32
|
|
||||||
errorIcon.tooltip.maxWidth: 300
|
|
||||||
height: implicitHeight
|
|
||||||
|
|
||||||
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 {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
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: root.marketDetailsAvailable && !!tooltip.text
|
|
||||||
}
|
|
||||||
StatusTextWithLoadingState {
|
|
||||||
id: currencyBalance
|
|
||||||
|
|
||||||
anchors.right: parent.right
|
|
||||||
visible: !errorIcon.visible && root.marketDetailsAvailable
|
|
||||||
|
|
||||||
loading: root.marketDetailsLoading
|
|
||||||
text: loading ? Constants.dummyText : root.marketBalance
|
|
||||||
}
|
|
||||||
Row {
|
|
||||||
anchors.right: parent.right
|
|
||||||
spacing: 6
|
|
||||||
visible: !errorIcon.visible && root.marketDetailsAvailable
|
|
||||||
|
|
||||||
StatusTextWithLoadingState {
|
|
||||||
id: change24HourPercentageText
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
customColor: d.textColor
|
|
||||||
font.pixelSize: 13
|
|
||||||
loading: root.marketDetailsLoading
|
|
||||||
|
|
||||||
text: qsTr("%1 %2%", "[up/down/none character depending on value sign] [localized percentage value]%")
|
|
||||||
.arg(d.upDownTriangle).arg(LocaleUtils.numberToLocaleString(root.marketChangePct24hour, 2))
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
width: 1
|
|
||||||
height: 12
|
|
||||||
color: Theme.palette.directColor9
|
|
||||||
}
|
|
||||||
StatusTextWithLoadingState {
|
|
||||||
id: currencyPrice
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
customColor: d.textColor
|
|
||||||
font.pixelSize: 13
|
|
||||||
loading: root.marketDetailsLoading
|
|
||||||
text: loading ? Constants.dummyText : root.marketCurrencyPrice
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
active: d.isCommunityToken
|
|
||||||
|
|
||||||
sourceComponent: ManageTokensCommunityTag {
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
communityImage: root.communityIcon
|
|
||||||
communityName: root.communityName
|
|
||||||
communityId: root.communityId
|
|
||||||
|
|
||||||
asset.letterSize: 12
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
acceptedButtons: Qt.LeftButton
|
|
||||||
onSingleTapped: root.communityClicked(root.communityId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
states: State {
|
|
||||||
name: "unknownToken"
|
|
||||||
when: !root.icon.toString()
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
target: root.asset
|
|
||||||
isLetterIdenticon: true
|
|
||||||
color: Theme.palette.miscColor5
|
|
||||||
name: root.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -22,7 +22,6 @@ InformationTag 1.0 InformationTag.qml
|
||||||
InformationTile 1.0 InformationTile.qml
|
InformationTile 1.0 InformationTile.qml
|
||||||
Input 1.0 Input.qml
|
Input 1.0 Input.qml
|
||||||
LoadingTokenDelegate 1.0 LoadingTokenDelegate.qml
|
LoadingTokenDelegate 1.0 LoadingTokenDelegate.qml
|
||||||
LoadingTokenDelegateNew 1.0 LoadingTokenDelegateNew.qml
|
|
||||||
LinkPreviewDebugView 1.0 LinkPreviewDebugView.qml
|
LinkPreviewDebugView 1.0 LinkPreviewDebugView.qml
|
||||||
ProfilePerspectiveSelector 1.0 ProfilePerspectiveSelector.qml
|
ProfilePerspectiveSelector 1.0 ProfilePerspectiveSelector.qml
|
||||||
RadioButtonSelector 1.0 RadioButtonSelector.qml
|
RadioButtonSelector 1.0 RadioButtonSelector.qml
|
||||||
|
@ -44,7 +43,6 @@ StyledTextEditWithLoadingState 1.0 StyledTextEditWithLoadingState.qml
|
||||||
StyledTextField 1.0 StyledTextField.qml
|
StyledTextField 1.0 StyledTextField.qml
|
||||||
Timer 1.0 Timer.qml
|
Timer 1.0 Timer.qml
|
||||||
TokenDelegate 1.0 TokenDelegate.qml
|
TokenDelegate 1.0 TokenDelegate.qml
|
||||||
TokenDelegateNew 1.0 TokenDelegateNew.qml
|
|
||||||
TransactionAddress 1.0 TransactionAddress.qml
|
TransactionAddress 1.0 TransactionAddress.qml
|
||||||
TransactionAddressTile 1.0 TransactionAddressTile.qml
|
TransactionAddressTile 1.0 TransactionAddressTile.qml
|
||||||
TransactionDataTile 1.0 TransactionDataTile.qml
|
TransactionDataTile 1.0 TransactionDataTile.qml
|
||||||
|
|
|
@ -1,197 +1,147 @@
|
||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
import Qt.labs.settings 1.1
|
|
||||||
|
import QtQml.Models 2.15
|
||||||
|
|
||||||
import StatusQ 0.1
|
import StatusQ 0.1
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
import StatusQ.Components 0.1
|
|
||||||
import StatusQ.Popups 0.1
|
|
||||||
import StatusQ.Popups.Dialog 0.1
|
import StatusQ.Popups.Dialog 0.1
|
||||||
import StatusQ.Models 0.1
|
|
||||||
import StatusQ.Internal 0.1
|
import AppLayouts.Wallet.controls 1.0
|
||||||
|
import shared.controls 1.0
|
||||||
|
import shared.popups 1.0
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
import shared.stores 1.0
|
Control {
|
||||||
import shared.controls 1.0
|
|
||||||
import shared.popups 1.0
|
|
||||||
|
|
||||||
import AppLayouts.Wallet.controls 1.0
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
// expected roles: name, symbol, balances, currencyPrice, changePct24hour, communityId, communityName, communityImage
|
/**
|
||||||
required property var controller
|
Expected model structure:
|
||||||
|
|
||||||
property var currencyStore
|
key [string] - unique identifier of a token, e.g "0x3234235"
|
||||||
property var networkConnectionStore
|
symbol [string] - token's symbol e.g. "ETH" or "SNT"
|
||||||
required property var tokensStore
|
name [string] - token's name e.g. "Ether" or "Dai"
|
||||||
property var overview
|
icon [url] - token's icon url
|
||||||
property bool assetDetailsLaunched: false
|
balance [double] - tokens balance is the commonly used unit, e.g. 1.2 for 1.2 ETH, used
|
||||||
property bool filterVisible
|
for sorting and computing market value
|
||||||
property bool areAssetsLoading: false
|
balanceText [string] - formatted and localized balance. This is not done internally because
|
||||||
property string addressFilters
|
it may depend on many external factors
|
||||||
property string networkFilters
|
error [string] - error message related to balance
|
||||||
|
|
||||||
signal assetClicked(var token)
|
marketDetailsAvailable [bool] - specifies if market datails are available for given token
|
||||||
signal sendRequested(string symbol)
|
marketDetailsLoading [bool] - specifies if market datails are available for given token
|
||||||
signal receiveRequested(string symbol)
|
marketPrice [double] - specifies market price in currently used currency
|
||||||
signal launchSwapModal(string tokensKey)
|
marketChangePct24hour [double] - percentage price change in last 24 hours, e.g. 0.5 for 0.5% of price change
|
||||||
signal switchToCommunityRequested(string communityId)
|
|
||||||
signal manageTokensRequested()
|
|
||||||
|
|
||||||
spacing: 0
|
communityId [string] - for community assets, unique identifier of a community, e.g. "0x6734235"
|
||||||
|
communityName [string] - for community assets, name of a community e.g. "Crypto Kitties"
|
||||||
|
communityIcon [url] - for community assets, community's icon url
|
||||||
|
|
||||||
|
position [int] - if custom order available, display position defined by the user via token management
|
||||||
|
canBeHidden [bool] - specifies if given token can be hidden (e.g. ETH should be always visible)
|
||||||
|
**/
|
||||||
|
property var model
|
||||||
|
|
||||||
|
// enables global loading state useful when real data are not yet available
|
||||||
|
property bool loading
|
||||||
|
|
||||||
|
// shows/hides list sorter
|
||||||
|
property bool sorterVisible
|
||||||
|
|
||||||
|
// allows/disables choosing custom sort order from a sorter
|
||||||
|
property bool customOrderAvailable
|
||||||
|
|
||||||
|
// switches configuring right click menu
|
||||||
|
property bool sendEnabled: true
|
||||||
|
property bool swapEnabled: true
|
||||||
|
property bool swapVisible: true
|
||||||
|
|
||||||
|
property string balanceError
|
||||||
|
|
||||||
|
// global market data error, presented for all tokens expecting market data
|
||||||
|
property string marketDataError
|
||||||
|
|
||||||
|
// formatting function for fiat currency values
|
||||||
|
property var formatFiat: balance => `${balance.toLocaleString(Qt.locale())} XYZ`
|
||||||
|
|
||||||
|
signal sendRequested(string key)
|
||||||
|
signal receiveRequested(string key)
|
||||||
|
signal swapRequested(string key)
|
||||||
|
signal assetClicked(string key)
|
||||||
|
signal communityClicked(string communityKey)
|
||||||
|
signal hideRequested(string key)
|
||||||
|
signal hideCommunityAssets(string communityKey)
|
||||||
|
signal manageTokensRequested
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
property int selectedAssetIndex: -1
|
|
||||||
readonly property int loadingItemsCount: 25
|
readonly property int loadingItemsCount: 25
|
||||||
|
|
||||||
readonly property bool isCustomView: cmbTokenOrder.currentValue === SortOrderComboBox.TokenOrderCustom
|
|
||||||
|
|
||||||
function tokenIsVisible(symbol, currentCurrencyBalance, isCommunityAsset) {
|
|
||||||
// NOTE Backend returns ETH, SNT, STT and DAI by default
|
|
||||||
if (!root.controller.filterAcceptsSymbol(symbol)) // explicitely hidden
|
|
||||||
return false
|
|
||||||
if (isCommunityAsset)
|
|
||||||
return true
|
|
||||||
// Received tokens can have 0 balance, which indicate previously owned token
|
|
||||||
if (root.tokensStore.displayAssetsBelowBalance) {
|
|
||||||
const threshold = root.tokensStore.getDisplayAssetsBelowBalanceThresholdDisplayAmount()
|
|
||||||
if (threshold > 0)
|
|
||||||
return currentCurrencyBalance > threshold
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTotalBalance(balances, decimals, key) {
|
SortFilterProxyModel {
|
||||||
let totalBalance = 0
|
id: sfpm
|
||||||
let nwFilters = root.networkFilters.split(":")
|
|
||||||
let addrFilters = root.addressFilters.split(":")
|
sourceModel: root.model ?? null
|
||||||
for(let i=0; i<balances.count; i++) {
|
|
||||||
let balancePerAddressPerChain = SQUtils.ModelUtils.get(balances, i)
|
|
||||||
if (nwFilters.includes(balancePerAddressPerChain.chainId+"") &&
|
|
||||||
addrFilters.includes(balancePerAddressPerChain.account)) {
|
|
||||||
totalBalance+=SQUtils.AmountsArithmetic.toNumber(balancePerAddressPerChain[key], decimals)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return totalBalance
|
|
||||||
}
|
|
||||||
|
|
||||||
property SortFilterProxyModel customSFPM: SortFilterProxyModel {
|
|
||||||
sourceModel: root.controller.sourceModel
|
|
||||||
proxyRoles: [
|
proxyRoles: [
|
||||||
|
// helper role for rendering section delegate
|
||||||
FastExpressionRole {
|
FastExpressionRole {
|
||||||
name: "currentBalance"
|
name: "isCommunity"
|
||||||
expression: d.getTotalBalance(model.balances, model.decimals, "balance")
|
expression: !!communityId ? "community" : ""
|
||||||
expectedRoles: ["balances", "decimals"]
|
expectedRoles: ["communityId"]
|
||||||
},
|
},
|
||||||
FastExpressionRole {
|
FastExpressionRole {
|
||||||
name: "currentCurrencyBalance"
|
name: "marketBalance"
|
||||||
expression: {
|
expression: balance * marketPrice
|
||||||
if(!model.communityId) {
|
expectedRoles: ["balance", "marketPrice"]
|
||||||
if (!!model.marketDetails) {
|
|
||||||
return model.currentBalance * model.marketDetails.currencyPrice.amount
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return model.currentBalance
|
|
||||||
}
|
|
||||||
expectedRoles: ["marketDetails", "communityId", "currentBalance"]
|
|
||||||
},
|
|
||||||
FastExpressionRole {
|
|
||||||
name: "tokenPrice"
|
|
||||||
expression: model.marketDetails.currencyPrice.amount
|
|
||||||
expectedRoles: ["marketDetails"]
|
|
||||||
},
|
},
|
||||||
FastExpressionRole {
|
FastExpressionRole {
|
||||||
name: "change1DayFiat"
|
name: "change1DayFiat"
|
||||||
expression: {
|
expression: marketBalance * (1 - (1 / (marketChangePct24hour / 100 + 1)))
|
||||||
if (!model.isCommunityAsset && !!model.marketDetails) {
|
expectedRoles: ["marketBalance", "marketChangePct24hour"]
|
||||||
const balance1DayAgo = d.getTotalBalance(model.balances, model.decimals, "balance1DayAgo")
|
|
||||||
const change = (model.currentBalance * model.marketDetails.currencyPrice.amount) - (balance1DayAgo * (model.marketDetails.currencyPrice.amount - model.marketDetails.change24hour))
|
|
||||||
return change
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
expectedRoles: ["marketDetails", "balances", "decimals", "currentBalance", "isCommunityAsset"]
|
|
||||||
},
|
|
||||||
FastExpressionRole {
|
|
||||||
name: "isCommunityAsset"
|
|
||||||
expression: !!model.communityId
|
|
||||||
expectedRoles: ["communityId"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
filters: [
|
|
||||||
FastExpressionFilter {
|
|
||||||
expression: {
|
|
||||||
root.controller.revision
|
|
||||||
root.tokensStore.displayAssetsBelowBalance
|
|
||||||
return d.tokenIsVisible(model.symbol, model.currentCurrencyBalance, model.isCommunityAsset)
|
|
||||||
}
|
|
||||||
expectedRoles: ["symbol", "currentCurrencyBalance", "isCommunityAsset"]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
sorters: [
|
sorters: [
|
||||||
RoleSorter {
|
RoleSorter {
|
||||||
roleName: "isCommunityAsset"
|
roleName: "isCommunity"
|
||||||
},
|
|
||||||
FastExpressionSorter {
|
|
||||||
expression: {
|
|
||||||
root.controller.revision
|
|
||||||
return root.controller.compareTokens(modelLeft.symbol, modelRight.symbol)
|
|
||||||
}
|
|
||||||
enabled: d.isCustomView
|
|
||||||
expectedRoles: ["symbol"]
|
|
||||||
},
|
},
|
||||||
RoleSorter {
|
RoleSorter {
|
||||||
roleName: cmbTokenOrder.currentSortRoleName
|
roleName: sortOrderComboBox.currentSortRoleName
|
||||||
sortOrder: cmbTokenOrder.currentSortOrder
|
sortOrder: sortOrderComboBox.currentSortOrder
|
||||||
enabled: !d.isCustomView
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Settings {
|
|
||||||
id: settings
|
|
||||||
category: "AssetsViewSortSettings"
|
|
||||||
property int currentSortValue: SortOrderComboBox.TokenOrderCurrencyBalance
|
|
||||||
property alias currentSortOrder: cmbTokenOrder.currentSortOrder
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
settings.sync()
|
|
||||||
cmbTokenOrder.currentIndex = cmbTokenOrder.indexOfValue(settings.currentSortValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onDestruction: {
|
|
||||||
settings.currentSortValue = cmbTokenOrder.currentValue
|
|
||||||
}
|
|
||||||
|
|
||||||
|
contentItem: ColumnLayout {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillHeight: false
|
||||||
Layout.preferredHeight: root.filterVisible ? implicitHeight : 0
|
Layout.preferredHeight: root.sorterVisible ? implicitHeight : 0
|
||||||
|
|
||||||
|
opacity: root.sorterVisible ? 1 : 0
|
||||||
spacing: 20
|
spacing: 20
|
||||||
opacity: root.filterVisible ? 1 : 0
|
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
|
|
||||||
Behavior on Layout.preferredHeight { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } }
|
Behavior on Layout.preferredHeight {
|
||||||
Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } }
|
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
|
||||||
|
|
||||||
StatusDialogDivider {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusDialogDivider { Layout.fillWidth: true }
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: false
|
||||||
|
|
||||||
spacing: Style.current.halfPadding
|
spacing: Style.current.halfPadding
|
||||||
|
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
|
@ -201,18 +151,28 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
SortOrderComboBox {
|
SortOrderComboBox {
|
||||||
id: cmbTokenOrder
|
id: sortOrderComboBox
|
||||||
|
|
||||||
objectName: "cmbTokenOrder"
|
objectName: "cmbTokenOrder"
|
||||||
hasCustomOrderDefined: root.controller.hasSettings
|
hasCustomOrderDefined: root.customOrderAvailable
|
||||||
|
|
||||||
model: [
|
model: [
|
||||||
{ value: SortOrderComboBox.TokenOrderCurrencyBalance, text: qsTr("Asset balance value"), icon: "", sortRoleName: "currentCurrencyBalance" }, // custom SFPM ExpressionRole on "enabledNetworkCurrencyBalance" amount
|
{ value: SortOrderComboBox.TokenOrderCurrencyBalance,
|
||||||
{ value: SortOrderComboBox.TokenOrderBalance, text: qsTr("Asset balance"), icon: "", sortRoleName: "currentBalance" }, // custom SFPM ExpressionRole on "enabledNetworkBalance" amount
|
text: qsTr("Asset balance value"), icon: "", sortRoleName: "marketBalance" },
|
||||||
{ value: SortOrderComboBox.TokenOrderCurrencyPrice, text: qsTr("Asset value"), icon: "", sortRoleName: "tokenPrice" }, // custom SFPM ExpressionRole on "currencyPrice" amount
|
{ value: SortOrderComboBox.TokenOrderBalance,
|
||||||
{ value: SortOrderComboBox.TokenOrder1DChange, text: qsTr("1d change: balance value"), icon: "", sortRoleName: "change1DayFiat" }, // custom SFPM ExpressionRole
|
text: qsTr("Asset balance"), icon: "", sortRoleName: "balance" },
|
||||||
{ value: SortOrderComboBox.TokenOrderAlpha, text: qsTr("Asset name"), icon: "", sortRoleName: "name" },
|
{ value: SortOrderComboBox.TokenOrderCurrencyPrice,
|
||||||
{ value: SortOrderComboBox.TokenOrderCustom, text: qsTr("Custom order"), icon: "", sortRoleName: "" },
|
text: qsTr("Asset value"), icon: "", sortRoleName: "marketPrice" },
|
||||||
{ value: SortOrderComboBox.TokenOrderNone, text: "---", icon: "", sortRoleName: "" }, // separator
|
{ value: SortOrderComboBox.TokenOrder1DChange,
|
||||||
{ value: SortOrderComboBox.TokenOrderCreateCustom, text: hasCustomOrderDefined ? qsTr("Edit custom order →") : qsTr("Create custom order →"),
|
text: qsTr("1d change: balance value"), icon: "", sortRoleName: "change1DayFiat" },
|
||||||
|
{ value: SortOrderComboBox.TokenOrderAlpha,
|
||||||
|
text: qsTr("Asset name"), icon: "", sortRoleName: "name" },
|
||||||
|
{ value: SortOrderComboBox.TokenOrderCustom,
|
||||||
|
text: qsTr("Custom order"), icon: "", sortRoleName: "position" },
|
||||||
|
{ value: SortOrderComboBox.TokenOrderNone,
|
||||||
|
text: "---", icon: "", sortRoleName: "" }, // separator
|
||||||
|
{ value: SortOrderComboBox.TokenOrderCreateCustom,
|
||||||
|
text: hasCustomOrderDefined ? qsTr("Edit custom order →") : qsTr("Create custom order →"),
|
||||||
icon: "", sortRoleName: "" }
|
icon: "", sortRoleName: "" }
|
||||||
]
|
]
|
||||||
onCreateOrEditRequested: {
|
onCreateOrEditRequested: {
|
||||||
|
@ -221,95 +181,78 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusDialogDivider {
|
StatusDialogDivider { Layout.fillWidth: true }
|
||||||
Layout.fillWidth: true
|
}
|
||||||
|
|
||||||
|
DelegateModel {
|
||||||
|
id: regularModel
|
||||||
|
|
||||||
|
model: sfpm
|
||||||
|
|
||||||
|
delegate: TokenDelegate {
|
||||||
|
objectName: `AssetView_TokenListItem_${model.symbol}`
|
||||||
|
|
||||||
|
width: ListView.view.width
|
||||||
|
|
||||||
|
name: model.name
|
||||||
|
icon: model.icon
|
||||||
|
balance: model.balanceText
|
||||||
|
marketBalance: root.formatFiat(model.marketBalance)
|
||||||
|
|
||||||
|
marketDetailsAvailable: model.marketDetailsAvailable
|
||||||
|
marketDetailsLoading: model.marketDetailsLoading
|
||||||
|
marketCurrencyPrice: root.formatFiat(model.change1DayFiat)
|
||||||
|
marketChangePct24hour: model.marketChangePct24hour
|
||||||
|
|
||||||
|
communityId: model.communityId
|
||||||
|
communityName: model.communityName ?? ""
|
||||||
|
communityIcon: model.communityIcon ?? ""
|
||||||
|
|
||||||
|
errorTooltipText_1: model.error
|
||||||
|
errorTooltipText_2: root.marketDataError
|
||||||
|
|
||||||
|
errorMode: !!root.balanceError
|
||||||
|
errorIcon.tooltip.text: root.balanceError
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (mouse.button === Qt.LeftButton)
|
||||||
|
root.assetClicked(model.key)
|
||||||
|
else if (mouse.button === Qt.RightButton)
|
||||||
|
tokenContextMenu.createObject(this, { model }).popup(mouse)
|
||||||
|
}
|
||||||
|
|
||||||
|
onCommunityClicked: root.communityClicked(model.communityId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DelegateModel {
|
||||||
|
id: loadingModel
|
||||||
|
|
||||||
|
model: d.loadingItemsCount
|
||||||
|
|
||||||
|
delegate: LoadingTokenDelegate {
|
||||||
|
objectName: `AssetView_LoadingTokenDelegate_${model.index}`
|
||||||
|
|
||||||
|
width: ListView.view.width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusListView {
|
StatusListView {
|
||||||
id: assetsListView
|
id: listView
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: Style.current.padding
|
|
||||||
Layout.preferredHeight: contentHeight
|
|
||||||
Layout.fillHeight: true
|
|
||||||
objectName: "assetViewStatusListView"
|
|
||||||
model: root.areAssetsLoading ? d.loadingItemsCount : d.customSFPM
|
|
||||||
delegate: delegateLoader
|
|
||||||
section {
|
|
||||||
property: "isCommunityAsset"
|
|
||||||
delegate: Loader {
|
|
||||||
width: ListView.view.width
|
|
||||||
required property string section
|
|
||||||
sourceComponent: section === "true" ? sectionDelegate : null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
objectName: "assetViewStatusListView"
|
||||||
id: sectionDelegate
|
|
||||||
AssetsSectionDelegate {
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
model: root.loading ? loadingModel : regularModel
|
||||||
|
|
||||||
|
section {
|
||||||
|
property: "isCommunity"
|
||||||
|
delegate: AssetsSectionDelegate {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: qsTr("Community minted")
|
text: qsTr("Community minted")
|
||||||
onInfoButtonClicked: Global.openPopup(communityInfoPopupCmp)
|
onInfoButtonClicked: communityInfoPopup.createObject(this).open()
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: delegateLoader
|
|
||||||
Loader {
|
|
||||||
property var modelData: model
|
|
||||||
property int delegateIndex: index
|
|
||||||
width: ListView.view.width
|
|
||||||
sourceComponent: root.areAssetsLoading ? loadingTokenDelegate : tokenDelegate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: loadingTokenDelegate
|
|
||||||
LoadingTokenDelegate {
|
|
||||||
objectName: "AssetView_LoadingTokenDelegate_" + delegateIndex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: tokenDelegate
|
|
||||||
TokenDelegate {
|
|
||||||
objectName: "AssetView_TokenListItem_" + (!!modelData ? modelData.symbol : "")
|
|
||||||
readonly property string balance: !!modelData && !!modelData.currentBalance ? "%1".arg(modelData.currentBalance) : "" // Needed for the tests
|
|
||||||
errorTooltipText_1: !!modelData && !!networkConnectionStore ? networkConnectionStore.getBlockchainNetworkDownTextForToken(modelData.balances) : ""
|
|
||||||
errorTooltipText_2: !!networkConnectionStore ? networkConnectionStore.getMarketNetworkDownText() : ""
|
|
||||||
subTitle: {
|
|
||||||
if (!modelData || !modelData.symbol) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if (networkConnectionStore && networkConnectionStore.noTokenBalanceAvailable) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return LocaleUtils.currencyAmountToLocaleString(root.currencyStore.getCurrencyAmount(modelData.currentBalance, modelData.symbol))
|
|
||||||
}
|
|
||||||
currencyBalance.text: {
|
|
||||||
let totalCurrencyBalance = modelData && modelData.currentCurrencyBalance ? modelData.currentCurrencyBalance : 0
|
|
||||||
return currencyStore.formatCurrencyAmount(totalCurrencyBalance, currencyStore.currentCurrency)
|
|
||||||
}
|
|
||||||
errorMode: !!networkConnectionStore ? networkConnectionStore.noBlockchainConnectionAndNoCache && !networkConnectionStore.noMarketConnectionAndNoCache : false
|
|
||||||
errorIcon.tooltip.text: !!networkConnectionStore ? networkConnectionStore.noBlockchainConnectionAndNoCacheText : ""
|
|
||||||
onClicked: (itemId, mouse) => {
|
|
||||||
if (mouse.button === Qt.LeftButton) {
|
|
||||||
RootStore.getHistoricalDataForToken(modelData.symbol, root.currencyStore.currentCurrency)
|
|
||||||
d.selectedAssetIndex = delegateIndex
|
|
||||||
assetClicked(assetsListView.model.get(delegateIndex))
|
|
||||||
} else if (mouse.button === Qt.RightButton) {
|
|
||||||
Global.openMenu(tokenContextMenu, this,
|
|
||||||
{symbol: modelData.symbol, assetName: modelData.name, assetImage: symbolUrl,
|
|
||||||
communityId: modelData.communityId, communityName: modelData.communityName,
|
|
||||||
communityImage: modelData.communityImage, tokensKey: modelData.tokensKey})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onSwitchToCommunityRequested: root.switchToCommunityRequested(communityId)
|
|
||||||
Component.onCompleted: {
|
|
||||||
// on Model reset if the detail view is shown, update the data in background.
|
|
||||||
if(root.assetDetailsLaunched && delegateIndex === d.selectedAssetIndex) {
|
|
||||||
assetClicked(assetsListView.model.get(delegateIndex))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -317,92 +260,73 @@ ColumnLayout {
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: tokenContextMenu
|
id: tokenContextMenu
|
||||||
StatusMenu {
|
|
||||||
|
AssetContextMenu {
|
||||||
|
required property var model
|
||||||
|
|
||||||
|
readonly property string key: model.key
|
||||||
|
readonly property string communityKey: model.communityId
|
||||||
|
|
||||||
onClosed: destroy()
|
onClosed: destroy()
|
||||||
|
|
||||||
property string tokensKey
|
sendEnabled: root.sendEnabled
|
||||||
property string symbol
|
swapEnabled: root.swapEnabled
|
||||||
property string assetName
|
swapVisible: root.swapVisible
|
||||||
property string assetImage
|
hideVisible: model.canBeHidden
|
||||||
property string communityId
|
communityHideVisible: !!model.isCommunity
|
||||||
property string communityName
|
|
||||||
property string communityImage
|
|
||||||
|
|
||||||
StatusAction {
|
onSendRequested: root.sendRequested(key)
|
||||||
enabled: root.networkConnectionStore.sendBuyBridgeEnabled && !root.overview.isWatchOnlyAccount && root.overview.canSend
|
onReceiveRequested: root.receiveRequested(key)
|
||||||
visibleOnDisabled: true
|
onSwapRequested: root.swapRequested(key)
|
||||||
icon.name: "send"
|
|
||||||
text: qsTr("Send")
|
onHideRequested:
|
||||||
onTriggered: root.sendRequested(symbol)
|
confirmHideAssetPopup.createObject(parent, { model }).open()
|
||||||
}
|
onCommunityHideRequested:
|
||||||
StatusAction {
|
confirmHideCommunityAssetsPopup.createObject(parent, { model }).open()
|
||||||
icon.name: "receive"
|
|
||||||
text: qsTr("Receive")
|
onManageTokensRequested: root.manageTokensRequested()
|
||||||
onTriggered: root.receiveRequested(symbol)
|
|
||||||
}
|
|
||||||
StatusAction {
|
|
||||||
icon.name: "swap"
|
|
||||||
text: qsTr("Swap")
|
|
||||||
enabled: Global.featureFlags.swapEnabled && !root.overview.isWatchOnlyAccount
|
|
||||||
visibleOnDisabled: Global.featureFlags.swapEnabled
|
|
||||||
onTriggered: root.launchSwapModal(tokensKey)
|
|
||||||
}
|
|
||||||
StatusMenuSeparator {}
|
|
||||||
StatusAction {
|
|
||||||
icon.name: "settings"
|
|
||||||
text: qsTr("Manage tokens")
|
|
||||||
onTriggered: root.manageTokensRequested()
|
|
||||||
}
|
|
||||||
StatusAction {
|
|
||||||
enabled: symbol !== Constants.ethToken
|
|
||||||
type: StatusAction.Type.Danger
|
|
||||||
icon.name: "hide"
|
|
||||||
text: qsTr("Hide asset")
|
|
||||||
onTriggered: Global.openConfirmHideAssetPopup(symbol, assetName, assetImage, !!communityId)
|
|
||||||
}
|
|
||||||
StatusAction {
|
|
||||||
enabled: !!communityId
|
|
||||||
type: StatusAction.Type.Danger
|
|
||||||
icon.name: "hide"
|
|
||||||
text: qsTr("Hide all assets from this community")
|
|
||||||
onTriggered: Global.openPopup(confirmHideCommunityAssetsPopup, {communityId, communityName, communityImage})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: communityInfoPopupCmp
|
id: communityInfoPopup
|
||||||
CommunityAssetsInfoPopup {}
|
|
||||||
|
CommunityAssetsInfoPopup {
|
||||||
|
destroyOnClose: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: confirmHideAssetPopup
|
||||||
|
|
||||||
|
ConfirmHideAssetPopup {
|
||||||
|
destroyOnClose: true
|
||||||
|
|
||||||
|
required property var model
|
||||||
|
|
||||||
|
symbol: model.symbol
|
||||||
|
name: model.name
|
||||||
|
icon: model.icon
|
||||||
|
|
||||||
|
onConfirmButtonClicked: {
|
||||||
|
root.hideRequested(model.key)
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: confirmHideCommunityAssetsPopup
|
id: confirmHideCommunityAssetsPopup
|
||||||
ConfirmationDialog {
|
|
||||||
property string communityId
|
|
||||||
property string communityName
|
|
||||||
property string communityImage
|
|
||||||
|
|
||||||
width: 520
|
ConfirmHideCommunityAssetsPopup {
|
||||||
destroyOnClose: true
|
required property var model
|
||||||
confirmButtonLabel: qsTr("Hide '%1' assets").arg(communityName)
|
|
||||||
cancelBtnType: ""
|
name: model.communityName
|
||||||
showCancelButton: true
|
icon: model.communityIcon
|
||||||
headerSettings.title: qsTr("Hide %1 community assets").arg(communityName)
|
|
||||||
headerSettings.asset.name: communityImage
|
|
||||||
confirmationText: qsTr("Are you sure you want to hide all community assets minted by %1? You will no longer see or be able to interact with these assets anywhere inside Status.").arg(communityName)
|
|
||||||
onCancelButtonClicked: close()
|
|
||||||
onConfirmButtonClicked: {
|
onConfirmButtonClicked: {
|
||||||
root.controller.showHideGroup(communityId, false)
|
root.hideCommunityAssets(model.communityId)
|
||||||
close()
|
close();
|
||||||
Global.displayToastMessage(
|
|
||||||
qsTr("%1 community assets were successfully hidden. You can toggle asset visibility via %2.").arg(communityName)
|
|
||||||
.arg(`<a style="text-decoration:none" href="#${Constants.appSection.profile}/${Constants.settingsSubsection.wallet}/${Constants.walletSettingsSubsection.manageAssets}">` + qsTr("Settings", "Go to Settings") + "</a>"),
|
|
||||||
"",
|
|
||||||
"checkmark-circle",
|
|
||||||
false,
|
|
||||||
Constants.ephemeralNotificationType.success,
|
|
||||||
""
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,333 +0,0 @@
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Controls 2.15
|
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
|
|
||||||
import QtQml.Models 2.15
|
|
||||||
|
|
||||||
import StatusQ 0.1
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
import StatusQ.Popups.Dialog 0.1
|
|
||||||
|
|
||||||
import AppLayouts.Wallet.controls 1.0
|
|
||||||
import shared.controls 1.0
|
|
||||||
import shared.popups 1.0
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
|
||||||
|
|
||||||
|
|
||||||
Control {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
/**
|
|
||||||
Expected model structure:
|
|
||||||
|
|
||||||
key [string] - unique identifier of a token, e.g "0x3234235"
|
|
||||||
symbol [string] - token's symbol e.g. "ETH" or "SNT"
|
|
||||||
name [string] - token's name e.g. "Ether" or "Dai"
|
|
||||||
icon [url] - token's icon url
|
|
||||||
balance [double] - tokens balance is the commonly used unit, e.g. 1.2 for 1.2 ETH, used
|
|
||||||
for sorting and computing market value
|
|
||||||
balanceText [string] - formatted and localized balance. This is not done internally because
|
|
||||||
it may depend on many external factors
|
|
||||||
error [string] - error message related to balance
|
|
||||||
|
|
||||||
marketDetailsAvailable [bool] - specifies if market datails are available for given token
|
|
||||||
marketDetailsLoading [bool] - specifies if market datails are available for given token
|
|
||||||
marketPrice [double] - specifies market price in currently used currency
|
|
||||||
marketChangePct24hour [double] - percentage price change in last 24 hours, e.g. 0.5 for 0.5% of price change
|
|
||||||
|
|
||||||
communityId [string] - for community assets, unique identifier of a community, e.g. "0x6734235"
|
|
||||||
communityName [string] - for community assets, name of a community e.g. "Crypto Kitties"
|
|
||||||
communityIcon [url] - for community assets, community's icon url
|
|
||||||
|
|
||||||
position [int] - if custom order available, display position defined by the user via token management
|
|
||||||
canBeHidden [bool] - specifies if given token can be hidden (e.g. ETH should be always visible)
|
|
||||||
**/
|
|
||||||
property var model
|
|
||||||
|
|
||||||
// enables global loading state useful when real data are not yet available
|
|
||||||
property bool loading
|
|
||||||
|
|
||||||
// shows/hides list sorter
|
|
||||||
property bool sorterVisible
|
|
||||||
|
|
||||||
// allows/disables choosing custom sort order from a sorter
|
|
||||||
property bool customOrderAvailable
|
|
||||||
|
|
||||||
// switches configuring right click menu
|
|
||||||
property bool sendEnabled: true
|
|
||||||
property bool swapEnabled: true
|
|
||||||
property bool swapVisible: true
|
|
||||||
|
|
||||||
property string balanceError
|
|
||||||
|
|
||||||
// global market data error, presented for all tokens expecting market data
|
|
||||||
property string marketDataError
|
|
||||||
|
|
||||||
// formatting function for fiat currency values
|
|
||||||
property var formatFiat: balance => `${balance.toLocaleString(Qt.locale())} XYZ`
|
|
||||||
|
|
||||||
signal sendRequested(string key)
|
|
||||||
signal receiveRequested(string key)
|
|
||||||
signal swapRequested(string key)
|
|
||||||
signal assetClicked(string key)
|
|
||||||
signal communityClicked(string communityKey)
|
|
||||||
signal hideRequested(string key)
|
|
||||||
signal hideCommunityAssets(string communityKey)
|
|
||||||
signal manageTokensRequested
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: d
|
|
||||||
|
|
||||||
readonly property int loadingItemsCount: 25
|
|
||||||
}
|
|
||||||
|
|
||||||
SortFilterProxyModel {
|
|
||||||
id: sfpm
|
|
||||||
|
|
||||||
sourceModel: root.model
|
|
||||||
|
|
||||||
proxyRoles: [
|
|
||||||
// helper role for rendering section delegate
|
|
||||||
FastExpressionRole {
|
|
||||||
name: "isCommunity"
|
|
||||||
expression: !!communityId ? "community" : ""
|
|
||||||
expectedRoles: ["communityId"]
|
|
||||||
},
|
|
||||||
FastExpressionRole {
|
|
||||||
name: "marketBalance"
|
|
||||||
expression: balance * marketPrice
|
|
||||||
expectedRoles: ["balance", "marketPrice"]
|
|
||||||
},
|
|
||||||
FastExpressionRole {
|
|
||||||
name: "change1DayFiat"
|
|
||||||
expression: marketBalance * (1 - (1 / (marketChangePct24hour / 100 + 1)))
|
|
||||||
expectedRoles: ["marketBalance", "marketChangePct24hour"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
sorters: [
|
|
||||||
RoleSorter {
|
|
||||||
roleName: "isCommunity"
|
|
||||||
},
|
|
||||||
RoleSorter {
|
|
||||||
roleName: sortOrderComboBox.currentSortRoleName
|
|
||||||
sortOrder: sortOrderComboBox.currentSortOrder
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.fillHeight: false
|
|
||||||
Layout.preferredHeight: root.sorterVisible ? implicitHeight : 0
|
|
||||||
|
|
||||||
opacity: root.sorterVisible ? 1 : 0
|
|
||||||
spacing: 20
|
|
||||||
visible: opacity > 0
|
|
||||||
|
|
||||||
Behavior on Layout.preferredHeight {
|
|
||||||
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusDialogDivider { Layout.fillWidth: true }
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: false
|
|
||||||
|
|
||||||
spacing: Style.current.halfPadding
|
|
||||||
|
|
||||||
StatusBaseText {
|
|
||||||
color: Theme.palette.baseColor1
|
|
||||||
font.pixelSize: Style.current.additionalTextSize
|
|
||||||
text: qsTr("Sort by:")
|
|
||||||
}
|
|
||||||
|
|
||||||
SortOrderComboBox {
|
|
||||||
id: sortOrderComboBox
|
|
||||||
|
|
||||||
objectName: "cmbTokenOrder"
|
|
||||||
hasCustomOrderDefined: root.customOrderAvailable
|
|
||||||
|
|
||||||
model: [
|
|
||||||
{ value: SortOrderComboBox.TokenOrderCurrencyBalance,
|
|
||||||
text: qsTr("Asset balance value"), icon: "", sortRoleName: "marketBalance" },
|
|
||||||
{ value: SortOrderComboBox.TokenOrderBalance,
|
|
||||||
text: qsTr("Asset balance"), icon: "", sortRoleName: "balance" },
|
|
||||||
{ value: SortOrderComboBox.TokenOrderCurrencyPrice,
|
|
||||||
text: qsTr("Asset value"), icon: "", sortRoleName: "marketPrice" },
|
|
||||||
{ value: SortOrderComboBox.TokenOrder1DChange,
|
|
||||||
text: qsTr("1d change: balance value"), icon: "", sortRoleName: "change1DayFiat" },
|
|
||||||
{ value: SortOrderComboBox.TokenOrderAlpha,
|
|
||||||
text: qsTr("Asset name"), icon: "", sortRoleName: "name" },
|
|
||||||
{ value: SortOrderComboBox.TokenOrderCustom,
|
|
||||||
text: qsTr("Custom order"), icon: "", sortRoleName: "position" },
|
|
||||||
{ value: SortOrderComboBox.TokenOrderNone,
|
|
||||||
text: "---", icon: "", sortRoleName: "" }, // separator
|
|
||||||
{ value: SortOrderComboBox.TokenOrderCreateCustom,
|
|
||||||
text: hasCustomOrderDefined ? qsTr("Edit custom order →") : qsTr("Create custom order →"),
|
|
||||||
icon: "", sortRoleName: "" }
|
|
||||||
]
|
|
||||||
onCreateOrEditRequested: {
|
|
||||||
root.manageTokensRequested()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusDialogDivider { Layout.fillWidth: true }
|
|
||||||
}
|
|
||||||
|
|
||||||
DelegateModel {
|
|
||||||
id: regularModel
|
|
||||||
|
|
||||||
model: sfpm
|
|
||||||
|
|
||||||
delegate: TokenDelegateNew {
|
|
||||||
objectName: `AssetView_TokenListItem_${model.symbol}`
|
|
||||||
|
|
||||||
width: ListView.view.width
|
|
||||||
|
|
||||||
name: model.name
|
|
||||||
icon: model.icon
|
|
||||||
balance: model.balanceText
|
|
||||||
marketBalance: root.formatFiat(model.marketBalance)
|
|
||||||
|
|
||||||
marketDetailsAvailable: model.marketDetailsAvailable
|
|
||||||
marketDetailsLoading: model.marketDetailsLoading
|
|
||||||
marketCurrencyPrice: root.formatFiat(model.change1DayFiat)
|
|
||||||
marketChangePct24hour: model.marketChangePct24hour
|
|
||||||
|
|
||||||
communityId: model.communityId
|
|
||||||
communityName: model.communityName ?? ""
|
|
||||||
communityIcon: model.communityIcon ?? ""
|
|
||||||
|
|
||||||
errorTooltipText_1: model.error
|
|
||||||
errorTooltipText_2: root.marketDataError
|
|
||||||
|
|
||||||
errorMode: !!root.balanceError
|
|
||||||
errorIcon.tooltip.text: root.balanceError
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
if (mouse.button === Qt.LeftButton)
|
|
||||||
root.assetClicked(model.key)
|
|
||||||
else if (mouse.button === Qt.RightButton)
|
|
||||||
tokenContextMenu.createObject(this, { model }).popup(mouse)
|
|
||||||
}
|
|
||||||
|
|
||||||
onCommunityClicked: root.communityClicked(model.communityId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DelegateModel {
|
|
||||||
id: loadingModel
|
|
||||||
|
|
||||||
model: d.loadingItemsCount
|
|
||||||
|
|
||||||
delegate: LoadingTokenDelegateNew {
|
|
||||||
objectName: `AssetView_LoadingTokenDelegate_${model.index}`
|
|
||||||
|
|
||||||
width: ListView.view.width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusListView {
|
|
||||||
id: listView
|
|
||||||
|
|
||||||
objectName: "assetViewStatusListView"
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
model: root.loading ? loadingModel : regularModel
|
|
||||||
|
|
||||||
section {
|
|
||||||
property: "isCommunity"
|
|
||||||
delegate: AssetsSectionDelegate {
|
|
||||||
width: parent.width
|
|
||||||
text: qsTr("Community minted")
|
|
||||||
onInfoButtonClicked: communityInfoPopup.createObject(this).open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: tokenContextMenu
|
|
||||||
|
|
||||||
AssetContextMenu {
|
|
||||||
required property var model
|
|
||||||
|
|
||||||
readonly property string key: model.key
|
|
||||||
readonly property string communityKey: model.communityId
|
|
||||||
|
|
||||||
onClosed: destroy()
|
|
||||||
|
|
||||||
sendEnabled: root.sendEnabled
|
|
||||||
swapEnabled: root.swapEnabled
|
|
||||||
swapVisible: root.swapVisible
|
|
||||||
hideVisible: model.canBeHidden
|
|
||||||
communityHideVisible: !!model.isCommunity
|
|
||||||
|
|
||||||
onSendRequested: root.sendRequested(key)
|
|
||||||
onReceiveRequested: root.receiveRequested(key)
|
|
||||||
onSwapRequested: root.swapRequested(key)
|
|
||||||
|
|
||||||
onHideRequested:
|
|
||||||
confirmHideAssetPopup.createObject(parent, { model }).open()
|
|
||||||
onCommunityHideRequested:
|
|
||||||
confirmHideCommunityAssetsPopup.createObject(parent, { model }).open()
|
|
||||||
|
|
||||||
onManageTokensRequested: root.manageTokensRequested()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: communityInfoPopup
|
|
||||||
|
|
||||||
CommunityAssetsInfoPopup {
|
|
||||||
destroyOnClose: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: confirmHideAssetPopup
|
|
||||||
|
|
||||||
ConfirmHideAssetPopup {
|
|
||||||
destroyOnClose: true
|
|
||||||
|
|
||||||
required property var model
|
|
||||||
|
|
||||||
symbol: model.symbol
|
|
||||||
name: model.name
|
|
||||||
icon: model.icon
|
|
||||||
|
|
||||||
onConfirmButtonClicked: {
|
|
||||||
root.hideRequested(model.key)
|
|
||||||
close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: confirmHideCommunityAssetsPopup
|
|
||||||
|
|
||||||
ConfirmHideCommunityAssetsPopup {
|
|
||||||
required property var model
|
|
||||||
|
|
||||||
name: model.communityName
|
|
||||||
icon: model.communityIcon
|
|
||||||
|
|
||||||
onConfirmButtonClicked: {
|
|
||||||
root.hideCommunityAssets(model.communityId)
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,6 @@
|
||||||
AssetContextMenu 1.0 AssetContextMenu.qml
|
AssetContextMenu 1.0 AssetContextMenu.qml
|
||||||
AssetsView 1.0 AssetsView.qml
|
AssetsView 1.0 AssetsView.qml
|
||||||
AssetsViewAdaptor 1.0 AssetsViewAdaptor.qml
|
AssetsViewAdaptor 1.0 AssetsViewAdaptor.qml
|
||||||
AssetsViewNew 1.0 AssetsViewNew.qml
|
|
||||||
ConfirmHideAssetPopup 1.0 ConfirmHideAssetPopup.qml
|
ConfirmHideAssetPopup 1.0 ConfirmHideAssetPopup.qml
|
||||||
ConfirmHideCommunityAssetsPopup 1.0 ConfirmHideCommunityAssetsPopup.qml
|
ConfirmHideCommunityAssetsPopup 1.0 ConfirmHideCommunityAssetsPopup.qml
|
||||||
EnsResolver 1.0 EnsResolver.qml
|
EnsResolver 1.0 EnsResolver.qml
|
||||||
|
|
Loading…
Reference in New Issue