fix: Reimplemented selectors using `StatusComboBox`

This commit is contained in:
Igor Sirotin 2022-07-31 10:17:07 +03:00 committed by Lukáš Tinkl
parent be6240e41c
commit 5fb2be95ef
6 changed files with 101 additions and 170 deletions

@ -1 +1 @@
Subproject commit f4bf830ae7af5979255b383920980bf4d3a4b251
Subproject commit 63ff9b82d1f13c063dddbb244a255a9886705fc7

View File

@ -686,15 +686,6 @@ Assets won&#8217;t be sent yet.</source>
Assets won&#8217;t be sent yet.</translation>
</message>
</context>
<context>
<name>AddressSourceSelector</name>
<message>
<location filename="../imports/shared/controls/AddressSourceSelector.qml" line="29" />
<location filename="../imports/shared/controls/AddressSourceSelector.qml" line="29" />
<source>Invalid source</source>
<translation>Invalid source</translation>
</message>
</context>
<context>
<name>AdvancedAddAccountView</name>
<message>

View File

@ -1,49 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
import utils 1.0
Item {
id: root
property var sources: []
property var selectedSource: sources.length ? sources[0] : null
property int dropdownWidth: 220
height: select.height
StatusSelect {
id: select
anchors.left: parent.left
anchors.right: parent.right
model: root.sources
selectedItemComponent: Item {
anchors.fill: parent
StatusBaseText {
id: selectedTextField
text: !!root.selectedSource ? root.selectedSource.text : qsTr("Invalid source")
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 15
verticalAlignment: Text.AlignVCenter
height: 24
color: Theme.palette.directColor1
}
}
selectMenu.delegate: StatusMenuItemDelegate {
statusPopupMenu: select
action: StatusMenuItem {
text: root.sources[index].text
onTriggered: function () {
root.selectedSource = root.sources[index]
}
}
}
}
}

View File

@ -18,10 +18,9 @@ Item {
id: root
property var contactsStore
property var selectedContact
height: select.height
property int dropdownWidth: width
property string validationError: qsTr("Please select a contact")
property alias validationErrorAlignment: select.validationErrorAlignment
// property alias validationErrorAlignment: comboBox.validationErrorAlignment
property bool isValid: false
property alias isPending: ensResolver.isPending
@ -37,6 +36,8 @@ Item {
}
}
implicitHeight: comboBox.implicitHeight
Component.onCompleted: {
if (root.readOnly) {
return
@ -53,14 +54,14 @@ Item {
let isValidAddress = Utils.isValidAddress(selectedContact.address)
let isDefaultValue = selectedContact.alias === selectAContact
let isValid = (selectedContact.ensVerified && isValidAddress) || isPending || isValidAddress
select.validationError = ""
comboBox.validationError = ""
if (!isValid && !isDefaultValue &&
(
!selectedContact.ensVerified ||
(selectedContact.ensVerified && isResolvedAddress)
)
) {
select.validationError = !selectedContact.ensVerified ? noEnsAddressMessage : validationError
comboBox.validationError = !selectedContact.ensVerified ? noEnsAddressMessage : validationError
}
root.isValid = isValid
return isValid
@ -83,20 +84,22 @@ Item {
customHeight: 56
}
StatusSelect {
id: select
StatusComboBox {
id: comboBox
label: ""
model: root.contactsStore.myContactsModel
width: parent.width
visible: !root.readOnly
menuAlignment: StatusSelect.MenuAlignment.Left
selectedItemComponent: Item {
anchors.fill: parent
control.popup.width: dropdownWidth
control.padding: 14
enabled: control.count > 0
contentItem: RowLayout {
spacing: 4
StatusSmartIdenticon {
id: iconImg
anchors.left: parent.left
anchors.leftMargin: 14
anchors.verticalCenter: parent.verticalCenter
image.width: (!!selectedContact && !!selectedContact.displayIcon) ? 32 : 0
image.height: 32
image.source: (!!selectedContact && !!selectedContact.displayIcon) ? selectedContact.displayIcon : ""
@ -104,37 +107,77 @@ Item {
}
StatusBaseText {
id: selectedTextField
visible: comboBox.control.count > 0
text: !!selectedContact ? selectedContact.alias : ""
anchors.left: iconImg.right
anchors.leftMargin: 4
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 15
height: 22
verticalAlignment: Text.AlignVCenter
color: Theme.palette.directColor1
}
}
zeroItemsView: Item {
height: 186
StatusBaseText {
anchors.fill: parent
visible: comboBox.control.count == 0
text: qsTr("You dont have any contacts yet")
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 13
height: 18
color: Theme.palette.baseColor1
}
}
selectMenu.delegate: menuItem
selectMenu.width: dropdownWidth
delegate: StatusItemDelegate {
id: itemContainer
property var currentContact: Utils.getContactDetailsAsJson(pubKey)
highlighted: index === comboBox.control.highlightedIndex
width: parent.width
onClicked: {
root.selectedContact = itemContainer.currentContact
}
contentItem: RowLayout {
spacing: 12
StatusSmartIdenticon {
image.source: currentContact.displayIcon
}
ColumnLayout {
Layout.fillWidth: true
StatusBaseText {
Layout.fillWidth: true
text: currentContact.alias
font.pixelSize: 15
color: Theme.palette.directColor1
}
RowLayout {
Layout.fillWidth: true
StatusBaseText {
Layout.fillWidth: true
text: currentContact.name + " • "
visible: currentContact.ensVerified
color: Theme.palette.baseColor1
font.pixelSize: 12
}
StatusBaseText {
Layout.fillWidth: true
Layout.maximumWidth: 85
text: currentContact.publicKey
elide: Text.ElideMiddle
color: Theme.palette.baseColor1
font.pixelSize: 12
}
}
}
}
}
}
EnsResolver {
id: ensResolver
anchors.top: select.bottom
anchors.right: select.right
anchors.top: comboBox.bottom
anchors.right: comboBox.right
anchors.topMargin: Style.current.halfPadding
debounceDelay: 0
onResolved: {
@ -149,67 +192,4 @@ Item {
}
}
}
Component {
id: menuItem
MenuItem {
id: itemContainer
property bool isFirstItem: index === 0
property bool isLastItem: index === root.contactsStore.myContactsModel.count - 1
property var currentContact: Utils.getContactDetailsAsJson(pubKey)
width: parent.width
height: visible ? 72 : 0
StatusSmartIdenticon {
id: iconImg
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
image.source: currentContact.displayIcon
}
Column {
anchors.left: iconImg.right
anchors.leftMargin: 12
anchors.verticalCenter: parent.verticalCenter
StatusBaseText {
text: currentContact.alias
font.pixelSize: 15
color: Theme.palette.directColor1
height: 22
}
Row {
StatusBaseText {
text: currentContact.name + " • "
visible: currentContact.ensVerified
color: Theme.palette.baseColor1
font.pixelSize: 12
height: 16
}
StatusBaseText {
text: currentContact.publicKey
width: 85
elide: Text.ElideMiddle
color: Theme.palette.baseColor1
font.pixelSize: 12
height: 16
}
}
}
background: Rectangle {
color: itemContainer.highlighted ? Theme.palette.statusSelect.menuItemHoverBackgroundColor : Theme.palette.statusSelect.menuItemBackgroundColor
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: itemContainer
onClicked: {
root.selectedContact = itemContainer.currentContact
resolveEns()
select.selectMenu.close()
}
}
}
}
}

View File

@ -17,7 +17,7 @@ Item {
property var accounts
property int inputWidth: 272
property int sourceSelectWidth: 136
property int sourceSelectWidth: 150
property alias label: txtLabel.text
property alias labelFont: txtLabel.font
property alias input: inpAddress.input
@ -31,10 +31,10 @@ Item {
property bool isSelectorVisible: true
property bool addContactEnabled: true
property bool isPending: {
if (!selAddressSource.selectedSource) {
if (!selAddressSource.currentValue) {
return false
}
switch (selAddressSource.selectedSource.value) {
switch (selAddressSource.currentValue.value) {
case RecipientSelector.Type.Address:
return inpAddress.isPending
case RecipientSelector.Type.Contact:
@ -42,12 +42,15 @@ Item {
case RecipientSelector.Type.Account:
return false // AccountSelector is never pending
}
return false;
}
readonly property var sources: [
{ text: qsTr("Address"), value: RecipientSelector.Type.Address, visible: true },
{ text: qsTr("My account"), value: RecipientSelector.Type.Account, visible: true },
{ text: qsTr("Contact"), value: RecipientSelector.Type.Contact, visible: true }
]
property var selectedType: RecipientSelector.Type.Address
enum Type {
@ -58,10 +61,10 @@ Item {
function validate() {
let isValid = true
if (!selAddressSource.selectedSource) {
if (!selAddressSource.currentValue) {
return root.isValid
}
switch (selAddressSource.selectedSource.value) {
switch (selAddressSource.currentValue.value) {
case RecipientSelector.Type.Address:
isValid = inpAddress.isValid
break
@ -76,13 +79,9 @@ Item {
return isValid
}
function getSourceByType(type) {
return root.sources.find(source => source.value === type)
}
onSelectedTypeChanged: {
function updateAddressComboBox() {
if (selectedType !== undefined) {
selAddressSource.selectedSource = getSourceByType(selectedType)
selAddressSource.control.currentIndex = selAddressSource.control.indexOfValue(selectedType)
}
if (!selectedRecipient) {
return
@ -114,6 +113,14 @@ Item {
}
}
onSelectedTypeChanged: {
updateAddressComboBox();
}
Component.onCompleted: {
updateAddressComboBox();
}
implicitHeight: inpAddress.height + txtLabel.height
Text {
@ -162,7 +169,7 @@ Item {
parentWidth: parent.width
addContactEnabled: root.addContactEnabled
onSelectedAddressChanged: {
if (!selAddressSource.selectedSource || (selAddressSource.selectedSource && selAddressSource.selectedSource.value !== RecipientSelector.Type.Address)) {
if (!selAddressSource.currentValue || (selAddressSource.currentValue && selAddressSource.currentValue.value !== RecipientSelector.Type.Address)) {
return
}
@ -182,7 +189,7 @@ Item {
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
onSelectedContactChanged: {
if (!selectedContact || !selAddressSource.selectedSource || !selectedContact.address || (selAddressSource.selectedSource && selAddressSource.selectedSource.value !== RecipientSelector.Type.Contact)) {
if (!selectedContact || !selAddressSource.currentValue || !selectedContact.address || (selAddressSource.currentValue && selAddressSource.currentValue.value !== RecipientSelector.Type.Contact)) {
return
}
const { address, name, alias, pubKey, icon, isContact, ensVerified } = selectedContact
@ -202,7 +209,7 @@ Item {
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
onSelectedAccountChanged: {
if (!selectedAccount || !selAddressSource.selectedSource || (selAddressSource.selectedSource && selAddressSource.selectedSource.value !== RecipientSelector.Type.Account)) {
if (!selectedAccount || !selAddressSource.currentValue || (selAddressSource.currentValue && selAddressSource.currentValue.value !== RecipientSelector.Type.Account)) {
return
}
const { address, name, color, assets, fiatBalance } = selectedAccount
@ -210,20 +217,23 @@ Item {
}
onIsValidChanged: root.validate()
}
AddressSourceSelector {
StatusComboBox {
id: selAddressSource
visible: isSelectorVisible && !root.readOnly
sources: root.sources.filter(source => source.visible)
model: root.sources.filter(source => source.visible)
width: sourceSelectWidth
Layout.preferredWidth: root.sourceSelectWidth
Layout.alignment: Qt.AlignTop
onSelectedSourceChanged: {
if (root.readOnly || !selectedSource) {
control.textRole: "text"
control.valueRole: "value"
onCurrentValueChanged: {
if (root.readOnly || !currentValue) {
return
}
let address, name
switch (selectedSource.value) {
switch (currentValue) {
case RecipientSelector.Type.Address:
inpAddress.visible = true
selContact.visible = selAccount.visible = false

View File

@ -1,5 +1,4 @@
AddressInput 1.0 AddressInput.qml
AddressSourceSelector 1.0 AddressSourceSelector.qml
AssetAndAmountInput 1.0 AssetAndAmountInput.qml
AssetDelegate 1.0 AssetDelegate.qml
ContactSelector 1.0 ContactSelector.qml