2023-05-23 08:44:35 +00:00
|
|
|
import QtQuick 2.15
|
2024-10-15 19:26:12 +00:00
|
|
|
import QtQuick.Layouts 1.15
|
|
|
|
import QtQuick.Controls 2.15
|
|
|
|
import QtQuick.Window 2.15
|
2023-05-23 08:44:35 +00:00
|
|
|
|
2024-08-27 14:35:52 +00:00
|
|
|
import StatusQ 0.1
|
2023-05-23 08:44:35 +00:00
|
|
|
import StatusQ.Components 0.1
|
|
|
|
import StatusQ.Core.Theme 0.1
|
|
|
|
import StatusQ.Core 0.1
|
|
|
|
import StatusQ.Controls 0.1
|
|
|
|
import StatusQ.Popups 0.1
|
|
|
|
|
|
|
|
import shared.controls 1.0
|
|
|
|
import utils 1.0
|
|
|
|
import shared.stores 1.0
|
|
|
|
|
|
|
|
import "../stores" as WalletStores
|
|
|
|
|
2024-05-22 08:13:39 +00:00
|
|
|
import AppLayouts.Profile.stores 1.0 as ProfileStores
|
|
|
|
|
2023-12-20 10:46:33 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// NOTE:
|
|
|
|
//
|
|
|
|
// The address should be marked as shown (calling `mainModule.addressWasShown(address)`) if the user interacts with
|
|
|
|
// actions in the menu that reveals the address.
|
|
|
|
//
|
|
|
|
// That call is not added now, just because the only place where this menu is used is in the transaction details view
|
|
|
|
// and the address will be already marked as shown when the user opens the transaction details view.
|
|
|
|
//
|
|
|
|
// This note here is just to remember that if this menu is used in other places, the address should be marked as shown.
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2023-05-23 08:44:35 +00:00
|
|
|
StatusMenu {
|
|
|
|
id: root
|
|
|
|
|
2024-05-22 08:13:39 +00:00
|
|
|
property ProfileStores.ContactsStore contactsStore
|
|
|
|
property NetworkConnectionStore networkConnectionStore
|
2023-07-21 10:55:36 +00:00
|
|
|
property bool areTestNetworksEnabled: false
|
2024-02-20 09:31:04 +00:00
|
|
|
property bool isGoerliEnabled: false
|
2023-05-23 08:44:35 +00:00
|
|
|
|
|
|
|
signal openSendModal(address: string)
|
|
|
|
|
|
|
|
enum AddressType {
|
|
|
|
Address,
|
|
|
|
Sender,
|
|
|
|
Receiver,
|
|
|
|
Tx,
|
|
|
|
InputData,
|
|
|
|
Contract
|
|
|
|
}
|
|
|
|
|
|
|
|
QtObject {
|
|
|
|
id: d
|
|
|
|
|
|
|
|
property string selectedAddress: ""
|
2024-03-15 16:43:12 +00:00
|
|
|
property string cleanSelectedAddress: d.selectedAddress.split(":").pop()
|
2023-05-23 08:44:35 +00:00
|
|
|
|
|
|
|
property string addressName: ""
|
|
|
|
property string addressEns: ""
|
2023-12-29 13:10:55 +00:00
|
|
|
property string colorId: ""
|
2023-05-23 08:44:35 +00:00
|
|
|
|
|
|
|
property string contractName: ""
|
|
|
|
|
|
|
|
property int addressType: TransactionAddressMenu.AddressType.Address
|
|
|
|
|
2024-03-15 16:43:12 +00:00
|
|
|
readonly property QtObject exp: Constants.networkExplorerLinks
|
|
|
|
readonly property QtObject chains: Constants.networkShortChainNames
|
|
|
|
readonly property bool isAddress: d.addressType !== TransactionAddressMenu.Tx
|
|
|
|
|
2023-05-23 08:44:35 +00:00
|
|
|
function getViewText(target) {
|
|
|
|
switch(d.addressType) {
|
|
|
|
case TransactionAddressMenu.AddressType.Contract:
|
|
|
|
if (d.contractName.length > 0)
|
|
|
|
return qsTr("View %1 contract address on %2").arg(d.contractName).arg(target)
|
|
|
|
return qsTr("View contract address on %1").arg(target)
|
|
|
|
case TransactionAddressMenu.AddressType.InputData:
|
|
|
|
return qsTr("View input data on %1").arg(target)
|
|
|
|
case TransactionAddressMenu.AddressType.Tx:
|
|
|
|
return qsTr("View transaction on %1").arg(target)
|
|
|
|
case TransactionAddressMenu.AddressType.Sender:
|
|
|
|
return qsTr("View sender address on %1").arg(target)
|
|
|
|
case TransactionAddressMenu.AddressType.Receiver:
|
|
|
|
return qsTr("View receiver address on %1").arg(target)
|
|
|
|
default:
|
|
|
|
return qsTr("View address on %1").arg(target)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-22 10:03:15 +00:00
|
|
|
function refreshShowOnActionsVisiblity(shortChainNameList) {
|
|
|
|
for (let i = 0 ; i < shortChainNameList.length ; i++) {
|
|
|
|
switch(shortChainNameList[i].toLowerCase()) {
|
2024-03-15 16:43:12 +00:00
|
|
|
case d.chains.arbitrum:
|
2023-09-22 10:03:15 +00:00
|
|
|
showOnArbiscanAction.enabled = true
|
|
|
|
break
|
2024-03-15 16:43:12 +00:00
|
|
|
case d.chains.optimism:
|
2023-09-22 10:03:15 +00:00
|
|
|
showOnOptimismAction.enabled = true
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
showOnEtherscanAction.enabled = true
|
|
|
|
break
|
|
|
|
}
|
2023-06-12 08:39:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-23 08:44:35 +00:00
|
|
|
function openMenu(delegate) {
|
2023-05-31 09:25:16 +00:00
|
|
|
const x = delegate.width - 40
|
2023-05-23 08:44:35 +00:00
|
|
|
const y = delegate.height / 2 + 20
|
|
|
|
root.popup(delegate, x, y)
|
|
|
|
}
|
|
|
|
|
|
|
|
readonly property TextMetrics contentMetrics: TextMetrics {
|
|
|
|
id: contentMetrics
|
|
|
|
font.pixelSize: root.fontSettings.pixelSize
|
2024-10-15 19:26:12 +00:00
|
|
|
font.family: Theme.baseFont.name
|
2023-05-23 08:44:35 +00:00
|
|
|
text: {
|
|
|
|
// Getting longest possible text
|
|
|
|
if (showOnEtherscanAction.enabled) {
|
|
|
|
return showOnEtherscanAction.text
|
|
|
|
} else if (showOnArbiscanAction.enabled) {
|
|
|
|
return showOnArbiscanAction.text
|
|
|
|
}
|
|
|
|
return showOnOptimismAction.text
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-22 10:03:15 +00:00
|
|
|
function openSenderMenu(delegate, address, chainShortNameList = []) {
|
2023-05-23 08:44:35 +00:00
|
|
|
d.addressType = TransactionAddressMenu.AddressType.Sender
|
2023-09-22 10:03:15 +00:00
|
|
|
openEthAddressMenu(delegate, address, chainShortNameList)
|
2023-05-23 08:44:35 +00:00
|
|
|
}
|
|
|
|
|
2023-09-22 10:03:15 +00:00
|
|
|
function openReceiverMenu(delegate, address, chainShortNameList = []) {
|
2023-05-23 08:44:35 +00:00
|
|
|
d.addressType = TransactionAddressMenu.AddressType.Receiver
|
2023-09-22 10:03:15 +00:00
|
|
|
openEthAddressMenu(delegate, address, chainShortNameList)
|
2023-05-23 08:44:35 +00:00
|
|
|
}
|
|
|
|
|
2023-09-22 10:03:15 +00:00
|
|
|
function openEthAddressMenu(delegate, address, chainShortNameList = []) {
|
2023-05-23 08:44:35 +00:00
|
|
|
d.selectedAddress = address
|
|
|
|
|
2023-05-31 09:25:16 +00:00
|
|
|
address = address.toLowerCase()
|
2023-05-23 08:44:35 +00:00
|
|
|
const contactPubKey = "" // TODO retrive contact public key or contact data directly from address
|
|
|
|
let contactData = Utils.getContactDetailsAsJson(contactPubKey)
|
|
|
|
let isWalletAccount = false
|
|
|
|
const isContact = contactData.isContact
|
|
|
|
if (isContact) {
|
|
|
|
d.addressName = contactData.name
|
|
|
|
} else {
|
2023-12-29 13:10:55 +00:00
|
|
|
// Revisit here after this issue (resolving source for preferred chains...):
|
|
|
|
// https://github.com/status-im/status-desktop/issues/13109
|
2023-05-23 08:44:35 +00:00
|
|
|
d.addressName = WalletStores.RootStore.getNameForWalletAddress(address)
|
|
|
|
isWalletAccount = d.addressName.length > 0
|
|
|
|
if (!isWalletAccount) {
|
2023-12-29 13:10:55 +00:00
|
|
|
let savedAddress = WalletStores.RootStore.getSavedAddress(address)
|
|
|
|
d.addressName = savedAddress.name
|
|
|
|
d.addressEns = savedAddress.ens
|
|
|
|
d.colorId = savedAddress.colorId
|
2023-05-23 08:44:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
showOnEtherscanAction.enabled = true
|
2024-03-15 16:43:12 +00:00
|
|
|
showOnArbiscanAction.enabled = address.includes(d.chains.arbitrum + ":")
|
|
|
|
showOnOptimismAction.enabled = address.includes(d.chains.optimism + ":")
|
2023-09-22 10:03:15 +00:00
|
|
|
d.refreshShowOnActionsVisiblity(chainShortNameList)
|
2023-05-23 08:44:35 +00:00
|
|
|
saveAddressAction.enabled = d.addressName.length === 0
|
|
|
|
editAddressAction.enabled = !isWalletAccount && !isContact && d.addressName.length > 0
|
2024-02-02 09:55:56 +00:00
|
|
|
|
|
|
|
if (root.networkConnectionStore.sendBuyBridgeEnabled)
|
|
|
|
sendToAddressAction.enabled = true
|
|
|
|
|
2023-05-23 08:44:35 +00:00
|
|
|
showQrAction.enabled = true
|
|
|
|
|
|
|
|
d.openMenu(delegate)
|
|
|
|
}
|
|
|
|
|
2023-09-22 10:03:15 +00:00
|
|
|
function openTxMenu(delegate, address, chainShortNameList=[]) {
|
2023-05-23 08:44:35 +00:00
|
|
|
d.addressType = TransactionAddressMenu.AddressType.Tx
|
|
|
|
d.selectedAddress = address
|
2023-09-22 10:03:15 +00:00
|
|
|
d.refreshShowOnActionsVisiblity(chainShortNameList)
|
2023-05-23 08:44:35 +00:00
|
|
|
d.openMenu(delegate)
|
|
|
|
}
|
|
|
|
|
2023-09-22 10:03:15 +00:00
|
|
|
function openContractMenu(delegate, address, chainShortNameList=[], name="") {
|
2023-05-23 08:44:35 +00:00
|
|
|
d.addressType = TransactionAddressMenu.AddressType.Contract
|
|
|
|
d.contractName = name
|
|
|
|
d.selectedAddress = address
|
2023-09-22 10:03:15 +00:00
|
|
|
d.refreshShowOnActionsVisiblity(chainShortNameList)
|
2023-05-23 08:44:35 +00:00
|
|
|
d.openMenu(delegate)
|
|
|
|
}
|
|
|
|
|
|
|
|
function openInputDataMenu(delegate, address) {
|
|
|
|
d.addressType = TransactionAddressMenu.AddressType.InputData
|
|
|
|
d.selectedAddress = address
|
|
|
|
d.openMenu(delegate)
|
|
|
|
}
|
|
|
|
|
|
|
|
onClosed: {
|
|
|
|
d.addressType = TransactionAddressMenu.AddressType.Address
|
|
|
|
d.contractName = ""
|
|
|
|
|
|
|
|
showOnEtherscanAction.enabled = false
|
|
|
|
showOnArbiscanAction.enabled = false
|
|
|
|
showOnOptimismAction.enabled = false
|
|
|
|
showQrAction.enabled = false
|
|
|
|
saveAddressAction.enabled = false
|
|
|
|
editAddressAction.enabled = false
|
|
|
|
sendToAddressAction.enabled = false
|
|
|
|
}
|
|
|
|
|
|
|
|
// Additional offset for menu icon
|
|
|
|
contentWidth: contentMetrics.width + 50
|
|
|
|
hideDisabledItems: true
|
|
|
|
|
|
|
|
StatusAction {
|
|
|
|
id: showOnEtherscanAction
|
|
|
|
enabled: false
|
|
|
|
text: d.getViewText(qsTr("Etherscan"))
|
2023-06-13 08:18:53 +00:00
|
|
|
icon.name: "link"
|
2023-06-05 06:22:30 +00:00
|
|
|
onTriggered: {
|
2024-03-15 16:43:12 +00:00
|
|
|
let url = Utils.getEtherscanUrl(d.chains.mainnet, root.areTestNetworksEnabled, !root.isGoerliEnabled,
|
|
|
|
d.cleanSelectedAddress, d.isAddress)
|
|
|
|
Global.openLink(url)
|
2023-06-05 06:22:30 +00:00
|
|
|
}
|
2023-05-23 08:44:35 +00:00
|
|
|
}
|
|
|
|
StatusAction {
|
|
|
|
id: showOnArbiscanAction
|
|
|
|
enabled: false
|
|
|
|
text: d.getViewText(qsTr("Arbiscan"))
|
2023-06-13 08:18:53 +00:00
|
|
|
icon.name: "link"
|
2023-06-05 06:22:30 +00:00
|
|
|
onTriggered: {
|
2024-03-15 16:43:12 +00:00
|
|
|
let url = Utils.getEtherscanUrl(d.chains.arbitrum, root.areTestNetworksEnabled, !root.isGoerliEnabled,
|
|
|
|
d.cleanSelectedAddress, d.isAddress)
|
|
|
|
Global.openLink(url)
|
2023-06-05 06:22:30 +00:00
|
|
|
}
|
2023-05-23 08:44:35 +00:00
|
|
|
}
|
|
|
|
StatusAction {
|
|
|
|
id: showOnOptimismAction
|
|
|
|
enabled: false
|
|
|
|
text: d.getViewText(qsTr("Optimism Explorer"))
|
2023-06-13 08:18:53 +00:00
|
|
|
icon.name: "link"
|
2023-06-05 06:22:30 +00:00
|
|
|
onTriggered: {
|
2024-03-15 16:43:12 +00:00
|
|
|
let url = Utils.getEtherscanUrl(d.chains.optimism, root.areTestNetworksEnabled, !root.isGoerliEnabled,
|
|
|
|
d.cleanSelectedAddress, d.isAddress)
|
|
|
|
Global.openLink(url)
|
2023-06-05 06:22:30 +00:00
|
|
|
}
|
2023-05-23 08:44:35 +00:00
|
|
|
}
|
2023-06-13 08:18:53 +00:00
|
|
|
StatusSuccessAction {
|
2023-05-23 08:44:35 +00:00
|
|
|
id: copyAddressAction
|
|
|
|
successText: {
|
|
|
|
switch(d.addressType) {
|
|
|
|
case TransactionAddressMenu.AddressType.Contract:
|
|
|
|
return qsTr("Contract address copied")
|
|
|
|
case TransactionAddressMenu.AddressType.InputData:
|
|
|
|
return qsTr("Input data copied")
|
|
|
|
case TransactionAddressMenu.AddressType.Tx:
|
|
|
|
return qsTr("Tx hash copied")
|
|
|
|
case TransactionAddressMenu.AddressType.Sender:
|
|
|
|
return qsTr("Sender address copied")
|
|
|
|
case TransactionAddressMenu.AddressType.Receiver:
|
|
|
|
return qsTr("Receiver address copied")
|
|
|
|
default:
|
|
|
|
return qsTr("Address copied")
|
|
|
|
}
|
|
|
|
}
|
2023-06-13 08:18:53 +00:00
|
|
|
text: {
|
2023-05-23 08:44:35 +00:00
|
|
|
switch(d.addressType) {
|
|
|
|
case TransactionAddressMenu.AddressType.Contract:
|
|
|
|
return qsTr("Copy contract address")
|
|
|
|
case TransactionAddressMenu.AddressType.InputData:
|
|
|
|
return qsTr("Copy input data")
|
|
|
|
case TransactionAddressMenu.AddressType.Tx:
|
|
|
|
return qsTr("Copy Tx hash")
|
|
|
|
case TransactionAddressMenu.AddressType.Sender:
|
|
|
|
return qsTr("Copy sender address")
|
|
|
|
case TransactionAddressMenu.AddressType.Receiver:
|
|
|
|
return qsTr("Copy receiver address")
|
|
|
|
default:
|
|
|
|
return qsTr("Copy address")
|
|
|
|
}
|
|
|
|
}
|
2023-06-13 08:18:53 +00:00
|
|
|
icon.name: "copy"
|
2024-08-27 14:35:52 +00:00
|
|
|
onTriggered: ClipboardUtils.setText(d.selectedAddress)
|
2023-05-23 08:44:35 +00:00
|
|
|
}
|
|
|
|
StatusAction {
|
|
|
|
id: showQrAction
|
|
|
|
enabled: false
|
|
|
|
text: {
|
|
|
|
switch(d.addressType) {
|
|
|
|
case TransactionAddressMenu.AddressType.Sender:
|
|
|
|
return qsTr("Show sender address QR")
|
|
|
|
case TransactionAddressMenu.AddressType.Receiver:
|
|
|
|
return qsTr("Show receiver address QR")
|
|
|
|
default:
|
|
|
|
return qsTr("Show address QR")
|
|
|
|
}
|
|
|
|
}
|
2023-06-13 08:18:53 +00:00
|
|
|
icon.name: "qr"
|
2023-05-23 08:44:35 +00:00
|
|
|
onTriggered: {
|
2024-01-15 09:19:25 +00:00
|
|
|
onTriggered: Global.openShowQRPopup({
|
|
|
|
showSingleAccount: true,
|
|
|
|
switchingAccounsEnabled: false,
|
|
|
|
hasFloatingButtons: false,
|
|
|
|
name: d.addressName,
|
|
|
|
address: d.selectedAddress,
|
|
|
|
colorId: d.colorId,
|
|
|
|
})
|
2023-05-23 08:44:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
StatusAction {
|
|
|
|
id: saveAddressAction
|
|
|
|
enabled: false
|
|
|
|
text: {
|
|
|
|
switch(d.addressType) {
|
|
|
|
case TransactionAddressMenu.AddressType.Sender:
|
|
|
|
return qsTr("Save sender address")
|
|
|
|
case TransactionAddressMenu.AddressType.Receiver:
|
|
|
|
return qsTr("Save receiver address")
|
|
|
|
default:
|
|
|
|
return qsTr("Save address")
|
|
|
|
}
|
|
|
|
}
|
2023-06-13 08:18:53 +00:00
|
|
|
icon.name: "star-icon-outline"
|
2023-05-23 08:44:35 +00:00
|
|
|
onTriggered: {
|
2023-12-26 10:19:41 +00:00
|
|
|
Global.openAddEditSavedAddressesPopup({
|
2024-10-03 20:13:01 +00:00
|
|
|
addAddress: true,
|
|
|
|
address: d.selectedAddress,
|
|
|
|
ens: d.addressEns
|
|
|
|
})
|
2023-05-23 08:44:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
StatusAction {
|
|
|
|
id: editAddressAction
|
|
|
|
enabled: false
|
|
|
|
text: qsTr("Edit saved address")
|
2023-06-13 08:18:53 +00:00
|
|
|
icon.name: "pencil-outline"
|
2023-12-26 10:19:41 +00:00
|
|
|
onTriggered: Global.openAddEditSavedAddressesPopup({
|
2023-05-23 08:44:35 +00:00
|
|
|
edit: true,
|
|
|
|
name: d.addressName,
|
|
|
|
address: d.selectedAddress,
|
|
|
|
ens: d.addressEns,
|
2024-10-03 20:13:01 +00:00
|
|
|
colorId: d.colorId})
|
2023-05-23 08:44:35 +00:00
|
|
|
}
|
|
|
|
StatusAction {
|
|
|
|
id: sendToAddressAction
|
|
|
|
enabled: false
|
|
|
|
text: {
|
|
|
|
switch(d.addressType) {
|
|
|
|
case TransactionAddressMenu.AddressType.Sender:
|
|
|
|
return qsTr("Send to sender address")
|
|
|
|
case TransactionAddressMenu.AddressType.Receiver:
|
|
|
|
return qsTr("Send to receiver address")
|
|
|
|
default:
|
|
|
|
return qsTr("Send to address")
|
|
|
|
}
|
|
|
|
}
|
2023-06-13 08:18:53 +00:00
|
|
|
icon.name: "send"
|
2023-05-23 08:44:35 +00:00
|
|
|
onTriggered: root.openSendModal(d.selectedAddress)
|
|
|
|
}
|
|
|
|
}
|