fix(wallet): Update amount to send decimal handling (#14399)

This commit is contained in:
Cuteivist 2024-04-15 07:28:29 +02:00 committed by GitHub
parent d3f037f93b
commit 7cb59576a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 227 additions and 13 deletions

View File

@ -0,0 +1,66 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import StatusQ.Controls 0.1
import Storybook 1.0
import utils 1.0
import shared.controls 1.0
SplitView {
id: root
orientation: Qt.Horizontal
Item {
SplitView.fillWidth: true
SplitView.fillHeight: true
StatusAmountInput {
id: input
anchors.centerIn: parent
}
}
LogsAndControlsPanel {
SplitView.minimumWidth: 300
SplitView.preferredWidth: 400
SplitView.fillHeight: true
ColumnLayout {
Layout.fillWidth: true
RowLayout {
Layout.fillWidth: true
Label {
text: "Valid:"
}
Label {
Layout.fillWidth: true
Layout.alignment: Qt.AlignRight
horizontalAlignment: Text.AlignRight
font.bold: true
text: input.valid ? "true" : "false"
}
}
RowLayout {
Layout.fillWidth: true
Label {
text: "Locale:"
}
Label {
Layout.fillWidth: true
Layout.alignment: Qt.AlignRight
horizontalAlignment: Text.AlignRight
font.bold: true
text: input.locale.name
}
}
}
}
}
// category: Controls
// https://www.figma.com/file/eM26pyHZUeAwMLviaS1KJn/%E2%9A%99%EF%B8%8F-Wallet-Settings%3A-Manage-Tokens?type=design&node-id=305-139866&mode=design&t=g49O9LFh8PkuPxZB-0

View File

@ -0,0 +1,97 @@
import QtQuick 2.15
import QtTest 1.15
import StatusQ.Controls 0.1
import Storybook 1.0
import shared.controls 1.0
Item {
id: root
width: 600
height: 400
Component {
id: componentUnderTest
StatusAmountInput {
id: input
anchors.centerIn: parent
locale: Qt.locale("en_US") // US uses period as decimal point
}
}
TestCase {
name: "StatusAmountInput"
when: windowShown
property StatusAmountInput controlUnderTest: null
function init() {
controlUnderTest = createTemporaryObject(componentUnderTest, root)
controlUnderTest.forceActiveFocus()
}
function test_decimalPoint() {
verify(!!controlUnderTest)
keyClick(Qt.Key_1)
keyClick(Qt.Key_2)
keyClick(Qt.Key_Comma)
keyClick(Qt.Key_2)
compare(controlUnderTest.text, "12.2")
keyClick(Qt.Key_Period)
compare(controlUnderTest.text, "12.2", "There can be only single decimal point")
controlUnderTest.text = ""
compare(controlUnderTest.text.length, 0)
keyClick(Qt.Key_5)
keyClick(Qt.Key_3)
keyClick(Qt.Key_Period)
keyClick(Qt.Key_3)
compare(controlUnderTest.text, "53.3")
keyClick(Qt.Key_Comma)
compare(controlUnderTest.text, "53.3", "There can be only single decimal point")
controlUnderTest.text = ""
compare(controlUnderTest.text.length, 0)
controlUnderTest.locale = Qt.locale("pl_PL") // PL uses comma as decimal point
keyClick(Qt.Key_6)
keyClick(Qt.Key_2)
keyClick(Qt.Key_Period)
keyClick(Qt.Key_1)
compare(controlUnderTest.text, "62,1")
}
function test_unallowedKeys() {
verify(!!controlUnderTest)
keyClick(Qt.Key_1)
for (let i = Qt.Key_A ; i <= Qt.Key_BracketRight ; i++) {
keyClick(i)
}
keyClick(Qt.Key_Space)
keyClick(Qt.Key_3)
compare(controlUnderTest.text, "13")
}
function test_defaultValidation() {
verify(!!controlUnderTest)
verify(!controlUnderTest.valid)
keyClick(Qt.Key_4)
verify(controlUnderTest.valid)
controlUnderTest.text = "-12"
verify(!controlUnderTest.valid, "Amount below zero is not allowed")
}
}
}

View File

@ -279,7 +279,7 @@ Rectangle {
color: Theme.palette.pinColor1 color: Theme.palette.pinColor1
} }
} }
StatusInput { StatusAmountInput {
id: advancedInput id: advancedInput
Layout.preferredWidth: layout.width Layout.preferredWidth: layout.width
maximumHeight: 32 maximumHeight: 32
@ -287,6 +287,7 @@ Rectangle {
bottomPadding: 0 bottomPadding: 0
leftPadding: 8 leftPadding: 8
rightPadding: 5 rightPadding: 5
locale: root.locale
input.edit.color: { // crash workaround, https://bugreports.qt.io/browse/QTBUG-107795 input.edit.color: { // crash workaround, https://bugreports.qt.io/browse/QTBUG-107795
if (root.state === "error") if (root.state === "error")
return Theme.palette.dangerColor1 return Theme.palette.dangerColor1

View File

@ -0,0 +1,34 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import StatusQ.Core 0.1
import StatusQ.Controls.Validators 0.1
// StatusInput variation that allows only one decimal point and only numbers
StatusInput {
id: root
property var locale: LocaleUtils.userInputLocale
input.edit.objectName: "amountInput"
validators: [
StatusFloatValidator {
bottom: 0
errorMessage: ""
locale: LocaleUtils.userInputLocale
}
]
onKeyPressed: (event) => {
// additionally accept dot (.) and convert it to the correct decimal point char
if (event.key === Qt.Key_Period || event.key === Qt.Key_Comma) {
// Only one decimal point is allowed
if(root.text.indexOf(root.locale.decimalPoint) === -1)
root.input.insert(root.input.cursorPosition, root.locale.decimalPoint)
event.accepted = true
} else if ((event.key > Qt.Key_9 && event.key <= Qt.Key_BraceRight) || event.key === Qt.Key_Space) {
event.accepted = true
}
}
}

View File

@ -273,6 +273,13 @@ Item {
*/ */
signal editingFinished() signal editingFinished()
function insert(position, text) {
let pos = edit.cursorVisible ? edit.cursorPosition : -1
edit.insert(position, text)
if (pos >= 0)
edit.cursorPosition = position <= pos ? pos + 1 : pos
}
onFocusChanged: { onFocusChanged: {
if(focus) edit.forceActiveFocus() if(focus) edit.forceActiveFocus()
} }
@ -369,7 +376,7 @@ Item {
focus: true focus: true
font.pixelSize: 15 font.pixelSize: 15
font.family: Theme.palette.baseFont.name font.family: Theme.palette.baseFont.name
color: root.enabled ? Theme.palette.directColor1 : Theme.palette.baseColor1 color: root.enabled ? Theme.palette.directColor1 : Theme.palette.baseColor1
wrapMode: root.multiline ? Text.WrapAtWordBoundaryOrAnywhere : TextEdit.NoWrap wrapMode: root.multiline ? Text.WrapAtWordBoundaryOrAnywhere : TextEdit.NoWrap
Keys.onReturnPressed: { Keys.onReturnPressed: {

View File

@ -27,6 +27,7 @@ StatusLabeledSlider 0.1 StatusLabeledSlider.qml
StatusSelect 0.1 StatusSelect.qml StatusSelect 0.1 StatusSelect.qml
StatusBaseInput 0.1 StatusBaseInput.qml StatusBaseInput 0.1 StatusBaseInput.qml
StatusInput 0.1 StatusInput.qml StatusInput 0.1 StatusInput.qml
StatusAmountInput 0.1 StatusAmountInput.qml
StatusPickerButton 0.1 StatusPickerButton.qml StatusPickerButton 0.1 StatusPickerButton.qml
StatusPinInput 0.1 StatusPinInput.qml StatusPinInput 0.1 StatusPinInput.qml
StatusProgressBar 0.1 StatusProgressBar.qml StatusProgressBar 0.1 StatusProgressBar.qml

View File

@ -6,7 +6,7 @@ import Qt.labs.settings 1.0
QtObject { QtObject {
id: root id: root
readonly property var userInputLocale: Qt.locale("en_US") readonly property var userInputLocale: Qt.locale()
function integralPartLength(num) { function integralPartLength(num) {
num = Math.abs(num) num = Math.abs(num)

View File

@ -111,6 +111,7 @@
<file>StatusQ/Controls/StatusImageCrop.qml</file> <file>StatusQ/Controls/StatusImageCrop.qml</file>
<file>StatusQ/Controls/StatusImageSelector.qml</file> <file>StatusQ/Controls/StatusImageSelector.qml</file>
<file>StatusQ/Controls/StatusInput.qml</file> <file>StatusQ/Controls/StatusInput.qml</file>
<file>StatusQ/Controls/StatusAmountInput.qml</file>
<file>StatusQ/Controls/StatusItemDelegate.qml</file> <file>StatusQ/Controls/StatusItemDelegate.qml</file>
<file>StatusQ/Controls/StatusItemPicker.qml</file> <file>StatusQ/Controls/StatusItemPicker.qml</file>
<file>StatusQ/Controls/StatusLabeledSlider.qml</file> <file>StatusQ/Controls/StatusLabeledSlider.qml</file>

View File

@ -138,8 +138,17 @@ ColumnLayout {
if(!addOrUpdateButton.enabled) if(!addOrUpdateButton.enabled)
return return
if(event.key === Qt.Key_Enter || event.key === Qt.Key_Return) // additionally accept dot (.) and convert it to the correct decimal point char
if (event.key === Qt.Key_Period || event.key === Qt.Key_Comma) {
// Only one decimal point is allowed
if(amountInput.text.indexOf(amountInput.locale.decimalPoint) === -1)
amountInput.textField.insert(amountInput.textField.cursorPosition, amountInput.locale.decimalPoint)
event.accepted = true
} else if ((event.key > Qt.Key_9 && event.key <= Qt.Key_BraceRight) || event.key === Qt.Key_Space) {
event.accepted = true
} else if(event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
addOrUpdateButton.clicked() addOrUpdateButton.clicked()
}
} }
onVisibleChanged: { onVisibleChanged: {
if(visible) if(visible)

View File

@ -606,7 +606,7 @@ SettingsContentBase {
text: qsTr("Choose a number between 1 and 100") text: qsTr("Choose a number between 1 and 100")
} }
StatusInput { StatusAmountInput {
id: numberInput id: numberInput
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -616,7 +616,7 @@ SettingsContentBase {
input.text: root.advancedStore.logMaxBackups input.text: root.advancedStore.logMaxBackups
placeholderText: qsTr("Number between 1 and 100") placeholderText: qsTr("Number between 1 and 100")
validators: [ validators: [
StatusFloatValidator { StatusIntValidator {
bottom: 1 bottom: 1
top: 100 top: 100
errorMessage: qsTr("Number needs to be between 1 and 100") errorMessage: qsTr("Number needs to be between 1 and 100")

View File

@ -504,8 +504,7 @@ StatusDialog {
totalTokenFeesInFiat = gasTimeEstimate.totalTokenFees * d.selectedHolding.marketDetails.currencyPrice.amount totalTokenFeesInFiat = gasTimeEstimate.totalTokenFees * d.selectedHolding.marketDetails.currencyPrice.amount
d.totalFeesInFiat = d.currencyStore.getFiatValue(gasTimeEstimate.totalFeesInEth, Constants.ethToken) + totalTokenFeesInFiat d.totalFeesInFiat = d.currencyStore.getFiatValue(gasTimeEstimate.totalFeesInEth, Constants.ethToken) + totalTokenFeesInFiat
if (!!d.selectedHolding.type && (d.selectedHolding.type === Constants.TokenType.ERC20 if (d.selectedHolding.type === Constants.TokenType.ERC20 || d.selectedHolding.type === Constants.TokenType.Native) {
|| d.selectedHolding.type === Constants.TokenType.ETH)) {
// If assets // If assets
d.totalAmountToReceive = popup.store.getWei2Eth(txRoutes.amountToReceive, d.selectedHolding.decimals) d.totalAmountToReceive = popup.store.getWei2Eth(txRoutes.amountToReceive, d.selectedHolding.decimals)
} else { } else {

View File

@ -7,7 +7,7 @@ import StatusQ.Core.Theme 0.1
import utils 1.0 import utils 1.0
StatusInput { StatusAmountInput {
id: cursorInput id: cursorInput
leftPadding: 0 leftPadding: 0
@ -16,7 +16,6 @@ StatusInput {
bottomPadding: 0 bottomPadding: 0
placeholderText: "" placeholderText: ""
input.edit.objectName: "amountInput"
input.edit.cursorVisible: true input.edit.cursorVisible: true
input.edit.font.pixelSize: Utils.getFontSizeBasedOnLetterCount(text) input.edit.font.pixelSize: Utils.getFontSizeBasedOnLetterCount(text)
input.placeholderFont.pixelSize: 34 input.placeholderFont.pixelSize: 34

View File

@ -131,7 +131,7 @@ ColumnLayout {
id: topAmountToSendInput id: topAmountToSendInput
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.maximumWidth: 250 Layout.maximumWidth: 250
Layout.preferredWidth: !!text ? input.edit.paintedWidth Layout.preferredWidth: !!text ? input.edit.paintedWidth + 2
: textMetrics.advanceWidth : textMetrics.advanceWidth
placeholderText: d.zeroString placeholderText: d.zeroString
input.edit.color: input.valid ? Theme.palette.directColor1 input.edit.color: input.valid ? Theme.palette.directColor1
@ -143,7 +143,7 @@ ColumnLayout {
id: floatValidator id: floatValidator
bottom: 0 bottom: 0
errorMessage: "" errorMessage: ""
locale: LocaleUtils.userInputLocale locale: topAmountToSendInput.locale
}, },
StatusValidator { StatusValidator {
errorMessage: "" errorMessage: ""
@ -168,7 +168,7 @@ ColumnLayout {
Keys.onReleased: { Keys.onReleased: {
const amount = LocaleUtils.numberFromLocaleString( const amount = LocaleUtils.numberFromLocaleString(
topAmountToSendInput.text, topAmountToSendInput.text,
LocaleUtils.userInputLocale) locale)
if (!isNaN(amount)) if (!isNaN(amount))
d.waitTimer.restart() d.waitTimer.restart()
} }