refactor(Wallet/SendModal): Removed backend / store dependences from `RouterPanel` and child components

Pushed store's calls to `SendModal` from `RouterPanel` and children.
This commit is contained in:
Noelia 2024-07-16 12:41:39 +02:00
parent 347e88385f
commit 329dd0c95e
7 changed files with 298 additions and 140 deletions

View File

@ -500,6 +500,8 @@ StatusDialog {
objectName: "sendModalScroll"
readonly property string selectedSymbol: !!selectedAsset && !!selectedAsset.symbol ? selectedAsset.symbol : ""
Layout.fillWidth: true
Layout.fillHeight: true
Layout.topMargin: Style.current.bigPadding
@ -511,24 +513,55 @@ StatusDialog {
visible: recipientInputLoader.ready &&
(amountToSendInput.inputNumberValid || d.isCollectiblesTransfer)
store: popup.store
interactive: popup.interactive
selectedRecipient: popup.preSelectedRecipient
ensAddressOrEmpty: recipientInputLoader.resolvedENSAddress
amountToSend: amountToSendInput.cryptoValueToSendFloat
minSendCryptoDecimals: amountToSendInput.minSendCryptoDecimals
minReceiveCryptoDecimals: amountToSendInput.minReceiveCryptoDecimals
selectedAsset: d.selectedHolding
onReCalculateSuggestedRoute: popup.recalculateRoutesAndFees()
errorType: d.errorType
isLoading: popup.isLoading
isBridgeTx: d.isBridgeTx
isCollectiblesTransfer: d.isCollectiblesTransfer
bestRoutes: popup.bestRoutes
totalFeesInFiat: d.totalFeesInFiat
showUnPreferredChains: popup.store.showUnPreferredChains
currentCurrency: popup.store.currencyStore.currentCurrency
// Models
flatNetworksModel: popup.store.flatNetworksModel
fromNetworksList: fromNetworksRouteModel
toNetworksList: toNetworksRouteModel
weiToEth: function(wei) {
if(!!selectedAsset && (selectedAsset.type === Constants.TokenType.Native ||
selectedAsset.type === Constants.TokenType.ERC20))
return parseFloat(popup.store.getWei2Eth(wei, selectedAsset.decimals))
return 0
}
formatFiat: popup.store.currencyStore.formatCurrencyAmount
formatFiatSendMinDecimals: function(amount, applyMinDecimals) {
if(applyMinDecimals)
popup.store.currencyStore.formatCurrencyAmount(amount, selectedSymbol, {"minDecimals": amountToSendInput.minSendCryptoDecimals})
else
popup.store.currencyStore.formatCurrencyAmount(amount, selectedSymbol)
}
formatFiatReceiveMinDecimals: function(amount, applyMinDecimals) {
if(applyMinDecimals)
popup.store.currencyStore.formatCurrencyAmount(amount, selectedSymbol, {"minDecimals": amountToSendInput.minReceiveCryptoDecimals})
else
popup.store.currencyStore.formatCurrencyAmount(amount, selectedSymbol)
}
getGasEthValue: popup.store.currencyStore.getGasEthValue
getFiatValue: popup.store.currencyStore.getFiatValue
getNetworkName: popup.store.getNetworkName
onRecalculateSuggestedRoute: popup.recalculateRoutesAndFees()
onToggleShowUnPreferredChains: popup.store.toggleShowUnPreferredChains()
onToggleToDisabledChains: popup.store.toggleToDisabledChains(chainId)
onToggleFromDisabledChains: popup.store.toggleFromDisabledChains(chainId)
onLockCard: popup.store.lockCard(chainId, amount, lock)
onSetRouteDisabledChains: popup.store.setRouteDisabledChains(chainId, disabled)
}
}

View File

@ -16,11 +16,11 @@ Item {
property var selectedAsset
property string currentCurrency
property var bestRoutes
property var formatFiat: function () {}
property var getGasEthValue: function () {}
property var getFiatValue: function () {}
property var formatCurrencyAmount: function () {}
property var getNetworkName: function () {}
width: parent.width
@ -28,6 +28,7 @@ Item {
Column {
id: advancedGasSelector
width: parent.width
anchors.top: parent.top
anchors.topMargin: Style.current.halfPadding
@ -40,8 +41,23 @@ Item {
// Normal transaction
Repeater {
model: root.bestRoutes
StatusListItem {
id: listItem
property double totalGasAmountL1Eth: {
const l1FeeInGWei = modelData.gasFees.l1GasFee
const l1FeeInEth = globalUtils.wei2Eth(l1FeeInGWei, 9)
return l1FeeInEth
}
property double totalGasAmountEth: {
let maxFees = modelData.gasFees.maxFeePerGasM
let gasPrice = modelData.gasFees.eip1559Enabled ? maxFees : modelData.gasFees.gasPrice
return root.getGasEthValue(gasPrice , modelData.gasAmount)
}
property double totalGasAmountFiat: root.getFiatValue(totalGasAmountEth, Constants.ethToken) + root.getFiatValue(totalGasAmountL1Eth, Constants.ethToken)
color: Theme.palette.statusListItem.backgroundColor
width: parent.width
asset.name: "tiny/gas"
@ -50,35 +66,21 @@ Item {
statusListItemIcon.opacity: modelData.isFirstSimpleTx
title: qsTr("%1 transaction fee").arg(root.getNetworkName(modelData.fromNetwork))
subTitle: {
let primaryFee = root.formatCurrencyAmount(totalGasAmountEth, Constants.ethToken)
let primaryFee = root.formatFiat(totalGasAmountEth, Constants.ethToken)
if (modelData.gasFees.eip1559Enabled && modelData.gasFees.l1GasFee > 0) {
return qsTr("L1 fee: %1\nL2 fee: %2")
.arg(root.formatCurrencyAmount(totalGasAmountL1Eth, Constants.ethToken))
.arg(root.formatFiat(totalGasAmountL1Eth, Constants.ethToken))
.arg(primaryFee)
}
return primaryFee
}
property double totalGasAmountL1Eth: {
const l1FeeInGWei = modelData.gasFees.l1GasFee
const l1FeeInEth = globalUtils.wei2Eth(l1FeeInGWei, 9)
return l1FeeInEth
}
property double totalGasAmountEth: {
let maxFees = modelData.gasFees.maxFeePerGasM
let gasPrice = modelData.gasFees.eip1559Enabled ? maxFees : modelData.gasFees.gasPrice
return root.getGasEthValue(gasPrice , modelData.gasAmount)
}
property double totalGasAmountFiat: root.getFiatValue(totalGasAmountEth, Constants.ethToken) + root.getFiatValue(totalGasAmountL1Eth, Constants.ethToken)
statusListItemSubTitle.width: listItem.width/2 - Style.current.smallPadding
statusListItemSubTitle.elide: Text.ElideMiddle
statusListItemSubTitle.wrapMode: Text.NoWrap
components: [
StatusBaseText {
Layout.alignment: Qt.AlignRight
text: root.formatCurrencyAmount(totalGasAmountFiat, root.currentCurrency)
text: root.formatFiat(totalGasAmountFiat, root.currentCurrency)
font.pixelSize: 15
color: Theme.palette.baseColor1
}
@ -89,8 +91,14 @@ Item {
// Approval transaction
Repeater {
model: root.bestRoutes
StatusListItem {
id: listItem1
property double approvalGasFees: modelData.approvalGasFees
property string approvalGasFeesSymbol: Constants.ethToken
property double approvalGasFeesFiat: root.getFiatValue(approvalGasFees, approvalGasFeesSymbol)
color: Theme.palette.statusListItem.backgroundColor
width: parent.width
asset.name: "tiny/checkmark"
@ -98,10 +106,7 @@ Item {
statusListItemIcon.active: true
statusListItemIcon.opacity: modelData.isFirstSimpleTx
title: qsTr("Approve %1 %2 Bridge").arg(root.getNetworkName(modelData.fromNetwork)).arg(root.selectedAsset.symbol)
property double approvalGasFees: modelData.approvalGasFees
property string approvalGasFeesSymbol: Constants.ethToken
property double approvalGasFeesFiat: root.getFiatValue(approvalGasFees, approvalGasFeesSymbol)
subTitle: root.formatCurrencyAmount(approvalGasFees, approvalGasFeesSymbol)
subTitle: root.formatFiat(approvalGasFees, approvalGasFeesSymbol)
statusListItemSubTitle.width: listItem1.width/2 - Style.current.smallPadding
statusListItemSubTitle.elide: Text.ElideMiddle
statusListItemSubTitle.wrapMode: Text.NoWrap
@ -109,7 +114,7 @@ Item {
components: [
StatusBaseText {
Layout.alignment: Qt.AlignRight
text: root.formatCurrencyAmount(approvalGasFeesFiat, root.currentCurrency)
text: root.formatFiat(approvalGasFeesFiat, root.currentCurrency)
font.pixelSize: 15
color: Theme.palette.baseColor1
}
@ -120,9 +125,14 @@ Item {
// Bridge
Repeater {
id: bridgeRepeater
model: root.bestRoutes
delegate: StatusListItem {
id: listItem2
property double tokenFees: modelData.tokenFees
property double tokenFeesFiat: root.getFiatValue(tokenFees, root.selectedAsset.symbol)
color: Theme.palette.statusListItem.backgroundColor
width: parent.width
asset.name: "tiny/bridge"
@ -130,16 +140,14 @@ Item {
statusListItemIcon.active: true
statusListItemIcon.opacity: modelData.isFirstBridgeTx
title: qsTr("%1 -> %2 bridge").arg(root.getNetworkName(modelData.fromNetwork)).arg(root.getNetworkName(modelData.toNetwork))
property double tokenFees: modelData.tokenFees
property double tokenFeesFiat: root.getFiatValue(tokenFees, root.selectedAsset.symbol)
subTitle: root.formatCurrencyAmount(tokenFees, root.selectedAsset.symbol)
subTitle: root.formatFiat(tokenFees, root.selectedAsset.symbol)
visible: modelData.bridgeName !== "Transfer"
statusListItemSubTitle.width: 100
statusListItemSubTitle.elide: Text.ElideMiddle
components: [
StatusBaseText {
Layout.alignment: Qt.AlignRight
text: root.formatCurrencyAmount(tokenFeesFiat, root.currentCurrency)
text: root.formatFiat(tokenFeesFiat, root.currentCurrency)
font.pixelSize: 15
color: Theme.palette.baseColor1
}

View File

@ -2,7 +2,6 @@
import QtQuick.Layouts 1.13
import utils 1.0
import shared.stores 1.0
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
@ -16,28 +15,43 @@ import shared.popups.send.views 1.0
StatusScrollView {
id: root
property var store
property var currencyStore : store.currencyStore
property var selectedRecipient
property string ensAddressOrEmpty: ""
property var selectedAsset
property double amountToSend
property int minSendCryptoDecimals: 0
property int minReceiveCryptoDecimals: 0
property bool isLoading: false
property bool advancedOrCustomMode: (tabBar.currentIndex === 1) || (tabBar.currentIndex === 2)
property bool errorMode: advancedNetworkRoutingPage.errorMode
property bool interactive: true
property bool isBridgeTx: false
property bool isCollectiblesTransfer: false
property var fromNetworksList
property var toNetworksList
property var suggestedToNetworksList
property int errorType: Constants.NoError
property var bestRoutes
property double totalFeesInFiat
property bool showUnPreferredChains
property string currentCurrency
signal reCalculateSuggestedRoute()
readonly property bool advancedOrCustomMode: (tabBar.currentIndex === 1) || (tabBar.currentIndex === 2)
readonly property bool errorMode: advancedNetworkRoutingPage.errorMode
// Models:
property var suggestedToNetworksList
property var fromNetworksList
property var toNetworksList
property var flatNetworksModel
property var formatFiat: function () {}
property var formatFiatSendMinDecimals: function (amount, applyMinDecimals) {}
property var formatFiatReceiveMinDecimals: function (amount, applyMinDecimals) {}
property var weiToEth: function(wei) {}
property var getGasEthValue: function () {}
property var getFiatValue: function () {}
property var getNetworkName: function () {}
signal recalculateSuggestedRoute()
signal toggleShowUnPreferredChains()
signal toggleToDisabledChains(int chainId)
signal toggleFromDisabledChains(int chainId)
signal lockCard(int chainId, string amount, bool lock)
signal setRouteDisabledChains(int chainId, bool disabled)
QtObject {
id: d
@ -52,15 +66,19 @@ StatusScrollView {
StatusSwitchTabBar {
id: tabBar
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
visible: !root.isCollectiblesTransfer
StatusSwitchTabButton {
text: qsTr("Simple")
}
StatusSwitchTabButton {
text: qsTr("Advanced")
}
StatusSwitchTabButton {
text: qsTr("Custom")
}
@ -68,6 +86,7 @@ StatusScrollView {
StackLayout {
id: stackLayout
anchors.top: !root.isCollectiblesTransfer ? tabBar.bottom: parent.top
anchors.topMargin: !root.isCollectiblesTransfer ? Style.current.bigPadding: 0
height: currentIndex == 0 ? networksSimpleRoutingPage.height + networksSimpleRoutingPage.anchors.margins + Style.current.bigPadding:
@ -77,72 +96,81 @@ StatusScrollView {
Rectangle {
id: simple
radius: d.backgroundRectRadius
color: d.backgroundRectColor
NetworksSimpleRoutingView {
id: networksSimpleRoutingPage
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: Style.current.padding
isBridgeTx: root.isBridgeTx
isCollectiblesTransfer: root.isCollectiblesTransfer
minReceiveCryptoDecimals: root.minReceiveCryptoDecimals
isLoading: root.isLoading
store: root.store
errorMode: root.errorMode
errorType: root.errorType
// Models:
fromNetworksList: root.fromNetworksList
toNetworksList: root.suggestedToNetworksList
// Collectibles don't have a symbol
selectedSymbol: !!root.selectedAsset && !!root.selectedAsset.symbol ? root.selectedAsset.symbol: ""
weiToEth: function(wei) {
if(!!selectedAsset && root.selectedAsset !== undefined)
return parseFloat(store.getWei2Eth(wei, root.selectedAsset.decimals))
}
formatCurrencyAmount: root.currencyStore.formatCurrencyAmount
reCalculateSuggestedRoute: function() {
root.reCalculateSuggestedRoute()
}
flatNetworksModel: root.flatNetworksModel
formatFiat: root.formatFiatReceiveMinDecimals
weiToEth: root.weiToEth
onRecalculateSuggestedRoute: root.recalculateSuggestedRoute()
onSetRouteDisabledChains: root.setRouteDisabledChains(chainId, disabled)
}
}
Rectangle {
id: advanced
radius: d.backgroundRectRadius
color: d.backgroundRectColor
NetworksAdvancedCustomRoutingView {
id: advancedNetworkRoutingPage
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: Style.current.padding
store: root.store
showUnPreferredChains: root.showUnPreferredChains
customMode: tabBar.currentIndex === 2
selectedRecipient: root.selectedRecipient
ensAddressOrEmpty: root.ensAddressOrEmpty
amountToSend: root.amountToSend
minSendCryptoDecimals: root.minSendCryptoDecimals
minReceiveCryptoDecimals: root.minReceiveCryptoDecimals
selectedAsset: root.selectedAsset
onReCalculateSuggestedRoute: root.reCalculateSuggestedRoute()
fromNetworksList: root.fromNetworksList
toNetworksList: root.toNetworksList
isLoading: root.isLoading
interactive: root.interactive
isBridgeTx: root.isBridgeTx
errorType: root.errorType
weiToEth: function(wei) {
if(!!selectedAsset && (selectedAsset.type === Constants.TokenType.Native || selectedAsset.type === Constants.TokenType.ERC20))
return parseFloat(store.getWei2Eth(wei, selectedAsset.decimals))
return 0
}
// Models
fromNetworksList: root.fromNetworksList
toNetworksList: root.toNetworksList
formatFiat: root.formatFiatMinDecimals
weiToEth: root.weiToEth
onRecalculateSuggestedRoute: root.recalculateSuggestedRoute()
onToggleShowUnPreferredChains: root.toggleShowUnPreferredChains
onToggleToDisabledChains: root.toggleToDisabledChains(chainId)
onToggleFromDisabledChains: root.toggleFromDisabledChains(chainId)
onLockCard: root.lockCard(chainId, amount, lock)
}
}
}
FeesView {
id: fees
width: parent.width
anchors.top: stackLayout.bottom
anchors.topMargin: Style.current.bigPadding
@ -151,9 +179,14 @@ StatusScrollView {
selectedAsset: root.selectedAsset
isLoading: root.isLoading
bestRoutes: root.bestRoutes
store: root.store
gasFiatAmount: root.totalFeesInFiat
errorType: root.errorType
currentCurrency: root.currentCurrency
getGasEthValue: root.getGasEthValue
getFiatValue: root.getFiatValue
getNetworkName: root.getNetworkName
formatFiat: root.formatFiat
}
}

View File

@ -7,9 +7,7 @@ import StatusQ.Core.Theme 0.1
import utils 1.0
import shared.stores 1.0
import "../controls"
import shared.popups.send.controls 1.0
Rectangle {
id: root
@ -17,10 +15,14 @@ Rectangle {
property double gasFiatAmount
property bool isLoading: false
property var bestRoutes
property var store
property var currencyStore: store.currencyStore
property var selectedAsset
property int errorType: Constants.NoError
property string currentCurrency
property var formatFiat: function () {}
property var getGasEthValue: function () {}
property var getFiatValue: function () {}
property var getNetworkName: function () {}
radius: 13
color: Theme.palette.indirectColor1
@ -28,6 +30,7 @@ Rectangle {
RowLayout {
id: feesLayout
spacing: 10
anchors.top: parent.top
anchors.left: parent.left
@ -35,21 +38,26 @@ Rectangle {
StatusRoundIcon {
id: feesIcon
Layout.alignment: Qt.AlignTop
radius: 8
asset.name: "fees"
asset.color: Theme.palette.directColor1
}
Column {
id: columnLayout
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
Layout.preferredWidth: root.width - feesIcon.width - Style.current.xlPadding
spacing: isLoading ? 4 : 0
Item {
width: parent.width
height: childrenRect.height
StatusBaseText {
id: text
anchors.left: parent.left
font.pixelSize: 15
font.weight: Font.Medium
@ -57,30 +65,37 @@ Rectangle {
text: qsTr("Fees")
wrapMode: Text.WordWrap
}
StatusBaseText {
id: totalFeesAdvanced
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
id: totalFeesAdvanced
text: root.isLoading ? "..." : root.currencyStore.formatCurrencyAmount(root.gasFiatAmount, root.currencyStore.currentCurrency)
text: root.isLoading ? "..." : root.formatFiat(root.gasFiatAmount, root.currentCurrency)
font.pixelSize: 15
color: Theme.palette.directColor1
visible: !!root.bestRoutes && root.bestRoutes !== undefined && root.bestRoutes.count > 0
}
}
GasSelector {
id: gasSelector
width: parent.width
getGasEthValue: root.currencyStore.getGasEthValue
getFiatValue: root.currencyStore.getFiatValue
formatCurrencyAmount: root.currencyStore.formatCurrencyAmount
currentCurrency: root.currencyStore.currentCurrency
currentCurrency: root.currentCurrency
visible: root.errorType === Constants.NoError && !root.isLoading
bestRoutes: root.bestRoutes
selectedAsset: root.selectedAsset
getNetworkName: root.store.getNetworkName
getGasEthValue: root.getGasEthValue
getFiatValue: root.getFiatValue
getNetworkName: root.getNetworkName
formatFiat: root.formatFiat
}
GasValidator {
id: gasValidator
width: parent.width
isLoading: root.isLoading
errorType: root.errorType

View File

@ -10,39 +10,46 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import "../controls"
import shared.popups.send.controls 1.0
Item {
id: root
property var store
readonly property var currencyStore: store.currencyStore
property string receiverIdentityText
property var selectedAsset
property bool customMode: false
property double amountToSend
property int minSendCryptoDecimals: 0
property int minReceiveCryptoDecimals: 0
property bool errorMode: d.customAmountToSend > root.amountToSend
property bool interactive: true
property var weiToEth: function(wei) {}
property var reCalculateSuggestedRoute: function() {}
property var fromNetworksList
property var toNetworksList
property int errorType: Constants.NoError
property bool isLoading
property bool showUnPreferredChains
readonly property bool errorMode: d.customAmountToSend > root.amountToSend
// Models
property var fromNetworksList
property var toNetworksList
// Formatting function for fiat currency values
property var formatFiat: function(amount, applyMinDecimals) {}
// Formatting function wei to eth
property var weiToEth: function(wei) {}
signal recalculateSuggestedRoute()
signal toggleToDisabledChains(int chainId)
signal toggleFromDisabledChains(int chainId)
signal lockCard(int chainId, string amount, bool lock)
QtObject {
id: d
property double customAmountToSend: 0
// Collectibles don't have a symbol
readonly property string selectedSymbol: !!selectedAsset && !!selectedAsset.symbol ? selectedAsset.symbol : ""
function resetAllSetValues() {
for(var i = 0; i<fromNetworksRepeater.count; i++) {
fromNetworksRepeater.itemAt(i).routeOnNetwork = 0
}
for(var i = 0; i<toNetworksRepeater.count; i++) {
for(i = 0; i<toNetworksRepeater.count; i++) {
toNetworksRepeater.itemAt(i).routeOnNetwork = 0
toNetworksRepeater.itemAt(i).bentLine = 0
}
@ -72,35 +79,40 @@ Item {
RowLayout {
id: networkCardsLayout
width: parent.width
ColumnLayout {
id: fromNetworksLayout
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
spacing: 12
StatusBaseText {
Layout.maximumWidth: 100
elide: Text.ElideRight
font.pixelSize: 10
color: Theme.palette.baseColor1
text: qsTr("Your Balances").toUpperCase()
}
Repeater {
id: fromNetworksRepeater
model: root.fromNetworksList
StatusCard {
id: fromNetwork
locale: LocaleUtils.userInputLocale
objectName: model.chainId
property double advancedInputCurrencyAmount: selectedAsset !== undefined && advancedInput.valid ? LocaleUtils.numberFromLocaleString(advancedInput.text, LocaleUtils.userInputLocale) : 0.0
property var tokenBalance: model.tokenBalance
onTokenBalanceChanged: maxAdvancedValue = model.tokenBalance.amount
property var toNetworks: model.toNetworks
property int routeOnNetwork: 0
onToNetworksChanged: d.draw()
primaryText: model.chainName
secondaryText: (model.tokenBalance.amount === 0 && root.amountToSend > 0) ?
qsTr("No Balance") : !model.hasGas ? qsTr("No Gas") : root.currencyStore.formatCurrencyAmount(advancedInputCurrencyAmount, d.selectedSymbol, {"minDecimals": root.minSendCryptoDecimals})
tertiaryText: root.errorMode && advancedInputCurrencyAmount > 0 ? qsTr("EXCEEDS SEND AMOUNT"): qsTr("BALANCE: ") + root.currencyStore.formatCurrencyAmount(model.tokenBalance.amount, d.selectedSymbol)
qsTr("No Balance") : !model.hasGas ? qsTr("No Gas") : root.formatFiat(advancedInputCurrencyAmount, true)
tertiaryText: root.errorMode && advancedInputCurrencyAmount > 0 ? qsTr("EXCEEDS SEND AMOUNT"): qsTr("BALANCE: ") + root.formatFiat(model.tokenBalance.amount, false)
locked: model.locked
preCalculatedAdvancedText: {
if(locked && model.lockedAmount) {
@ -119,28 +131,35 @@ Item {
advancedMode: root.customMode
disabled: !model.isRouteEnabled
clickable: root.interactive
onTokenBalanceChanged: maxAdvancedValue = model.tokenBalance.amount
onToNetworksChanged: d.draw()
onClicked: {
store.toggleFromDisabledChains(model.chainId)
store.lockCard(model.chainId, 0, false)
root.toggleFromDisabledChains(model.chainId)
root.lockCard(model.chainId, 0, false)
root.reCalculateSuggestedRoute()
}
onLockCard: {
let amount = lock ? (advancedInputCurrencyAmount * Math.pow(10, root.selectedAsset.decimals)).toString(16) : ""
store.lockCard(model.chainId, amount, lock)
root.lockCard(model.chainId, amount, lock)
d.calculateCustomAmounts()
root.reCalculateSuggestedRoute()
}
}
}
}
BalanceExceeded {
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
errorType: root.errorType
visible: root.errorType === Constants.NoRoute
}
ColumnLayout {
id: toNetworksLayout
Layout.alignment: Qt.AlignRight | Qt.AlignTop
spacing: 12
@ -151,14 +170,15 @@ Item {
StatusBaseText {
id: receiverIdentityText
text: root.receiverIdentityText
Layout.fillWidth: true
text: root.receiverIdentityText
font.pixelSize: 10
color: Theme.palette.baseColor1
elide: Text.ElideMiddle
horizontalAlignment: Text.AlignRight
}
StatusBaseText {
font.pixelSize: receiverIdentityText.font.pixelSize
color: receiverIdentityText.color
@ -169,18 +189,21 @@ Item {
Repeater {
id: toNetworksRepeater
model: root.toNetworksList
StatusCard {
id: toCard
locale: LocaleUtils.userInputLocale
objectName: model.chainId
property bool preferred: model.isRoutePreferred
property int bentLine: 0
property int routeOnNetwork: 0
primaryText: model.chainName
secondaryText: root.currencyStore.formatCurrencyAmount(root.weiToEth(model.amountOut), d.selectedSymbol, {"minDecimals": root.minReceiveCryptoDecimals})
secondaryText: root.formatFiat(root.weiToEth(model.amountOut), true)
tertiaryText: state === "unpreferred" ? qsTr("UNPREFERRED") : ""
state: !preferred ? "unpreferred" : "default"
opacity: preferred || store.showUnPreferredChains ? 1 : 0
opacity: preferred || root.showUnPreferredChains ? 1 : 0
cardIcon.source: Style.svg(model.iconUrl)
disabledText: qsTr("Disabled")
disableText: qsTr("Disable")
@ -188,8 +211,9 @@ Item {
disabled: !model.isRouteEnabled
clickable: root.interactive
loading: root.isLoading
onClicked: {
store.toggleToDisabledChains(model.chainId)
root.toggleToDisabledChains(model.chainId)
root.reCalculateSuggestedRoute()
}
}
@ -199,6 +223,7 @@ Item {
Canvas {
id: canvas
x: networkCardsLayout.x + fromNetworksLayout.x
y: networkCardsLayout.y
width: networkCardsLayout.width

View File

@ -10,29 +10,39 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import "../controls"
import shared.popups.send.controls 1.0
ColumnLayout {
id: root
property var store
property var selectedRecipient
property string ensAddressOrEmpty: ""
property double amountToSend
property int minSendCryptoDecimals: 0
property int minReceiveCryptoDecimals: 0
property bool customMode: false
property var selectedAsset
property bool isLoading: false
property bool errorMode: networksLoader.item ? networksLoader.item.errorMode : false
property var weiToEth: function(wei) {}
property bool interactive: true
property bool isBridgeTx: false
property int errorType: Constants.NoError
property bool showUnPreferredChains
readonly property bool errorMode: networksLoader.item ? networksLoader.item.errorMode : false
// Models:
property var toNetworksList
property var fromNetworksList
property int errorType: Constants.NoError
signal reCalculateSuggestedRoute()
// Formatting function for fiat currency values
property var formatFiat: function(amount, applyMinDecimals) {}
// Formatting function wei to eth
property var weiToEth: function(wei) {}
signal recalculateSuggestedRoute()
signal toggleShowUnPreferredChains()
signal toggleToDisabledChains(int chainId)
signal toggleFromDisabledChains(int chainId)
signal lockCard(int chainId, string amount, bool lock)
RowLayout {
Layout.fillWidth: true
@ -40,27 +50,34 @@ ColumnLayout {
StatusRoundIcon {
Layout.alignment: Qt.AlignTop
radius: 8
asset.name: "flash"
asset.color: Theme.palette.directColor1
}
ColumnLayout {
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
RowLayout {
Layout.fillWidth: true
StatusBaseText {
Layout.fillWidth: true
font.pixelSize: 15
font.weight: Font.Medium
color: Theme.palette.directColor1
text: qsTr("Networks")
wrapMode: Text.WordWrap
}
StatusButton {
Layout.alignment: Qt.AlignRight
Layout.preferredHeight: 22
verticalPadding: -1
checkable: true
size: StatusBaseButton.Size.Small
icon.name: checked ? "show" : "hide"
@ -68,45 +85,54 @@ ColumnLayout {
icon.width: 16
text: checked ? qsTr("Hide Unpreferred Networks"): qsTr("Show Unpreferred Networks")
visible: !isBridgeTx
checked: root.store.showUnPreferredChains
checked: root.showUnPreferredChains
onClicked: {
root.store.toggleShowUnPreferredChains()
root.reCalculateSuggestedRoute()
root.toggleShowUnPreferredChains()
root.recalculateSuggestedRoute()
}
}
}
StatusBaseText {
Layout.fillWidth: true
font.pixelSize: 15
color: Theme.palette.baseColor1
text: qsTr("The networks where the recipient will receive tokens. Amounts calculated automatically for the lowest cost.")
wrapMode: Text.WordWrap
}
Loader {
id: networksLoader
Layout.fillWidth: true
Layout.preferredHeight: item.height
Layout.topMargin: Style.current.padding
visible: active
sourceComponent: NetworkCardsComponent {
store: root.store
receiverIdentityText: root.ensAddressOrEmpty.length > 0 ?
root.ensAddressOrEmpty : !!root.selectedRecipient ?
StatusQUtils.Utils.elideText(root.selectedRecipient.address, 6, 4).toUpperCase() : ""
amountToSend: root.amountToSend
minSendCryptoDecimals: root.minSendCryptoDecimals
minReceiveCryptoDecimals: root.minReceiveCryptoDecimals
customMode: root.customMode
selectedAsset: root.selectedAsset
reCalculateSuggestedRoute: function() {
root.reCalculateSuggestedRoute()
}
toNetworksList: root.toNetworksList
fromNetworksList: root.fromNetworksList
weiToEth: root.weiToEth
interactive: root.interactive
errorType: root.errorType
isLoading: root.isLoading
showUnPreferredChains: root.showUnPreferredChains
// Models
toNetworksList: root.toNetworksList
fromNetworksList: root.fromNetworksList
weiToEth: root.weiToEth
formatFiat: root.formatFiat
onRecalculateSuggestedRoute: root.recalculateSuggestedRoute()
onToggleToDisabledChains: root.toggleToDisabledChains(chainId)
onToggleFromDisabledChains: root.toogleFromDisabledChains(chainId)
onLockCard: root.lockCard(chainId,amount, lock)
}
}
}

View File

@ -11,24 +11,31 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ 0.1
import "../controls"
import shared.popups.send.controls 1.0
RowLayout {
id: root
property var store
property int minReceiveCryptoDecimals: 0
property bool isLoading: false
property bool isBridgeTx: false
property bool isCollectiblesTransfer: false
property var fromNetworksList
property var toNetworksList
property var weiToEth: function(wei) {}
property var formatCurrencyAmount: function () {}
property var reCalculateSuggestedRoute: function() {}
property bool errorMode: false
property int errorType: Constants.NoError
property string selectedSymbol
// Models:
property var fromNetworksList
property var toNetworksList
property var flatNetworksModel
// Formatting function for fiat currency values
property var formatFiat: function(amount, applyMinDecimals) {}
// Formatting function wei to eth
property var weiToEth: function(wei) {}
signal recalculateSuggestedRoute
signal setRouteDisabledChains(int chainId, bool disabled)
spacing: 10
StatusRoundIcon {
@ -37,10 +44,12 @@ RowLayout {
asset.name: "flash"
asset.color: Theme.palette.directColor1
}
ColumnLayout {
Layout.alignment: Qt.AlignTop
Layout.preferredWidth: root.width
spacing: 4
StatusBaseText {
Layout.maximumWidth: parent.width
font.pixelSize: 15
@ -49,6 +58,7 @@ RowLayout {
text: qsTr("Networks")
wrapMode: Text.WordWrap
}
StatusBaseText {
Layout.maximumWidth: parent.width
font.pixelSize: 15
@ -57,6 +67,7 @@ RowLayout {
qsTr("The networks where the recipient will receive tokens. Amounts calculated automatically for the lowest cost.")
wrapMode: Text.WordWrap
}
ScrollView {
Layout.fillWidth: true
Layout.preferredHeight: visible ? row.height + 10 : 0
@ -67,9 +78,11 @@ RowLayout {
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
clip: true
visible: root.isBridgeTx ? true : !root.isLoading ? root.errorType === Constants.NoError : false
Column {
id: row
spacing: Style.current.padding
Repeater {
id: repeater
objectName: "networksList"
@ -78,7 +91,7 @@ RowLayout {
const m = isBridgeTx ? root.fromNetworksList : root.toNetworksList
return !!m ? m : null
}
rightModel: root.store.flatNetworksModel
rightModel: root.flatNetworksModel
joinRole: "chainId"
}
@ -86,10 +99,12 @@ RowLayout {
}
}
}
BalanceExceeded {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Style.current.smallPadding
errorType: root.errorType
isLoading: root.isLoading && !root.isBridgeTx
}
@ -101,6 +116,7 @@ RowLayout {
Component {
id: routeItem
StatusListItem {
objectName: model.chainName
leftPadding: 5
@ -111,7 +127,7 @@ RowLayout {
if(root.isCollectiblesTransfer)
return ""
let amountOut = root.weiToEth(model.amountOut)
return root.formatCurrencyAmount(amountOut, root.selectedSymbol, {"minDecimals": root.minReceiveCryptoDecimals})
return root.formatFiat(amountOut, true)
}
statusListItemSubTitle.color: root.errorMode ? Theme.palette.dangerColor1 : Theme.palette.primaryColor1
asset.width: 32
@ -124,8 +140,10 @@ RowLayout {
Component {
id: networkItem
StatusRadioButton {
id: gasRectangle
width: contentItem.implicitWidth
contentItem: StatusListItem {
id: card
@ -134,7 +152,7 @@ RowLayout {
rightPadding: 5
implicitWidth: 410
title: chainName
subTitle: root.formatCurrencyAmount(tokenBalance.amount, root.selectedSymbol)
subTitle: root.formatFiat(tokenBalance.amount, false)
statusListItemSubTitle.color: Theme.palette.primaryColor1
asset.width: 32
asset.height: 32
@ -150,9 +168,9 @@ RowLayout {
onClicked: gasRectangle.toggle()
}
onCheckedChanged: {
store.setRouteDisabledChains(chainId, !gasRectangle.checked)
root.setRouteDisabledChains(chainId, !gasRectangle.checked)
if(checked)
root.reCalculateSuggestedRoute()
root.recalculateSuggestedRoute()
}
checked: index === 0
indicator: Item {
@ -160,9 +178,9 @@ RowLayout {
height: card.height
}
Component.onCompleted: {
store.setRouteDisabledChains(chainId, !gasRectangle.checked)
root.setRouteDisabledChains(chainId, !gasRectangle.checked)
if(index === (repeater.count -1))
root.reCalculateSuggestedRoute()
root.recalculateSuggestedRoute()
}
}
}