feat(@wallet): calculate progress for activity tx

fixes #10762
This commit is contained in:
Anthony Laibe 2023-05-24 08:22:29 +02:00 committed by Anthony Laibe
parent d924d5a94a
commit 1e5fee981e
14 changed files with 63 additions and 325 deletions

View File

@ -161,6 +161,12 @@ QtObject:
return item.getChainName() return item.getChainName()
return "" return ""
proc getNetworkLayer*(self: Model, chainId: int): string {.slot.} =
for item in self.items:
if(item.getChainId() == chainId):
return $item.getLayer()
return ""
proc getNetworkIconUrl*(self: Model, shortName: string): string {.slot.} = proc getNetworkIconUrl*(self: Model, shortName: string): string {.slot.} =
for item in self.items: for item in self.items:
if cmpIgnoreCase(item.getShortName(), shortName) == 0: if cmpIgnoreCase(item.getShortName(), shortName) == 0:

View File

@ -110,8 +110,8 @@ proc getChainIdForChat*(self: Controller): int =
proc getChainIdForBrowser*(self: Controller): int = proc getChainIdForBrowser*(self: Controller): int =
return self.networkService.getNetworkForBrowser().chainId return self.networkService.getNetworkForBrowser().chainId
proc getLastTxBlockNumber*(self: Controller): string = proc getLatestBlockNumber*(self: Controller, chainId: int): string =
return self.transactionService.getLastTxBlockNumber(self.networkService.getNetworkForBrowser().chainId) return self.transactionService.getLatestBlockNumber(chainId)
proc getEnabledChainIds*(self: Controller): seq[int] = proc getEnabledChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId) return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)

View File

@ -60,7 +60,7 @@ method refreshTransactions*(self: AccessInterface) {.base.} =
method viewDidLoad*(self: AccessInterface) {.base.} = method viewDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method getLastTxBlockNumber*(self: AccessInterface): string {.base.} = method getLatestBlockNumber*(self: AccessInterface, chainId: int): string {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method transactionsToItems*(self: AccessInterface, transactions: seq[TransactionDto], collectibles: seq[CollectibleDto]): seq[Item] {.base.} = method transactionsToItems*(self: AccessInterface, transactions: seq[TransactionDto], collectibles: seq[CollectibleDto]): seq[Item] {.base.} =

View File

@ -132,8 +132,8 @@ method getChainIdForChat*(self: Module): int =
method getChainIdForBrowser*(self: Module): int = method getChainIdForBrowser*(self: Module): int =
return self.controller.getChainIdForBrowser() return self.controller.getChainIdForBrowser()
method getLastTxBlockNumber*(self: Module): string = method getLatestBlockNumber*(self: Module, chainId: int): string =
return self.controller.getLastTxBlockNumber() return self.controller.getLatestBlockNumber(chainId)
method transactionWasSent*(self: Module, result: string) = method transactionWasSent*(self: Module, result: string) =
self.view.setPendingTx(self.transactionsToItems(self.controller.getPendingTransactions(), @[])) self.view.setPendingTx(self.transactionsToItems(self.controller.getPendingTransactions(), @[]))

View File

@ -138,8 +138,8 @@ QtObject:
proc getChainIdForBrowser*(self: View): int {.slot.} = proc getChainIdForBrowser*(self: View): int {.slot.} =
return self.delegate.getChainIdForBrowser() return self.delegate.getChainIdForBrowser()
proc getLastTxBlockNumber*(self: View): string {.slot.} = proc getLatestBlockNumber*(self: View, chainId: int): string {.slot.} =
return self.delegate.getLastTxBlockNumber() return self.delegate.getLatestBlockNumber(chainId)
proc setPendingTx*(self: View, pendingTx: seq[Item]) = proc setPendingTx*(self: View, pendingTx: seq[Item]) =
for tx in pendingTx: for tx in pendingTx:

View File

@ -530,7 +530,7 @@ QtObject:
error "Error estimating transaction time", message = e.msg error "Error estimating transaction time", message = e.msg
return EstimatedTime.Unknown return EstimatedTime.Unknown
proc getLastTxBlockNumber*(self: Service, chainId: int): string = proc getLatestBlockNumber*(self: Service, chainId: int): string =
try: try:
let response = eth.getBlockByNumber(chainId, "latest") let response = eth.getBlockByNumber(chainId, "latest")
return response.result{"number"}.getStr return response.result{"number"}.getStr

View File

@ -47,11 +47,11 @@ SplitView {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
width: 500 width: 500
error: failureCheckBox.checked error: failureCheckBox.checked
isMainnetTx: mainnetCheckbox.checked isLayer1: mainnetCheckbox.checked
confirmations: confirmationsSlider.value confirmations: confirmationsSlider.value
duration: durationSlider.to duration: durationSlider.to
progress: durationSlider.value progress: durationSlider.value
chainName: isMainnetTx ? "Mainnet" :"Optimism" chainName: isLayer1 ? "Mainnet" :"Optimism"
} }
Rectangle { Rectangle {
@ -64,11 +64,11 @@ SplitView {
anchors.topMargin: 20 anchors.topMargin: 20
width: 500 width: 500
error: failureCheckBox.checked error: failureCheckBox.checked
isMainnetTx: mainnetCheckbox.checked isLayer1: mainnetCheckbox.checked
confirmations: confirmationsSlider.value confirmations: confirmationsSlider.value
duration: durationSlider.to duration: durationSlider.to
progress: durationSlider.value progress: durationSlider.value
chainName: isMainnetTx ? "Mainnet" :"Optimism" chainName: isLayer1 ? "Mainnet" :"Optimism"
confirmationTimeStamp: 1670419848 confirmationTimeStamp: 1670419848
finalisationTimeStamp: 1670419848 finalisationTimeStamp: 1670419848
failedTimeStamp: 1670419848 failedTimeStamp: 1670419848

View File

@ -8,11 +8,11 @@ import StatusQ.Controls 0.1
ColumnLayout { ColumnLayout {
id: root id: root
property bool isMainnetTx: true property bool isLayer1: true
property bool error: false property bool error: false
property int steps: isMainnetTx ? 64 : 1 property int steps: isLayer1 ? 64 : 1
property int confirmations: 0 property int confirmations: 0
property int confirmationBlocks: isMainnetTx ? 4 : 1 property int confirmationBlocks: isLayer1 ? 4 : 1
property string chainName property string chainName
property color fillColor: Theme.palette.blockProgressBarColor property color fillColor: Theme.palette.blockProgressBarColor
@ -28,7 +28,7 @@ ColumnLayout {
QtObject { QtObject {
id: d id: d
readonly property bool finalized: isMainnetTx ? confirmations >= steps : progress === duration readonly property bool finalized: isLayer1 ? confirmations >= steps : progress === duration
readonly property bool confirmed: confirmations >= confirmationBlocks readonly property bool confirmed: confirmations >= confirmationBlocks
readonly property int hoursInADay: 24 readonly property int hoursInADay: 24
} }
@ -62,7 +62,7 @@ ColumnLayout {
id: blockProgressBar id: blockProgressBar
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
visible: root.isMainnetTx visible: root.isLayer1
steps: root.steps steps: root.steps
completedSteps: root.confirmations completedSteps: root.confirmations
blockSet: root.confirmationBlocks blockSet: root.confirmationBlocks
@ -70,7 +70,7 @@ ColumnLayout {
} }
RowLayout { RowLayout {
spacing: 2 spacing: 2
visible: !root.isMainnetTx visible: !root.isLayer1
Rectangle { Rectangle {
Layout.preferredWidth: 3 Layout.preferredWidth: 3
Layout.fillHeight: true Layout.fillHeight: true
@ -99,7 +99,7 @@ ColumnLayout {
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1
lineHeight: 18 lineHeight: 18
lineHeightMode: Text.FixedHeight lineHeightMode: Text.FixedHeight
text: d.finalized && !root.error ? qsTr("In epoch %1").arg(root.confirmations) : d.confirmed && !root.isMainnetTx ? text: d.finalized && !root.error ? qsTr("In epoch %1").arg(root.confirmations) : d.confirmed && !root.isLayer1 ?
qsTr("%n day(s) until finality", "", Math.ceil((root.duration - root.progress)/d.hoursInADay)): qsTr("%n day(s) until finality", "", Math.ceil((root.duration - root.progress)/d.hoursInADay)):
qsTr("%1 / %2 confirmations").arg(root.confirmations).arg(root.steps) qsTr("%1 / %2 confirmations").arg(root.confirmations).arg(root.steps)
} }

View File

@ -13,22 +13,36 @@ ColumnLayout {
id: root id: root
// To-do adapt this for multi-tx, not sure how the data will look for that yet // To-do adapt this for multi-tx, not sure how the data will look for that yet
property bool isMainnetTx: true property bool isLayer1: true
property bool error: false property bool error: false
property int confirmations: 0 property int confirmations: 0
property string chainName property string chainName
property int duration: 0 property double timeStamp
property int progress: 0
property double confirmationTimeStamp
property double finalisationTimeStamp
property double failedTimeStamp
spacing: 32 spacing: 32
QtObject { QtObject {
id: d id: d
readonly property bool finalized: (isMainnetTx ? confirmations >= progressBar.steps : progress === duration) && !error readonly property bool finalized: (isLayer1 ? confirmations >= progressBar.steps : progress === duration) && !error
readonly property bool confirmed: confirmations >= progressBar.confirmationBlocks && !error readonly property bool confirmed: confirmations >= progressBar.confirmationBlocks && !error
readonly property double confirmationTimeStamp: {
if (root.isLayer1) {
return root.timeStamp + 12 * 4 // A block on layer1 is every 12s
}
return root.timeStamp
}
readonly property double finalisationTimeStamp: {
if (root.isLayer1) {
return root.timeStamp + 12 * 64 // A block on layer1 is every 12s
}
return root.timeStamp + 604800 // 7 days in seconds
}
readonly property int duration: 168 // 7 days in hours
readonly property int progress: (Math.floor(Date.now() / 1000) - root.timeStamp) / 3600
} }
Separator { Separator {
@ -41,10 +55,10 @@ ColumnLayout {
Layout.topMargin: 8 Layout.topMargin: 8
Layout.fillWidth: true Layout.fillWidth: true
error: root.error error: root.error
isMainnetTx: root.isMainnetTx isLayer1: root.isLayer1
confirmations: root.confirmations confirmations: root.confirmations
duration: root.duration duration: d.duration
progress: root.progress progress: d.progress
chainName: root.chainName chainName: root.chainName
} }
@ -69,7 +83,7 @@ ColumnLayout {
color: Theme.palette.directColor1 color: Theme.palette.directColor1
lineHeight: 18 lineHeight: 18
lineHeightMode: Text.FixedHeight lineHeightMode: Text.FixedHeight
text: LocaleUtils.formatDateTime(root.confirmationTimeStamp * 1000, Locale.LongFormat) text: LocaleUtils.formatDateTime(d.confirmationTimeStamp * 1000, Locale.LongFormat)
} }
} }
@ -92,7 +106,7 @@ ColumnLayout {
color: Theme.palette.directColor1 color: Theme.palette.directColor1
lineHeight: 18 lineHeight: 18
lineHeightMode: Text.FixedHeight lineHeightMode: Text.FixedHeight
text: LocaleUtils.formatDateTime(root.finalisationTimeStamp * 1000, Locale.LongFormat) text: LocaleUtils.formatDateTime(d.finalisationTimeStamp * 1000, Locale.LongFormat)
} }
} }
@ -115,7 +129,7 @@ ColumnLayout {
color: Theme.palette.directColor1 color: Theme.palette.directColor1
lineHeight: 18 lineHeight: 18
lineHeightMode: Text.FixedHeight lineHeightMode: Text.FixedHeight
text: LocaleUtils.formatDateTime(root.failedTimeStamp * 1000, Locale.LongFormat) text: LocaleUtils.formatDateTime(root.timeStamp * 1000, Locale.LongFormat)
} }
} }
} }

View File

@ -118,18 +118,10 @@ QtObject {
localAccountSensitiveSettings.hideSignPhraseModal = value; localAccountSensitiveSettings.hideSignPhraseModal = value;
} }
function getLatestBlockNumber() { function getLatestBlockNumber(chainId) {
// TODO: Move to transaction root module and not wallet return walletSectionTransactions.getLatestBlockNumber(chainId)
// Not Refactored Yet
// return walletModel.getLatestBlockNumber()
} }
function setInitialRange() {
// Not Refactored Yet
// walletModel.setInitialRange()
}
function setFilterAddress(address) { function setFilterAddress(address) {
walletSection.setFilterAddress(address) walletSection.setFilterAddress(address)
} }

View File

@ -92,13 +92,10 @@ Item {
WalletTxProgressBlock { WalletTxProgressBlock {
width: Math.min(513, root.width) width: Math.min(513, root.width)
error: transactionHeader.transactionStatus === TransactionDelegate.TransactionStatus.Failed error: transactionHeader.transactionStatus === TransactionDelegate.TransactionStatus.Failed
// To-do once we have days for finalisation for tx other than eth set this to true and also provide duration and progress values isLayer1: RootStore.getNetworkLayer(root.transaction.chainId) == 1
isMainnetTx: true confirmations: root.isTransactionValid ? Math.abs(WalletStores.RootStore.getLatestBlockNumber(root.transaction.chainId) - RootStore.hex2Dec(root.transaction.blockNumber)): 0
confirmations: root.isTransactionValid ? Math.abs(RootStore.getLatestBlockNumber() - RootStore.hex2Dec(root.transaction.blockNumber)): 0 chainName: root.isTransactionValid ? RootStore.getNetworkFullName(root.transaction.chainId): ""
chainName: root.isTransactionValid ? RootStore.getNetworkFullName(transaction.chainId): "" timeStamp: root.isTransactionValid ? transaction.timestamp: ""
confirmationTimeStamp: root.isTransactionValid ? transaction.timestamp: ""
finalisationTimeStamp: root.isTransactionValid ? transaction.timestamp: ""
failedTimeStamp: root.isTransactionValid ? transaction.timestamp: ""
} }
SavedAddressesDelegate { SavedAddressesDelegate {
@ -196,7 +193,7 @@ Item {
primaryText: qsTr("Confirmations") primaryText: qsTr("Confirmations")
secondaryText: { secondaryText: {
if(root.isTransactionValid) if(root.isTransactionValid)
return Math.abs(RootStore.getLatestBlockNumber() - RootStore.hex2Dec(root.transaction.blockNumber)) return Math.abs(WalletStores.RootStore.getLatestBlockNumber(root.transaction.chainId) - RootStore.hex2Dec(root.transaction.blockNumber))
else else
return "" return ""
} }

View File

@ -1,270 +0,0 @@
import QtQuick 2.13
import utils 1.0
import shared 1.0
import shared.panels 1.0
import shared.popups 1.0
import "../stores"
// TODO: replace with StatusModal
ModalPopup {
id: popup
property var transaction
title: qsTr("Transaction Details")
readonly property bool isTransactionValid: transaction !== undefined
Item {
id: confirmations
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
anchors.top: parent.top
anchors.topMargin: Style.current.smallPadding
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
height: children[0].height + children[1].height + Style.current.smallPadding
StyledText {
id: confirmationsCount
text: {
if(popup.isTransactionValid)
return RootStore.getLatestBlockNumber() - RootStore.hex2Dec(transaction.blockNumber) + qsTr(" confirmation(s)")
else
return ""
}
font.pixelSize: 14
}
StyledText {
id: confirmationsInfo
text: qsTr("When the transaction has 12 confirmations you can consider it settled.")
wrapMode: Text.WordWrap
font.pixelSize: 14
font.weight: Font.Medium
color: Style.current.secondaryText
anchors.top: confirmationsCount.bottom
anchors.topMargin: Style.current.smallPadding
width: parent.width
}
}
Separator {
id: separator
anchors.top: confirmations.bottom
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: -Style.current.padding
anchors.right: parent.right
anchors.rightMargin: -Style.current.padding
}
Item {
id: block
anchors.top: separator.bottom
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
height: children[0].height
StyledText {
id: labelBlock
text: qsTr("Block")
font.pixelSize: 14
font.weight: Font.Medium
color: Style.current.secondaryText
}
StyledText {
id: valueBlock
text: popup.isTransactionValid ? RootStore.hex2Dec(transaction.blockNumber) : ""
font.pixelSize: 14
anchors.left: labelBlock.right
anchors.leftMargin: Style.current.padding
}
}
Item {
id: hash
anchors.top: block.bottom
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
height: children[0].height
StyledText {
id: labelHash
text: qsTr("Hash")
font.pixelSize: 14
font.weight: Font.Medium
color: Style.current.secondaryText
}
Address {
id: valueHash
text: popup.isTransactionValid ? transaction.id : ""
width: 160
maxWidth: parent.width - labelHash.width - Style.current.padding
color: Style.current.textColor
font.pixelSize: 14
anchors.left: labelHash.right
anchors.leftMargin: Style.current.padding
}
}
Item {
id: from
anchors.top: hash.bottom
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
height: children[0].height
StyledText {
id: labelFrom
text: qsTr("From")
font.pixelSize: 14
font.weight: Font.Medium
color: Style.current.secondaryText
}
Address {
id: valueFrom
text: popup.isTransactionValid ? transaction.from: ""
color: Style.current.textColor
width: 160
font.pixelSize: 14
anchors.left: labelFrom.right
anchors.leftMargin: Style.current.padding
}
}
Item {
id: toItem
anchors.top: from.bottom
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
height: children[0].height
StyledText {
id: labelTo
text: qsTr("To")
font.pixelSize: 14
font.weight: Font.Medium
color: Style.current.secondaryText
}
Address {
id: valueTo
text: popup.isTransactionValid ? transaction.to: ""
color: Style.current.textColor
width: 160
font.pixelSize: 14
anchors.left: labelTo.right
anchors.leftMargin: Style.current.padding
}
}
Item {
id: gasLimitItem
anchors.top: toItem.bottom
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
height: children[0].height
StyledText {
id: labelGasLimit
text: qsTr("Gas limit")
font.pixelSize: 14
font.weight: Font.Medium
color: Style.current.secondaryText
}
StyledText {
id: valueGasLimit
text: popup.isTransactionValid ? LocaleUtils.currencyAmountToLocaleString(transaction.gasLimit): ""
font.pixelSize: 14
anchors.left: labelGasLimit.right
anchors.leftMargin: Style.current.padding
}
}
Item {
id: gasPriceItem
anchors.top: gasLimitItem.bottom
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
height: children[0].height
StyledText {
id: labelGasPrice
text: qsTr("Gas price")
font.pixelSize: 14
font.weight: Font.Medium
color: Style.current.secondaryText
}
StyledText {
id: valueGasPrice
text: popup.isTransactionValid ? LocaleUtils.currencyAmountToLocaleString(transaction.gasPrice): ""
font.pixelSize: 14
anchors.left: labelGasPrice.right
anchors.leftMargin: Style.current.padding
}
}
Item {
id: gasUsedItem
anchors.top: gasPriceItem.bottom
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
height: children[0].height
StyledText {
id: labelGasUsed
text: qsTr("Gas used")
font.pixelSize: 14
font.weight: Font.Medium
color: Style.current.secondaryText
}
StyledText {
id: valueGasUsed
text: popup.isTransactionValid ? LocaleUtils.currencyAmountToLocaleString(transaction.gasUsed): ""
font.pixelSize: 14
anchors.left: labelGasUsed.right
anchors.leftMargin: Style.current.padding
}
}
Item {
id: nonceItem
anchors.top: gasUsedItem.bottom
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
height: children[0].height
StyledText {
id: labelNonce
text: qsTr("Nonce")
font.pixelSize: 14
font.weight: Font.Medium
color: Style.current.secondaryText
}
StyledText {
id: valueNonce
text: popup.isTransactionValid ? RootStore.hex2Dec(transaction.nonce) : ""
font.pixelSize: 14
anchors.left: labelNonce.right
anchors.leftMargin: Style.current.padding
}
}
}

View File

@ -12,7 +12,6 @@ NicknamePopup 1.0 NicknamePopup.qml
ModalPopup 1.0 ModalPopup.qml ModalPopup 1.0 ModalPopup.qml
PopupMenu 1.0 PopupMenu.qml PopupMenu 1.0 PopupMenu.qml
SendModal 1.0 SendModal.qml SendModal 1.0 SendModal.qml
TransactionModal 1.0 TransactionModal.qml
TransactionSettingsConfirmationPopup 1.0 TransactionSettingsConfirmationPopup.qml TransactionSettingsConfirmationPopup 1.0 TransactionSettingsConfirmationPopup.qml
UnblockContactConfirmationDialog 1.0 UnblockContactConfirmationDialog.qml UnblockContactConfirmationDialog 1.0 UnblockContactConfirmationDialog.qml
UserStatusContextMenu 1.0 UserStatusContextMenu.qml UserStatusContextMenu 1.0 UserStatusContextMenu.qml

View File

@ -58,6 +58,10 @@ QtObject {
return networksModule.all.getNetworkFullName(chainId) return networksModule.all.getNetworkFullName(chainId)
} }
function getNetworkLayer(chainId) {
return networksModule.all.getNetworkLayer(chainId)
}
function getNetworkIconUrl(symbol) { function getNetworkIconUrl(symbol) {
return networksModule.all.getNetworkIconUrl(symbol) return networksModule.all.getNetworkIconUrl(symbol)
} }
@ -210,10 +214,6 @@ QtObject {
return walletSectionSavedAddresses.deleteSavedAddress(address, ens) return walletSectionSavedAddresses.deleteSavedAddress(address, ens)
} }
function getLatestBlockNumber() {
return walletSectionTransactions.getLastTxBlockNumber()
}
function getCurrencyAmount(amount, symbol) { function getCurrencyAmount(amount, symbol) {
return currencyStore.getCurrencyAmount(amount, symbol) return currencyStore.getCurrencyAmount(amount, symbol)
} }