fix(SendModal): fix various issues with SendModal

- Fix errors when switching between assets and collectibles tabs
  - Fix by controlling the order of instantiation between model and
    delegates not to mix models and delegates from different sources
- Fix size errors
- Various improvements

Updates: #14212
This commit is contained in:
Stefan 2024-03-28 19:47:49 +02:00 committed by Stefan Dunca
parent 3750b9933e
commit ee23cce575
8 changed files with 76 additions and 22 deletions

View File

@ -62,6 +62,7 @@ QtObject {
return 0 return 0
} }
console.assert(typeof num !== "undefined", "passed number should not be undefined")
return num.toString().split('.')[1].length return num.toString().split('.')[1].length
} }

View File

@ -328,7 +328,8 @@ StatusDialog {
maxInputBalance: d.maxInputBalance maxInputBalance: d.maxInputBalance
currentCurrency: d.currencyStore.currentCurrency currentCurrency: d.currencyStore.currentCurrency
multiplierIndex: d.isSelectedHoldingValidAsset // Collectibles do not have decimals
multiplierIndex: d.isSelectedHoldingValidAsset && !!holdingSelector.selectedItem && !!holdingSelector.selectedItem.decimals
? holdingSelector.selectedItem.decimals ? holdingSelector.selectedItem.decimals
: 0 : 0
@ -402,8 +403,8 @@ StatusDialog {
collectibles: popup.preSelectedAccount ? popup.nestedCollectiblesModel : null collectibles: popup.preSelectedAccount ? popup.nestedCollectiblesModel : null
networksModel: popup.store.flatNetworksModel networksModel: popup.store.flatNetworksModel
onlyAssets: holdingSelector.onlyAssets onlyAssets: holdingSelector.onlyAssets
onTokenSelected: { onTokenSelected: function (symbolOrTokenKey, holdingType) {
d.setSelectedHoldingId(symbol, holdingType) d.setSelectedHoldingId(symbolOrTokenKey, holdingType)
} }
onTokenHovered: { onTokenHovered: {
if(hovered) { if(hovered) {
@ -502,7 +503,15 @@ StatusDialog {
if (!!d.selectedHolding && !!d.selectedHolding.marketDetails && !!d.selectedHolding.marketDetails.currencyPrice) if (!!d.selectedHolding && !!d.selectedHolding.marketDetails && !!d.selectedHolding.marketDetails.currencyPrice)
totalTokenFeesInFiat = gasTimeEstimate.totalTokenFees * d.selectedHolding.marketDetails.currencyPrice.amount totalTokenFeesInFiat = gasTimeEstimate.totalTokenFees * d.selectedHolding.marketDetails.currencyPrice.amount
d.totalFeesInFiat = d.currencyStore.getFiatValue(gasTimeEstimate.totalFeesInEth, Constants.ethToken) + totalTokenFeesInFiat d.totalFeesInFiat = d.currencyStore.getFiatValue(gasTimeEstimate.totalFeesInEth, Constants.ethToken) + totalTokenFeesInFiat
if (!!d.selectedHolding.type && (d.selectedHolding.type === Constants.TokenType.ERC20
|| d.selectedHolding.type === Constants.TokenType.ETH)) {
// If assets
d.totalAmountToReceive = popup.store.getWei2Eth(txRoutes.amountToReceive, d.selectedHolding.decimals) d.totalAmountToReceive = popup.store.getWei2Eth(txRoutes.amountToReceive, d.selectedHolding.decimals)
} else {
// If collectible
d.totalAmountToReceive = txRoutes.amountToReceive
}
networkSelector.toNetworksList = txRoutes.toNetworksModel networkSelector.toNetworksList = txRoutes.toNetworksModel
popup.isLoading = false popup.isLoading = false
} }

View File

@ -12,6 +12,12 @@ import utils 1.0
StatusListItem { StatusListItem {
id: root id: root
required property var model
required property string name
required property string symbol
required property int decimals
required property var balances
signal tokenSelected(var selectedToken) signal tokenSelected(var selectedToken)
signal tokenHovered(var selectedToken, bool hovered) signal tokenHovered(var selectedToken, bool hovered)
property var formatCurrentCurrencyAmount: function(balance){} property var formatCurrentCurrencyAmount: function(balance){}

View File

@ -56,13 +56,13 @@ StatusListItem {
width: !!icon ? 15: 0 width: !!icon ? 15: 0
height: !!icon ? 15 : 0 height: !!icon ? 15 : 0
color: Theme.palette.directColor1 color: Theme.palette.directColor1
icon: modelData.walletType === Constants.watchWalletType ? "show" : "" icon: !!modelData && modelData.walletType === Constants.watchWalletType ? "show" : ""
} }
StatusIcon { StatusIcon {
width: !!icon ? 15: 0 width: !!icon ? 15: 0
height: !!icon ? 15 : 0 height: !!icon ? 15 : 0
color: Theme.palette.directColor1 color: Theme.palette.directColor1
icon: modelData.migratedToKeycard ? "keycard" : "" icon: !!modelData && modelData.migratedToKeycard ? "keycard" : ""
} }
} }
}, },

View File

@ -226,15 +226,29 @@ Item {
property var groupName: model.groupName property var groupName: model.groupName
property var isGroup: model.isGroup property var isGroup: model.isGroup
property var count: model.count property var count: model.count
}
}
// Switch models and delegate in the right order not to mix different models and delegates
function updateComponents() {
holdingItemSelector.comboBoxModel = []
sourceComponent: d.isCurrentBrowsingTypeAsset ? assetComboBoxDelegate : collectibleComboBoxDelegate sourceComponent: d.isCurrentBrowsingTypeAsset ? assetComboBoxDelegate : collectibleComboBoxDelegate
holdingItemSelector.comboBoxModel = d.isCurrentBrowsingTypeAsset
? root.assetsModel
: d.collectibleComboBoxModel
}
Component.onCompleted: updateComponents()
Connections {
target: d
function onIsCurrentBrowsingTypeAssetChanged() {
holdingItemSelector.updateComponents()
} }
} }
comboBoxModel: null
comboBoxPopupHeader: headerComponent comboBoxPopupHeader: headerComponent
itemTextFn: d.isCurrentBrowsingTypeAsset ? d.assetTextFn : d.collectibleTextFn itemTextFn: d.isCurrentBrowsingTypeAsset ? d.assetTextFn : d.collectibleTextFn
itemIconSourceFn: d.isCurrentBrowsingTypeAsset ? d.assetIconSourceFn : d.collectibleIconSourceFn itemIconSourceFn: d.isCurrentBrowsingTypeAsset ? d.assetIconSourceFn : d.collectibleIconSourceFn
comboBoxModel: d.isCurrentBrowsingTypeAsset ? root.assetsModel : d.collectibleComboBoxModel
onComboBoxModelChanged: updateHasCommunityTokens() onComboBoxModelChanged: updateHasCommunityTokens()
function updateHasCommunityTokens() { function updateHasCommunityTokens() {
@ -348,7 +362,7 @@ Item {
rightModel: root.networksModel rightModel: root.networksModel
joinRole: "chainId" joinRole: "chainId"
} }
onTokenSelected: { onTokenSelected: function (selectedToken) {
holdingItemSelector.selectedItem = selectedToken holdingItemSelector.selectedItem = selectedToken
d.currentHoldingType = Constants.TokenType.ERC20 d.currentHoldingType = Constants.TokenType.ERC20
root.itemSelected(selectedToken.symbol, Constants.TokenType.ERC20) root.itemSelected(selectedToken.symbol, Constants.TokenType.ERC20)

View File

@ -33,7 +33,8 @@ Item {
QtObject { QtObject {
id: d id: d
property double customAmountToSend: 0 property double customAmountToSend: 0
readonly property string selectedSymbol: !!selectedAsset ? selectedAsset.symbol : "" // Collectibles don't have a symbol
readonly property string selectedSymbol: !!selectedAsset && !!selectedAsset.symbol ? selectedAsset.symbol : ""
function resetAllSetValues() { function resetAllSetValues() {
for(var i = 0; i<fromNetworksRepeater.count; i++) { for(var i = 0; i<fromNetworksRepeater.count; i++) {

View File

@ -88,7 +88,8 @@ Item {
errorMode: root.errorMode errorMode: root.errorMode
errorType: root.errorType errorType: root.errorType
toNetworksList: root.toNetworksList toNetworksList: root.toNetworksList
selectedSymbol: !!root.selectedAsset ? root.selectedAsset.symbol: "" // Collectibles don't have a symbol
selectedSymbol: !!root.selectedAsset && !!root.selectedAsset.symbol ? root.selectedAsset.symbol: ""
weiToEth: function(wei) { weiToEth: function(wei) {
if(!!selectedAsset && root.selectedAsset !== undefined) if(!!selectedAsset && root.selectedAsset !== undefined)
return parseFloat(store.getWei2Eth(wei, root.selectedAsset.decimals)) return parseFloat(store.getWei2Eth(wei, root.selectedAsset.decimals))
@ -124,9 +125,14 @@ Item {
isBridgeTx: root.isBridgeTx isBridgeTx: root.isBridgeTx
errorType: root.errorType errorType: root.errorType
weiToEth: function(wei) { weiToEth: function(wei) {
if(!!selectedAsset && selectedAsset !== undefined) if(!!selectedAsset && !!selectedAsset.type
&& (selectedAsset.type === Constants.TokenType.Native
|| selectedAsset.type === Constants.TokenType.ERC20)
) {
return parseFloat(store.getWei2Eth(wei, selectedAsset.decimals)) return parseFloat(store.getWei2Eth(wei, selectedAsset.decimals))
} }
return 0
}
} }
} }
} }

View File

@ -38,6 +38,8 @@ Item {
if(!visible) { if(!visible) {
if (!!root.collectibles) if (!!root.collectibles)
root.collectibles.currentGroupId = "" root.collectibles.currentGroupId = ""
// Send Modal doesn't open with a valid headerItem
if (!!tokenList.headerItem && !!tokenList.headerItem.input)
tokenList.headerItem.input.edit.clear() tokenList.headerItem.input.edit.clear()
} }
} }
@ -145,9 +147,21 @@ Item {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
header: d.isBrowsingTypeERC20 ? tokenHeader : collectibleHeader // Control order of components not to mix models and delegates
model: d.isBrowsingTypeERC20 ? root.assets : collectiblesModel function resetComponents() {
delegate: d.isBrowsingTypeERC20 ? tokenDelegate : collectiblesDelegate 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 property bool hasCommunityTokens: false
function updateHasCommunityTokens() { function updateHasCommunityTokens() {
@ -205,14 +219,17 @@ Item {
Component { Component {
id: tokenDelegate id: tokenDelegate
TokenBalancePerChainDelegate { TokenBalancePerChainDelegate {
width: ListView.view.width width: tokenList.width
selectedSenderAccount: root.selectedSenderAccount selectedSenderAccount: root.selectedSenderAccount
balancesModel: LeftJoinModel { balancesModel: LeftJoinModel {
leftModel: !!model & !!model.balances ? model.balances : null leftModel: !!model & !!model.balances ? model.balances : null
rightModel: root.networksModel rightModel: root.networksModel
joinRole: "chainId" joinRole: "chainId"
} }
onTokenSelected: root.tokenSelected(symbol, Constants.TokenType.ERC20) onTokenSelected: function (selectedToken) {
root.tokenSelected(selectedToken.symbol, Constants.TokenType.ERC20)
}
onTokenHovered: root.tokenHovered(symbol, Constants.TokenType.ERC20, hovered) onTokenHovered: root.tokenHovered(symbol, Constants.TokenType.ERC20, hovered)
formatCurrentCurrencyAmount: function(balance){ formatCurrentCurrencyAmount: function(balance){
return root.formatCurrentCurrencyAmount(balance) return root.formatCurrentCurrencyAmount(balance)
@ -227,7 +244,7 @@ Item {
SearchBoxWithRightIcon { SearchBoxWithRightIcon {
showTopBorder: !root.onlyAssets showTopBorder: !root.onlyAssets
showBottomBorder: false showBottomBorder: false
width: ListView.view.width width: tokenList.width
placeholderText: qsTr("Search for token or enter token address") placeholderText: qsTr("Search for token or enter token address")
onTextChanged: Qt.callLater(d.updateAssetSearchText, text) onTextChanged: Qt.callLater(d.updateAssetSearchText, text)
} }
@ -235,7 +252,7 @@ Item {
Component { Component {
id: collectiblesDelegate id: collectiblesDelegate
CollectibleNestedDelegate { CollectibleNestedDelegate {
width: ListView.view.width width: tokenList.width
onItemHovered: root.tokenHovered(selectedItem.uid, tokenType, hovered) onItemHovered: root.tokenHovered(selectedItem.uid, tokenType, hovered)
onItemSelected: { onItemSelected: {
if (isGroup) { if (isGroup) {
@ -250,7 +267,7 @@ Item {
Component { Component {
id: collectibleHeader id: collectibleHeader
ColumnLayout { ColumnLayout {
width: parent.width width: tokenList.width
spacing: 0 spacing: 0
CollectibleBackButtonWithInfo { CollectibleBackButtonWithInfo {
Layout.fillWidth: true Layout.fillWidth: true