fix: Reimplemented selectors using `StatusComboBox`
This commit is contained in:
parent
be6240e41c
commit
5fb2be95ef
|
@ -1 +1 @@
|
||||||
Subproject commit f4bf830ae7af5979255b383920980bf4d3a4b251
|
Subproject commit 63ff9b82d1f13c063dddbb244a255a9886705fc7
|
|
@ -686,15 +686,6 @@ Assets won’t be sent yet.</source>
|
||||||
Assets won’t be sent yet.</translation>
|
Assets won’t be sent yet.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</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>
|
<context>
|
||||||
<name>AdvancedAddAccountView</name>
|
<name>AdvancedAddAccountView</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -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]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,10 +18,9 @@ Item {
|
||||||
id: root
|
id: root
|
||||||
property var contactsStore
|
property var contactsStore
|
||||||
property var selectedContact
|
property var selectedContact
|
||||||
height: select.height
|
|
||||||
property int dropdownWidth: width
|
property int dropdownWidth: width
|
||||||
property string validationError: qsTr("Please select a contact")
|
property string validationError: qsTr("Please select a contact")
|
||||||
property alias validationErrorAlignment: select.validationErrorAlignment
|
// property alias validationErrorAlignment: comboBox.validationErrorAlignment
|
||||||
property bool isValid: false
|
property bool isValid: false
|
||||||
property alias isPending: ensResolver.isPending
|
property alias isPending: ensResolver.isPending
|
||||||
|
|
||||||
|
@ -37,6 +36,8 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
implicitHeight: comboBox.implicitHeight
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (root.readOnly) {
|
if (root.readOnly) {
|
||||||
return
|
return
|
||||||
|
@ -53,14 +54,14 @@ Item {
|
||||||
let isValidAddress = Utils.isValidAddress(selectedContact.address)
|
let isValidAddress = Utils.isValidAddress(selectedContact.address)
|
||||||
let isDefaultValue = selectedContact.alias === selectAContact
|
let isDefaultValue = selectedContact.alias === selectAContact
|
||||||
let isValid = (selectedContact.ensVerified && isValidAddress) || isPending || isValidAddress
|
let isValid = (selectedContact.ensVerified && isValidAddress) || isPending || isValidAddress
|
||||||
select.validationError = ""
|
comboBox.validationError = ""
|
||||||
if (!isValid && !isDefaultValue &&
|
if (!isValid && !isDefaultValue &&
|
||||||
(
|
(
|
||||||
!selectedContact.ensVerified ||
|
!selectedContact.ensVerified ||
|
||||||
(selectedContact.ensVerified && isResolvedAddress)
|
(selectedContact.ensVerified && isResolvedAddress)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
select.validationError = !selectedContact.ensVerified ? noEnsAddressMessage : validationError
|
comboBox.validationError = !selectedContact.ensVerified ? noEnsAddressMessage : validationError
|
||||||
}
|
}
|
||||||
root.isValid = isValid
|
root.isValid = isValid
|
||||||
return isValid
|
return isValid
|
||||||
|
@ -83,20 +84,22 @@ Item {
|
||||||
customHeight: 56
|
customHeight: 56
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusSelect {
|
StatusComboBox {
|
||||||
id: select
|
id: comboBox
|
||||||
label: ""
|
label: ""
|
||||||
model: root.contactsStore.myContactsModel
|
model: root.contactsStore.myContactsModel
|
||||||
width: parent.width
|
width: parent.width
|
||||||
visible: !root.readOnly
|
visible: !root.readOnly
|
||||||
menuAlignment: StatusSelect.MenuAlignment.Left
|
|
||||||
selectedItemComponent: Item {
|
control.popup.width: dropdownWidth
|
||||||
anchors.fill: parent
|
control.padding: 14
|
||||||
|
|
||||||
|
enabled: control.count > 0
|
||||||
|
|
||||||
|
contentItem: RowLayout {
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
StatusSmartIdenticon {
|
StatusSmartIdenticon {
|
||||||
id: iconImg
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 14
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
image.width: (!!selectedContact && !!selectedContact.displayIcon) ? 32 : 0
|
image.width: (!!selectedContact && !!selectedContact.displayIcon) ? 32 : 0
|
||||||
image.height: 32
|
image.height: 32
|
||||||
image.source: (!!selectedContact && !!selectedContact.displayIcon) ? selectedContact.displayIcon : ""
|
image.source: (!!selectedContact && !!selectedContact.displayIcon) ? selectedContact.displayIcon : ""
|
||||||
|
@ -104,37 +107,77 @@ Item {
|
||||||
}
|
}
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
id: selectedTextField
|
id: selectedTextField
|
||||||
|
visible: comboBox.control.count > 0
|
||||||
text: !!selectedContact ? selectedContact.alias : ""
|
text: !!selectedContact ? selectedContact.alias : ""
|
||||||
anchors.left: iconImg.right
|
|
||||||
anchors.leftMargin: 4
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
height: 22
|
height: 22
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
color: Theme.palette.directColor1
|
color: Theme.palette.directColor1
|
||||||
}
|
}
|
||||||
}
|
|
||||||
zeroItemsView: Item {
|
|
||||||
height: 186
|
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
anchors.fill: parent
|
visible: comboBox.control.count == 0
|
||||||
text: qsTr("You don’t have any contacts yet")
|
text: qsTr("You don’t have any contacts yet")
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
height: 18
|
|
||||||
color: Theme.palette.baseColor1
|
color: Theme.palette.baseColor1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectMenu.delegate: menuItem
|
delegate: StatusItemDelegate {
|
||||||
selectMenu.width: dropdownWidth
|
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 {
|
EnsResolver {
|
||||||
id: ensResolver
|
id: ensResolver
|
||||||
anchors.top: select.bottom
|
anchors.top: comboBox.bottom
|
||||||
anchors.right: select.right
|
anchors.right: comboBox.right
|
||||||
anchors.topMargin: Style.current.halfPadding
|
anchors.topMargin: Style.current.halfPadding
|
||||||
debounceDelay: 0
|
debounceDelay: 0
|
||||||
onResolved: {
|
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ Item {
|
||||||
|
|
||||||
property var accounts
|
property var accounts
|
||||||
property int inputWidth: 272
|
property int inputWidth: 272
|
||||||
property int sourceSelectWidth: 136
|
property int sourceSelectWidth: 150
|
||||||
property alias label: txtLabel.text
|
property alias label: txtLabel.text
|
||||||
property alias labelFont: txtLabel.font
|
property alias labelFont: txtLabel.font
|
||||||
property alias input: inpAddress.input
|
property alias input: inpAddress.input
|
||||||
|
@ -31,10 +31,10 @@ Item {
|
||||||
property bool isSelectorVisible: true
|
property bool isSelectorVisible: true
|
||||||
property bool addContactEnabled: true
|
property bool addContactEnabled: true
|
||||||
property bool isPending: {
|
property bool isPending: {
|
||||||
if (!selAddressSource.selectedSource) {
|
if (!selAddressSource.currentValue) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
switch (selAddressSource.selectedSource.value) {
|
switch (selAddressSource.currentValue.value) {
|
||||||
case RecipientSelector.Type.Address:
|
case RecipientSelector.Type.Address:
|
||||||
return inpAddress.isPending
|
return inpAddress.isPending
|
||||||
case RecipientSelector.Type.Contact:
|
case RecipientSelector.Type.Contact:
|
||||||
|
@ -42,12 +42,15 @@ Item {
|
||||||
case RecipientSelector.Type.Account:
|
case RecipientSelector.Type.Account:
|
||||||
return false // AccountSelector is never pending
|
return false // AccountSelector is never pending
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property var sources: [
|
readonly property var sources: [
|
||||||
{ text: qsTr("Address"), value: RecipientSelector.Type.Address, visible: true },
|
{ text: qsTr("Address"), value: RecipientSelector.Type.Address, visible: true },
|
||||||
{ text: qsTr("My account"), value: RecipientSelector.Type.Account, visible: true },
|
{ text: qsTr("My account"), value: RecipientSelector.Type.Account, visible: true },
|
||||||
{ text: qsTr("Contact"), value: RecipientSelector.Type.Contact, visible: true }
|
{ text: qsTr("Contact"), value: RecipientSelector.Type.Contact, visible: true }
|
||||||
]
|
]
|
||||||
|
|
||||||
property var selectedType: RecipientSelector.Type.Address
|
property var selectedType: RecipientSelector.Type.Address
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
|
@ -58,10 +61,10 @@ Item {
|
||||||
|
|
||||||
function validate() {
|
function validate() {
|
||||||
let isValid = true
|
let isValid = true
|
||||||
if (!selAddressSource.selectedSource) {
|
if (!selAddressSource.currentValue) {
|
||||||
return root.isValid
|
return root.isValid
|
||||||
}
|
}
|
||||||
switch (selAddressSource.selectedSource.value) {
|
switch (selAddressSource.currentValue.value) {
|
||||||
case RecipientSelector.Type.Address:
|
case RecipientSelector.Type.Address:
|
||||||
isValid = inpAddress.isValid
|
isValid = inpAddress.isValid
|
||||||
break
|
break
|
||||||
|
@ -76,13 +79,9 @@ Item {
|
||||||
return isValid
|
return isValid
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSourceByType(type) {
|
function updateAddressComboBox() {
|
||||||
return root.sources.find(source => source.value === type)
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelectedTypeChanged: {
|
|
||||||
if (selectedType !== undefined) {
|
if (selectedType !== undefined) {
|
||||||
selAddressSource.selectedSource = getSourceByType(selectedType)
|
selAddressSource.control.currentIndex = selAddressSource.control.indexOfValue(selectedType)
|
||||||
}
|
}
|
||||||
if (!selectedRecipient) {
|
if (!selectedRecipient) {
|
||||||
return
|
return
|
||||||
|
@ -114,6 +113,14 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSelectedTypeChanged: {
|
||||||
|
updateAddressComboBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
updateAddressComboBox();
|
||||||
|
}
|
||||||
|
|
||||||
implicitHeight: inpAddress.height + txtLabel.height
|
implicitHeight: inpAddress.height + txtLabel.height
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
@ -162,7 +169,7 @@ Item {
|
||||||
parentWidth: parent.width
|
parentWidth: parent.width
|
||||||
addContactEnabled: root.addContactEnabled
|
addContactEnabled: root.addContactEnabled
|
||||||
onSelectedAddressChanged: {
|
onSelectedAddressChanged: {
|
||||||
if (!selAddressSource.selectedSource || (selAddressSource.selectedSource && selAddressSource.selectedSource.value !== RecipientSelector.Type.Address)) {
|
if (!selAddressSource.currentValue || (selAddressSource.currentValue && selAddressSource.currentValue.value !== RecipientSelector.Type.Address)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +189,7 @@ Item {
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
onSelectedContactChanged: {
|
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
|
return
|
||||||
}
|
}
|
||||||
const { address, name, alias, pubKey, icon, isContact, ensVerified } = selectedContact
|
const { address, name, alias, pubKey, icon, isContact, ensVerified } = selectedContact
|
||||||
|
@ -202,7 +209,7 @@ Item {
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
onSelectedAccountChanged: {
|
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
|
return
|
||||||
}
|
}
|
||||||
const { address, name, color, assets, fiatBalance } = selectedAccount
|
const { address, name, color, assets, fiatBalance } = selectedAccount
|
||||||
|
@ -210,20 +217,23 @@ Item {
|
||||||
}
|
}
|
||||||
onIsValidChanged: root.validate()
|
onIsValidChanged: root.validate()
|
||||||
}
|
}
|
||||||
AddressSourceSelector {
|
StatusComboBox {
|
||||||
id: selAddressSource
|
id: selAddressSource
|
||||||
visible: isSelectorVisible && !root.readOnly
|
visible: isSelectorVisible && !root.readOnly
|
||||||
sources: root.sources.filter(source => source.visible)
|
model: root.sources.filter(source => source.visible)
|
||||||
width: sourceSelectWidth
|
width: sourceSelectWidth
|
||||||
Layout.preferredWidth: root.sourceSelectWidth
|
Layout.preferredWidth: root.sourceSelectWidth
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
|
|
||||||
onSelectedSourceChanged: {
|
control.textRole: "text"
|
||||||
if (root.readOnly || !selectedSource) {
|
control.valueRole: "value"
|
||||||
|
|
||||||
|
onCurrentValueChanged: {
|
||||||
|
if (root.readOnly || !currentValue) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let address, name
|
let address, name
|
||||||
switch (selectedSource.value) {
|
switch (currentValue) {
|
||||||
case RecipientSelector.Type.Address:
|
case RecipientSelector.Type.Address:
|
||||||
inpAddress.visible = true
|
inpAddress.visible = true
|
||||||
selContact.visible = selAccount.visible = false
|
selContact.visible = selAccount.visible = false
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
AddressInput 1.0 AddressInput.qml
|
AddressInput 1.0 AddressInput.qml
|
||||||
AddressSourceSelector 1.0 AddressSourceSelector.qml
|
|
||||||
AssetAndAmountInput 1.0 AssetAndAmountInput.qml
|
AssetAndAmountInput 1.0 AssetAndAmountInput.qml
|
||||||
AssetDelegate 1.0 AssetDelegate.qml
|
AssetDelegate 1.0 AssetDelegate.qml
|
||||||
ContactSelector 1.0 ContactSelector.qml
|
ContactSelector 1.0 ContactSelector.qml
|
||||||
|
|
Loading…
Reference in New Issue