2020-08-06 07:25:53 +00:00
|
|
|
import QtQuick 2.13
|
|
|
|
import QtQuick.Controls 2.13
|
|
|
|
import QtQuick.Layouts 1.13
|
|
|
|
import QtGraphicalEffects 1.13
|
2021-09-28 15:04:06 +00:00
|
|
|
|
2021-10-27 10:25:42 +00:00
|
|
|
import StatusQ.Controls 0.1
|
|
|
|
|
2021-09-28 15:04:06 +00:00
|
|
|
import utils 1.0
|
2020-08-06 07:25:53 +00:00
|
|
|
|
2021-10-14 11:51:28 +00:00
|
|
|
import "."
|
|
|
|
import "../panels"
|
2021-10-14 09:20:18 +00:00
|
|
|
|
2020-08-06 07:25:53 +00:00
|
|
|
Item {
|
|
|
|
id: root
|
2022-01-04 12:06:05 +00:00
|
|
|
|
|
|
|
property var contactsStore
|
|
|
|
|
2020-08-06 07:25:53 +00:00
|
|
|
property var accounts
|
|
|
|
property int inputWidth: 272
|
2022-07-31 07:17:07 +00:00
|
|
|
property int sourceSelectWidth: 150
|
2020-08-12 03:40:25 +00:00
|
|
|
property alias label: txtLabel.text
|
2022-03-01 10:14:13 +00:00
|
|
|
property alias labelFont: txtLabel.font
|
|
|
|
property alias input: inpAddress.input
|
2020-08-12 03:40:25 +00:00
|
|
|
// If supplied, additional info will be displayed top-right in danger colour (red)
|
|
|
|
property alias additionalInfo: txtAddlInfo.text
|
2020-09-03 20:43:08 +00:00
|
|
|
property var selectedRecipient
|
2020-08-12 03:40:25 +00:00
|
|
|
property bool readOnly: false
|
2022-04-04 11:26:30 +00:00
|
|
|
readonly property string addressValidationError: qsTr("Invalid ethereum address")
|
2022-04-13 10:21:12 +00:00
|
|
|
property alias wrongInputValidationError: inpAddress.wrongInputValidationError
|
2022-11-11 18:18:09 +00:00
|
|
|
property alias ownAddressError: inpAddress.ownAddressError
|
2020-10-28 07:44:09 +00:00
|
|
|
property bool isValid: false
|
2022-03-01 10:14:13 +00:00
|
|
|
property bool isSelectorVisible: true
|
|
|
|
property bool addContactEnabled: true
|
2020-10-29 03:07:34 +00:00
|
|
|
property bool isPending: {
|
2022-08-08 18:21:56 +00:00
|
|
|
switch (selAddressSource.currentValue) {
|
2020-10-29 03:07:34 +00:00
|
|
|
case RecipientSelector.Type.Address:
|
|
|
|
return inpAddress.isPending
|
|
|
|
case RecipientSelector.Type.Contact:
|
|
|
|
return selContact.isPending
|
2020-11-03 10:29:56 +00:00
|
|
|
case RecipientSelector.Type.Account:
|
|
|
|
return false // AccountSelector is never pending
|
2020-10-29 03:07:34 +00:00
|
|
|
}
|
2022-07-31 07:17:07 +00:00
|
|
|
return false;
|
2020-10-29 03:07:34 +00:00
|
|
|
}
|
2022-07-31 07:17:07 +00:00
|
|
|
|
2020-08-20 04:45:29 +00:00
|
|
|
readonly property var sources: [
|
2022-04-04 11:26:30 +00:00
|
|
|
{ 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 }
|
2020-08-20 04:45:29 +00:00
|
|
|
]
|
2022-07-31 07:17:07 +00:00
|
|
|
|
2020-10-28 07:44:09 +00:00
|
|
|
property var selectedType: RecipientSelector.Type.Address
|
2022-01-17 08:56:44 +00:00
|
|
|
|
2020-08-13 08:24:51 +00:00
|
|
|
enum Type {
|
|
|
|
Address,
|
|
|
|
Contact,
|
|
|
|
Account
|
|
|
|
}
|
|
|
|
|
2020-08-06 07:25:53 +00:00
|
|
|
function validate() {
|
2022-08-08 18:21:56 +00:00
|
|
|
switch (selAddressSource.currentValue) {
|
2020-10-28 07:44:09 +00:00
|
|
|
case RecipientSelector.Type.Address:
|
2022-08-08 18:21:56 +00:00
|
|
|
root.isValid = inpAddress.isValid
|
2020-10-28 07:44:09 +00:00
|
|
|
break
|
|
|
|
case RecipientSelector.Type.Contact:
|
2022-08-08 18:21:56 +00:00
|
|
|
root.isValid = selContact.isValid
|
2020-10-28 07:44:09 +00:00
|
|
|
break
|
|
|
|
case RecipientSelector.Type.Account:
|
2022-08-08 18:21:56 +00:00
|
|
|
root.isValid = selAccount.isValid
|
2020-10-28 07:44:09 +00:00
|
|
|
break
|
2020-08-06 07:25:53 +00:00
|
|
|
}
|
2022-08-08 18:21:56 +00:00
|
|
|
return root.isValid
|
2020-08-06 07:25:53 +00:00
|
|
|
}
|
|
|
|
|
2022-07-31 07:17:07 +00:00
|
|
|
function updateAddressComboBox() {
|
2020-10-28 07:44:09 +00:00
|
|
|
if (selectedType !== undefined) {
|
2022-07-31 07:17:07 +00:00
|
|
|
selAddressSource.control.currentIndex = selAddressSource.control.indexOfValue(selectedType)
|
2020-10-28 07:44:09 +00:00
|
|
|
}
|
|
|
|
if (!selectedRecipient) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
switch (root.selectedType) {
|
|
|
|
case RecipientSelector.Type.Address:
|
2021-04-13 17:49:24 +00:00
|
|
|
inpAddress.input.text = selectedRecipient.name || ""
|
2020-10-28 07:44:09 +00:00
|
|
|
inpAddress.visible = true
|
|
|
|
selContact.visible = selAccount.visible = false
|
2020-12-09 14:10:09 +00:00
|
|
|
if(!!selectedRecipient.address){
|
|
|
|
inpAddress.selectedAddress = selectedRecipient.address
|
|
|
|
}
|
2020-10-28 07:44:09 +00:00
|
|
|
break
|
|
|
|
case RecipientSelector.Type.Contact:
|
|
|
|
selContact.selectedContact = selectedRecipient
|
2020-10-29 23:08:07 +00:00
|
|
|
// TODO: we shouldn't have to call resolveEns from the outside.
|
|
|
|
// It should be handled automatically when selectedContact is
|
|
|
|
// updated, however, handling it on property change causes an
|
|
|
|
// infinite loop
|
|
|
|
selContact.resolveEns()
|
2020-10-28 07:44:09 +00:00
|
|
|
selContact.visible = true
|
|
|
|
inpAddress.visible = selAccount.visible = false
|
|
|
|
break
|
|
|
|
case RecipientSelector.Type.Account:
|
|
|
|
selAccount.selectedAccount = selectedRecipient
|
|
|
|
selAccount.visible = true
|
|
|
|
inpAddress.visible = selContact.visible = false
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-31 07:17:07 +00:00
|
|
|
onSelectedTypeChanged: {
|
|
|
|
updateAddressComboBox();
|
|
|
|
}
|
|
|
|
|
|
|
|
Component.onCompleted: {
|
|
|
|
updateAddressComboBox();
|
|
|
|
}
|
|
|
|
|
2022-07-20 14:54:30 +00:00
|
|
|
implicitHeight: inpAddress.height + txtLabel.height
|
|
|
|
|
2020-08-06 07:25:53 +00:00
|
|
|
Text {
|
|
|
|
id: txtLabel
|
|
|
|
visible: label !== ""
|
2022-04-04 11:26:30 +00:00
|
|
|
text: qsTr("Recipient")
|
2020-08-06 07:25:53 +00:00
|
|
|
font.pixelSize: 13
|
2022-09-15 15:23:51 +00:00
|
|
|
font.family: Style.current.baseFont.name
|
2020-08-12 03:40:25 +00:00
|
|
|
font.weight: Font.Medium
|
2020-08-06 07:25:53 +00:00
|
|
|
color: Style.current.textColor
|
|
|
|
height: 18
|
|
|
|
}
|
|
|
|
|
2020-08-12 03:40:25 +00:00
|
|
|
Text {
|
|
|
|
id: txtAddlInfo
|
|
|
|
visible: text !== ""
|
|
|
|
text: ""
|
|
|
|
font.pixelSize: 13
|
2022-09-15 15:23:51 +00:00
|
|
|
font.family: Style.current.baseFont.name
|
2020-08-12 03:40:25 +00:00
|
|
|
font.weight: Font.Medium
|
|
|
|
color: Style.current.danger
|
|
|
|
height: 18
|
|
|
|
anchors.right: parent.right
|
|
|
|
}
|
|
|
|
|
2020-08-06 07:25:53 +00:00
|
|
|
RowLayout {
|
|
|
|
anchors.top: txtLabel.bottom
|
|
|
|
anchors.topMargin: 7
|
|
|
|
anchors.left: parent.left
|
|
|
|
anchors.right: parent.right
|
|
|
|
spacing: 8
|
|
|
|
|
|
|
|
AddressInput {
|
|
|
|
id: inpAddress
|
2022-01-17 08:56:44 +00:00
|
|
|
|
|
|
|
contactsStore: root.contactsStore
|
|
|
|
|
2020-08-06 07:25:53 +00:00
|
|
|
width: root.inputWidth
|
2021-04-13 17:49:24 +00:00
|
|
|
input.label: ""
|
|
|
|
input.readOnly: root.readOnly
|
2020-10-28 07:44:09 +00:00
|
|
|
visible: true
|
2020-08-12 03:40:25 +00:00
|
|
|
Layout.preferredWidth: selAddressSource.visible ? root.inputWidth : parent.width
|
2020-08-06 07:25:53 +00:00
|
|
|
Layout.alignment: Qt.AlignTop
|
|
|
|
Layout.fillWidth: true
|
2020-08-12 03:40:25 +00:00
|
|
|
validationError: root.addressValidationError
|
2021-04-13 17:49:24 +00:00
|
|
|
parentWidth: parent.width
|
2022-03-01 10:14:13 +00:00
|
|
|
addContactEnabled: root.addContactEnabled
|
2020-08-06 07:25:53 +00:00
|
|
|
onSelectedAddressChanged: {
|
2022-08-08 18:21:56 +00:00
|
|
|
if (selAddressSource.currentValue !== RecipientSelector.Type.Address)
|
2020-08-12 03:40:25 +00:00
|
|
|
return
|
2020-11-04 12:37:53 +00:00
|
|
|
root.selectedRecipient = { address: selectedAddress, type: RecipientSelector.Type.Address }
|
2020-08-20 04:45:29 +00:00
|
|
|
}
|
2020-10-28 07:44:09 +00:00
|
|
|
onIsValidChanged: root.validate()
|
2020-08-06 07:25:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ContactSelector {
|
|
|
|
id: selContact
|
2022-01-04 12:06:05 +00:00
|
|
|
contactsStore: root.contactsStore
|
2020-08-06 07:25:53 +00:00
|
|
|
visible: false
|
|
|
|
width: root.inputWidth
|
|
|
|
dropdownWidth: parent.width
|
2020-10-28 07:44:09 +00:00
|
|
|
readOnly: root.readOnly
|
2020-08-12 03:40:25 +00:00
|
|
|
Layout.preferredWidth: selAddressSource.visible ? root.inputWidth : parent.width
|
2020-08-06 07:25:53 +00:00
|
|
|
Layout.alignment: Qt.AlignTop
|
|
|
|
Layout.fillWidth: true
|
|
|
|
onSelectedContactChanged: {
|
2022-08-08 18:21:56 +00:00
|
|
|
if (!selectedContact || !selectedContact.address || selAddressSource.currentValue !== RecipientSelector.Type.Contact)
|
|
|
|
return;
|
2022-04-13 13:39:19 +00:00
|
|
|
const { address, name, alias, pubKey, icon, isContact, ensVerified } = selectedContact
|
|
|
|
root.selectedRecipient = { address, name, alias, pubKey, icon, isContact, ensVerified, type: RecipientSelector.Type.Contact }
|
2020-08-20 04:45:29 +00:00
|
|
|
}
|
2020-10-28 07:44:09 +00:00
|
|
|
onIsValidChanged: root.validate()
|
2020-08-06 07:25:53 +00:00
|
|
|
}
|
|
|
|
|
2021-10-27 10:25:42 +00:00
|
|
|
StatusAccountSelector {
|
2020-08-06 07:25:53 +00:00
|
|
|
id: selAccount
|
|
|
|
accounts: root.accounts
|
|
|
|
visible: false
|
|
|
|
width: root.inputWidth
|
|
|
|
dropdownWidth: parent.width
|
|
|
|
label: ""
|
2020-08-12 03:40:25 +00:00
|
|
|
Layout.preferredWidth: selAddressSource.visible ? root.inputWidth : parent.width
|
2020-08-06 07:25:53 +00:00
|
|
|
Layout.alignment: Qt.AlignTop
|
|
|
|
Layout.fillWidth: true
|
|
|
|
onSelectedAccountChanged: {
|
2022-08-08 18:21:56 +00:00
|
|
|
if (!selectedAccount || selAddressSource.currentValue !== RecipientSelector.Type.Account)
|
|
|
|
return;
|
2021-11-04 18:55:21 +00:00
|
|
|
const { address, name, color, assets, fiatBalance } = selectedAccount
|
|
|
|
root.selectedRecipient = { address, name, color, assets, fiatBalance, type: RecipientSelector.Type.Account }
|
2020-08-06 07:25:53 +00:00
|
|
|
}
|
2020-10-28 07:44:09 +00:00
|
|
|
onIsValidChanged: root.validate()
|
2020-08-06 07:25:53 +00:00
|
|
|
}
|
2022-08-08 18:21:56 +00:00
|
|
|
|
2022-07-31 07:17:07 +00:00
|
|
|
StatusComboBox {
|
2020-08-06 07:25:53 +00:00
|
|
|
id: selAddressSource
|
2022-03-01 10:14:13 +00:00
|
|
|
visible: isSelectorVisible && !root.readOnly
|
2022-07-31 07:17:07 +00:00
|
|
|
model: root.sources.filter(source => source.visible)
|
2020-08-06 07:25:53 +00:00
|
|
|
width: sourceSelectWidth
|
|
|
|
Layout.preferredWidth: root.sourceSelectWidth
|
|
|
|
Layout.alignment: Qt.AlignTop
|
2020-10-28 07:44:09 +00:00
|
|
|
|
2022-07-31 07:17:07 +00:00
|
|
|
control.textRole: "text"
|
|
|
|
control.valueRole: "value"
|
|
|
|
|
|
|
|
onCurrentValueChanged: {
|
2022-08-08 18:21:56 +00:00
|
|
|
if (root.readOnly) {
|
2020-08-12 03:40:25 +00:00
|
|
|
return
|
|
|
|
}
|
2020-08-13 08:24:51 +00:00
|
|
|
let address, name
|
2022-07-31 07:17:07 +00:00
|
|
|
switch (currentValue) {
|
2020-10-28 07:44:09 +00:00
|
|
|
case RecipientSelector.Type.Address:
|
2020-08-06 07:25:53 +00:00
|
|
|
inpAddress.visible = true
|
|
|
|
selContact.visible = selAccount.visible = false
|
|
|
|
root.height = Qt.binding(function() { return inpAddress.height + txtLabel.height })
|
2020-08-13 08:24:51 +00:00
|
|
|
root.selectedRecipient = { address: inpAddress.selectedAddress, type: RecipientSelector.Type.Address }
|
2020-10-28 07:44:09 +00:00
|
|
|
if (root.selectedType !== RecipientSelector.Type.Address) root.selectedType = RecipientSelector.Type.Address
|
2020-08-20 04:45:29 +00:00
|
|
|
root.isValid = inpAddress.isValid
|
2020-08-06 07:25:53 +00:00
|
|
|
break;
|
2020-10-28 07:44:09 +00:00
|
|
|
case RecipientSelector.Type.Contact:
|
2020-08-06 07:25:53 +00:00
|
|
|
selContact.visible = true
|
|
|
|
inpAddress.visible = selAccount.visible = false
|
|
|
|
root.height = Qt.binding(function() { return selContact.height + txtLabel.height })
|
2022-03-30 15:30:28 +00:00
|
|
|
let { alias, isContact, ensVerified } = selContact.selectedContact
|
2020-08-13 08:24:51 +00:00
|
|
|
address = selContact.selectedContact.address
|
|
|
|
name = selContact.selectedContact.name
|
2022-03-30 15:30:28 +00:00
|
|
|
root.selectedRecipient = { address, name, alias, isContact, ensVerified, type: RecipientSelector.Type.Contact }
|
2020-10-28 07:44:09 +00:00
|
|
|
if (root.selectedType !== RecipientSelector.Type.Contact) root.selectedType = RecipientSelector.Type.Contact
|
2020-08-20 04:45:29 +00:00
|
|
|
root.isValid = selContact.isValid
|
2020-08-06 07:25:53 +00:00
|
|
|
break;
|
2020-10-28 07:44:09 +00:00
|
|
|
case RecipientSelector.Type.Account:
|
2020-08-06 07:25:53 +00:00
|
|
|
selAccount.visible = true
|
|
|
|
inpAddress.visible = selContact.visible = false
|
|
|
|
root.height = Qt.binding(function() { return selAccount.height + txtLabel.height })
|
2021-11-04 18:55:21 +00:00
|
|
|
const { color, assets, fiatBalance } = selAccount.selectedAccount
|
2020-08-13 08:24:51 +00:00
|
|
|
address = selAccount.selectedAccount.address
|
|
|
|
name = selAccount.selectedAccount.name
|
2021-11-04 18:55:21 +00:00
|
|
|
root.selectedRecipient = { address, name, color, assets, fiatBalance, type: RecipientSelector.Type.Account }
|
2020-10-28 07:44:09 +00:00
|
|
|
if (root.selectedType !== RecipientSelector.Type.Account) root.selectedType = RecipientSelector.Type.Account
|
2020-08-20 04:45:29 +00:00
|
|
|
root.isValid = selAccount.isValid
|
2020-08-06 07:25:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|