fix(wallet): Update amount to send decimal handling

This commit is contained in:
Emil Sawicki 2024-04-12 15:58:02 +02:00 committed by Iuri Matias
parent 35ec3e7297
commit 521971c9b5
12 changed files with 226 additions and 11 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
}
}
StatusInput {
StatusAmountInput {
id: advancedInput
Layout.preferredWidth: layout.width
maximumHeight: 32
@ -287,6 +287,7 @@ Rectangle {
bottomPadding: 0
leftPadding: 8
rightPadding: 5
locale: root.locale
input.edit.color: { // crash workaround, https://bugreports.qt.io/browse/QTBUG-107795
if (root.state === "error")
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()
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: {
if(focus) edit.forceActiveFocus()
}

View File

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

View File

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

View File

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

View File

@ -138,8 +138,17 @@ ColumnLayout {
if(!addOrUpdateButton.enabled)
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()
}
}
onVisibleChanged: {
if(visible)

View File

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

View File

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

View File

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