mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-10 06:16:32 +00:00
d8b0145eb3
Add gas estimate for sticker pack purchase. Update transaction for sticker pack purchase. Add GasValidator component which validates gas is selected correctly and displays an error message if not. This component is not visible until it is not valid (at which point the valdiation error message is displayed). In a future PR, need to: 1. estimate gas for token txfer (sendTransaction) via a normalised method for estimating gas for EthSend 2. move sticker pack purchase to use an EthSend object so gas can be estimated and tx sent
292 lines
9.7 KiB
QML
292 lines
9.7 KiB
QML
import QtQuick 2.13
|
|
import QtQuick.Controls 2.13
|
|
import QtQuick.Layouts 1.13
|
|
import "../imports"
|
|
import "./"
|
|
|
|
Item {
|
|
id: root
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
height: sliderWrapper.height + Style.current.smallPadding + txtNetworkFee.height + buttonAdvanced.height
|
|
property double slowestGasPrice: 0
|
|
property double fastestGasPrice: 100
|
|
property double stepSize: ((root.fastestGasPrice - root.slowestGasPrice) / 10).toFixed(1)
|
|
property var getGasEthValue: function () {}
|
|
property var getFiatValue: function () {}
|
|
property string defaultCurrency: "USD"
|
|
property alias selectedGasPrice: inputGasPrice.text
|
|
property alias selectedGasLimit: inputGasLimit.text
|
|
property double selectedGasEthValue
|
|
property double selectedGasFiatValue
|
|
property string greaterThan0ErrorMessage: qsTr("Must be greater than 0")
|
|
//% "This needs to be a number"
|
|
property string invalidInputErrorMessage: qsTrId("this-needs-to-be-a-number")
|
|
property string noInputErrorMessage: qsTr("Please enter an amount")
|
|
property bool isValid: true
|
|
property var reset: function() {}
|
|
|
|
function defaultGasPrice() {
|
|
return ((50 * (root.fastestGasPrice - root.slowestGasPrice) / 100) + root.slowestGasPrice)
|
|
}
|
|
|
|
function resetInternal() {
|
|
slowestGasPrice = 0
|
|
fastestGasPrice = 100
|
|
inputGasLimit.text = "21000"
|
|
customNetworkFeeDialog.isValid = true
|
|
inputGasPrice.text = Qt.binding(defaultGasPrice)
|
|
gasSlider.value = Qt.binding(defaultGasPrice)
|
|
}
|
|
|
|
function updateGasEthValue() {
|
|
// causes error on application load without this null check
|
|
if (!inputGasPrice || !inputGasLimit) {
|
|
return
|
|
}
|
|
let ethValue = root.getGasEthValue(inputGasPrice.text, inputGasLimit.text)
|
|
let fiatValue = root.getFiatValue(ethValue, "ETH", root.defaultCurrency)
|
|
let summary = Utils.stripTrailingZeros(ethValue) + " ETH ~" + fiatValue + " " + root.defaultCurrency.toUpperCase()
|
|
labelGasPriceSummary.text = summary
|
|
labelGasPriceSummaryAdvanced.text = summary
|
|
selectedGasEthValue = ethValue
|
|
selectedGasFiatValue = fiatValue
|
|
}
|
|
|
|
StyledText {
|
|
id: txtNetworkFee
|
|
anchors.top: parent.top
|
|
anchors.left: parent.left
|
|
//% "Network fee"
|
|
text: qsTrId("network-fee")
|
|
font.weight: Font.Medium
|
|
font.pixelSize: 13
|
|
color: Style.current.textColor
|
|
}
|
|
|
|
StyledText {
|
|
id: labelGasPriceSummary
|
|
anchors.top: parent.top
|
|
anchors.right: parent.right
|
|
font.weight: Font.Medium
|
|
font.pixelSize: 13
|
|
color: Style.current.secondaryText
|
|
}
|
|
|
|
Item {
|
|
id: sliderWrapper
|
|
anchors.topMargin: Style.current.smallPadding
|
|
anchors.top: labelGasPriceSummary.bottom
|
|
height: sliderWrapper.visible ? gasSlider.height + labelSlow.height + Style.current.padding : 0
|
|
width: parent.width
|
|
visible: Number(root.selectedGasPrice) >= Number(root.slowestGasPrice) && Number(root.selectedGasPrice) <= Number(root.fastestGasPrice)
|
|
|
|
StatusSlider {
|
|
id: gasSlider
|
|
minimumValue: root.slowestGasPrice
|
|
maximumValue: root.fastestGasPrice
|
|
stepSize: root.stepSize
|
|
value: root.defaultGasPrice()
|
|
onValueChanged: {
|
|
if (!isNaN(gasSlider.value)) {
|
|
inputGasPrice.text = gasSlider.value + ""
|
|
root.updateGasEthValue()
|
|
}
|
|
}
|
|
visible: parent.visible
|
|
}
|
|
|
|
StyledText {
|
|
id: labelSlow
|
|
anchors.top: gasSlider.bottom
|
|
anchors.topMargin: Style.current.padding
|
|
anchors.left: parent.left
|
|
//% "Slow"
|
|
text: qsTrId("slow")
|
|
font.pixelSize: 15
|
|
color: Style.current.textColor
|
|
visible: parent.visible
|
|
}
|
|
|
|
StyledText {
|
|
id: labelOptimal
|
|
anchors.top: gasSlider.bottom
|
|
anchors.topMargin: Style.current.padding
|
|
anchors.horizontalCenter: gasSlider.horizontalCenter
|
|
//% "Optimal"
|
|
text: qsTrId("optimal")
|
|
font.pixelSize: 15
|
|
color: Style.current.textColor
|
|
visible: parent.visible
|
|
}
|
|
|
|
StyledText {
|
|
id: labelFast
|
|
anchors.top: gasSlider.bottom
|
|
anchors.topMargin: Style.current.padding
|
|
anchors.right: parent.right
|
|
//% "Fast"
|
|
text: qsTrId("fast")
|
|
font.pixelSize: 15
|
|
color: Style.current.textColor
|
|
visible: parent.visible
|
|
}
|
|
}
|
|
|
|
StyledButton {
|
|
id: buttonReset
|
|
anchors.top: sliderWrapper.bottom
|
|
anchors.topMargin: sliderWrapper.visible ? Style.current.smallPadding : 0
|
|
anchors.right: buttonAdvanced.left
|
|
anchors.rightMargin: -Style.current.padding
|
|
//% "Reset"
|
|
label: qsTrId("reset")
|
|
btnColor: "transparent"
|
|
textSize: 13
|
|
visible: !sliderWrapper.visible
|
|
onClicked: {
|
|
gasSlider.value = root.defaultGasPrice()
|
|
inputGasPrice.text = root.defaultGasPrice()
|
|
}
|
|
}
|
|
|
|
StyledButton {
|
|
id: buttonAdvanced
|
|
anchors.top: sliderWrapper.bottom
|
|
anchors.topMargin: sliderWrapper.visible ? Style.current.smallPadding : 0
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: -Style.current.padding
|
|
//% "Advanced"
|
|
label: qsTrId("advanced")
|
|
btnColor: "transparent"
|
|
textSize: 13
|
|
onClicked: {
|
|
customNetworkFeeDialog.open()
|
|
}
|
|
}
|
|
|
|
ModalPopup {
|
|
id: customNetworkFeeDialog
|
|
//% "Custom Network Fee"
|
|
title: qsTrId("custom-network-fee")
|
|
height: 286
|
|
width: 400
|
|
property bool isValid: true
|
|
|
|
onIsValidChanged: {
|
|
root.isValid = isValid
|
|
}
|
|
|
|
function validate() {
|
|
// causes error on application load without a null check
|
|
if (!inputGasLimit || !inputGasPrice) {
|
|
return
|
|
}
|
|
inputGasLimit.validationError = ""
|
|
inputGasPrice.validationError = ""
|
|
const noInputLimit = inputGasLimit.text === ""
|
|
const noInputPrice = inputGasPrice.text === ""
|
|
if (noInputLimit) {
|
|
inputGasLimit.validationError = root.noInputErrorMessage
|
|
}
|
|
if (noInputPrice) {
|
|
inputGasPrice.validationError = root.noInputErrorMessage
|
|
}
|
|
if (isNaN(inputGasLimit.text)) {
|
|
inputGasLimit.validationError = invalidInputErrorMessage
|
|
}
|
|
if (isNaN(inputGasPrice.text)) {
|
|
inputGasPrice.validationError = invalidInputErrorMessage
|
|
}
|
|
let inputLimit = parseFloat(inputGasLimit.text || "0.00")
|
|
let inputPrice = parseFloat(inputGasPrice.text || "0.00")
|
|
if (inputLimit === 0.00) {
|
|
inputGasLimit.validationError = root.greaterThan0ErrorMessage
|
|
}
|
|
if (inputPrice === 0.00) {
|
|
inputGasPrice.validationError = root.greaterThan0ErrorMessage
|
|
}
|
|
const isValid = inputGasLimit.validationError === "" && inputGasPrice.validationError === ""
|
|
customNetworkFeeDialog.isValid = isValid
|
|
return isValid
|
|
}
|
|
|
|
Input {
|
|
id: inputGasLimit
|
|
//% "Gas limit"
|
|
label: qsTrId("gas-limit")
|
|
text: "21000"
|
|
customHeight: 56
|
|
anchors.top: parent.top
|
|
anchors.left: parent.left
|
|
anchors.right: inputGasPrice.left
|
|
anchors.rightMargin: Style.current.padding
|
|
placeholderText: "21000"
|
|
validationErrorAlignment: TextEdit.AlignRight
|
|
validationErrorTopMargin: 8
|
|
onTextChanged: {
|
|
if (customNetworkFeeDialog.validate()) {
|
|
root.updateGasEthValue()
|
|
}
|
|
}
|
|
}
|
|
|
|
Input {
|
|
id: inputGasPrice
|
|
//% "Gas price"
|
|
label: qsTrId("gas-price")
|
|
anchors.top: parent.top
|
|
anchors.left: undefined
|
|
anchors.right: parent.right
|
|
width: 130
|
|
customHeight: 56
|
|
text: root.defaultGasPrice()
|
|
placeholderText: "20"
|
|
onTextChanged: {
|
|
if (inputGasPrice.text.trim() === "") {
|
|
inputGasPrice.text = root.defaultGasPrice()
|
|
}
|
|
if (customNetworkFeeDialog.validate()) {
|
|
root.updateGasEthValue()
|
|
}
|
|
}
|
|
|
|
StyledText {
|
|
color: Style.current.darkGrey
|
|
//% "Gwei"
|
|
text: qsTrId("gwei")
|
|
anchors.top: parent.top
|
|
anchors.topMargin: 42
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: Style.current.padding
|
|
font.pixelSize: 15
|
|
}
|
|
}
|
|
|
|
StyledText {
|
|
id: labelGasPriceSummaryAdvanced
|
|
anchors.bottom: parent.bottom
|
|
anchors.bottomMargin: Style.current.smallPadding
|
|
anchors.right: parent.right
|
|
font.weight: Font.Medium
|
|
font.pixelSize: 13
|
|
color: Style.current.secondaryText
|
|
}
|
|
|
|
footer: StyledButton {
|
|
id: applyButton
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: Style.current.smallPadding
|
|
label: qsTr("Apply")
|
|
anchors.bottom: parent.bottom
|
|
disabled: !customNetworkFeeDialog.isValid
|
|
onClicked: {
|
|
if (customNetworkFeeDialog.validate()) {
|
|
root.updateGasEthValue()
|
|
}
|
|
customNetworkFeeDialog.close()
|
|
}
|
|
}
|
|
}
|
|
}
|