659 lines
28 KiB
QML
659 lines
28 KiB
QML
import QtQuick 2.15
|
||
import QtQuick.Layouts 1.15
|
||
import QtQml 2.15
|
||
|
||
import StatusQ.Components 0.1
|
||
import StatusQ.Core.Theme 0.1
|
||
import StatusQ.Core 0.1
|
||
import StatusQ.Controls 0.1
|
||
import StatusQ.Core.Utils 0.1 as SQUtils
|
||
|
||
import AppLayouts.Wallet 1.0
|
||
import AppLayouts.Wallet.stores 1.0 as WalletStores
|
||
|
||
import utils 1.0
|
||
import shared 1.0
|
||
import shared.stores 1.0 as SharedStores
|
||
|
||
/*!
|
||
\qmltype TransactionDelegate
|
||
\inherits StatusListItem
|
||
\inqmlmodule shared.controls
|
||
\since shared.controls 1.0
|
||
\brief Delegate for transaction activity list
|
||
|
||
Delegate to display transaction activity data.
|
||
|
||
\qml
|
||
TransactionDelegate {
|
||
id: delegate
|
||
width: ListView.view.width
|
||
modelData: model.activityEntry
|
||
flatNetworks: root.flatNetworks
|
||
currenciesStore: root.currencyStore
|
||
walletRootStore: WalletStores.RootStore
|
||
loading: isModelDataValid
|
||
}
|
||
\endqml
|
||
|
||
Additional usages should be handled using states.
|
||
*/
|
||
|
||
StatusListItem {
|
||
id: root
|
||
|
||
signal retryClicked()
|
||
|
||
property var modelData
|
||
property string timeStampText: isModelDataValid ? LocaleUtils.formatRelativeTimestamp(modelData.timestamp * 1000) : ""
|
||
property bool showAllAccounts: false
|
||
property bool displayValues: true
|
||
|
||
required property var flatNetworks
|
||
|
||
required property SharedStores.CurrenciesStore currenciesStore
|
||
required property WalletStores.RootStore walletRootStore
|
||
|
||
readonly property bool isModelDataValid: modelData !== undefined && !!modelData
|
||
|
||
readonly property string txID: isModelDataValid ? modelData.id : "INVALID"
|
||
readonly property int transactionStatus: isModelDataValid ? modelData.status : Constants.TransactionStatus.Pending
|
||
readonly property bool isMultiTransaction: isModelDataValid && modelData.isMultiTransaction
|
||
readonly property string currentCurrency: currenciesStore.currentCurrency
|
||
readonly property double cryptoValue: isModelDataValid ? modelData.amount : 0.0
|
||
readonly property double fiatValue: isModelDataValid ? currenciesStore.getFiatValue(cryptoValue, modelData.symbol) : 0.0
|
||
readonly property double inCryptoValue: isModelDataValid ? modelData.inAmount : 0.0
|
||
readonly property double inFiatValue: isModelDataValid && isMultiTransaction ? currenciesStore.getFiatValue(inCryptoValue, modelData.inSymbol): 0.0
|
||
readonly property double outCryptoValue: isModelDataValid ? modelData.outAmount : 0.0
|
||
readonly property double outFiatValue: isModelDataValid && isMultiTransaction ? currenciesStore.getFiatValue(outCryptoValue, modelData.outSymbol): 0.0
|
||
readonly property string networkColor: isModelDataValid ? SQUtils.ModelUtils.getByKey(flatNetworks, "chainId", modelData.chainId, "chainColor") : ""
|
||
readonly property string networkName: isModelDataValid ? SQUtils.ModelUtils.getByKey(flatNetworks, "chainId", modelData.chainId, "chainName") : ""
|
||
readonly property string networkNameIn: isMultiTransaction ? SQUtils.ModelUtils.getByKey(flatNetworks, "chainId", modelData.chainIdIn, "chainName") : ""
|
||
readonly property string networkNameOut: isMultiTransaction ? SQUtils.ModelUtils.getByKey(flatNetworks, "chainId", modelData.chainIdOut, "chainName") : ""
|
||
readonly property string addressNameTo: isModelDataValid ? walletRootStore.getNameForAddress(modelData.recipient) : ""
|
||
readonly property string addressNameFrom: isModelDataValid ? walletRootStore.getNameForAddress(modelData.sender) : ""
|
||
readonly property bool isNFT: isModelDataValid && modelData.isNFT
|
||
readonly property bool isCommunityAssetViaAirdrop: isModelDataValid && !!communityId && d.txType === Constants.TransactionType.Mint
|
||
readonly property string communityId: isModelDataValid && modelData.communityId ? modelData.communityId : ""
|
||
property var community: null
|
||
readonly property bool isCommunityToken: !!community && Object.keys(community).length > 0
|
||
readonly property string communityImage: isCommunityToken ? community.image : ""
|
||
readonly property string communityName: isCommunityToken ? community.name : ""
|
||
|
||
readonly property var dAppDetails: {
|
||
if (!isModelDataValid) {
|
||
return null
|
||
}
|
||
if (modelData.txType === Constants.TransactionType.Approve) {
|
||
return walletRootStore.getDappDetails(modelData.chainId, modelData.approvalSpender)
|
||
}
|
||
if (modelData.txType === Constants.TransactionType.Swap) {
|
||
return walletRootStore.getDappDetails(modelData.chainId, modelData.interactedContractAddress)
|
||
}
|
||
return null
|
||
}
|
||
|
||
readonly property string dAppIcon: dAppDetails ? dAppDetails.icon : ""
|
||
readonly property string dAppUrl: dAppDetails ? dAppDetails.url : ""
|
||
readonly property string dAppName: dAppDetails ? dAppDetails.name : ""
|
||
|
||
readonly property string transactionValue: {
|
||
if (!isModelDataValid) {
|
||
return qsTr("N/A")
|
||
} else if (root.isNFT) {
|
||
let value = ""
|
||
if (d.txType === Constants.TransactionType.Mint) {
|
||
value += modelData.amount + " "
|
||
}
|
||
value += (modelData.nftName ? modelData.nftName : "#" + modelData.tokenID)
|
||
return value
|
||
} else if (!modelData.symbol && !!modelData.tokenAddress) {
|
||
return "%1 (%2)".arg(root.currenciesStore.formatCurrencyAmount(cryptoValue, "")).arg(Utils.compactAddress(modelData.tokenAddress, 4))
|
||
}
|
||
return root.currenciesStore.formatCurrencyAmount(cryptoValue, modelData.symbol)
|
||
}
|
||
|
||
readonly property string inTransactionValue: {
|
||
if (!isModelDataValid || !isMultiTransaction) {
|
||
return qsTr("N/A")
|
||
} else if (!modelData.inSymbol && !!modelData.tokenInAddress) {
|
||
return "%1 (%2)".arg(root.currenciesStore.formatCurrencyAmount(inCryptoValue, "")).arg(Utils.compactAddress(modelData.tokenInAddress, 4))
|
||
}
|
||
return currenciesStore.formatCurrencyAmount(inCryptoValue, modelData.inSymbol)
|
||
}
|
||
readonly property string outTransactionValue: {
|
||
if (!isModelDataValid || !isMultiTransaction) {
|
||
return qsTr("N/A")
|
||
} else if (!modelData.outSymbol && !!modelData.tokenOutAddress) {
|
||
return "%1 (%2)".arg(root.currenciesStore.formatCurrencyAmount(outCryptoValue, "")).arg(Utils.compactAddress(modelData.tokenOutAddress, 4))
|
||
}
|
||
return currenciesStore.formatCurrencyAmount(outCryptoValue, modelData.outSymbol)
|
||
}
|
||
|
||
readonly property string tokenImage: {
|
||
if (!isModelDataValid || d.txType === Constants.TransactionType.ContractDeployment)
|
||
return ""
|
||
if (root.isNFT) {
|
||
return modelData.nftImageUrl ? modelData.nftImageUrl : ""
|
||
} else {
|
||
return Constants.tokenIcon(isMultiTransaction ? modelData.outSymbol : modelData.symbol)
|
||
}
|
||
}
|
||
|
||
readonly property string inTokenImage: isModelDataValid ? Constants.tokenIcon(modelData.inSymbol) : ""
|
||
|
||
readonly property string toAddress: !!addressNameTo ?
|
||
addressNameTo :
|
||
isModelDataValid ?
|
||
Utils.compactAddress(modelData.recipient, 4) :
|
||
""
|
||
|
||
readonly property string fromAddress: !!addressNameFrom ?
|
||
addressNameFrom :
|
||
isModelDataValid ?
|
||
Utils.compactAddress(modelData.sender, 4) :
|
||
""
|
||
|
||
readonly property string interactedContractAddress: isModelDataValid ? Utils.compactAddress(modelData.interactedContractAddress, 4) : ""
|
||
readonly property string approvalSpender: isModelDataValid ? Utils.compactAddress(modelData.approvalSpender, 4) : ""
|
||
|
||
property StatusAssetSettings statusIconAsset: StatusAssetSettings {
|
||
width: 12
|
||
height: 12
|
||
bgWidth: width + 2
|
||
bgHeight: bgWidth
|
||
bgRadius: bgWidth / 2
|
||
bgColor: root.color
|
||
color: "transparent"
|
||
name: {
|
||
switch(root.transactionStatus) {
|
||
case Constants.TransactionStatus.Pending:
|
||
return Theme.svg("transaction/pending")
|
||
case Constants.TransactionStatus.Complete:
|
||
case Constants.TransactionStatus.Finalised:
|
||
return Theme.svg("transaction/confirmed")
|
||
case Constants.TransactionStatus.Failed:
|
||
return Theme.svg("transaction/failed")
|
||
default:
|
||
return ""
|
||
}
|
||
}
|
||
}
|
||
|
||
property StatusAssetSettings tokenIconAsset: StatusAssetSettings {
|
||
width: 20
|
||
height: 20
|
||
bgWidth: width + 2
|
||
bgHeight: height + 2
|
||
bgRadius: bgWidth / 2
|
||
bgColor: d.lightTheme && Constants.isDefaultTokenIcon(root.tokenImage) ?
|
||
Theme.palette.white : "transparent"
|
||
color: "transparent"
|
||
isImage: !loading
|
||
name: root.tokenImage
|
||
isLetterIdenticon: loading
|
||
}
|
||
|
||
QtObject {
|
||
id: d
|
||
|
||
property int loadingPixelSize: 13
|
||
property int datePixelSize: 12
|
||
property int titlePixelSize: 15
|
||
property int subtitlePixelSize: 13
|
||
property bool showRetryButton: false
|
||
|
||
readonly property bool isLightTheme: Theme.palette.name === Constants.lightThemeName
|
||
property color animatedBgColor
|
||
property int txType: walletRootStore.getTransactionType(root.modelData)
|
||
|
||
readonly property var secondIconAsset: StatusAssetSettings {
|
||
width: root.tokenIconAsset.width
|
||
height: root.tokenIconAsset.height
|
||
bgWidth: width + 2
|
||
bgHeight: height + 2
|
||
bgRadius: bgWidth / 2
|
||
bgColor: Theme.palette.white
|
||
isImage: root.tokenIconAsset.isImage
|
||
color: root.tokenIconAsset.color
|
||
name: d.secondIconSource
|
||
isLetterIdenticon: root.tokenIconAsset.isLetterIdenticon
|
||
}
|
||
|
||
readonly property string secondIconSource: {
|
||
if (!root.isModelDataValid || root.isNFT) {
|
||
return ""
|
||
}
|
||
|
||
if (modelData.txType === Constants.TransactionType.Swap) {
|
||
return root.inTokenImage
|
||
} else if (modelData.txType === Constants.TransactionType.Approve) {
|
||
return root.dAppIcon
|
||
}
|
||
return ""
|
||
}
|
||
readonly property bool isSecondIconVisible: secondIconSource !== ""
|
||
}
|
||
|
||
function getSubtitle(allAccounts, description) {
|
||
if (root.isCommunityAssetViaAirdrop) {
|
||
let communityInfo = ""
|
||
if (!description) {
|
||
// Showing image only in delegate. In description url shouldn't be showed
|
||
communityInfo += "<img src='" + root.communityImage + "' width='18' height='18' </img> "
|
||
}
|
||
communityInfo += root.communityName
|
||
return qsTr("%1 (community asset) from %2 on %3").arg(root.transactionValue).arg(communityInfo).arg(root.networkName)
|
||
}
|
||
|
||
switch(d.txType) {
|
||
case Constants.TransactionType.Send:
|
||
// Cross chain send. Use bridge pattern
|
||
if (root.networkNameIn != root.networkNameOut && root.networkNameIn && root.networkNameOut) {
|
||
if (allAccounts)
|
||
return qsTr("%1 from %2 to %3 on %4 and %5").arg(inTransactionValue).arg(fromAddress).arg(toAddress).arg(networkNameOut).arg(networkNameIn)
|
||
return qsTr("%1 to %2 on %3 and %4").arg(inTransactionValue).arg(toAddress).arg(networkNameOut).arg(networkNameIn)
|
||
}
|
||
|
||
if (allAccounts)
|
||
return qsTr("%1 from %2 to %3 on %4").arg(transactionValue).arg(fromAddress).arg(toAddress).arg(networkName)
|
||
return qsTr("%1 to %2 on %3").arg(transactionValue).arg(toAddress).arg(networkName)
|
||
|
||
case Constants.TransactionType.Receive:
|
||
// Cross chain receive. Use bridge pattern
|
||
if (root.networkNameIn != root.networkNameOut && root.networkNameIn && root.networkNameOut) {
|
||
if (allAccounts)
|
||
return qsTr("%1 from %2 to %3 on %4 and %5").arg(inTransactionValue).arg(fromAddress).arg(toAddress).arg(networkNameOut).arg(networkNameIn)
|
||
return qsTr("%1 from %2 on %3 and %4").arg(inTransactionValue).arg(toAddress).arg(networkNameOut).arg(networkNameIn)
|
||
}
|
||
|
||
if (allAccounts)
|
||
return qsTr("%1 from %2 to %3 on %4").arg(transactionValue).arg(fromAddress).arg(toAddress).arg(networkName)
|
||
return qsTr("%1 from %2 on %3").arg(transactionValue).arg(fromAddress).arg(networkName)
|
||
case Constants.TransactionType.Destroy:
|
||
if (allAccounts)
|
||
return qsTr("%1 at %2 on %3 in %4").arg(inTransactionValue).arg(toAddress).arg(networkName).arg(toAddress)
|
||
return qsTr("%1 at %2 on %3").arg(inTransactionValue).arg(toAddress).arg(networkName)
|
||
case Constants.TransactionType.Swap:
|
||
if (allAccounts)
|
||
return qsTr("%1 to %2 in %3 on %4").arg(outTransactionValue).arg(inTransactionValue).arg(fromAddress).arg(networkName)
|
||
return qsTr("%1 to %2 on %3").arg(outTransactionValue).arg(inTransactionValue).arg(networkName)
|
||
case Constants.TransactionType.Bridge:
|
||
if (allAccounts)
|
||
return qsTr("%1 from %2 to %3 in %4").arg(outTransactionValue).arg(networkNameOut).arg(networkNameIn).arg(fromAddress)
|
||
return qsTr("%1 from %2 to %3").arg(outTransactionValue).arg(networkNameOut).arg(networkNameIn)
|
||
case Constants.TransactionType.ContractDeployment:
|
||
const name = addressNameTo || addressNameFrom
|
||
return qsTr("Via %1 on %2").arg(name).arg(networkName)
|
||
case Constants.TransactionType.Mint:
|
||
if (allAccounts)
|
||
return qsTr("%1 via %2 in %3").arg(transactionValue).arg(networkName).arg(toAddress)
|
||
return qsTr("%1 via %2").arg(transactionValue).arg(networkName)
|
||
case Constants.TransactionType.Approve:
|
||
if (root.dAppUrl !== "") {
|
||
if (allAccounts)
|
||
return qsTr("%1 in %2 for %3 on %4").arg(transactionValue).arg(toAddress).arg(dAppUrl).arg(networkName)
|
||
return qsTr("%1 for %2 on %3").arg(transactionValue).arg(dAppUrl).arg(networkName)
|
||
}
|
||
if (allAccounts)
|
||
return qsTr("%1 in %2 for %3 on %4").arg(transactionValue).arg(fromAddress).arg(approvalSpender).arg(networkName)
|
||
return qsTr("%1 for %2 on %3").arg(transactionValue).arg(approvalSpender).arg(networkName)
|
||
default:
|
||
// Unknown contract interaction
|
||
if (allAccounts)
|
||
return qsTr("Between %1 and %2 on %3").arg(fromAddress).arg(interactedContractAddress).arg(networkName)
|
||
return qsTr("With %1 on %2").arg(interactedContractAddress).arg(networkName)
|
||
}
|
||
}
|
||
|
||
rightPadding: 16
|
||
enabled: !loading
|
||
loading: !isModelDataValid
|
||
color: {
|
||
if (bgColorAnimation.running) {
|
||
return d.animatedBgColor
|
||
}
|
||
return sensor.containsMouse ? Theme.palette.baseColor5 : Theme.palette.transparent
|
||
}
|
||
|
||
statusListItemIcon.active: (loading || root.asset.name)
|
||
asset {
|
||
width: 24
|
||
height: 24
|
||
isImage: false
|
||
imgIsIdenticon: true
|
||
isLetterIdenticon: loading
|
||
name: {
|
||
if (!root.isModelDataValid)
|
||
return ""
|
||
|
||
switch(d.txType) {
|
||
case Constants.TransactionType.Send:
|
||
return "send"
|
||
case Constants.TransactionType.Receive:
|
||
return "receive"
|
||
case Constants.TransactionType.Mint:
|
||
return "token"
|
||
case Constants.TransactionType.Destroy:
|
||
return "destroy"
|
||
case Constants.TransactionType.Swap:
|
||
return "swap"
|
||
case Constants.TransactionType.Bridge:
|
||
return "bridge"
|
||
case Constants.TransactionType.ContractDeployment:
|
||
return "contract_deploy"
|
||
case Constants.TransactionType.Approve:
|
||
return "approve"
|
||
default:
|
||
return "contract_deploy"
|
||
}
|
||
}
|
||
bgColor: "transparent"
|
||
color: Theme.palette.directColor1
|
||
bgBorderWidth: 1
|
||
bgBorderColor: Theme.palette.primaryColor3
|
||
}
|
||
|
||
sensor.children: [
|
||
StatusRoundIcon {
|
||
id: leftIconStatusIcon
|
||
visible: !root.loading
|
||
anchors {
|
||
right: root.statusListItemIcon.right
|
||
bottom: root.statusListItemIcon.bottom
|
||
}
|
||
asset: root.statusIconAsset
|
||
}
|
||
]
|
||
|
||
// Title
|
||
title: {
|
||
if (root.loading) {
|
||
return "dummmy"
|
||
} else if (!root.isModelDataValid) {
|
||
return ""
|
||
}
|
||
|
||
const isPending = root.transactionStatus === Constants.TransactionStatus.Pending
|
||
const failed = root.transactionStatus === Constants.TransactionStatus.Failed
|
||
switch(d.txType) {
|
||
case Constants.TransactionType.Send:
|
||
return failed ? qsTr("Send failed") : (isPending ? qsTr("Sending") : qsTr("Sent"))
|
||
case Constants.TransactionType.Receive:
|
||
return failed ? qsTr("Receive failed") : (isPending ? qsTr("Receiving") : qsTr("Received"))
|
||
case Constants.TransactionType.Destroy:
|
||
return failed ? qsTr("Destroy failed") : (isPending ? qsTr("Destroying") : qsTr("Destroyed"))
|
||
case Constants.TransactionType.Swap:
|
||
return failed ? qsTr("Swap failed") : (isPending ? qsTr("Swapping") : qsTr("Swapped"))
|
||
case Constants.TransactionType.Bridge:
|
||
return failed ? qsTr("Bridge failed") : (isPending ? qsTr("Bridging") : qsTr("Bridged"))
|
||
case Constants.TransactionType.ContractDeployment:
|
||
return failed ? qsTr("Contract deployment failed") : (isPending ? qsTr("Deploying contract") : qsTr("Contract deployed"))
|
||
case Constants.TransactionType.Mint:
|
||
if (isNFT)
|
||
return failed ? qsTr("Collectible minting failed") : (isPending ? qsTr("Minting collectible") : qsTr("Collectible minted"))
|
||
return failed ? qsTr("Token minting failed") : (isPending ? qsTr("Minting token") : qsTr("Token minted"))
|
||
case Constants.TransactionType.Approve:
|
||
return failed ? qsTr("Failed to set spending cap") : (isPending ? qsTr("Setting spending cap") : qsTr("Spending cap set"))
|
||
default:
|
||
return qsTr("Interaction")
|
||
}
|
||
}
|
||
statusListItemTitleArea.anchors.rightMargin: root.rightPadding
|
||
statusListItemTitle.font.weight: Font.DemiBold
|
||
statusListItemTitle.font.pixelSize: root.loading ? d.loadingPixelSize : d.titlePixelSize
|
||
|
||
// title icons and date
|
||
statusListItemTitleIcons.sourceComponent: Row {
|
||
spacing: 8
|
||
Row {
|
||
id: tokenImagesRow
|
||
visible: !root.loading && !!root.tokenIconAsset.name
|
||
spacing: secondTokenImage.visible ? -tokenImage.width * 0.2 : 0
|
||
StatusRoundIcon {
|
||
id: tokenImage
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
asset: root.tokenIconAsset
|
||
}
|
||
StatusRoundIcon {
|
||
id: secondTokenImage
|
||
visible: d.isSecondIconVisible
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
asset: d.secondIconAsset
|
||
}
|
||
}
|
||
StatusTextWithLoadingState {
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
text: root.loading ? root.title : root.timeStampText
|
||
verticalAlignment: Qt.AlignVCenter
|
||
font.pixelSize: root.loading ? d.loadingPixelSize : d.datePixelSize
|
||
visible: !!text
|
||
loading: root.loading
|
||
customColor: Theme.palette.baseColor1
|
||
leftPadding: tokenImagesRow.visible ? 0 : parent.spacing
|
||
}
|
||
}
|
||
|
||
// subtitle
|
||
subTitle: {
|
||
if (root.loading) {
|
||
return "dummy text dummy text dummy text dummy text dummy text dummy text"
|
||
}
|
||
|
||
if (!root.isModelDataValid) {
|
||
return ""
|
||
}
|
||
|
||
return getSubtitle(root.showAllAccounts, false)
|
||
}
|
||
statusListItemSubTitle.textFormat: root.isCommunityAssetViaAirdrop ? Text.RichText : Text.AutoText
|
||
statusListItemSubTitle.maximumLoadingStateWidth: 400
|
||
statusListItemSubTitle.customColor: Theme.palette.directColor1
|
||
statusListItemSubTitle.font.pixelSize: root.loading ? d.loadingPixelSize : d.subtitlePixelSize
|
||
statusListItemTagsRowLayout.anchors.topMargin: 4 // Spacing between title row nad subtitle row
|
||
|
||
// Right side components
|
||
components: [
|
||
Loader {
|
||
active: root.displayValues && !headerStatusLoader.active
|
||
visible: active
|
||
sourceComponent: ColumnLayout {
|
||
StatusTextWithLoadingState {
|
||
id: cryptoValueText
|
||
text: {
|
||
if (root.loading) {
|
||
return "dummy text"
|
||
} else if (!root.isModelDataValid || root.isNFT) {
|
||
return ""
|
||
}
|
||
|
||
switch(d.txType) {
|
||
case Constants.TransactionType.Send:
|
||
return "−" + root.transactionValue
|
||
case Constants.TransactionType.Receive:
|
||
return "+" + root.transactionValue
|
||
case Constants.TransactionType.Swap:
|
||
let outValue = root.outTransactionValue
|
||
outValue = outValue.replace('<', '<')
|
||
let inValue = root.inTransactionValue
|
||
inValue = inValue.replace('<', '<')
|
||
return "<font color=\"%1\">-%2</font> <font color=\"%3\">/</font> <font color=\"%4\">+%5</font>"
|
||
.arg(Theme.palette.directColor1)
|
||
.arg(outValue)
|
||
.arg(Theme.palette.baseColor1)
|
||
.arg(Theme.palette.successColor1)
|
||
.arg(inValue)
|
||
case Constants.TransactionType.Bridge:
|
||
case Constants.TransactionType.Approve:
|
||
default:
|
||
return ""
|
||
}
|
||
}
|
||
horizontalAlignment: Qt.AlignRight
|
||
Layout.alignment: Qt.AlignRight
|
||
font.pixelSize: root.loading ? d.loadingPixelSize : 13
|
||
customColor: {
|
||
if (!root.isModelDataValid)
|
||
return ""
|
||
|
||
switch(d.txType) {
|
||
case Constants.TransactionType.Receive:
|
||
case Constants.TransactionType.Swap:
|
||
return Theme.palette.successColor1
|
||
default:
|
||
return Theme.palette.directColor1
|
||
}
|
||
}
|
||
loading: root.loading
|
||
}
|
||
StatusTextWithLoadingState {
|
||
id: fiatValueText
|
||
Layout.alignment: Qt.AlignRight
|
||
horizontalAlignment: Qt.AlignRight
|
||
text: {
|
||
if (root.loading) {
|
||
return "dummy text"
|
||
} else if (!root.isModelDataValid || root.isNFT || !modelData.symbol) {
|
||
return ""
|
||
}
|
||
|
||
switch(d.txType) {
|
||
case Constants.TransactionType.Send:
|
||
return "−" + root.currenciesStore.formatCurrencyAmount(root.fiatValue, root.currentCurrency)
|
||
case Constants.TransactionType.Receive:
|
||
return "+" + root.currenciesStore.formatCurrencyAmount(root.fiatValue, root.currentCurrency)
|
||
case Constants.TransactionType.Swap:
|
||
return "-%1 / +%2".arg(root.currenciesStore.formatCurrencyAmount(root.outFiatValue, root.currentCurrency))
|
||
.arg(root.currenciesStore.formatCurrencyAmount(root.inFiatValue, root.currentCurrency))
|
||
case Constants.TransactionType.Bridge:
|
||
case Constants.TransactionType.Approve:
|
||
default:
|
||
return ""
|
||
}
|
||
}
|
||
font.pixelSize: root.loading ? d.loadingPixelSize : 12
|
||
customColor: Theme.palette.baseColor1
|
||
loading: root.loading
|
||
}
|
||
}
|
||
},
|
||
Loader {
|
||
id: headerStatusLoader
|
||
active: false
|
||
visible: active
|
||
sourceComponent: Rectangle {
|
||
id: statusRect
|
||
width: transactionTypeIcon.width + (retryButton.visible ? retryButton.width + 5 : 0)
|
||
height: transactionTypeIcon.height
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
color: "transparent"
|
||
radius: 100
|
||
border {
|
||
width: retryButton.visible ? 1 : 0
|
||
color: root.asset.bgBorderColor
|
||
}
|
||
|
||
StatusButton {
|
||
id: retryButton
|
||
anchors.left: parent.left
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
anchors.leftMargin: 10
|
||
radius: height / 2
|
||
height: parent.height * 0.7
|
||
verticalPadding: 0
|
||
horizontalPadding: radius
|
||
text: qsTr("Retry")
|
||
size: StatusButton.Small
|
||
type: StatusButton.Primary
|
||
visible: d.showRetryButton
|
||
onClicked: root.retryClicked()
|
||
}
|
||
|
||
StatusSmartIdenticon {
|
||
id: transactionTypeIcon
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
anchors.right: parent.right
|
||
enabled: false
|
||
asset: root.asset
|
||
active: !!root.asset.name
|
||
loading: root.loading
|
||
name: root.title
|
||
}
|
||
|
||
StatusRoundIcon {
|
||
visible: !root.loading
|
||
anchors {
|
||
right: transactionTypeIcon.right
|
||
bottom: transactionTypeIcon.bottom
|
||
}
|
||
asset: root.statusIconAsset
|
||
}
|
||
}
|
||
}
|
||
]
|
||
|
||
states: [
|
||
State {
|
||
name: "header"
|
||
PropertyChanges {
|
||
target: headerStatusLoader
|
||
active: true
|
||
}
|
||
PropertyChanges {
|
||
target: leftIconStatusIcon
|
||
visible: false
|
||
}
|
||
PropertyChanges {
|
||
target: root.statusListItemIcon
|
||
active: false
|
||
}
|
||
PropertyChanges {
|
||
target: root.asset
|
||
bgBorderWidth: d.showRetryButton ? 0 : 1
|
||
width: 34
|
||
height: 34
|
||
bgWidth: 56
|
||
bgHeight: 56
|
||
}
|
||
PropertyChanges {
|
||
target: root.statusIconAsset
|
||
width: 17
|
||
height: 17
|
||
}
|
||
// PropertyChanges { // TODO uncomment when retry failed tx is implemented
|
||
// target: d
|
||
// titlePixelSize: 17
|
||
// datePixelSize: 13
|
||
// subtitlePixelSize: 15
|
||
// loadingPixelSize: 14
|
||
// showRetryButton: (!root.loading && root.transactionStatus === Constants.TransactionStatus.Failed && walletRootStore.isOwnedAccount(modelData.sender))
|
||
// }
|
||
}
|
||
]
|
||
|
||
ColorAnimation {
|
||
id: bgColorAnimation
|
||
|
||
target: d
|
||
property: "animatedBgColor"
|
||
from: d.isLightTheme ? "#33869eff" : "#1a4360df"
|
||
to: "transparent"
|
||
duration: 1000
|
||
alwaysRunToEnd: true
|
||
|
||
onStopped: {
|
||
modelData.doneHighlighting()
|
||
}
|
||
}
|
||
// Add a delay before the animation to make it easier to notice when scrolling
|
||
Timer {
|
||
id: delayAnimation
|
||
interval: 250
|
||
running: root.visible && isModelDataValid && modelData.highlight
|
||
repeat: false
|
||
onTriggered: {
|
||
bgColorAnimation.start()
|
||
}
|
||
}
|
||
}
|