import QtQuick 2.13 import QtQuick.Layouts 1.13 import QtQuick.Controls 2.14 import QtQuick.Window 2.12 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 "../controls" import "../stores" as WalletStores import ".." Item { id: root property var overview: WalletStores.RootStore.overview property var contactsStore property var transaction property var sendModal readonly property bool isTransactionValid: transaction !== undefined && !!transaction QtObject { id: d readonly property bool isIncoming: root.isTransactionValid ? root.transaction.to === root.overview.mixedcaseAddress : false readonly property bool isNFT: root.isTransactionValid ? root.transaction.isNFT : false readonly property string savedAddressNameTo: root.isTransactionValid ? d.getNameForSavedWalletAddress(transaction.to) : "" readonly property string savedAddressNameFrom: root.isTransactionValid ? d.getNameForSavedWalletAddress(transaction.from): "" readonly property string from: root.isTransactionValid ? !!savedAddressNameFrom ? savedAddressNameFrom : Utils.compactAddress(transaction.from, 4): "" readonly property string to: root.isTransactionValid ? !!savedAddressNameTo ? savedAddressNameTo : Utils.compactAddress(transaction.to, 4): "" readonly property string savedAddressEns: root.isTransactionValid ? RootStore.getEnsForSavedWalletAddress(isIncoming ? transaction.from : transaction.to) : "" readonly property string savedAddressChains: root.isTransactionValid ? RootStore.getChainShortNamesForSavedWalletAddress(isIncoming ? transaction.from : transaction.to) : "" function getNameForSavedWalletAddress(address) { return RootStore.getNameForSavedWalletAddress(address) } } StatusScrollView { anchors.top: parent.top anchors.left: parent.left width: parent.width height: parent.height contentHeight: column.height contentWidth: parent.width Column { id: column width: parent.width - Style.current.xlPadding spacing: Style.current.bigPadding TransactionDelegate { objectName: "transactionDetailHeader" width: parent.width modelData: transaction isIncoming: d.isIncoming currentCurrency: RootStore.currentCurrency cryptoValue: root.isTransactionValid ? transaction.value.amount: 0.0 fiatValue: root.isTransactionValid ? RootStore.getFiatValue(cryptoValue, symbol, currentCurrency): 0.0 networkIcon: root.isTransactionValid ? RootStore.getNetworkIcon(transaction.chainId): "" networkColor: root.isTransactionValid ? RootStore.getNetworkColor(transaction.chainId): "" networkName: root.isTransactionValid ? RootStore.getNetworkShortName(transaction.chainId): "" symbol: root.isTransactionValid ? transaction.symbol : "" transferStatus: root.isTransactionValid ? RootStore.hex2Dec(transaction.txStatus): "" shortTimeStamp: root.isTransactionValid ? LocaleUtils.formatTime(transaction.timestamp * 1000, Locale.ShortFormat): "" savedAddressNameTo: root.isTransactionValid ? RootStore.getNameForSavedWalletAddress(transaction.to): "" savedAddressNameFrom: root.isTransactionValid ? RootStore.getNameForSavedWalletAddress(transaction.from): "" isSummary: false sensor.enabled: false color: Theme.palette.statusListItem.backgroundColor state: "big" } SavedAddressesDelegate { width: parent.width name: d.isIncoming ? d.savedAddressNameFrom : d.savedAddressNameTo address: root.isTransactionValid ? d.isIncoming ? transaction.from : transaction.to : "" ens: d.savedAddressEns chainShortNames: d.savedAddressChains title: d.isIncoming ? d.from : d.to subTitle: root.isTransactionValid ? d.isIncoming ? !!d.savedAddressNameFrom ? Utils.compactAddress(transaction.from, 4) : "" : !!d.savedAddressNameTo ? Utils.compactAddress(transaction.to, 4) : "": "" store: WalletStores.RootStore contactsStore: root.contactsStore onOpenSendModal: root.sendModal.open(address); saveAddress: function(name, address, favourite, chainShortNames, ens) { RootStore.createOrUpdateSavedAddress(name, address, favourite, chainShortNames, ens) } deleteSavedAddress: function(address, ens) { RootStore.deleteSavedAddress(address, ens) } } StatusExpandableItem { width: parent.width anchors.horizontalCenter: parent.horizontalCenter type: StatusExpandableItem.Type.Tertiary expandable: true primaryText: qsTr("Transaction summary") expandableComponent: transactionSummary separatorVisible: false expanded: true } StatusExpandableItem { width: parent.width anchors.horizontalCenter: parent.horizontalCenter type: StatusExpandableItem.Type.Tertiary expandable: true primaryText: qsTr("Fees") expandableComponent: fees expanded: true } InformationTile { maxWidth: parent.width primaryText: qsTr("Data") secondaryText: root.isTransactionValid ? root.transaction.input : "" copy: true onCopyClicked: RootStore.copyToClipboard(textToCopy) } } } Component { id: transactionSummary Column { id: column width: parent.width spacing: 8 TransactionDelegate { width: parent.width modelData: transaction isIncoming: d.isIncoming currentCurrency: RootStore.currentCurrency cryptoValue: root.isTransactionValid ? transaction.value.amount: 0.0 fiatValue: root.isTransactionValid ? RootStore.getFiatValue(cryptoValue, symbol, currentCurrency): 0.0 networkIcon: root.isTransactionValid ? RootStore.getNetworkIcon(transaction.chainId) : "" networkColor: root.isTransactionValid ? RootStore.getNetworkColor(transaction.chainId): "" networkName: root.isTransactionValid ? RootStore.getNetworkShortName(transaction.chainId): "" symbol: root.isTransactionValid ? transaction.symbol : "" transferStatus: root.isTransactionValid ? RootStore.hex2Dec(transaction.txStatus): "" shortTimeStamp: root.isTransactionValid ? LocaleUtils.formatTime(transaction.timestamp * 1000, Locale.ShortFormat): "" savedAddressNameTo: root.isTransactionValid ? RootStore.getNameForSavedWalletAddress(transaction.to): "" savedAddressNameFrom: root.isTransactionValid ? RootStore.getNameForSavedWalletAddress(transaction.from): "" isSummary: false sensor.enabled: false color: Theme.palette.statusListItem.backgroundColor border.width: 1 border.color: Theme.palette.directColor8 } Row { spacing: 8 InformationTile { maxWidth: parent.width primaryText: qsTr("Time") secondaryText: root.transaction !== undefined && !!root.transaction ? qsTr("%1 on %2"). arg(LocaleUtils.formatTime(transaction.timestamp * 1000, Locale.ShortFormat)). arg(LocaleUtils.formatDate(transaction.timestamp * 1000, Locale.ShortFormat)): "" } InformationTile { maxWidth: parent.width primaryText: qsTr("Confirmations") secondaryText: { if(root.isTransactionValid) return Math.abs(RootStore.getLatestBlockNumber() - RootStore.hex2Dec(root.transaction.blockNumber)) else return "" } } InformationTile { maxWidth: parent.width primaryText: qsTr("Nonce") secondaryText: root.isTransactionValid ? RootStore.hex2Dec(root.transaction.nonce) : "" } InformationTile { maxWidth: parent.width primaryText: qsTr("TokenID") secondaryText: root.isTransactionValid ? root.transaction.tokenID : "" visible: root.isTransactionValid && d.isNFT } } } } Component { id: fees Column { width: parent.width spacing: 8 Row { spacing: 8 InformationTile { id: baseFee maxWidth: parent.width primaryText: qsTr("Base fee") secondaryText: root.isTransactionValid ? qsTr("%1").arg(LocaleUtils.currencyAmountToLocaleString(root.transaction.baseGasFees)) : "" } InformationTile { maxWidth: parent.width primaryText: qsTr("Tip") secondaryText: root.isTransactionValid ? "%1 • ". arg(LocaleUtils.currencyAmountToLocaleString(root.transaction.maxPriorityFeePerGas)). arg(Theme.palette.baseColor1) + qsTr("Max: %1"). arg(LocaleUtils.currencyAmountToLocaleString(root.transaction.maxFeePerGas)) + "" : "" secondaryLabel.textFormat: Text.RichText } } InformationTile { maxWidth: parent.width primaryText: qsTr("Total fee") secondaryText: root.isTransactionValid ? "%1 • ". arg(LocaleUtils.currencyAmountToLocaleString(root.transaction.totalFees)). arg(Theme.palette.baseColor1) + qsTr("Max: %1"). arg(LocaleUtils.currencyAmountToLocaleString(root.transaction.maxTotalFees)) + "" : "" secondaryLabel.textFormat: Text.RichText } } } }