feat(@deaktop/wallet): Add bridge view

fixes #8236
This commit is contained in:
Khushboo Mehta 2022-11-23 18:58:22 +01:00 committed by Khushboo-dev-cpp
parent 75b5a583dd
commit 9ded9d4ffa
20 changed files with 485 additions and 194 deletions

View File

@ -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):

View File

@ -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>

View File

@ -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

View File

@ -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 {

View File

@ -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
} }
} }

View File

@ -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) : "---"
}
}
}
]
}

View File

@ -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

View File

@ -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}
} }

View File

@ -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
} }
} }

View File

@ -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() {

View File

@ -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

View File

@ -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
}
}
}
}

View File

@ -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,

View File

@ -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()
}
} }
} }

View File

@ -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()
} }
} }
} }

View File

@ -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"
} }
} }
} }

View File

@ -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

View File

@ -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
}
}
}
}
}

View File

@ -695,6 +695,7 @@ QtObject {
ENSRegister, ENSRegister,
ENSRelease, ENSRelease,
ENSSetPubKey, ENSSetPubKey,
StickersBuy StickersBuy,
Bridge
} }
} }

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit 5b69985b189cae2a5e36153fa4be58afe075b446 Subproject commit 4c29c97591f5a68cb6c8f63290db8d1f1b778398