parent
75b5a583dd
commit
9ded9d4ffa
|
@ -194,7 +194,6 @@ class StatusWalletScreen:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
type(SendPopup.AMOUNT_INPUT.value, amount)
|
type(SendPopup.AMOUNT_INPUT.value, amount)
|
||||||
|
|
||||||
if token != Tokens.ETH.value:
|
|
||||||
click_obj_by_name(SendPopup.ASSET_SELECTOR.value)
|
click_obj_by_name(SendPopup.ASSET_SELECTOR.value)
|
||||||
asset_list = get_obj(SendPopup.ASSET_LIST.value)
|
asset_list = get_obj(SendPopup.ASSET_LIST.value)
|
||||||
for index in range(asset_list.count):
|
for index in range(asset_list.count):
|
||||||
|
|
|
@ -10380,5 +10380,6 @@
|
||||||
<file>assets/img/icons/unfavourite.svg</file>
|
<file>assets/img/icons/unfavourite.svg</file>
|
||||||
<file>assets/img/icons/youtube.svg</file>
|
<file>assets/img/icons/youtube.svg</file>
|
||||||
<file>assets/twemoji/LICENSE</file>
|
<file>assets/twemoji/LICENSE</file>
|
||||||
|
<file>assets/img/icons/bridge.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="21" height="14" viewBox="0 0 21 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M18.5 0.999984H6.72C5.61 -0.230016 3.71 -0.320016 2.5 0.799984C1.86 1.35998 1.5 2.15998 1.5 2.99998V12C1.23478 12 0.98043 12.1053 0.792893 12.2929C0.605357 12.4804 0.5 12.7348 0.5 13V14H8.5V13C8.5 12.7348 8.39464 12.4804 8.20711 12.2929C8.01957 12.1053 7.76522 12 7.5 12V4.99998H18.5C19.0304 4.99998 19.5391 4.78927 19.9142 4.4142C20.2893 4.03912 20.5 3.53042 20.5 2.99998C20.5 2.46955 20.2893 1.96084 19.9142 1.58577C19.5391 1.2107 19.0304 0.999984 18.5 0.999984ZM6 12H3V5.59998C3.93 6.13998 5.07 6.13998 6 5.59998V12ZM4.5 4.49998C4.10218 4.49998 3.72064 4.34195 3.43934 4.06064C3.15804 3.77934 3 3.39781 3 2.99998C3 2.60216 3.15804 2.22063 3.43934 1.93932C3.72064 1.65802 4.10218 1.49998 4.5 1.49998C4.89782 1.49998 5.27936 1.65802 5.56066 1.93932C5.84196 2.22063 6 2.60216 6 2.99998C6 3.39781 5.84196 3.77934 5.56066 4.06064C5.27936 4.34195 4.89782 4.49998 4.5 4.49998ZM9 3.99998L7.5 1.99998H9L10.5 3.99998H9ZM13 3.99998L11.5 1.99998H13L14.5 3.99998H13ZM17 3.99998L15.5 1.99998H17L18.5 3.99998H17Z" fill="#4360DF"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -54,6 +54,16 @@ Rectangle {
|
||||||
Global.openPopup(buySellModal);
|
Global.openPopup(buySellModal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusFlatButton {
|
||||||
|
id: bridgeBtn
|
||||||
|
icon.name: "bridge"
|
||||||
|
text: qsTr("Bridge")
|
||||||
|
onClicked: function () {
|
||||||
|
sendModal.isBridgeTx = true
|
||||||
|
sendModal.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
|
|
@ -1093,15 +1093,19 @@ Item {
|
||||||
this.active = false
|
this.active = false
|
||||||
}
|
}
|
||||||
property var selectedAccount
|
property var selectedAccount
|
||||||
|
property bool isBridgeTx
|
||||||
sourceComponent: SendModal {
|
sourceComponent: SendModal {
|
||||||
onClosed: {
|
onClosed: {
|
||||||
sendModal.closed()
|
sendModal.closed()
|
||||||
|
sendModal.isBridgeTx = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onLoaded: {
|
onLoaded: {
|
||||||
if (!!sendModal.selectedAccount) {
|
if (!!sendModal.selectedAccount) {
|
||||||
item.selectedAccount = sendModal.selectedAccount
|
item.selectedAccount = sendModal.selectedAccount
|
||||||
}
|
}
|
||||||
|
if(isBridgeTx)
|
||||||
|
item.isBridgeTx = sendModal.isBridgeTx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
import QtQuick.Controls 2.13
|
||||||
|
|
||||||
|
import StatusQ.Popups 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
import StatusQ.Components 0.1
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
StatusListItem {
|
||||||
|
property string currentCurrencySymbol
|
||||||
|
|
||||||
|
title: name
|
||||||
|
subTitle: `${enabledNetworkBalance} ${symbol}`
|
||||||
|
asset.name: symbol ? Style.png("tokens/" + symbol) : ""
|
||||||
|
asset.isImage: true
|
||||||
|
components: [
|
||||||
|
Column {
|
||||||
|
id: valueColumn
|
||||||
|
property string textColor: Math.sign(Number(changePct24hour)) === 0 ? Theme.palette.baseColor1 :
|
||||||
|
Math.sign(Number(changePct24hour)) === -1 ? Theme.palette.dangerColor1 :
|
||||||
|
Theme.palette.successColor1
|
||||||
|
StatusBaseText {
|
||||||
|
anchors.right: parent.right
|
||||||
|
font.pixelSize: 15
|
||||||
|
font.strikeout: false
|
||||||
|
text: enabledNetworkCurrencyBalance.toLocaleCurrencyString(Qt.locale(), currentCurrencySymbol)
|
||||||
|
}
|
||||||
|
Row {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
spacing: 8
|
||||||
|
StatusBaseText {
|
||||||
|
id: change24HourText
|
||||||
|
font.pixelSize: 15
|
||||||
|
font.strikeout: false
|
||||||
|
color: valueColumn.textColor
|
||||||
|
text: currencyPrice.toLocaleCurrencyString(Qt.locale(), currentCurrencySymbol)
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
width: 1
|
||||||
|
height: change24HourText.implicitHeight
|
||||||
|
color: Theme.palette.directColor9
|
||||||
|
}
|
||||||
|
StatusBaseText {
|
||||||
|
font.pixelSize: 15
|
||||||
|
font.strikeout: false
|
||||||
|
color: valueColumn.textColor
|
||||||
|
text: changePct24hour !== "" ? "%1%".arg(changePct24hour) : "---"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -30,3 +30,4 @@ AssetsDetailsHeader 1.0 AssetsDetailsHeader.qml
|
||||||
InformationTag 1.0 InformationTag.qml
|
InformationTag 1.0 InformationTag.qml
|
||||||
TransactionDetailsHeader.qml 1.0 TransactionDetailsHeader.qml
|
TransactionDetailsHeader.qml 1.0 TransactionDetailsHeader.qml
|
||||||
SavedAddressesDelegate 1.0 SavedAddressesDelegate.qml
|
SavedAddressesDelegate 1.0 SavedAddressesDelegate.qml
|
||||||
|
TokenDelegate 1.0 TokenDelegate.qml
|
||||||
|
|
|
@ -29,13 +29,14 @@ Item {
|
||||||
|
|
||||||
// Define this in the usage to get balance in currency selected by user
|
// Define this in the usage to get balance in currency selected by user
|
||||||
property var getCurrencyBalanceString: function (currencyBalance) { return "" }
|
property var getCurrencyBalanceString: function (currencyBalance) { return "" }
|
||||||
|
property string placeholderText
|
||||||
|
|
||||||
function resetInternal() {
|
function resetInternal() {
|
||||||
assets = null
|
assets = null
|
||||||
selectedAsset = null
|
selectedAsset = null
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitWidth: 106
|
implicitWidth: comboBox.width
|
||||||
implicitHeight: comboBox.implicitHeight
|
implicitHeight: comboBox.implicitHeight
|
||||||
|
|
||||||
onSelectedAssetChanged: {
|
onSelectedAssetChanged: {
|
||||||
|
@ -59,7 +60,7 @@ Item {
|
||||||
StatusComboBox {
|
StatusComboBox {
|
||||||
id: comboBox
|
id: comboBox
|
||||||
objectName: "assetSelectorButton"
|
objectName: "assetSelectorButton"
|
||||||
width: parent.width
|
width: control.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
|
||||||
control.padding: 4
|
control.padding: 4
|
||||||
|
@ -86,25 +87,28 @@ Item {
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: comboBox.control.hovered ? Theme.palette.primaryColor2 : Theme.palette.directColor8
|
border.color: comboBox.control.hovered ? Theme.palette.primaryColor2 : Theme.palette.directColor8
|
||||||
radius: 16
|
radius: 16
|
||||||
|
width: rowLayout.width
|
||||||
|
implicitHeight: 48
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: RowLayout {
|
contentItem: RowLayout {
|
||||||
|
id: rowLayout
|
||||||
spacing: 8
|
spacing: 8
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
Layout.maximumWidth: 50
|
|
||||||
Layout.leftMargin: 8
|
Layout.leftMargin: 8
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
color: Theme.palette.directColor1
|
color: !!root.selectedAsset ? Theme.palette.directColor1: Theme.palette.baseColor1
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
text: d.text
|
text: !!root.selectedAsset ? d.text : placeholderText
|
||||||
}
|
}
|
||||||
StatusRoundedImage {
|
StatusRoundedImage {
|
||||||
Layout.preferredWidth: 40
|
Layout.preferredWidth: 40
|
||||||
Layout.preferredHeight: 40
|
Layout.preferredHeight: 40
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
visible: !!d.iconSource
|
||||||
image.source: d.iconSource
|
image.source: d.iconSource
|
||||||
image.onStatusChanged: {
|
image.onStatusChanged: {
|
||||||
if (image.status === Image.Error) {
|
if (image.status === Image.Error) {
|
||||||
|
@ -112,6 +116,10 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Item {
|
||||||
|
width: 8
|
||||||
|
height: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
control.indicator: null
|
control.indicator: null
|
||||||
|
@ -122,16 +130,14 @@ Item {
|
||||||
padding: 16
|
padding: 16
|
||||||
objectName: "AssetSelector_ItemDelegate_" + symbol
|
objectName: "AssetSelector_ItemDelegate_" + symbol
|
||||||
onClicked: {
|
onClicked: {
|
||||||
// TODO: move this out of StatusQ, this involves dependency on BE code
|
|
||||||
// WARNING: Wrong ComboBox value processing. Check `StatusAccountSelector` for more info.
|
// WARNING: Wrong ComboBox value processing. Check `StatusAccountSelector` for more info.
|
||||||
root.userSelectedToken = symbol
|
root.userSelectedToken = symbol
|
||||||
root.selectedAsset = {name: name, symbol: symbol, totalBalance: totalBalance, totalCurrencyBalance: totalCurrencyBalance, balances: balances, decimals: decimals}
|
root.selectedAsset = {name: name, symbol: symbol, totalBalance: totalBalance, totalCurrencyBalance: totalCurrencyBalance, balances: balances, decimals: decimals}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move this out of StatusQ, this involves dependency on BE code
|
|
||||||
// WARNING: Wrong ComboBox value processing. Check `StatusAccountSelector` for more info.
|
// WARNING: Wrong ComboBox value processing. Check `StatusAccountSelector` for more info.
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if ((userSelectedToken === "" && index === 0) || symbol === userSelectedToken)
|
if (symbol === userSelectedToken)
|
||||||
root.selectedAsset = { name: name, symbol: symbol, totalBalance: totalBalance, totalCurrencyBalance: totalCurrencyBalance, balances: balances, decimals: decimals}
|
root.selectedAsset = { name: name, symbol: symbol, totalBalance: totalBalance, totalCurrencyBalance: totalCurrencyBalance, balances: balances, decimals: decimals}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ import "../views"
|
||||||
StatusDialog {
|
StatusDialog {
|
||||||
id: popup
|
id: popup
|
||||||
|
|
||||||
|
property bool isBridgeTx: false
|
||||||
|
|
||||||
property string preSelectedRecipient
|
property string preSelectedRecipient
|
||||||
property string preDefinedAmountToSend
|
property string preDefinedAmountToSend
|
||||||
property var preSelectedAsset
|
property var preSelectedAsset
|
||||||
|
@ -29,14 +31,14 @@ StatusDialog {
|
||||||
|
|
||||||
property alias modalHeader: modalHeader.text
|
property alias modalHeader: modalHeader.text
|
||||||
|
|
||||||
property alias selectedPriority: gasSelector.selectedPriority
|
property alias selectedPriority: fees.selectedPriority
|
||||||
property var store: TransactionStore{}
|
property var store: TransactionStore{}
|
||||||
property var contactsStore: store.contactStore
|
property var contactsStore: store.contactStore
|
||||||
property var selectedAccount: store.currentAccount
|
property var selectedAccount: store.currentAccount
|
||||||
property var bestRoutes
|
property var bestRoutes
|
||||||
property string addressText
|
property string addressText
|
||||||
property bool isLoading: false
|
property bool isLoading: false
|
||||||
property int sendType: Constants.SendType.Transfer
|
property int sendType: isBridgeTx ? Constants.SendType.Bridge : Constants.SendType.Transfer
|
||||||
property MessageDialog sendingError: MessageDialog {
|
property MessageDialog sendingError: MessageDialog {
|
||||||
id: sendingError
|
id: sendingError
|
||||||
title: qsTr("Error sending the transaction")
|
title: qsTr("Error sending the transaction")
|
||||||
|
@ -61,19 +63,19 @@ StatusDialog {
|
||||||
assetSelector.selectedAsset.symbol,
|
assetSelector.selectedAsset.symbol,
|
||||||
amountToSendInput.text,
|
amountToSendInput.text,
|
||||||
d.uuid,
|
d.uuid,
|
||||||
gasSelector.selectedPriority,
|
fees.selectedPriority,
|
||||||
JSON.stringify(popup.bestRoutes)
|
JSON.stringify(popup.bestRoutes)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
property var recalculateRoutesAndFees: Backpressure.debounce(popup, 600, function() {
|
property var recalculateRoutesAndFees: Backpressure.debounce(popup, 600, function() {
|
||||||
d.sendTxError = false
|
d.sendTxError = false
|
||||||
if(popup.selectedAccount && assetSelector.selectedAsset) {
|
if(!!popup.selectedAccount && !!assetSelector.selectedAsset) {
|
||||||
popup.isLoading = true
|
popup.isLoading = true
|
||||||
let amount = parseFloat(amountToSendInput.text) * Math.pow(10, assetSelector.selectedAsset.decimals)
|
let amount = parseFloat(amountToSendInput.text) * Math.pow(10, assetSelector.selectedAsset.decimals)
|
||||||
popup.store.suggestedRoutes(popup.selectedAccount.address, amount.toString(16), assetSelector.selectedAsset.symbol,
|
popup.store.suggestedRoutes(popup.selectedAccount.address, amount.toString(16), assetSelector.selectedAsset.symbol,
|
||||||
store.disabledChainIdsFromList, store.disabledChainIdsToList,
|
store.disabledChainIdsFromList, store.disabledChainIdsToList,
|
||||||
d.preferredChainIds, gasSelector.selectedPriority, popup.sendType)
|
d.preferredChainIds, fees.selectedPriority, popup.sendType)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -85,6 +87,10 @@ StatusDialog {
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
readonly property double maxFiatBalance: assetSelector.selectedAsset ? assetSelector.selectedAsset.totalBalance: 0
|
readonly property double maxFiatBalance: assetSelector.selectedAsset ? assetSelector.selectedAsset.totalBalance: 0
|
||||||
|
onMaxFiatBalanceChanged: {
|
||||||
|
floatValidator.top = maxFiatBalance
|
||||||
|
amountToSendInput.validate()
|
||||||
|
}
|
||||||
readonly property bool isReady: amountToSendInput.valid && !amountToSendInput.pending && recipientReady
|
readonly property bool isReady: amountToSendInput.valid && !amountToSendInput.pending && recipientReady
|
||||||
readonly property bool errorMode: (networkSelector.bestRoutes && networkSelector.bestRoutes.length <= 0) || networkSelector.errorMode || isNaN(amountToSendInput.text)
|
readonly property bool errorMode: (networkSelector.bestRoutes && networkSelector.bestRoutes.length <= 0) || networkSelector.errorMode || isNaN(amountToSendInput.text)
|
||||||
readonly property bool recipientReady: (isAddressValid || isENSValid) && !recipientSelector.isPending
|
readonly property bool recipientReady: (isAddressValid || isENSValid) && !recipientSelector.isPending
|
||||||
|
@ -147,8 +153,6 @@ StatusDialog {
|
||||||
onSelectedAccountChanged: popup.recalculateRoutesAndFees()
|
onSelectedAccountChanged: popup.recalculateRoutesAndFees()
|
||||||
|
|
||||||
onOpened: {
|
onOpened: {
|
||||||
popup.store.disabledChainIdsFromList = []
|
|
||||||
popup.store.disabledChainIdsToList = []
|
|
||||||
amountToSendInput.input.edit.forceActiveFocus()
|
amountToSendInput.input.edit.forceActiveFocus()
|
||||||
|
|
||||||
if(!!popup.preSelectedAsset) {
|
if(!!popup.preSelectedAsset) {
|
||||||
|
@ -163,6 +167,16 @@ StatusDialog {
|
||||||
recipientSelector.input.text = popup.preSelectedRecipient
|
recipientSelector.input.text = popup.preSelectedRecipient
|
||||||
d.waitTimer.restart()
|
d.waitTimer.restart()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(popup.isBridgeTx) {
|
||||||
|
recipientSelector.input.text = popup.selectedAccount.address
|
||||||
|
d.waitTimer.restart()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
popup.store.disabledChainIdsFromList = []
|
||||||
|
popup.store.disabledChainIdsToList = []
|
||||||
}
|
}
|
||||||
|
|
||||||
header: AccountsModalHeader {
|
header: AccountsModalHeader {
|
||||||
|
@ -186,14 +200,13 @@ StatusDialog {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: group1
|
id: group1
|
||||||
Layout.preferredWidth: parent.width
|
Layout.preferredWidth: parent.width
|
||||||
spacing: Style.current.padding
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.preferredWidth: parent.width
|
Layout.preferredWidth: parent.width
|
||||||
Layout.preferredHeight: assetAndAmmountSelector.height + Style.current.padding
|
Layout.preferredHeight: assetAndAmmountSelector.height + Style.current.padding
|
||||||
color: Theme.palette.baseColor3
|
color: Theme.palette.baseColor3
|
||||||
|
|
||||||
layer.enabled: scrollView.contentY > -8
|
layer.enabled: scrollView.contentY > 0
|
||||||
layer.effect: DropShadow {
|
layer.effect: DropShadow {
|
||||||
verticalOffset: 2
|
verticalOffset: 2
|
||||||
radius: 16
|
radius: 16
|
||||||
|
@ -214,7 +227,7 @@ StatusDialog {
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
id: modalHeader
|
id: modalHeader
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: qsTr("Send")
|
text: popup.isBridgeTx ? qsTr("Bridge") : qsTr("Send")
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
color: Theme.palette.directColor1
|
color: Theme.palette.directColor1
|
||||||
}
|
}
|
||||||
|
@ -237,14 +250,14 @@ StatusDialog {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: -Style.current.padding
|
anchors.leftMargin: -Style.current.padding
|
||||||
width: parent.width - assetSelector.width
|
width: parent.width - assetSelector.width
|
||||||
placeholderText: assetSelector.selectedAsset ? "%1 %2".arg(LocaleUtils.numberToLocaleString(0, 2)).arg(assetSelector.selectedAsset.symbol) : ""
|
placeholderText: assetSelector.selectedAsset ? "%1 %2".arg(LocaleUtils.numberToLocaleString(0, 2)).arg(assetSelector.selectedAsset.symbol) : LocaleUtils.numberToLocaleString(0, 2)
|
||||||
input.edit.color: d.errorMode ? Theme.palette.dangerColor1 : Theme.palette.directColor1
|
input.edit.color: d.errorMode ? Theme.palette.dangerColor1 : Theme.palette.directColor1
|
||||||
input.edit.readOnly: !popup.interactive
|
input.edit.readOnly: !popup.interactive
|
||||||
validators: [
|
validators: [
|
||||||
StatusFloatValidator{
|
StatusFloatValidator{
|
||||||
id: floatValidator
|
id: floatValidator
|
||||||
bottom: 0
|
bottom: 0
|
||||||
top: assetSelector.selectedAsset ? assetSelector.selectedAsset.totalBalance: 0
|
top: d.maxFiatBalance
|
||||||
errorMessage: ""
|
errorMessage: ""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -264,6 +277,7 @@ StatusDialog {
|
||||||
enabled: popup.interactive
|
enabled: popup.interactive
|
||||||
assets: popup.selectedAccount && popup.selectedAccount.assets ? popup.selectedAccount.assets : []
|
assets: popup.selectedAccount && popup.selectedAccount.assets ? popup.selectedAccount.assets : []
|
||||||
defaultToken: Style.png("tokens/DEFAULT-TOKEN@3x")
|
defaultToken: Style.png("tokens/DEFAULT-TOKEN@3x")
|
||||||
|
placeholderText: popup.isBridgeTx ? qsTr("Select token to bridge") : qsTr("Select token to send")
|
||||||
getCurrencyBalanceString: function (currencyBalance) {
|
getCurrencyBalanceString: function (currencyBalance) {
|
||||||
return "%1 %2".arg(Utils.toLocaleString(currencyBalance.toFixed(2), popup.store.locale, {"currency": true})).arg(popup.store.currentCurrency.toUpperCase())
|
return "%1 %2".arg(Utils.toLocaleString(currencyBalance.toFixed(2), popup.store.locale, {"currency": true})).arg(popup.store.currentCurrency.toUpperCase())
|
||||||
}
|
}
|
||||||
|
@ -306,10 +320,13 @@ StatusDialog {
|
||||||
input.edit.color: txtFiatBalance.input.edit.activeFocus ? Theme.palette.directColor1 : Theme.palette.baseColor1
|
input.edit.color: txtFiatBalance.input.edit.activeFocus ? Theme.palette.directColor1 : Theme.palette.baseColor1
|
||||||
input.edit.readOnly: true
|
input.edit.readOnly: true
|
||||||
text: {
|
text: {
|
||||||
|
if(!!assetSelector.selectedAsset) {
|
||||||
let fiatValue = popup.store.getFiatValue(amountToSendInput.text, assetSelector.selectedAsset.symbol, popup.store.currentCurrency)
|
let fiatValue = popup.store.getFiatValue(amountToSendInput.text, assetSelector.selectedAsset.symbol, popup.store.currentCurrency)
|
||||||
return parseFloat(fiatValue) === 0 ? LocaleUtils.numberToLocaleString(parseFloat(fiatValue), 2) : LocaleUtils.numberToLocaleString(parseFloat(fiatValue))
|
return parseFloat(fiatValue) === 0 ? LocaleUtils.numberToLocaleString(parseFloat(fiatValue), 2) : LocaleUtils.numberToLocaleString(parseFloat(fiatValue))
|
||||||
}
|
}
|
||||||
input.implicitHeight: 15
|
return LocaleUtils.numberToLocaleString(0, 2)
|
||||||
|
}
|
||||||
|
input.implicitHeight: Style.current.bigPadding
|
||||||
implicitWidth: txtFiatBalance.input.edit.contentWidth + 50
|
implicitWidth: txtFiatBalance.input.edit.contentWidth + 50
|
||||||
input.rightComponent: StatusBaseText {
|
input.rightComponent: StatusBaseText {
|
||||||
id: currencyText
|
id: currencyText
|
||||||
|
@ -326,14 +343,34 @@ StatusDialog {
|
||||||
// amountToSendInput.text = root.getCryptoValue(balance, popup.store.currentCurrency, assetSelector.selectedAsset.symbol)
|
// amountToSendInput.text = root.getCryptoValue(balance, popup.store.currentCurrency, assetSelector.selectedAsset.symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TokenListView {
|
||||||
|
id: tokenListRect
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
visible: !assetSelector.selectedAsset
|
||||||
|
assets: popup.selectedAccount && popup.selectedAccount.assets ? popup.selectedAccount.assets : []
|
||||||
|
currentCurrencySymbol: RootStore.currencyStore.currentCurrencySymbol
|
||||||
|
searchTokenSymbolByAddressFn: function (address) {
|
||||||
|
if(popup.selectedAccount) {
|
||||||
|
return popup.selectedAccount.findTokenSymbolByAddress(address)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
onTokenSelected: {
|
||||||
|
assetSelector.userSelectedToken = selectedToken.symbol
|
||||||
|
assetSelector.selectedAsset = selectedToken
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusScrollView {
|
StatusScrollView {
|
||||||
id: scrollView
|
id: scrollView
|
||||||
|
topPadding: 0
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.preferredWidth: parent.width
|
Layout.preferredWidth: parent.width
|
||||||
contentHeight: layout.height
|
contentHeight: layout.height + Style.current.padding
|
||||||
contentWidth: parent.width
|
contentWidth: parent.width
|
||||||
z: 0
|
z: 0
|
||||||
objectName: "sendModalScroll"
|
objectName: "sendModalScroll"
|
||||||
|
@ -341,13 +378,16 @@ StatusDialog {
|
||||||
Column {
|
Column {
|
||||||
id: layout
|
id: layout
|
||||||
width: scrollView.availableWidth
|
width: scrollView.availableWidth
|
||||||
spacing: Style.current.halfPadding
|
spacing: Style.current.bigPadding
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
||||||
StatusInput {
|
StatusInput {
|
||||||
id: recipientSelector
|
id: recipientSelector
|
||||||
property bool isPending: false
|
property bool isPending: false
|
||||||
|
|
||||||
|
height: visible ? implicitHeight: 0
|
||||||
|
visible: !isBridgeTx && !!assetSelector.selectedAsset
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
@ -419,7 +459,7 @@ StatusDialog {
|
||||||
recipientSelector.input.text = address
|
recipientSelector.input.text = address
|
||||||
d.waitTimer.restart()
|
d.waitTimer.restart()
|
||||||
}
|
}
|
||||||
visible: !d.recipientReady
|
visible: !d.recipientReady && !isBridgeTx && !!assetSelector.selectedAsset
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkSelector {
|
NetworkSelector {
|
||||||
|
@ -433,86 +473,30 @@ StatusDialog {
|
||||||
interactive: popup.interactive
|
interactive: popup.interactive
|
||||||
selectedAccount: popup.selectedAccount
|
selectedAccount: popup.selectedAccount
|
||||||
amountToSend: isNaN(parseFloat(amountToSendInput.text)) ? 0 : parseFloat(amountToSendInput.text)
|
amountToSend: isNaN(parseFloat(amountToSendInput.text)) ? 0 : parseFloat(amountToSendInput.text)
|
||||||
requiredGasInEth: gasSelector.selectedGasEthValue
|
requiredGasInEth: fees.selectedGasEthValue
|
||||||
selectedAsset: assetSelector.selectedAsset
|
selectedAsset: assetSelector.selectedAsset
|
||||||
onReCalculateSuggestedRoute: popup.recalculateRoutesAndFees()
|
onReCalculateSuggestedRoute: popup.recalculateRoutesAndFees()
|
||||||
visible: d.recipientReady
|
visible: d.recipientReady && !!assetSelector.selectedAsset
|
||||||
|
|
||||||
isLoading: popup.isLoading
|
isLoading: popup.isLoading
|
||||||
bestRoutes: popup.bestRoutes
|
bestRoutes: popup.bestRoutes
|
||||||
|
isBridgeTx: popup.isBridgeTx
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
FeesView {
|
||||||
id: fees
|
id: fees
|
||||||
radius: 13
|
|
||||||
color: Theme.palette.indirectColor1
|
|
||||||
height: text.height + gasSelector.height + gasValidator.height + Style.current.xlPadding
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: Style.current.bigPadding
|
anchors.leftMargin: Style.current.bigPadding
|
||||||
anchors.rightMargin: Style.current.bigPadding
|
anchors.rightMargin: Style.current.bigPadding
|
||||||
visible: d.recipientReady
|
visible: d.recipientReady && !!assetSelector.selectedAsset
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: feesLayout
|
|
||||||
spacing: 10
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: Style.current.padding
|
|
||||||
|
|
||||||
StatusRoundIcon {
|
|
||||||
id: feesIcon
|
|
||||||
Layout.alignment: Qt.AlignTop
|
|
||||||
radius: 8
|
|
||||||
asset.name: "fees"
|
|
||||||
}
|
|
||||||
Column {
|
|
||||||
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
|
|
||||||
Layout.preferredWidth: fees.width - feesIcon.width - Style.current.xlPadding
|
|
||||||
Item {
|
|
||||||
width: parent.width
|
|
||||||
height: childrenRect.height
|
|
||||||
StatusBaseText {
|
|
||||||
id: text
|
|
||||||
anchors.left: parent.left
|
|
||||||
font.pixelSize: 15
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.palette.directColor1
|
|
||||||
text: qsTr("Fees")
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
}
|
|
||||||
StatusBaseText {
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: Style.current.padding
|
|
||||||
id: totalFeesAdvanced
|
|
||||||
text: popup.isLoading ? "..." : gasSelector.selectedGasFiatValue
|
|
||||||
font.pixelSize: 15
|
|
||||||
color: Theme.palette.directColor1
|
|
||||||
visible: networkSelector.advancedOrCustomMode && popup.bestRoutes.length > 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GasSelector {
|
|
||||||
id: gasSelector
|
|
||||||
width: parent.width
|
|
||||||
getGasEthValue: popup.store.getGasEthValue
|
|
||||||
getFiatValue: popup.store.getFiatValue
|
|
||||||
currentCurrency: popup.store.currencyStore.currentCurrency
|
|
||||||
currentCurrencySymbol: popup.store.currencyStore.currentCurrencySymbol
|
|
||||||
visible: gasValidator.isValid && !popup.isLoading
|
|
||||||
advancedOrCustomMode: networkSelector.advancedOrCustomMode
|
|
||||||
bestRoutes: popup.bestRoutes
|
|
||||||
selectedTokenSymbol: assetSelector.selectedAsset ? assetSelector.selectedAsset.symbol: ""
|
selectedTokenSymbol: assetSelector.selectedAsset ? assetSelector.selectedAsset.symbol: ""
|
||||||
onSelectedPriorityChanged: popup.recalculateRoutesAndFees()
|
advancedOrCustomMode: networkSelector.advancedOrCustomMode
|
||||||
}
|
|
||||||
GasValidator {
|
|
||||||
id: gasValidator
|
|
||||||
width: parent.width
|
|
||||||
isLoading: popup.isLoading
|
isLoading: popup.isLoading
|
||||||
isValid: popup.bestRoutes ? popup.bestRoutes.length > 0 : true
|
bestRoutes: popup.bestRoutes
|
||||||
}
|
store: popup.store
|
||||||
}
|
onPriorityChanged: popup.recalculateRoutesAndFees()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -520,10 +504,11 @@ StatusDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
footer: SendModalFooter {
|
footer: SendModalFooter {
|
||||||
maxFiatFees: popup.isLoading ? "..." : gasSelector.selectedGasFiatValue
|
nextButtonText: popup.isBridgeTx ? qsTr("Bridge") : qsTr("Send")
|
||||||
selectedTimeEstimate: popup.isLoading? "..." : gasSelector.selectedTimeEstimate
|
maxFiatFees: popup.isLoading ? "..." : fees.selectedGasFiatValue
|
||||||
|
selectedTimeEstimate: popup.isLoading? "..." : fees.selectedTimeEstimate
|
||||||
pending: d.isPendingTx || popup.isLoading
|
pending: d.isPendingTx || popup.isLoading
|
||||||
visible: d.isReady && !isNaN(amountToSendInput.text) && gasValidator.isValid && !d.errorMode
|
visible: d.isReady && !isNaN(amountToSendInput.text) && fees.isValid && !d.errorMode
|
||||||
onNextButtonClicked: popup.sendTransaction()
|
onNextButtonClicked: popup.sendTransaction()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,7 +526,7 @@ StatusDialog {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
popup.bestRoutes = response.suggestedRoutes.best
|
popup.bestRoutes = response.suggestedRoutes.best
|
||||||
gasSelector.estimatedGasFeesTime = response.suggestedRoutes.gasTimeEstimates
|
fees.estimatedGasFeesTime = response.suggestedRoutes.gasTimeEstimates
|
||||||
popup.isLoading = false
|
popup.isLoading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,33 +26,29 @@ QtObject {
|
||||||
property var disabledChainIdsToList: []
|
property var disabledChainIdsToList: []
|
||||||
|
|
||||||
function addRemoveDisabledFromChain(chainID, isDisabled) {
|
function addRemoveDisabledFromChain(chainID, isDisabled) {
|
||||||
var tempList = disabledChainIdsFromList
|
|
||||||
if(isDisabled) {
|
if(isDisabled) {
|
||||||
tempList.push(chainID)
|
disabledChainIdsFromList.push(chainID)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for(var i = 0; i < tempList.length;i++) {
|
for(var i = 0; i < disabledChainIdsFromList.length;i++) {
|
||||||
if(tempList[i] === chainID) {
|
if(disabledChainIdsFromList[i] === chainID) {
|
||||||
tempList.splice(i, 1)
|
disabledChainIdsFromList.splice(i, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
disabledChainIdsFromList = tempList
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addRemoveDisabledToChain(chainID, isDisabled) {
|
function addRemoveDisabledToChain(chainID, isDisabled) {
|
||||||
var tempList = disabledChainIdsToList
|
|
||||||
if(isDisabled) {
|
if(isDisabled) {
|
||||||
tempList.push(chainID)
|
root.disabledChainIdsToList.push(chainID)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for(var i = 0; i < tempList.length;i++) {
|
for(var i = 0; i < root.disabledChainIdsToList.length;i++) {
|
||||||
if(tempList[i] === chainID) {
|
if(root.disabledChainIdsToList[i] === chainID) {
|
||||||
tempList.splice(i, 1)
|
root.disabledChainIdsToList.splice(i, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
disabledChainIdsToList = tempList
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEtherscanLink() {
|
function getEtherscanLink() {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import SortFilterProxyModel 0.2
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
import "../stores"
|
import "../stores"
|
||||||
|
import shared.controls 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
@ -41,50 +42,11 @@ Item {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: StatusListItem {
|
delegate: TokenDelegate {
|
||||||
readonly property string balance: enabledNetworkBalance // Needed for the tests
|
|
||||||
objectName: "AssetView_TokenListItem_" + symbol
|
objectName: "AssetView_TokenListItem_" + symbol
|
||||||
|
readonly property string balance: enabledNetworkBalance // Needed for the tests
|
||||||
|
currentCurrencySymbol: RootStore.currencyStore.currentCurrencySymbol
|
||||||
width: ListView.view.width
|
width: ListView.view.width
|
||||||
title: name
|
|
||||||
subTitle: `${enabledNetworkBalance} ${symbol}`
|
|
||||||
asset.name: symbol ? Style.png("tokens/" + symbol) : ""
|
|
||||||
asset.isImage: true
|
|
||||||
components: [
|
|
||||||
Column {
|
|
||||||
id: valueColumn
|
|
||||||
property string textColor: Math.sign(Number(changePct24hour)) === 0 ? Theme.palette.baseColor1 :
|
|
||||||
Math.sign(Number(changePct24hour)) === -1 ? Theme.palette.dangerColor1 :
|
|
||||||
Theme.palette.successColor1
|
|
||||||
StatusBaseText {
|
|
||||||
anchors.right: parent.right
|
|
||||||
font.pixelSize: 15
|
|
||||||
font.strikeout: false
|
|
||||||
text: enabledNetworkCurrencyBalance.toLocaleCurrencyString(Qt.locale(), RootStore.currencyStore.currentCurrencySymbol)
|
|
||||||
}
|
|
||||||
Row {
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
spacing: 8
|
|
||||||
StatusBaseText {
|
|
||||||
id: change24HourText
|
|
||||||
font.pixelSize: 15
|
|
||||||
font.strikeout: false
|
|
||||||
color: valueColumn.textColor
|
|
||||||
text: currencyPrice.toLocaleCurrencyString(Qt.locale(), RootStore.currencyStore.currentCurrencySymbol)
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
width: 1
|
|
||||||
height: change24HourText.implicitHeight
|
|
||||||
color: Theme.palette.directColor9
|
|
||||||
}
|
|
||||||
StatusBaseText {
|
|
||||||
font.pixelSize: 15
|
|
||||||
font.strikeout: false
|
|
||||||
color: valueColumn.textColor
|
|
||||||
text: changePct24hour !== "" ? "%1%".arg(changePct24hour) : "---"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
RootStore.getHistoricalDataForToken(symbol, RootStore.currencyStore.currentCurrency)
|
RootStore.getHistoricalDataForToken(symbol, RootStore.currencyStore.currentCurrency)
|
||||||
d.selectedAssetIndex = index
|
d.selectedAssetIndex = index
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
import QtQuick.Layouts 1.13
|
||||||
|
|
||||||
|
import StatusQ.Components 0.1
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
import "../controls"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias selectedPriority: gasSelector.selectedPriority
|
||||||
|
property alias selectedGasEthValue: gasSelector.selectedGasEthValue
|
||||||
|
property alias selectedGasFiatValue: gasSelector.selectedGasFiatValue
|
||||||
|
property alias selectedTimeEstimate: gasSelector.selectedTimeEstimate
|
||||||
|
property alias estimatedGasFeesTime: gasSelector.estimatedGasFeesTime
|
||||||
|
property alias isValid: gasValidator.isValid
|
||||||
|
|
||||||
|
property bool isLoading: false
|
||||||
|
property var bestRoutes
|
||||||
|
property var store
|
||||||
|
property var selectedTokenSymbol
|
||||||
|
property bool advancedOrCustomMode
|
||||||
|
signal priorityChanged()
|
||||||
|
|
||||||
|
radius: 13
|
||||||
|
color: Theme.palette.indirectColor1
|
||||||
|
height: text.height + gasSelector.height + gasValidator.height + Style.current.xlPadding
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: feesLayout
|
||||||
|
spacing: 10
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.margins: Style.current.padding
|
||||||
|
|
||||||
|
StatusRoundIcon {
|
||||||
|
id: feesIcon
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
radius: 8
|
||||||
|
asset.name: "fees"
|
||||||
|
}
|
||||||
|
Column {
|
||||||
|
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
|
||||||
|
Layout.preferredWidth: root.width - feesIcon.width - Style.current.xlPadding
|
||||||
|
Item {
|
||||||
|
width: parent.width
|
||||||
|
height: childrenRect.height
|
||||||
|
StatusBaseText {
|
||||||
|
id: text
|
||||||
|
anchors.left: parent.left
|
||||||
|
font.pixelSize: 15
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.palette.directColor1
|
||||||
|
text: qsTr("Fees")
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
StatusBaseText {
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Style.current.padding
|
||||||
|
id: totalFeesAdvanced
|
||||||
|
text: root.isLoading ? "..." : gasSelector.selectedGasFiatValue
|
||||||
|
font.pixelSize: 15
|
||||||
|
color: Theme.palette.directColor1
|
||||||
|
visible: root.advancedOrCustomMode && root.bestRoutes.length > 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GasSelector {
|
||||||
|
id: gasSelector
|
||||||
|
width: parent.width
|
||||||
|
getGasEthValue: root.store.getGasEthValue
|
||||||
|
getFiatValue: root.store.getFiatValue
|
||||||
|
currentCurrency: root.store.currencyStore.currentCurrency
|
||||||
|
currentCurrencySymbol: root.store.currencyStore.currentCurrencySymbol
|
||||||
|
visible: gasValidator.isValid && !root.isLoading
|
||||||
|
advancedOrCustomMode: root.advancedOrCustomMode
|
||||||
|
bestRoutes: root.bestRoutes
|
||||||
|
selectedTokenSymbol: root.selectedTokenSymbol
|
||||||
|
onSelectedPriorityChanged: root.priorityChanged()
|
||||||
|
}
|
||||||
|
GasValidator {
|
||||||
|
id: gasValidator
|
||||||
|
width: parent.width
|
||||||
|
isLoading: root.isLoading
|
||||||
|
isValid: root.bestRoutes ? root.bestRoutes.length > 0 : true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,7 +44,9 @@ Item {
|
||||||
function resetAllSetValues() {
|
function resetAllSetValues() {
|
||||||
for(var i = 0; i<fromNetworksRepeater.count; i++) {
|
for(var i = 0; i<fromNetworksRepeater.count; i++) {
|
||||||
fromNetworksRepeater.itemAt(i).amountToSend = 0
|
fromNetworksRepeater.itemAt(i).amountToSend = 0
|
||||||
|
fromNetworksRepeater.itemAt(i).isOnBestRoute = false
|
||||||
toNetworksRepeater.itemAt(i).amountToReceive = 0
|
toNetworksRepeater.itemAt(i).amountToReceive = 0
|
||||||
|
toNetworksRepeater.itemAt(i).isOnBestRoute = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,6 +78,7 @@ Item {
|
||||||
id: fromNetwork
|
id: fromNetwork
|
||||||
objectName: model.chainId
|
objectName: model.chainId
|
||||||
property double amountToSend: 0
|
property double amountToSend: 0
|
||||||
|
property bool isOnBestRoute: false
|
||||||
property string tokenBalanceOnChain: selectedAccount && selectedAccount!== undefined && selectedAsset!== undefined ? selectedAccount.getTokenBalanceOnChain(model.chainId, selectedAsset.symbol) : ""
|
property string tokenBalanceOnChain: selectedAccount && selectedAccount!== undefined && selectedAsset!== undefined ? selectedAccount.getTokenBalanceOnChain(model.chainId, selectedAsset.symbol) : ""
|
||||||
property var hasGas: selectedAccount.hasGas(model.chainId, model.nativeCurrencySymbol, requiredGasInEth)
|
property var hasGas: selectedAccount.hasGas(model.chainId, model.nativeCurrencySymbol, requiredGasInEth)
|
||||||
primaryText: model.chainName
|
primaryText: model.chainName
|
||||||
|
@ -91,8 +94,14 @@ Item {
|
||||||
clickable: root.interactive
|
clickable: root.interactive
|
||||||
onClicked: {
|
onClicked: {
|
||||||
store.addRemoveDisabledFromChain(model.chainId, disabled)
|
store.addRemoveDisabledFromChain(model.chainId, disabled)
|
||||||
|
// only recalculate if the a best route was disabled
|
||||||
|
if(root.bestRoutes.length === 0 || isOnBestRoute)
|
||||||
root.reCalculateSuggestedRoute()
|
root.reCalculateSuggestedRoute()
|
||||||
}
|
}
|
||||||
|
onVisibleChanged: {
|
||||||
|
if(visible)
|
||||||
|
disabled = store.disabledChainIdsFromList.includes(model.chainId)
|
||||||
|
}
|
||||||
// To-do needed for custom view
|
// To-do needed for custom view
|
||||||
// onAdvancedInputTextChanged: {
|
// onAdvancedInputTextChanged: {
|
||||||
// if(selectedNetwork && selectedNetwork.chainName === model.chainName) {
|
// if(selectedNetwork && selectedNetwork.chainName === model.chainName) {
|
||||||
|
@ -120,6 +129,7 @@ Item {
|
||||||
StatusCard {
|
StatusCard {
|
||||||
id: toCard
|
id: toCard
|
||||||
objectName: model.chainId
|
objectName: model.chainId
|
||||||
|
property bool isOnBestRoute: false
|
||||||
property double amountToReceive: 0
|
property double amountToReceive: 0
|
||||||
primaryText: model.chainName
|
primaryText: model.chainName
|
||||||
secondaryText: LocaleUtils.numberToLocaleString(amountToReceive)
|
secondaryText: LocaleUtils.numberToLocaleString(amountToReceive)
|
||||||
|
@ -135,8 +145,14 @@ Item {
|
||||||
clickable: root.interactive
|
clickable: root.interactive
|
||||||
onClicked: {
|
onClicked: {
|
||||||
store.addRemoveDisabledToChain(model.chainId, disabled)
|
store.addRemoveDisabledToChain(model.chainId, disabled)
|
||||||
|
// only recalculate if the a best route was disabled
|
||||||
|
if(root.bestRoutes.length === 0 || isOnBestRoute)
|
||||||
root.reCalculateSuggestedRoute()
|
root.reCalculateSuggestedRoute()
|
||||||
}
|
}
|
||||||
|
onVisibleChanged: {
|
||||||
|
if(visible)
|
||||||
|
disabled = store.disabledChainIdsToList.includes(model.chainId)
|
||||||
|
}
|
||||||
// To-do needed for custom view
|
// To-do needed for custom view
|
||||||
// onAdvancedInputTextChanged: {
|
// onAdvancedInputTextChanged: {
|
||||||
// if(selectedNetwork && selectedNetwork.chainName === model.chainName)
|
// if(selectedNetwork && selectedNetwork.chainName === model.chainName)
|
||||||
|
@ -190,6 +206,8 @@ Item {
|
||||||
let amountToReceive = weiToEth(bestRoutes[i].amountOut)
|
let amountToReceive = weiToEth(bestRoutes[i].amountOut)
|
||||||
fromN.amountToSend = amountToSend
|
fromN.amountToSend = amountToSend
|
||||||
toN.amountToReceive += amountToReceive
|
toN.amountToReceive += amountToReceive
|
||||||
|
fromN.isOnBestRoute = true
|
||||||
|
toN.isOnBestRoute = true
|
||||||
d.thereIsApossibleRoute = true
|
d.thereIsApossibleRoute = true
|
||||||
StatusQUtils.Utils.drawArrow(ctx, fromN.x + fromN.width,
|
StatusQUtils.Utils.drawArrow(ctx, fromN.x + fromN.width,
|
||||||
fromN.y + fromN.height/2,
|
fromN.y + fromN.height/2,
|
||||||
|
|
|
@ -14,7 +14,7 @@ import "../controls"
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
implicitHeight: visible ? tabBar.height + stackLayout.height + 2* Style.current.xlPadding : 0
|
implicitHeight: visible ? tabBar.height + stackLayout.height + Style.current.xlPadding : 0
|
||||||
|
|
||||||
property var store
|
property var store
|
||||||
property var selectedAccount
|
property var selectedAccount
|
||||||
|
@ -29,6 +29,7 @@ Item {
|
||||||
(tabBar.currentIndex === 2) ?
|
(tabBar.currentIndex === 2) ?
|
||||||
customNetworkRoutingPage.errorMode: false
|
customNetworkRoutingPage.errorMode: false
|
||||||
property bool interactive: true
|
property bool interactive: true
|
||||||
|
property bool isBridgeTx: false
|
||||||
|
|
||||||
signal reCalculateSuggestedRoute()
|
signal reCalculateSuggestedRoute()
|
||||||
|
|
||||||
|
@ -41,7 +42,6 @@ Item {
|
||||||
StatusSwitchTabBar {
|
StatusSwitchTabBar {
|
||||||
id: tabBar
|
id: tabBar
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: Style.current.bigPadding
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
StatusSwitchTabButton {
|
StatusSwitchTabButton {
|
||||||
text: qsTr("Simple")
|
text: qsTr("Simple")
|
||||||
|
@ -76,11 +76,16 @@ Item {
|
||||||
anchors.margins: Style.current.padding
|
anchors.margins: Style.current.padding
|
||||||
width: stackLayout.width - Style.current.bigPadding
|
width: stackLayout.width - Style.current.bigPadding
|
||||||
bestRoutes: root.bestRoutes
|
bestRoutes: root.bestRoutes
|
||||||
|
isBridgeTx: root.isBridgeTx
|
||||||
amountToSend: root.amountToSend
|
amountToSend: root.amountToSend
|
||||||
isLoading: root.isLoading
|
isLoading: root.isLoading
|
||||||
|
store: root.store
|
||||||
weiToEth: function(wei) {
|
weiToEth: function(wei) {
|
||||||
return "%1 %2".arg(LocaleUtils.numberToLocaleString(parseFloat(store.getWei2Eth(wei, selectedAsset.decimals)))).arg(selectedAsset.symbol)
|
return "%1 %2".arg(LocaleUtils.numberToLocaleString(parseFloat(store.getWei2Eth(wei, selectedAsset.decimals)))).arg(selectedAsset.symbol)
|
||||||
}
|
}
|
||||||
|
reCalculateSuggestedRoute: function() {
|
||||||
|
root.reCalculateSuggestedRoute()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,13 @@ import "../controls"
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property var store
|
||||||
property var bestRoutes
|
property var bestRoutes
|
||||||
property double amountToSend: 0
|
property double amountToSend: 0
|
||||||
property bool isLoading: false
|
property bool isLoading: false
|
||||||
|
property bool isBridgeTx: false
|
||||||
property var weiToEth: function(wei) {}
|
property var weiToEth: function(wei) {}
|
||||||
|
property var reCalculateSuggestedRoute: function() {}
|
||||||
|
|
||||||
spacing: 10
|
spacing: 10
|
||||||
|
|
||||||
|
@ -42,17 +45,10 @@ RowLayout {
|
||||||
Layout.maximumWidth: 410
|
Layout.maximumWidth: 410
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
color: Theme.palette.baseColor1
|
color: Theme.palette.baseColor1
|
||||||
text: qsTr("The networks where the receipient will receive tokens. Amounts calculated automatically for the lowest cost.")
|
text: isBridgeTx ? qsTr("Choose the network to bridge token to") :
|
||||||
|
qsTr("The networks where the receipient will receive tokens. Amounts calculated automatically for the lowest cost.")
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
}
|
}
|
||||||
BalanceExceeded {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.topMargin: Style.current.bigPadding
|
|
||||||
transferPossible: root.bestRoutes !== undefined ? root.bestRoutes.length > 0 : true
|
|
||||||
amountToSend: root.amountToSend
|
|
||||||
isLoading: root.isLoading
|
|
||||||
}
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: row.height + 10
|
Layout.preferredHeight: row.height + 10
|
||||||
|
@ -62,20 +58,39 @@ RowLayout {
|
||||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
|
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
|
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
|
||||||
clip: true
|
clip: true
|
||||||
visible: !root.isLoading ? root.bestRoutes !== undefined ? root.bestRoutes.length > 0 : true : false
|
visible: !root.isLoading ? root.isBridgeTx ? true : root.bestRoutes !== undefined ? root.bestRoutes.length > 0 : true : false
|
||||||
Row {
|
Row {
|
||||||
id: row
|
id: row
|
||||||
spacing: Style.current.padding
|
spacing: Style.current.padding
|
||||||
Repeater {
|
Repeater {
|
||||||
id: repeater
|
id: repeater
|
||||||
objectName: "networksList"
|
objectName: "networksList"
|
||||||
model: root.bestRoutes
|
model: isBridgeTx ? store.allNetworks : root.bestRoutes
|
||||||
|
delegate: isBridgeTx ? networkItem : routeItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BalanceExceeded {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.topMargin: Style.current.bigPadding
|
||||||
|
transferPossible: root.bestRoutes !== undefined ? root.bestRoutes.length > 0 : true
|
||||||
|
amountToSend: root.amountToSend
|
||||||
|
isLoading: root.isLoading
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonGroup {
|
||||||
|
buttons: repeater.children
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: routeItem
|
||||||
StatusListItem {
|
StatusListItem {
|
||||||
id: item
|
|
||||||
objectName: modelData.toNetwork.chainName
|
objectName: modelData.toNetwork.chainName
|
||||||
leftPadding: 5
|
leftPadding: 5
|
||||||
rightPadding: 5
|
rightPadding: 5
|
||||||
implicitWidth: 150
|
implicitWidth: 126
|
||||||
title: modelData.toNetwork.chainName
|
title: modelData.toNetwork.chainName
|
||||||
subTitle: root.weiToEth(modelData.amountIn)
|
subTitle: root.weiToEth(modelData.amountIn)
|
||||||
statusListItemSubTitle.color: Theme.palette.primaryColor1
|
statusListItemSubTitle.color: Theme.palette.primaryColor1
|
||||||
|
@ -86,6 +101,47 @@ RowLayout {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: networkItem
|
||||||
|
StatusRadioButton {
|
||||||
|
id: gasRectangle
|
||||||
|
width: contentItem.implicitWidth
|
||||||
|
contentItem: StatusListItem {
|
||||||
|
id: card
|
||||||
|
objectName: chainName
|
||||||
|
leftPadding: 5
|
||||||
|
rightPadding: 5
|
||||||
|
implicitWidth: 150
|
||||||
|
title: chainName
|
||||||
|
subTitle: root.weiToEth(balance)
|
||||||
|
statusListItemSubTitle.color: Theme.palette.primaryColor1
|
||||||
|
asset.width: 32
|
||||||
|
asset.height: 32
|
||||||
|
asset.name: Style.svg("tiny/" + iconUrl)
|
||||||
|
asset.isImage: true
|
||||||
|
color: {
|
||||||
|
if (sensor.containsMouse || highlighted || gasRectangle.checked) {
|
||||||
|
return Theme.palette.baseColor2
|
||||||
|
}
|
||||||
|
return Theme.palette.statusListItem.backgroundColor
|
||||||
|
}
|
||||||
|
onClicked: gasRectangle.toggle()
|
||||||
|
}
|
||||||
|
onCheckedChanged: {
|
||||||
|
store.addRemoveDisabledToChain(chainId, !gasRectangle.checked)
|
||||||
|
if(checked)
|
||||||
|
root.reCalculateSuggestedRoute()
|
||||||
|
}
|
||||||
|
checked: index === 0
|
||||||
|
indicator: Item {
|
||||||
|
width: card.width
|
||||||
|
height: card.height
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
store.addRemoveDisabledToChain(chainId, !gasRectangle.checked)
|
||||||
|
if(index === (repeater.count -1))
|
||||||
|
root.reCalculateSuggestedRoute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ Rectangle {
|
||||||
property string maxFiatFees: "..."
|
property string maxFiatFees: "..."
|
||||||
property alias selectedTimeEstimate: estimatedTime.text
|
property alias selectedTimeEstimate: estimatedTime.text
|
||||||
property bool pending: true
|
property bool pending: true
|
||||||
|
property alias nextButtonText: nextButton.text
|
||||||
|
|
||||||
signal nextButtonClicked()
|
signal nextButtonClicked()
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusFlatButton {
|
StatusFlatButton {
|
||||||
|
id: nextButton
|
||||||
text: qsTr("Send")
|
text: qsTr("Send")
|
||||||
objectName: "sendModalFooterSendButton"
|
objectName: "sendModalFooterSendButton"
|
||||||
size: StatusBaseButton.Size.Large
|
size: StatusBaseButton.Size.Large
|
||||||
|
@ -88,6 +90,7 @@ Rectangle {
|
||||||
enabled: !footer.pending
|
enabled: !footer.pending
|
||||||
loading: footer.pending
|
loading: footer.pending
|
||||||
onClicked: nextButtonClicked()
|
onClicked: nextButtonClicked()
|
||||||
|
icon.name: "password"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ import "../views"
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
clip: true
|
clip: true
|
||||||
implicitHeight: accountSelectionTabBar.height + stackLayout.height + Style.current.bigPadding
|
implicitHeight: visible ? accountSelectionTabBar.height + stackLayout.height + Style.current.bigPadding: 0
|
||||||
|
|
||||||
property var store
|
property var store
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@ Item {
|
||||||
StatusTabBar {
|
StatusTabBar {
|
||||||
id: accountSelectionTabBar
|
id: accountSelectionTabBar
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 20
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
import "../controls"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var assets: []
|
||||||
|
property string currentCurrencySymbol
|
||||||
|
signal tokenSelected(var selectedToken)
|
||||||
|
property var searchTokenSymbolByAddressFn: function (address) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
property string searchString
|
||||||
|
readonly property var updateSearchText: Backpressure.debounce(root, 1000, function(inputText) {
|
||||||
|
d.searchString = inputText
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
height: visible ? tokenList.height: 0
|
||||||
|
color: Theme.palette.indirectColor1
|
||||||
|
radius: 8
|
||||||
|
|
||||||
|
StatusListView {
|
||||||
|
id: tokenList
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: parent.top
|
||||||
|
width: parent.width
|
||||||
|
height: Math.min(433, tokenList.contentHeight)
|
||||||
|
|
||||||
|
model: SortFilterProxyModel {
|
||||||
|
sourceModel: root.assets
|
||||||
|
filters: [
|
||||||
|
ExpressionFilter {
|
||||||
|
expression: {
|
||||||
|
var tokenSymbolByAddress = searchTokenSymbolByAddressFn(d.searchString)
|
||||||
|
return symbol.startsWith(d.searchString.toUpperCase()) || name.toUpperCase().startsWith(d.searchString.toUpperCase()) || (tokenSymbolByAddress!=="" && symbol.startsWith(tokenSymbolByAddress))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
delegate: TokenDelegate {
|
||||||
|
objectName: "SendModal_AssetView_TokenListItem_" + symbol
|
||||||
|
readonly property string balance: enabledNetworkBalance // Needed for the tests
|
||||||
|
currentCurrencySymbol: root.currentCurrencySymbol
|
||||||
|
width: ListView.view.width
|
||||||
|
onClicked: {
|
||||||
|
tokenSelected({name: name, symbol: symbol, totalBalance: totalBalance, totalCurrencyBalance: totalCurrencyBalance, balances: balances, decimals: decimals})
|
||||||
|
}
|
||||||
|
color: sensor.containsMouse || highlighted ? Theme.palette.baseColor3 : "transparent"
|
||||||
|
}
|
||||||
|
headerPositioning: ListView.OverlayHeader
|
||||||
|
header: Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: childrenRect.height
|
||||||
|
color: Theme.palette.indirectColor1
|
||||||
|
radius: 8
|
||||||
|
z: 2
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
Item {
|
||||||
|
height: 5
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
StatusInput {
|
||||||
|
height: 50
|
||||||
|
width: parent.width
|
||||||
|
input.showBackground: false
|
||||||
|
placeholderText: qsTr("Search for token or enter token address")
|
||||||
|
input.rightComponent: StatusIcon {
|
||||||
|
icon: "search"
|
||||||
|
height: 17
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
}
|
||||||
|
onTextChanged: Qt.callLater(d.updateSearchText, text)
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
height: 1
|
||||||
|
width: parent.width
|
||||||
|
color: Theme.palette.baseColor3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -695,6 +695,7 @@ QtObject {
|
||||||
ENSRegister,
|
ENSRegister,
|
||||||
ENSRelease,
|
ENSRelease,
|
||||||
ENSSetPubKey,
|
ENSSetPubKey,
|
||||||
StickersBuy
|
StickersBuy,
|
||||||
|
Bridge
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5b69985b189cae2a5e36153fa4be58afe075b446
|
Subproject commit 4c29c97591f5a68cb6c8f63290db8d1f1b778398
|
Loading…
Reference in New Issue