import QtQuick 2.3 import utils 1.0 import shared 1.0 import shared.panels 1.0 import shared.popups 1.0 import shared.views.chat 1.0 import shared.controls.chat 1.0 import shared.controls 1.0 import shared.stores 1.0 Item { id: root width: rectangleBubble.width height: rectangleBubble.height property var store property var contactsStore property var transactionParams property var transactionParamsObject: { try { return JSON.parse(transactionParams) } catch (e) { console.error('Error parsing command parameters') console.error('JSON:', transactionParams) console.error('Error:', e) return { id: "", fromAddress: "", address: "", contract: "", value: "", transactionHash: "", commandState: 1, signature: null } } } property var token:{ try { return JSON.parse(transactionParamsObject.contract) } catch (e) { console.error('Error parsing command parameters') console.error('JSON:', transactionParamsObject.contract) console.error('Error:', e) return "" } } property var selectedRecipient: { return { address: transactionParamsObject.address, name: senderDisplayName, type: RecipientSelector.Type.Contact, alias: senderDisplayName } } property string tokenAmount: transactionParamsObject.value property string tokenSymbol: token.symbol || "" property string fiatValue: { if (!tokenAmount || !token.symbol) { return "0" } var defaultFiatSymbol = root.store.currentCurrency return root.store.getFiatValue(tokenAmount, token.symbol, defaultFiatSymbol) + " " + defaultFiatSymbol.toUpperCase() } property int state: transactionParamsObject.commandState // Any transaction where isCurrentUser is true is actually outgoing transaction. property bool outgoing: isCurrentUser property int innerMargin: 12 property bool isError: transactionParamsObject.contract === "{}" onTokenSymbolChanged: { if (!!tokenSymbol) { tokenImage.source = Style.png("tokens/"+root.tokenSymbol) } } Rectangle { id: rectangleBubble width: (bubbleLoader.active ? bubbleLoader.width : valueContainer.width) + timeText.width + 3 * root.innerMargin height: childrenRect.height + root.innerMargin radius: 16 color: Style.current.background border.color: Style.current.border border.width: 1 StyledText { id: title color: Style.current.secondaryText text: { if (root.state === Constants.transactionRequested) { let prefix = outgoing? "↑ " : "↓ " return prefix + qsTr("Transaction request") } return outgoing ? qsTr("↑ Outgoing transaction") : qsTr("↓ Incoming transaction") } font.weight: Font.Medium anchors.top: parent.top anchors.topMargin: Style.current.halfPadding anchors.left: parent.left anchors.leftMargin: root.innerMargin font.pixelSize: 13 } Item { id: valueContainer width: childrenRect.width height: tokenText.height + fiatText.height anchors.top: title.bottom anchors.topMargin: 4 anchors.left: parent.left anchors.leftMargin: root.innerMargin StyledText { id: txtError color: Style.current.danger visible: root.isError text: qsTr("Token not found on your current network") } Image { id: tokenImage visible: !root.isError width: 24 height: 24 anchors.verticalCenter: parent.verticalCenter } StyledText { id: tokenText visible: !root.isError color: Style.current.textColor text: `${root.tokenAmount} ${root.tokenSymbol}` anchors.left: tokenImage.right anchors.leftMargin: Style.current.halfPadding font.pixelSize: 22 } StyledText { id: fiatText visible: !root.isError color: Style.current.secondaryText text: root.fiatValue anchors.top: tokenText.bottom anchors.left: tokenText.left font.pixelSize: 13 } } Loader { id: bubbleLoader active: { return !root.isError && ( isCurrentUser || (!isCurrentUser && !(root.state === Constants.addressRequested || root.state === Constants.transactionRequested) ) ) } sourceComponent: stateBubbleComponent anchors.top: valueContainer.bottom anchors.topMargin: Style.current.halfPadding anchors.left: parent.left anchors.leftMargin: root.innerMargin } Component { id: stateBubbleComponent StateBubble { state: root.state outgoing: root.outgoing } } Loader { id: buttonsLoader active: !root.isError && ( (root.state === Constants.addressRequested && !root.outgoing) || (root.state === Constants.addressReceived && root.outgoing) || (root.state === Constants.transactionRequested && !root.outgoing) ) sourceComponent: root.outgoing ? signAndSendComponent : acceptTransactionComponent anchors.top: bubbleLoader.active ? bubbleLoader.bottom : valueContainer.bottom anchors.topMargin: bubbleLoader.active ? root.innerMargin : 20 width: parent.width } Component { id: acceptTransactionComponent AcceptTransactionView { state: root.state store: root.store contactsStore: root.contactsStore token: root.token fiatValue: root.fiatValue tokenAmount: root.tokenAmount selectedRecipient: root.selectedRecipient } } Component { id: signAndSendComponent SendTransactionButton { selectedAsset: token selectedAmount: tokenAmount selectedFiatAmount: fiatValue fromAddress: transactionParamsObject.fromAddress selectedRecipient: root.selectedRecipient onSendTransaction: { Global.openPopup(signTxComponent, {selectedAccount: { name: root.store.getAccountNameByAddress(fromAddress), address: fromAddress, color: root.store.getAccountIconColorByAddress(fromAddress), assets: root.store.getAccountAssetsByAddress(fromAddress) }}) } } } Component { id: signTxComponent SignTransactionModal { anchors.centerIn: parent store: root.store contactsStore: root.contactsStore selectedAsset: root.token selectedAmount: root.tokenAmount selectedRecipient: root.selectedRecipient selectedFiatAmount: root.fiatValue selectedType: RecipientSelector.Type.Contact chainId: root.store.getChainIdForChat() onClosed: destroy() msgId: messageId } } StyledText { id: timeText color: Style.current.secondaryText text: Utils.formatShortTime(timestamp, RootStore.accountSensitiveSettings.is24hTimeFormat) anchors.left: bubbleLoader.active ? bubbleLoader.right : undefined anchors.leftMargin: bubbleLoader.active ? 13 : 0 anchors.right: bubbleLoader.active ? undefined : parent.right anchors.rightMargin: bubbleLoader.active ? 0 : root.innerMargin anchors.bottom: bubbleLoader.active ? bubbleLoader.bottom : buttonsLoader.top anchors.bottomMargin: bubbleLoader.active ? -root.innerMargin : 7 font.pixelSize: 10 } } }