Wallet(SendModal): Old HodlingSelector and TokensListView removed
This commit is contained in:
parent
f6320f69cb
commit
4bf2f4df7a
|
@ -1,67 +0,0 @@
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Controls 2.15
|
|
||||||
|
|
||||||
import Models 1.0
|
|
||||||
import Storybook 1.0
|
|
||||||
|
|
||||||
import shared.popups.send.views 1.0
|
|
||||||
|
|
||||||
import AppLayouts.Wallet.stores 1.0
|
|
||||||
|
|
||||||
import StatusQ.Core.Utils 0.1
|
|
||||||
|
|
||||||
import shared.stores 1.0
|
|
||||||
import shared.stores.send 1.0
|
|
||||||
|
|
||||||
SplitView {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
orientation: Qt.Vertical
|
|
||||||
|
|
||||||
readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore {
|
|
||||||
assetsWithFilteredBalances: groupedAccountsAssetsModel
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionStore {
|
|
||||||
id: txStore
|
|
||||||
walletAssetStore: root.walletAssetStore
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property CurrenciesStore currencyStore: CurrenciesStore {}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
SplitView.fillWidth: true
|
|
||||||
SplitView.fillHeight: true
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: "lightgray"
|
|
||||||
}
|
|
||||||
|
|
||||||
TokenListView {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
|
|
||||||
width: 400
|
|
||||||
height: 600
|
|
||||||
|
|
||||||
assets: txStore.processedAssetsModel
|
|
||||||
collectibles: WalletNestedCollectiblesModel {}
|
|
||||||
networksModel: NetworksModel.flatNetworks
|
|
||||||
formatCurrentCurrencyAmount: function(balance){
|
|
||||||
return currencyStore.formatCurrencyAmount(balance, "USD")
|
|
||||||
}
|
|
||||||
formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){
|
|
||||||
return currencyStore.formatCurrencyAmountFromBigInt(balance, symbol, decimals)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogsAndControlsPanel {
|
|
||||||
SplitView.minimumHeight: 100
|
|
||||||
SplitView.preferredHeight: 100
|
|
||||||
|
|
||||||
SplitView.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// category: Views
|
|
|
@ -1,112 +0,0 @@
|
||||||
import QtQuick 2.15
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
readonly property var rootData: [
|
|
||||||
{
|
|
||||||
uid: "ID-Anniversary",
|
|
||||||
chainId: 1,
|
|
||||||
name: "Anniversary",
|
|
||||||
iconUrl: ModelsData.collectibles.anniversary,
|
|
||||||
collectionUid: "anniversary",
|
|
||||||
collectionName: "Anniversary",
|
|
||||||
isCollection: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
uid: "ID-SuperRare",
|
|
||||||
chainId: 1,
|
|
||||||
name: "SuperRare",
|
|
||||||
iconUrl: ModelsData.collectibles.superRare,
|
|
||||||
collectionUid: "super-rare",
|
|
||||||
collectionName: "SuperRare",
|
|
||||||
isCollection: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
uid: "cryptokitties",
|
|
||||||
chainId: 1,
|
|
||||||
name: "CryptoKitties",
|
|
||||||
iconUrl: ModelsData.collectibles.cryptoKitties,
|
|
||||||
collectionUid: "cryptokitties",
|
|
||||||
collectionName: "CryptoKitties",
|
|
||||||
isCollection: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
uid: "ID-Custom",
|
|
||||||
chainId: 1,
|
|
||||||
name: "Custom Collectible",
|
|
||||||
iconUrl: ModelsData.collectibles.custom,
|
|
||||||
collectionUid: "custom",
|
|
||||||
collectionName: "Custom",
|
|
||||||
isCollection: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
uid: "ID-Community1",
|
|
||||||
chainId: 1,
|
|
||||||
name: "Community Admin Token",
|
|
||||||
iconUrl: ModelsData.collectibles.mana,
|
|
||||||
collectionUid: "community-uid-1",
|
|
||||||
isCollection: false,
|
|
||||||
communityId: "community-id-1"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
readonly property var criptoKittiesData: [
|
|
||||||
{
|
|
||||||
uid: "ID-Kitty1",
|
|
||||||
chainId: 1,
|
|
||||||
name: "Furbeard",
|
|
||||||
iconUrl: ModelsData.collectibles.kitty1Big,
|
|
||||||
collectionUid: "cryptokitties",
|
|
||||||
collectionName: "CryptoKitties",
|
|
||||||
isCollection: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
uid: "ID-Kitty2",
|
|
||||||
chainId: 1,
|
|
||||||
name: "Magicat",
|
|
||||||
iconUrl: ModelsData.collectibles.kitty2Big,
|
|
||||||
collectionUid: "cryptokitties",
|
|
||||||
collectionName: "CryptoKitties",
|
|
||||||
isCollection: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
uid: "ID-Kitty3",
|
|
||||||
chainId: 1,
|
|
||||||
name: "Happy Meow",
|
|
||||||
iconUrl: ModelsData.collectibles.kitty3Big,
|
|
||||||
collectionUid: "cryptokitties",
|
|
||||||
collectionName: "CryptoKitties",
|
|
||||||
isCollection: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
uid: "ID-Kitty4",
|
|
||||||
chainId: 1,
|
|
||||||
name: "Furbeard-2",
|
|
||||||
iconUrl: ModelsData.collectibles.kitty4Big,
|
|
||||||
collectionUid: "cryptokitties",
|
|
||||||
collectionName: "CryptoKitties",
|
|
||||||
isCollection: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
uid: "ID-Kitty5",
|
|
||||||
chainId: 1,
|
|
||||||
name: "Magicat-3",
|
|
||||||
iconUrl: ModelsData.collectibles.kitty5Big,
|
|
||||||
collectionUid: "cryptokitties",
|
|
||||||
collectionName: "CryptoKitties",
|
|
||||||
isCollection: false,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
property string currentCollectionUid
|
|
||||||
|
|
||||||
onCurrentCollectionUidChanged: {
|
|
||||||
clear()
|
|
||||||
if (currentCollectionUid === "") {
|
|
||||||
append(rootData)
|
|
||||||
} else if (currentCollectionUid === "cryptokitties") {
|
|
||||||
append(criptoKittiesData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: append(rootData)
|
|
||||||
}
|
|
|
@ -17,7 +17,6 @@ UsersModel 1.0 UsersModel.qml
|
||||||
WalletSendAccountsModel 1.0 WalletSendAccountsModel.qml
|
WalletSendAccountsModel 1.0 WalletSendAccountsModel.qml
|
||||||
WalletAccountsModel 1.0 WalletAccountsModel.qml
|
WalletAccountsModel 1.0 WalletAccountsModel.qml
|
||||||
WalletKeyPairModel 1.0 WalletKeyPairModel.qml
|
WalletKeyPairModel 1.0 WalletKeyPairModel.qml
|
||||||
WalletNestedCollectiblesModel 1.0 WalletNestedCollectiblesModel.qml
|
|
||||||
WalletTransactionsModel 1.0 WalletTransactionsModel.qml
|
WalletTransactionsModel 1.0 WalletTransactionsModel.qml
|
||||||
GroupedAccountsAssetsModel 1.0 GroupedAccountsAssetsModel.qml
|
GroupedAccountsAssetsModel 1.0 GroupedAccountsAssetsModel.qml
|
||||||
TokensBySymbolModel 1.0 TokensBySymbolModel.qml
|
TokensBySymbolModel 1.0 TokensBySymbolModel.qml
|
||||||
|
|
|
@ -44,7 +44,7 @@ QtObject {
|
||||||
property var toNetworksRouteModel: NetworksModel.sendToNetworks
|
property var toNetworksRouteModel: NetworksModel.sendToNetworks
|
||||||
property string selectedSenderAccountAddress
|
property string selectedSenderAccountAddress
|
||||||
readonly property QtObject collectiblesModel: ManageCollectiblesModel {}
|
readonly property QtObject collectiblesModel: ManageCollectiblesModel {}
|
||||||
readonly property QtObject nestedCollectiblesModel: WalletNestedCollectiblesModel {}
|
readonly property QtObject nestedCollectiblesModel: ListModel {}
|
||||||
|
|
||||||
readonly property QtObject walletSectionSendInst: QtObject {
|
readonly property QtObject walletSectionSendInst: QtObject {
|
||||||
signal transactionSent(var chainId, var txHash, var uuid, var error)
|
signal transactionSent(var chainId, var txHash, var uuid, var error)
|
||||||
|
@ -94,48 +94,6 @@ QtObject {
|
||||||
return SQUtils.ModelUtils.get(assetsList, idx)
|
return SQUtils.ModelUtils.get(assetsList, idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCollectible(uid) {
|
|
||||||
const idx = SQUtils.ModelUtils.indexOf(collectiblesModel, "uid", uid)
|
|
||||||
if (idx < 0) {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
return SQUtils.ModelUtils.get(collectiblesModel, idx)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSelectorCollectible(uid) {
|
|
||||||
const idx = SQUtils.ModelUtils.indexOf(nestedCollectiblesModel, "uid", uid)
|
|
||||||
if (idx < 0) {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
return SQUtils.ModelUtils.get(nestedCollectiblesModel, idx)
|
|
||||||
}
|
|
||||||
|
|
||||||
function assetToSelectorAsset(asset) {
|
|
||||||
return asset
|
|
||||||
}
|
|
||||||
|
|
||||||
function collectibleToSelectorCollectible(collectible) {
|
|
||||||
return {
|
|
||||||
uid: collectible.uid,
|
|
||||||
chainId: collectible.chainId,
|
|
||||||
name: collectible.name,
|
|
||||||
iconUrl: collectible.imageUrl,
|
|
||||||
collectionUid: collectible.collectionUid,
|
|
||||||
collectionName: collectible.collectionName,
|
|
||||||
isCollection: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function holdingToSelectorHolding(holding, holdingType) {
|
|
||||||
if (holdingType === Constants.TokenType.ERC20) {
|
|
||||||
return assetToSelectorAsset(holding)
|
|
||||||
} else if (holdingType === Constants.TokenType.ERC721) {
|
|
||||||
return collectibleToSelectorCollectible(holding)
|
|
||||||
} else {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property string currentCurrency: "USD"
|
readonly property string currentCurrency: "USD"
|
||||||
|
|
||||||
function getAllNetworksSupportedString() {
|
function getAllNetworksSupportedString() {
|
||||||
|
|
|
@ -10,7 +10,6 @@ import shared.stores.send 1.0
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||||
|
|
||||||
import shared.popups.send.panels 1.0
|
|
||||||
import "./controls"
|
import "./controls"
|
||||||
import "./views"
|
import "./views"
|
||||||
|
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Layouts 1.13
|
|
||||||
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
|
|
||||||
property int count
|
|
||||||
property string name
|
|
||||||
signal backClicked()
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id:d
|
|
||||||
readonly property int padding: 16
|
|
||||||
readonly property int backButtonWidth: 56
|
|
||||||
readonly property int backButtonHeight: 24
|
|
||||||
}
|
|
||||||
|
|
||||||
implicitHeight: 40
|
|
||||||
color: "transparent"
|
|
||||||
border.color: Theme.palette.baseColor2
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
RowLayout{
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
StatusIconTextButton {
|
|
||||||
Layout.preferredWidth: d.backButtonWidth
|
|
||||||
Layout.preferredHeight: d.backButtonHeight
|
|
||||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
|
||||||
Layout.leftMargin: d.padding
|
|
||||||
|
|
||||||
statusIcon: "previous"
|
|
||||||
icon.width: 16
|
|
||||||
icon.height: 16
|
|
||||||
text: qsTr("Back")
|
|
||||||
|
|
||||||
onClicked: backClicked()
|
|
||||||
}
|
|
||||||
StatusBaseText {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.rightMargin: d.padding
|
|
||||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: Text.AlignRight
|
|
||||||
elide: Text.ElideRight
|
|
||||||
text: "%1 %2".arg(count).arg(name)
|
|
||||||
font.pixelSize: 13
|
|
||||||
lineHeight: 18
|
|
||||||
lineHeightMode: Text.FixedHeight
|
|
||||||
color: Theme.palette.baseColor1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
import QtQuick 2.13
|
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Components 0.1
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
StatusListItem {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
signal itemSelected(var selectedItem)
|
|
||||||
signal itemHovered(var selectedItem, bool hovered)
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: d
|
|
||||||
|
|
||||||
function selectItem() {
|
|
||||||
root.itemSelected(model)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root.sensor
|
|
||||||
function onContainsMouseChanged() {
|
|
||||||
root.itemHovered(model, root.sensor.containsMouse)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
title: name
|
|
||||||
statusListItemTitleAside.font.pixelSize: 15
|
|
||||||
asset.name: iconUrl ?? ""
|
|
||||||
asset.isImage: true
|
|
||||||
asset.width: 32
|
|
||||||
asset.height: 32
|
|
||||||
statusListItemLabel.color: Theme.palette.directColor1
|
|
||||||
statusListItemInlineTagsSlot.spacing: 0
|
|
||||||
|
|
||||||
radius: sensor.containsMouse || root.highlighted ? 0 : 8
|
|
||||||
color: sensor.containsMouse || root.highlighted ? Theme.palette.baseColor2 : "transparent"
|
|
||||||
|
|
||||||
onClicked: d.selectItem()
|
|
||||||
|
|
||||||
components: [
|
|
||||||
StatusRoundedImage {
|
|
||||||
width: 20
|
|
||||||
height: 20
|
|
||||||
image.source: Style.svg("tiny/%1".arg(networkIconUrl)) ?? ""
|
|
||||||
visible: !isGroup && root.sensor.containsMouse
|
|
||||||
},
|
|
||||||
StatusBaseText {
|
|
||||||
id: label
|
|
||||||
text: count
|
|
||||||
font.pixelSize: 13
|
|
||||||
color: Theme.palette.baseColor1
|
|
||||||
visible: isGroup || (!root.sensor.containsMouse && count > 1)
|
|
||||||
},
|
|
||||||
StatusIcon {
|
|
||||||
icon: "tiny/chevron-right"
|
|
||||||
color: Theme.palette.baseColor1
|
|
||||||
width: 16
|
|
||||||
height: 16
|
|
||||||
visible: isGroup
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
import QtQuick 2.13
|
|
||||||
|
|
||||||
import StatusQ 0.1
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Components 0.1
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
|
||||||
import SortFilterProxyModel 0.2
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
StatusListItem {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
objectName: "tokenBalancePerChainDelegate"
|
|
||||||
|
|
||||||
signal tokenSelected(var selectedToken)
|
|
||||||
signal tokenHovered(var selectedToken, bool hovered)
|
|
||||||
property var formatCurrentCurrencyAmount: function(balance){}
|
|
||||||
property var formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){}
|
|
||||||
property var balancesModel
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: d
|
|
||||||
|
|
||||||
function selectToken() {
|
|
||||||
root.tokenSelected({name, symbol, balances, decimals})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root.sensor
|
|
||||||
function onContainsMouseChanged() {
|
|
||||||
root.tokenHovered({name, symbol, balances, decimals},
|
|
||||||
root.sensor.containsMouse)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
title: name
|
|
||||||
titleAsideText: symbol ?? ""
|
|
||||||
statusListItemTitleAside.font.pixelSize: 15
|
|
||||||
statusListItemTitleAside.width: statusListItemTitleArea.width - statusListItemTitle.width
|
|
||||||
statusListItemTitleAside.elide: Text.ElideRight
|
|
||||||
label: {
|
|
||||||
let balance = !!model && !!model.currentCurrencyBalance ? model.currentCurrencyBalance : 0
|
|
||||||
return root.formatCurrentCurrencyAmount(balance)
|
|
||||||
}
|
|
||||||
// Community assets have a dedicated image streamed from status-go
|
|
||||||
asset.name: !!model && !!model.image
|
|
||||||
? model.image
|
|
||||||
: Constants.tokenIcon(symbol)
|
|
||||||
asset.isImage: true
|
|
||||||
asset.width: 32
|
|
||||||
asset.height: 32
|
|
||||||
statusListItemLabel.anchors.verticalCenterOffset: -12
|
|
||||||
statusListItemLabel.color: Theme.palette.directColor1
|
|
||||||
statusListItemInlineTagsSlot.spacing: 0
|
|
||||||
tagsModel: root.balancesModel
|
|
||||||
tagsDelegate: expandedItem
|
|
||||||
tagsScrollBarVisible: false
|
|
||||||
|
|
||||||
radius: sensor.containsMouse || highlighted ? 0 : 8
|
|
||||||
color: sensor.containsMouse || highlighted ? Theme.palette.statusListItem.highlightColor : "transparent"
|
|
||||||
|
|
||||||
onClicked: d.selectToken()
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: expandedItem
|
|
||||||
StatusListItemTag {
|
|
||||||
height: 16
|
|
||||||
leftPadding: 0
|
|
||||||
title: root.formatCurrencyAmountFromBigInt(balance, symbol, decimals)
|
|
||||||
titleText.font.pixelSize: 12
|
|
||||||
closeButtonVisible: false
|
|
||||||
bgColor: "transparent"
|
|
||||||
asset.width: 16
|
|
||||||
asset.height: 16
|
|
||||||
asset.isImage: true
|
|
||||||
asset.name: Style.svg("tiny/%1".arg(model.iconUrl))
|
|
||||||
tagClickable: true
|
|
||||||
onTagClicked: d.selectToken()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,11 +3,8 @@ GasSelector 1.0 GasSelector.qml
|
||||||
GasValidator 1.0 GasValidator.qml
|
GasValidator 1.0 GasValidator.qml
|
||||||
ClearButton 1.0 ClearButton.qml
|
ClearButton 1.0 ClearButton.qml
|
||||||
SavedAddressListItem 1.0 SavedAddressListItem.qml
|
SavedAddressListItem 1.0 SavedAddressListItem.qml
|
||||||
TokenBalancePerChainDelegate 1.0 TokenBalancePerChainDelegate.qml
|
|
||||||
SearchBoxWithRightIcon 1.0 SearchBoxWithRightIcon.qml
|
SearchBoxWithRightIcon 1.0 SearchBoxWithRightIcon.qml
|
||||||
AmountInputWithCursor 1.0 AmountInputWithCursor.qml
|
AmountInputWithCursor 1.0 AmountInputWithCursor.qml
|
||||||
BalanceExceeded 1.0 BalanceExceeded.qml
|
BalanceExceeded 1.0 BalanceExceeded.qml
|
||||||
CollectibleBackButtonWithInfo 1.0 CollectibleBackButtonWithInfo.qml
|
|
||||||
CollectibleNestedDelegate 1.0 CollectibleNestedDelegate.qml
|
|
||||||
HeaderTitleText 1.0 HeaderTitleText.qml
|
HeaderTitleText 1.0 HeaderTitleText.qml
|
||||||
SendRecipientInput 1.0 SendRecipientInput.qml
|
SendRecipientInput 1.0 SendRecipientInput.qml
|
||||||
|
|
|
@ -1,137 +0,0 @@
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Controls 2.15
|
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
import StatusQ.Components 0.1
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property var comboBoxModel
|
|
||||||
|
|
||||||
property var selectedItem
|
|
||||||
property var hoveredItem
|
|
||||||
property string defaultIconSource
|
|
||||||
property string placeholderText
|
|
||||||
|
|
||||||
property var itemIconSourceFn: function (item) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
property var itemTextFn: function (item) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
property alias comboBoxControl: comboBox.control
|
|
||||||
property alias comboBoxDelegate: comboBox.delegate
|
|
||||||
property alias comboBoxListViewSection: comboBox.comboBoxListViewSection
|
|
||||||
property var comboBoxPopupHeader
|
|
||||||
|
|
||||||
property int contentIconSize: 21
|
|
||||||
property int contentTextSize: 28
|
|
||||||
|
|
||||||
function openPopup() {
|
|
||||||
root.comboBoxControl.popup.open()
|
|
||||||
}
|
|
||||||
|
|
||||||
implicitWidth: comboBox.width
|
|
||||||
implicitHeight: comboBox.implicitHeight
|
|
||||||
|
|
||||||
onSelectedItemChanged: {
|
|
||||||
let iconSource = itemIconSourceFn(selectedItem)
|
|
||||||
d.iconSource = !selectedItem ? "" : !!iconSource ? iconSource : defaultIconSource
|
|
||||||
let itemText = itemTextFn(selectedItem)
|
|
||||||
d.text = !!itemText ? itemText : placeholderText
|
|
||||||
}
|
|
||||||
|
|
||||||
onHoveredItemChanged: {
|
|
||||||
let iconSource = itemIconSourceFn(hoveredItem)
|
|
||||||
d.iconSource = !!iconSource ? iconSource : defaultIconSource
|
|
||||||
let itemText = itemTextFn(hoveredItem)
|
|
||||||
d.text = !!itemText ? itemText : placeholderText
|
|
||||||
}
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: d
|
|
||||||
|
|
||||||
property string iconSource: ""
|
|
||||||
onIconSourceChanged: tokenIcon.image.source = iconSource
|
|
||||||
property string text: qsTr("Select asset")
|
|
||||||
readonly property bool isItemSelected: !!root.selectedItem || !!root.hoveredItem
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusComboBox {
|
|
||||||
id: comboBox
|
|
||||||
objectName: "assetSelectorButton"
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
control.padding: 12
|
|
||||||
control.popup.width: 492
|
|
||||||
control.popup.x: -root.x
|
|
||||||
control.popup.verticalPadding: 0
|
|
||||||
|
|
||||||
popupContentItemObjectName: "assetSelectorList"
|
|
||||||
|
|
||||||
model: root.comboBoxModel
|
|
||||||
|
|
||||||
control.background: Rectangle {
|
|
||||||
color: !d.isItemSelected ? Theme.palette.primaryColor3 : "transparent"
|
|
||||||
border.width: d.isItemSelected ? 0 : 1
|
|
||||||
border.color: Theme.palette.directColor7
|
|
||||||
radius: 8
|
|
||||||
|
|
||||||
HoverHandler {
|
|
||||||
cursorShape: root.enabled ? Qt.PointingHandCursor : undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: RowLayout {
|
|
||||||
StatusRoundedImage {
|
|
||||||
id: tokenIcon
|
|
||||||
objectName: "holdingSelectorsTokenIcon"
|
|
||||||
Layout.preferredWidth: root.contentIconSize
|
|
||||||
Layout.preferredHeight: root.contentIconSize
|
|
||||||
visible: !!d.iconSource
|
|
||||||
image.source: d.iconSource
|
|
||||||
image.onStatusChanged: {
|
|
||||||
if (image.status === Image.Error) {
|
|
||||||
image.source = root.defaultIconSource
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StatusBaseText {
|
|
||||||
objectName: "holdingSelectorsContentItemText"
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.pixelSize: !selectedItem && !hoveredItem ? Theme.primaryTextFontSize : root.contentTextSize
|
|
||||||
elide: Text.ElideRight
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
color: Theme.palette.primaryColor1
|
|
||||||
text: d.text
|
|
||||||
}
|
|
||||||
StatusIcon {
|
|
||||||
Layout.preferredWidth: 16
|
|
||||||
Layout.preferredHeight: 16
|
|
||||||
icon: "chevron-down"
|
|
||||||
color: Theme.palette.primaryColor1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
control.indicator: null
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
control.currentIndex = -1
|
|
||||||
control.popup.contentItem.header = root.comboBoxPopupHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
control.popup.onOpened: {
|
|
||||||
control.currentIndex = -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,389 +0,0 @@
|
||||||
import QtQml 2.15
|
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
|
||||||
|
|
||||||
import StatusQ 0.1
|
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
import StatusQ.Components 0.1
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
import shared.controls 1.0
|
|
||||||
import shared.popups 1.0
|
|
||||||
import shared.popups.send 1.0
|
|
||||||
import "../controls"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property var assetsModel
|
|
||||||
property var collectiblesModel
|
|
||||||
property var networksModel
|
|
||||||
property bool onlyAssets: true
|
|
||||||
property string searchText
|
|
||||||
|
|
||||||
implicitWidth: holdingItemSelector.implicitWidth
|
|
||||||
implicitHeight: holdingItemSelector.implicitHeight
|
|
||||||
|
|
||||||
property var formatCurrentCurrencyAmount: function(balance){}
|
|
||||||
property var formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){}
|
|
||||||
|
|
||||||
signal itemHovered(string holdingId, var holdingType)
|
|
||||||
signal itemSelected(string holdingId, var holdingType)
|
|
||||||
|
|
||||||
property alias selectedItem: holdingItemSelector.selectedItem
|
|
||||||
property alias hoveredItem: holdingItemSelector.hoveredItem
|
|
||||||
|
|
||||||
property string searchPlaceholderText: {
|
|
||||||
if (d.isCurrentBrowsingTypeAsset) {
|
|
||||||
return qsTr("Search for token or enter token address")
|
|
||||||
} else if (d.isBrowsingGroup) {
|
|
||||||
return qsTr("Search %1").arg(d.currentBrowsingGroupName ?? qsTr("collectibles in collection"))
|
|
||||||
} else {
|
|
||||||
return qsTr("Search collectibles")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSelectedItem(item, holdingType) {
|
|
||||||
d.browsingHoldingType = holdingType
|
|
||||||
holdingItemSelector.selectedItem = null
|
|
||||||
d.currentHoldingType = holdingType
|
|
||||||
holdingItemSelector.selectedItem = item
|
|
||||||
}
|
|
||||||
|
|
||||||
function setHoveredItem(item, holdingType) {
|
|
||||||
d.browsingHoldingType = holdingType
|
|
||||||
holdingItemSelector.hoveredItem = null
|
|
||||||
d.currentHoldingType = holdingType
|
|
||||||
holdingItemSelector.hoveredItem = item
|
|
||||||
}
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: d
|
|
||||||
// Internal management properties and signals:
|
|
||||||
readonly property var holdingTypes: onlyAssets ?
|
|
||||||
[Constants.TokenType.ERC20] :
|
|
||||||
[Constants.TokenType.ERC20, Constants.TokenType.ERC721]
|
|
||||||
|
|
||||||
readonly property var tabsModel: onlyAssets ?
|
|
||||||
[qsTr("Assets")] :
|
|
||||||
[qsTr("Assets"), qsTr("Collectibles")]
|
|
||||||
|
|
||||||
readonly property var updateSearchText: Backpressure.debounce(root, 500, function(inputText) {
|
|
||||||
root.searchText = inputText
|
|
||||||
})
|
|
||||||
|
|
||||||
function isAsset(type) {
|
|
||||||
return type === Constants.TokenType.ERC20
|
|
||||||
}
|
|
||||||
|
|
||||||
function isCommunityItem(type) {
|
|
||||||
return type === Constants.CollectiblesNestedItemType.CommunityCollectible ||
|
|
||||||
type === Constants.CollectiblesNestedItemType.Community
|
|
||||||
}
|
|
||||||
|
|
||||||
function isGroupItem(type) {
|
|
||||||
return type === Constants.CollectiblesNestedItemType.Collection ||
|
|
||||||
type === Constants.CollectiblesNestedItemType.Community
|
|
||||||
}
|
|
||||||
|
|
||||||
property int browsingHoldingType: Constants.TokenType.ERC20
|
|
||||||
readonly property bool isCurrentBrowsingTypeAsset: isAsset(browsingHoldingType)
|
|
||||||
readonly property bool isBrowsingGroup: !isCurrentBrowsingTypeAsset && !!root.collectiblesModel && root.collectiblesModel.currentGroupId !== ""
|
|
||||||
property string currentBrowsingGroupName
|
|
||||||
|
|
||||||
property var currentHoldingType: Constants.TokenType.Unknown
|
|
||||||
|
|
||||||
readonly property string uppercaseSearchText: searchText.toUpperCase()
|
|
||||||
|
|
||||||
property var assetTextFn: function (asset) {
|
|
||||||
return !!asset && asset.symbol ? asset.symbol : ""
|
|
||||||
}
|
|
||||||
|
|
||||||
property var assetIconSourceFn: function (asset) {
|
|
||||||
if (!asset) {
|
|
||||||
return ""
|
|
||||||
} else if (asset.image) {
|
|
||||||
// Community assets have a dedicated image streamed from status-go
|
|
||||||
return asset.image
|
|
||||||
}
|
|
||||||
return Constants.tokenIcon(asset.symbol)
|
|
||||||
}
|
|
||||||
|
|
||||||
property var collectibleTextFn: function (item) {
|
|
||||||
if (!!item) {
|
|
||||||
return !!item.groupName ? item.groupName + ": " + item.name : item.name
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
property var collectibleIconSourceFn: function (item) {
|
|
||||||
return !!item && item.iconUrl ? item.iconUrl : ""
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property RolesRenamingModel renamedAllNetworksModel: RolesRenamingModel {
|
|
||||||
sourceModel: root.networksModel
|
|
||||||
mapping: RoleRename {
|
|
||||||
from: "iconUrl"
|
|
||||||
to: "networkIconUrl"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property LeftJoinModel collectibleNetworksJointModel: LeftJoinModel {
|
|
||||||
leftModel: root.collectiblesModel
|
|
||||||
rightModel: d.renamedAllNetworksModel
|
|
||||||
joinRole: "chainId"
|
|
||||||
}
|
|
||||||
|
|
||||||
property var collectibleComboBoxModel: SortFilterProxyModel {
|
|
||||||
sourceModel: d.collectibleNetworksJointModel
|
|
||||||
proxyRoles: [
|
|
||||||
FastExpressionRole {
|
|
||||||
name: "isCommunityAsset"
|
|
||||||
expression: d.isCommunityItem(model.itemType)
|
|
||||||
expectedRoles: ["itemType"]
|
|
||||||
},
|
|
||||||
FastExpressionRole {
|
|
||||||
name: "isGroup"
|
|
||||||
expression: d.isGroupItem(model.itemType)
|
|
||||||
expectedRoles: ["itemType"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
filters: [
|
|
||||||
ExpressionFilter {
|
|
||||||
expression: {
|
|
||||||
return d.uppercaseSearchText === "" || name.toUpperCase().startsWith(d.uppercaseSearchText)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
sorters: [
|
|
||||||
RoleSorter {
|
|
||||||
roleName: "isCommunityAsset"
|
|
||||||
sortOrder: Qt.DescendingOrder
|
|
||||||
},
|
|
||||||
RoleSorter {
|
|
||||||
roleName: "isGroup"
|
|
||||||
sortOrder: Qt.DescendingOrder
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// By design values:
|
|
||||||
readonly property int padding: 16
|
|
||||||
readonly property int headerTopMargin: 5
|
|
||||||
readonly property int tabBarTopMargin: 20
|
|
||||||
readonly property int tabBarHeight: 35
|
|
||||||
readonly property int bottomInset: 20
|
|
||||||
readonly property int assetContentIconSize: 21
|
|
||||||
readonly property int collectibleContentIconSize: 28
|
|
||||||
readonly property int assetContentTextSize: 28
|
|
||||||
readonly property int collectibleContentTextSize: 15
|
|
||||||
}
|
|
||||||
|
|
||||||
HoldingItemSelector {
|
|
||||||
id: holdingItemSelector
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
defaultIconSource: Style.png("tokens/DEFAULT-TOKEN@3x")
|
|
||||||
placeholderText: d.isCurrentBrowsingTypeAsset ? qsTr("Select asset") : qsTr("Select collectible")
|
|
||||||
property bool hasCommunityTokens: false
|
|
||||||
|
|
||||||
comboBoxDelegate: Item {
|
|
||||||
property var itemModel: model // read 'model' from the delegate's context
|
|
||||||
width: loader.width
|
|
||||||
height: loader.height
|
|
||||||
Loader {
|
|
||||||
id: loader
|
|
||||||
|
|
||||||
// inject model properties to the loaded item's context
|
|
||||||
// common
|
|
||||||
property var model: itemModel
|
|
||||||
property var chainId: model.chainId
|
|
||||||
property var name: model.name
|
|
||||||
property var tokenType: model.tokenType
|
|
||||||
// asset
|
|
||||||
property var symbol: model.symbol
|
|
||||||
property var totalBalance: model.totalBalance
|
|
||||||
property var marketDetails: model.marketDetails
|
|
||||||
property var decimals: model.decimals
|
|
||||||
property var balances: model.balancesModel
|
|
||||||
// collectible
|
|
||||||
property var uid: model.uid
|
|
||||||
property var iconUrl: model.iconUrl
|
|
||||||
property var networkIconUrl: model.networkIconUrl
|
|
||||||
property var groupId: model.groupId
|
|
||||||
property var groupName: model.groupName
|
|
||||||
property var isGroup: model.isGroup
|
|
||||||
property var count: model.count
|
|
||||||
|
|
||||||
sourceComponent: d.isCurrentBrowsingTypeAsset ? assetComboBoxDelegate : collectibleComboBoxDelegate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
comboBoxModel: d.isCurrentBrowsingTypeAsset
|
|
||||||
? root.assetsModel
|
|
||||||
: d.collectibleComboBoxModel
|
|
||||||
comboBoxPopupHeader: headerComponent
|
|
||||||
itemTextFn: d.isCurrentBrowsingTypeAsset ? d.assetTextFn : d.collectibleTextFn
|
|
||||||
itemIconSourceFn: d.isCurrentBrowsingTypeAsset ? d.assetIconSourceFn : d.collectibleIconSourceFn
|
|
||||||
onComboBoxModelChanged: updateHasCommunityTokens()
|
|
||||||
|
|
||||||
function updateHasCommunityTokens() {
|
|
||||||
hasCommunityTokens = Helpers.modelHasCommunityTokens(comboBoxModel, d.isCurrentBrowsingTypeAsset)
|
|
||||||
}
|
|
||||||
|
|
||||||
contentIconSize: d.isAsset(d.currentHoldingType) ? d.assetContentIconSize : d.collectibleContentIconSize
|
|
||||||
contentTextSize: d.isAsset(d.currentHoldingType) ? d.assetContentTextSize : d.collectibleContentTextSize
|
|
||||||
comboBoxListViewSection.property: "isCommunityAsset"
|
|
||||||
// TODO allow for different header/sections for the Swap modal
|
|
||||||
comboBoxListViewSection.delegate: AssetsSectionDelegate {
|
|
||||||
height: !!text ? 52 : 0 // if we bind to some property instead of hardcoded value it wont work nice when switching tabs or going inside collection and back
|
|
||||||
width: ListView.view.width
|
|
||||||
required property bool section
|
|
||||||
text: Helpers.assetsSectionTitle(section, holdingItemSelector.hasCommunityTokens, d.isBrowsingGroup, d.isCurrentBrowsingTypeAsset)
|
|
||||||
onInfoButtonClicked: Global.openPopup(communityInfoPopupCmp)
|
|
||||||
}
|
|
||||||
comboBoxControl.popup.onOpened: comboBoxControl.popup.contentItem.headerItem.focusSearch()
|
|
||||||
comboBoxControl.popup.onClosed: comboBoxControl.popup.contentItem.headerItem.clear()
|
|
||||||
|
|
||||||
comboBoxControl.popup.x: root.width - comboBoxControl.popup.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: communityInfoPopupCmp
|
|
||||||
CommunityAssetsInfoPopup {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: headerComponent
|
|
||||||
ColumnLayout {
|
|
||||||
function focusSearch() {
|
|
||||||
searchInput.input.forceActiveFocus()
|
|
||||||
}
|
|
||||||
|
|
||||||
function clear() {
|
|
||||||
searchInput.input.edit.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
width: holdingItemSelector.comboBoxControl.popup.width
|
|
||||||
Layout.topMargin: d.headerTopMargin
|
|
||||||
spacing: -1 // Used to overlap rectangles from row components
|
|
||||||
|
|
||||||
StatusTabBar {
|
|
||||||
id: tabBar
|
|
||||||
|
|
||||||
visible: !root.onlyAssets
|
|
||||||
Layout.preferredHeight: d.tabBarHeight
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: d.padding
|
|
||||||
Layout.rightMargin: d.padding
|
|
||||||
Layout.topMargin: d.tabBarTopMargin
|
|
||||||
Layout.bottomMargin: 6
|
|
||||||
currentIndex: d.holdingTypes.indexOf(d.browsingHoldingType)
|
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
|
||||||
if (currentIndex >= 0) {
|
|
||||||
d.browsingHoldingType = d.holdingTypes[currentIndex]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
id: tabLabelsRepeater
|
|
||||||
model: d.tabsModel
|
|
||||||
|
|
||||||
StatusTabButton {
|
|
||||||
text: modelData
|
|
||||||
width: implicitWidth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CollectibleBackButtonWithInfo {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: d.isBrowsingGroup
|
|
||||||
count: collectiblesModel ? collectiblesModel.count : 0
|
|
||||||
name: d.currentBrowsingGroupName
|
|
||||||
onBackClicked: {
|
|
||||||
if (!d.isCurrentBrowsingTypeAsset) {
|
|
||||||
searchInput.reset()
|
|
||||||
root.collectiblesModel.currentGroupId = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: searchInput.input.implicitHeight
|
|
||||||
|
|
||||||
color: "transparent"
|
|
||||||
border.color: Theme.palette.baseColor2
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
StatusInput {
|
|
||||||
id: searchInput
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
input.showBackground: false
|
|
||||||
placeholderText: root.searchPlaceholderText
|
|
||||||
onTextChanged: Qt.callLater(d.updateSearchText, text)
|
|
||||||
input.clearable: true
|
|
||||||
input.implicitHeight: 56
|
|
||||||
input.rightComponent: StatusFlatRoundButton {
|
|
||||||
icon.name: "search"
|
|
||||||
type: StatusFlatRoundButton.Type.Secondary
|
|
||||||
enabled: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: assetComboBoxDelegate
|
|
||||||
TokenBalancePerChainDelegate {
|
|
||||||
objectName: "AssetSelector_ItemDelegate_" + symbol
|
|
||||||
width: holdingItemSelector.comboBoxControl.popup.width
|
|
||||||
highlighted: !!holdingItemSelector.selectedItem && symbol === holdingItemSelector.selectedItem.symbol
|
|
||||||
balancesModel: LeftJoinModel {
|
|
||||||
leftModel: balances
|
|
||||||
rightModel: root.networksModel
|
|
||||||
joinRole: "chainId"
|
|
||||||
}
|
|
||||||
onTokenSelected: function (selectedToken) {
|
|
||||||
holdingItemSelector.selectedItem = selectedToken
|
|
||||||
d.currentHoldingType = Constants.TokenType.ERC20
|
|
||||||
root.itemSelected(selectedToken.symbol, Constants.TokenType.ERC20)
|
|
||||||
holdingItemSelector.comboBoxControl.popup.close()
|
|
||||||
}
|
|
||||||
formatCurrentCurrencyAmount: function(balance){
|
|
||||||
return root.formatCurrentCurrencyAmount(balance)
|
|
||||||
}
|
|
||||||
formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){
|
|
||||||
return root.formatCurrencyAmountFromBigInt(balance, symbol, decimals)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: collectibleComboBoxDelegate
|
|
||||||
CollectibleNestedDelegate {
|
|
||||||
objectName: "CollectibleSelector_ItemDelegate_" + groupId
|
|
||||||
width: holdingItemSelector.comboBoxControl.popup.width
|
|
||||||
highlighted: !!holdingItemSelector.selectedItem && uid === holdingItemSelector.selectedItem.uid
|
|
||||||
onItemSelected: {
|
|
||||||
if (isGroup) {
|
|
||||||
d.currentBrowsingGroupName = groupName
|
|
||||||
root.collectiblesModel.currentGroupId = groupId
|
|
||||||
} else {
|
|
||||||
holdingItemSelector.selectedItem = selectedItem
|
|
||||||
d.currentHoldingType = tokenType
|
|
||||||
root.itemSelected(selectedItem.uid, tokenType)
|
|
||||||
holdingItemSelector.comboBoxControl.popup.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,7 +17,6 @@ import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||||
|
|
||||||
import "../panels"
|
|
||||||
import "../controls"
|
import "../controls"
|
||||||
import "../views"
|
import "../views"
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1 @@
|
||||||
HoldingItemSelector 1.0 HoldingItemSelector.qml
|
|
||||||
HoldingSelector 1.0 HoldingSelector.qml
|
|
||||||
RecipientSelectorPanel 1.0 RecipientSelectorPanel.qml
|
RecipientSelectorPanel 1.0 RecipientSelectorPanel.qml
|
||||||
|
|
|
@ -1,297 +0,0 @@
|
||||||
import QtQml 2.15
|
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
|
||||||
|
|
||||||
import StatusQ 0.1
|
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
import StatusQ.Components 0.1
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
import shared.controls 1.0
|
|
||||||
import shared.popups 1.0
|
|
||||||
import shared.popups.send 1.0
|
|
||||||
import "../controls"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property var assets: null
|
|
||||||
property var collectibles: null
|
|
||||||
property var networksModel
|
|
||||||
property string assetSearchString
|
|
||||||
|
|
||||||
signal tokenSelected(string symbol, var holdingType)
|
|
||||||
signal tokenHovered(string symbol, var holdingType, bool hovered)
|
|
||||||
|
|
||||||
property bool onlyAssets: false
|
|
||||||
property int browsingHoldingType: Constants.TokenType.ERC20
|
|
||||||
property var formatCurrentCurrencyAmount: function(balance){}
|
|
||||||
property var formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){}
|
|
||||||
|
|
||||||
onVisibleChanged: {
|
|
||||||
if(!visible) {
|
|
||||||
if (!!root.collectibles)
|
|
||||||
root.collectibles.currentGroupId = ""
|
|
||||||
// Send Modal doesn't open with a valid headerItem
|
|
||||||
if (!!tokenList.headerItem && !!tokenList.headerItem.input)
|
|
||||||
tokenList.headerItem.input.edit.clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: d
|
|
||||||
readonly property var updateAssetSearchText: Backpressure.debounce(root, 1000, function(inputText) {
|
|
||||||
assetSearchString = inputText
|
|
||||||
})
|
|
||||||
|
|
||||||
property string collectibleSearchString
|
|
||||||
readonly property var updateCollectibleSearchText: Backpressure.debounce(root, 1000, function(inputText) {
|
|
||||||
d.collectibleSearchString = inputText
|
|
||||||
})
|
|
||||||
|
|
||||||
// Internal management properties and signals:
|
|
||||||
readonly property var holdingTypes: onlyAssets ?
|
|
||||||
[Constants.TokenType.ERC20] :
|
|
||||||
[Constants.TokenType.ERC20, Constants.TokenType.ERC721]
|
|
||||||
|
|
||||||
readonly property var tabsModel: onlyAssets ?
|
|
||||||
[qsTr("Assets")] :
|
|
||||||
[qsTr("Assets"), qsTr("Collectibles")]
|
|
||||||
|
|
||||||
property string currentBrowsingGroupName
|
|
||||||
|
|
||||||
readonly property RolesRenamingModel renamedAllNetworksModel: RolesRenamingModel {
|
|
||||||
sourceModel: root.networksModel
|
|
||||||
mapping: RoleRename {
|
|
||||||
from: "iconUrl"
|
|
||||||
to: "networkIconUrl"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property LeftJoinModel collectiblesNetworksJointModel: LeftJoinModel {
|
|
||||||
leftModel: root.collectibles
|
|
||||||
rightModel: d.renamedAllNetworksModel
|
|
||||||
joinRole: "chainId"
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property bool isBrowsingTypeERC20: root.browsingHoldingType === Constants.TokenType.ERC20
|
|
||||||
readonly property bool isBrowsingGroup: !isBrowsingTypeERC20 && !!root.collectibles && root.collectibles.currentGroupId !== ""
|
|
||||||
|
|
||||||
function isCommunityItem(type) {
|
|
||||||
return type === Constants.CollectiblesNestedItemType.CommunityCollectible ||
|
|
||||||
type === Constants.CollectiblesNestedItemType.Community
|
|
||||||
}
|
|
||||||
|
|
||||||
function isGroupItem(type) {
|
|
||||||
return type === Constants.CollectiblesNestedItemType.Collection ||
|
|
||||||
type === Constants.CollectiblesNestedItemType.Community
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusBaseText {
|
|
||||||
id: label
|
|
||||||
anchors.top: parent.top
|
|
||||||
elide: Text.ElideRight
|
|
||||||
text: qsTr("Token to send")
|
|
||||||
font.pixelSize: 13
|
|
||||||
color: Theme.palette.directColor1
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.top: label.bottom
|
|
||||||
anchors.topMargin: 8
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
color: Theme.palette.indirectColor1
|
|
||||||
radius: 8
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: column
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.topMargin: root.onlyAssets ? 0 : 20
|
|
||||||
|
|
||||||
StatusTabBar {
|
|
||||||
visible: !root.onlyAssets
|
|
||||||
Layout.preferredHeight: 40
|
|
||||||
Layout.fillWidth: true
|
|
||||||
currentIndex: d.holdingTypes.indexOf(root.browsingHoldingType)
|
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
|
||||||
if (currentIndex >= 0) {
|
|
||||||
root.browsingHoldingType = d.holdingTypes[currentIndex]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
id: tabLabelsRepeater
|
|
||||||
model: d.tabsModel
|
|
||||||
|
|
||||||
StatusTabButton {
|
|
||||||
text: modelData
|
|
||||||
width: implicitWidth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusListView {
|
|
||||||
id: tokenList
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
// Control order of components not to mix models and delegates
|
|
||||||
function resetComponents() {
|
|
||||||
tokenList.model = []
|
|
||||||
tokenList.delegate = d.isBrowsingTypeERC20 ? tokenDelegate : collectiblesDelegate
|
|
||||||
tokenList.header = d.isBrowsingTypeERC20 ? tokenHeader : collectibleHeader
|
|
||||||
tokenList.model = d.isBrowsingTypeERC20 ? root.assets : root.collectiblesModel
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: resetComponents()
|
|
||||||
Connections {
|
|
||||||
target: d
|
|
||||||
function onIsBrowsingTypeERC20Changed() {
|
|
||||||
tokenList.resetComponents()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
property bool hasCommunityTokens: false
|
|
||||||
function updateHasCommunityTokens() {
|
|
||||||
hasCommunityTokens = Helpers.modelHasCommunityTokens(model, d.isBrowsingTypeERC20)
|
|
||||||
}
|
|
||||||
|
|
||||||
onModelChanged: updateHasCommunityTokens()
|
|
||||||
section {
|
|
||||||
property: "isCommunityAsset"
|
|
||||||
delegate: AssetsSectionDelegate {
|
|
||||||
required property bool section
|
|
||||||
width: parent.width
|
|
||||||
height: !!text ? 52 : 0 // if we bind to some property instead of hardcoded value it wont work nice when switching tabs or going inside collection and back
|
|
||||||
text: Helpers.assetsSectionTitle(section, tokenList.hasCommunityTokens, d.isBrowsingGroup, d.isBrowsingTypeERC20)
|
|
||||||
onInfoButtonClicked: Global.openPopup(communityInfoPopupCmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
property var collectiblesModel: SortFilterProxyModel {
|
|
||||||
sourceModel: d.collectiblesNetworksJointModel
|
|
||||||
proxyRoles: [
|
|
||||||
FastExpressionRole {
|
|
||||||
name: "isCommunityAsset"
|
|
||||||
expression: d.isCommunityItem(model.itemType)
|
|
||||||
expectedRoles: ["itemType"]
|
|
||||||
},
|
|
||||||
FastExpressionRole {
|
|
||||||
name: "isGroup"
|
|
||||||
expression: d.isGroupItem(model.itemType)
|
|
||||||
expectedRoles: ["itemType"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
filters: [
|
|
||||||
ExpressionFilter {
|
|
||||||
expression: {
|
|
||||||
return d.collectibleSearchString === "" || name.toUpperCase().startsWith(d.collectibleSearchString.toUpperCase())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
sorters: [
|
|
||||||
RoleSorter {
|
|
||||||
roleName: "isCommunityAsset"
|
|
||||||
sortOrder: Qt.DescendingOrder
|
|
||||||
},
|
|
||||||
RoleSorter {
|
|
||||||
roleName: "isGroup"
|
|
||||||
sortOrder: Qt.DescendingOrder
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: tokenDelegate
|
|
||||||
TokenBalancePerChainDelegate {
|
|
||||||
width: tokenList.width
|
|
||||||
tagsScrollBarVisible: true
|
|
||||||
|
|
||||||
balancesModel: LeftJoinModel {
|
|
||||||
leftModel: !!model & !!model.balancesModel ? model.balancesModel : null
|
|
||||||
rightModel: root.networksModel
|
|
||||||
joinRole: "chainId"
|
|
||||||
}
|
|
||||||
onTokenSelected: function (selectedToken) {
|
|
||||||
root.tokenSelected(selectedToken.symbol, Constants.TokenType.ERC20)
|
|
||||||
}
|
|
||||||
onTokenHovered: root.tokenHovered(selectedToken.symbol, Constants.TokenType.ERC20, hovered)
|
|
||||||
formatCurrentCurrencyAmount: function(balance){
|
|
||||||
return root.formatCurrentCurrencyAmount(balance)
|
|
||||||
}
|
|
||||||
formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){
|
|
||||||
return root.formatCurrencyAmountFromBigInt(balance, symbol, decimals)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component {
|
|
||||||
id: tokenHeader
|
|
||||||
SearchBoxWithRightIcon {
|
|
||||||
showTopBorder: !root.onlyAssets
|
|
||||||
showBottomBorder: false
|
|
||||||
width: tokenList.width
|
|
||||||
placeholderText: qsTr("Search for token or enter token address")
|
|
||||||
onTextChanged: Qt.callLater(d.updateAssetSearchText, text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component {
|
|
||||||
id: collectiblesDelegate
|
|
||||||
CollectibleNestedDelegate {
|
|
||||||
width: tokenList.width
|
|
||||||
onItemHovered: root.tokenHovered(selectedItem.uid, Constants.TokenType.ERC721, hovered)
|
|
||||||
onItemSelected: {
|
|
||||||
if (isGroup) {
|
|
||||||
d.currentBrowsingGroupName = groupName
|
|
||||||
root.collectibles.currentGroupId = groupId
|
|
||||||
} else {
|
|
||||||
root.tokenSelected(selectedItem.uid, Constants.TokenType.ERC721)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component {
|
|
||||||
id: collectibleHeader
|
|
||||||
ColumnLayout {
|
|
||||||
width: tokenList.width
|
|
||||||
spacing: 0
|
|
||||||
CollectibleBackButtonWithInfo {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: d.isBrowsingGroup
|
|
||||||
count: root.collectibles.count
|
|
||||||
name: d.currentBrowsingGroupName
|
|
||||||
onBackClicked: {
|
|
||||||
searchBox.reset()
|
|
||||||
root.collectibles.currentGroupId = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SearchBoxWithRightIcon {
|
|
||||||
id: searchBox
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
showTopBorder: true
|
|
||||||
showBottomBorder: false
|
|
||||||
placeholderText: qsTr("Search collectibles")
|
|
||||||
onTextChanged: Qt.callLater(d.updateCollectibleSearchText, text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: communityInfoPopupCmp
|
|
||||||
CommunityAssetsInfoPopup {}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,9 +2,9 @@ AmountToReceive 1.0 AmountToReceive.qml
|
||||||
AmountToSend 1.0 AmountToSend.qml
|
AmountToSend 1.0 AmountToSend.qml
|
||||||
FeesView 1.0 FeesView.qml
|
FeesView 1.0 FeesView.qml
|
||||||
NetworkCardsComponent 1.0 NetworkCardsComponent.qml
|
NetworkCardsComponent 1.0 NetworkCardsComponent.qml
|
||||||
NetworksAdvancedCustomRoutingView 1.0 NetworksAdvancedCustomRoutingView.qml
|
|
||||||
NetworkSelector 1.0 NetworkSelector.qml
|
NetworkSelector 1.0 NetworkSelector.qml
|
||||||
|
NetworksAdvancedCustomRoutingView 1.0 NetworksAdvancedCustomRoutingView.qml
|
||||||
NetworksSimpleRoutingView 1.0 NetworksSimpleRoutingView.qml
|
NetworksSimpleRoutingView 1.0 NetworksSimpleRoutingView.qml
|
||||||
RecipientView 1.0 RecipientView.qml
|
RecipientView 1.0 RecipientView.qml
|
||||||
|
TabAddressSelectorView 1.0 TabAddressSelectorView.qml
|
||||||
TransactionModalFooter 1.0 TransactionModalFooter.qml
|
TransactionModalFooter 1.0 TransactionModalFooter.qml
|
||||||
TokenListView 1.0 TokenListView.qml
|
|
||||||
|
|
|
@ -104,50 +104,6 @@ QtObject {
|
||||||
return ModelUtils.get(collectiblesModel, idx)
|
return ModelUtils.get(collectiblesModel, idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelectorCollectible(uid) {
|
|
||||||
const idx = ModelUtils.indexOf(nestedCollectiblesModel, "uid", uid)
|
|
||||||
if (idx < 0) {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
return ModelUtils.get(nestedCollectiblesModel, idx)
|
|
||||||
}
|
|
||||||
|
|
||||||
function assetToSelectorAsset(asset) {
|
|
||||||
return asset
|
|
||||||
}
|
|
||||||
|
|
||||||
function collectibleToSelectorCollectible(collectible) {
|
|
||||||
var groupId = collectible.collectionUid
|
|
||||||
var groupName = collectible.collectionName
|
|
||||||
var itemType = Constants.CollectiblesNestedItemType.Collectible
|
|
||||||
if (collectible.communityId !== "") {
|
|
||||||
groupId = collectible.communityId
|
|
||||||
groupName = collectible.communityName
|
|
||||||
itemType = Constants.CollectiblesNestedItemType.CommunityCollectible
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
uid: collectible.uid,
|
|
||||||
chainId: collectible.chainId,
|
|
||||||
name: collectible.name,
|
|
||||||
iconUrl: collectible.imageUrl,
|
|
||||||
groupId: groupId,
|
|
||||||
groupName: groupName,
|
|
||||||
tokenType: collectible.tokenType,
|
|
||||||
itemType: itemType,
|
|
||||||
count: 1 // TODO: Properly handle count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function holdingToSelectorHolding(holding, holdingType) {
|
|
||||||
if (holdingType === Constants.TokenType.ERC20) {
|
|
||||||
return assetToSelectorAsset(holding)
|
|
||||||
} else if (holdingType === Constants.TokenType.ERC721 || holdingType === Constants.TokenType.ERC1155) {
|
|
||||||
return collectibleToSelectorCollectible(holding)
|
|
||||||
} else {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSenderAccount(address) {
|
function setSenderAccount(address) {
|
||||||
walletSectionSendInst.setSenderAccount(address)
|
walletSectionSendInst.setSenderAccount(address)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue