chore(wallet) remove requesting detailed transaction info for activity

Closes #11598
This commit is contained in:
Stefan 2023-08-29 19:57:38 +01:00 committed by Stefan Dunca
parent a3b739b81d
commit 8138e5edcf
10 changed files with 140 additions and 222 deletions

View File

@ -74,136 +74,45 @@ QtObject:
QtProperty[QVariant] recipientsModel:
read = getRecipientsModel
proc buildMultiTransactionExtraData(self: Controller, metadata: backend_activity.ActivityEntry, item: MultiTransactionDto): ExtraData =
proc buildMultiTransactionExtraData(self: Controller, metadata: backend_activity.ActivityEntry): ExtraData =
if metadata.symbolIn.isSome():
result.inAmount = self.currencyService.parseCurrencyValue(metadata.symbolIn.get(), metadata.amountIn)
if metadata.symbolOut.isSome():
result.outAmount = self.currencyService.parseCurrencyValue(metadata.symbolOut.get(), metadata.amountOut)
proc buildTransactionExtraData(self: Controller, metadata: backend_activity.ActivityEntry, item: ref TransactionDto): ExtraData =
proc buildTransactionExtraData(self: Controller, metadata: backend_activity.ActivityEntry): ExtraData =
if metadata.symbolIn.isSome():
result.inAmount = self.currencyService.parseCurrencyValue(metadata.symbolIn.get(), metadata.amountIn)
if metadata.symbolOut.isSome():
result.outAmount = self.currencyService.parseCurrencyValue(metadata.symbolOut.get(), metadata.amountOut)
proc getResolvedSymbol(self: Controller, transaction: TransactionDto): string =
if transaction.symbol != "":
result = transaction.symbol
else:
let contractSymbol = self.tokenService.findTokenSymbolByAddress(transaction.contract)
if contractSymbol != "":
result = contractSymbol
else:
result = "ETH"
proc backendToPresentation(self: Controller, backendEntities: seq[backend_activity.ActivityEntry]): seq[entry.ActivityEntry] =
var multiTransactionsIds: seq[int] = @[]
var transactionIdentities: seq[backend.TransactionIdentity] = @[]
var pendingTransactionIdentities: seq[backend.TransactionIdentity] = @[]
# Extract metadata required to fetch details
# TODO: see #11598. Temporary here to show the working API. Details for each entry will be done as required
# on a detail request from UI after metadata is extended to include the required info
let amountToCurrencyConvertor = proc(amount: UInt256, symbol: string): CurrencyAmount =
return currencyAmountToItem(self.currencyService.parseCurrencyValue(symbol, amount),
self.currencyService.getCurrencyFormat(symbol))
for backendEntry in backendEntities:
case backendEntry.payloadType:
var ae: entry.ActivityEntry
case backendEntry.getPayloadType():
of MultiTransaction:
multiTransactionsIds.add(backendEntry.id)
of SimpleTransaction:
transactionIdentities.add(backendEntry.transaction.get())
of PendingTransaction:
pendingTransactionIdentities.add(backendEntry.transaction.get())
var multiTransactions = initTable[int, MultiTransactionDto]()
if len(multiTransactionsIds) > 0:
let mts = transaction_service.getMultiTransactions(multiTransactionsIds)
for mt in mts:
multiTransactions[mt.id] = mt
var transactions = initTable[TransactionIdentity, ref TransactionDto]()
if len(transactionIdentities) > 0:
let response = backend.getTransfersForIdentities(transactionIdentities)
let res = response.result
if response.error != nil or res.kind != JArray or res.len == 0:
error "failed fetching transaction details; err: ", response.error, ", kind: ", res.kind, ", res.len: ", res.len
let transactionsDtos = res.getElems().map(x => x.toTransactionDto())
for dto in transactionsDtos:
transactions[TransactionIdentity(chainId: dto.chainId, hash: dto.id, address: dto.address)] = toRef(dto)
var pendingTransactions = initTable[TransactionIdentity, ref TransactionDto]()
if len(pendingTransactionIdentities) > 0:
let response = backend.getPendingTransactionsForIdentities(pendingTransactionIdentities)
let res = response.result
if response.error != nil or res.kind != JArray or res.len == 0:
error "failed fetching pending transactions details; err: ", response.error, ", kind: ", res.kind, ", res.len: ", res.len
let pendingTransactionsDtos = res.getElems().map(x => x.toPendingTransactionDto())
for dto in pendingTransactionsDtos:
pendingTransactions[TransactionIdentity(chainId: dto.chainId, hash: dto.id, address: dto.address)] = toRef(dto)
# Merge detailed transaction info in order
result = newSeqOfCap[entry.ActivityEntry](multiTransactions.len + transactions.len + pendingTransactions.len)
let extraData = self.buildMultiTransactionExtraData(backendEntry)
ae = entry.newMultiTransactionActivityEntry(backendEntry, extraData, amountToCurrencyConvertor)
of SimpleTransaction, PendingTransaction:
let extraData = self.buildTransactionExtraData(backendEntry)
ae = entry.newTransactionActivityEntry(backendEntry, self.addresses, extraData, amountToCurrencyConvertor)
result.add(ae)
proc fetchTxDetails*(self: Controller, entryIndex: int) {.slot.} =
let amountToCurrencyConvertor = proc(amount: UInt256, symbol: string): CurrencyAmount =
return currencyAmountToItem(self.currencyService.parseCurrencyValue(symbol, amount),
self.currencyService.getCurrencyFormat(symbol))
var mtIndex = 0
var tIndex = 0
var ptIndex = 0
for backendEntry in backendEntities:
case backendEntry.payloadType:
of MultiTransaction:
let id = multiTransactionsIds[mtIndex]
if multiTransactions.hasKey(id):
let mt = multiTransactions[id]
let extraData = self.buildMultiTransactionExtraData(backendEntry, mt)
result.add(entry.newMultiTransactionActivityEntry(mt, backendEntry, extraData, amountToCurrencyConvertor))
else:
error "failed to find multi transaction with id: ", id
mtIndex += 1
of SimpleTransaction:
let identity = transactionIdentities[tIndex]
if transactions.hasKey(identity):
let tr = transactions[identity]
tr.symbol = self.getResolvedSymbol(tr[])
let extraData = self.buildTransactionExtraData(backendEntry, tr)
result.add(entry.newTransactionActivityEntry(tr, backendEntry, self.addresses, extraData, amountToCurrencyConvertor))
else:
error "failed to find transaction with identity: ", identity
tIndex += 1
of PendingTransaction:
let identity = pendingTransactionIdentities[ptIndex]
if pendingTransactions.hasKey(identity):
let tr = pendingTransactions[identity]
tr.symbol = self.getResolvedSymbol(tr[])
let extraData = self.buildTransactionExtraData(backendEntry, tr)
result.add(entry.newTransactionActivityEntry(tr, backendEntry, self.addresses, extraData, amountToCurrencyConvertor))
else:
error "failed to find pending transaction with identity: ", identity
ptIndex += 1
proc fetchTxDetails*(self: Controller, id: string, isMultiTx: bool, isPending: bool) {.slot.} =
self.activityDetails = newActivityDetails(id, isMultiTx)
if isPending:
let entry = self.model.getEntry(entryIndex)
if entry == nil:
error "failed to find entry with index: ", entryIndex
return
try:
let amountToCurrencyConvertor = proc(amount: UInt256, symbol: string): CurrencyAmount =
return currencyAmountToItem(self.currencyService.parseCurrencyValue(symbol, amount),
self.currencyService.getCurrencyFormat(symbol))
if isMultiTx:
let res = backend_activity.getMultiTxDetails(parseInt(id))
if res.error != nil:
error "failed to fetch multi tx details: ", id
return
self.activityDetails = newActivityDetails(res.result, amountToCurrencyConvertor)
else:
let res = backend_activity.getTxDetails(id)
if res.error != nil:
error "failed to fetch tx details: ", id
return
self.activityDetails = newActivityDetails(res.result, amountToCurrencyConvertor)
self.activityDetails = newActivityDetails(entry.getMetadata(), amountToCurrencyConvertor)
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription

View File

@ -1,12 +1,10 @@
import NimQml, json, strformat, sequtils, strutils, logging, stint
import backend/transactions
import backend/activity as backend
import app/modules/shared_models/currency_amount
import app/global/global_singleton
import app_service/service/transaction/dto
import app_service/service/currency/dto as currency
import app_service/service/currency/service
@ -22,22 +20,10 @@ type
AmountToCurrencyConvertor* = proc (amount: UInt256, symbol: string): CurrencyAmount
# It is used to display an activity history entry in the QML UI
#
# TODO remove this legacy after the NFT is served async; see #11598
#
# Looking into going away from carying the whole detailed data and just keep the required data for the UI
# and request the detailed data on demand
#
# Outdated: The ActivityEntry contains one of the following instances transaction, pending transaction or multi-transaction
# Used to display an activity history header entry in the QML UI
QtObject:
type
ActivityEntry* = ref object of QObject
# TODO: these should be removed; see #11598
multi_transaction: MultiTransactionDto
transaction: ref TransactionDto
isPending: bool
valueConvertor: AmountToCurrencyConvertor
metadata: backend.ActivityEntry
extradata: ExtraData
@ -54,74 +40,57 @@ QtObject:
proc delete*(self: ActivityEntry) =
self.QObject.delete
proc newMultiTransactionActivityEntry*(mt: MultiTransactionDto, metadata: backend.ActivityEntry, extradata: ExtraData, valueConvertor: AmountToCurrencyConvertor): ActivityEntry =
proc newMultiTransactionActivityEntry*(metadata: backend.ActivityEntry, extradata: ExtraData, valueConvertor: AmountToCurrencyConvertor): ActivityEntry =
new(result, delete)
result.multi_transaction = mt
result.transaction = nil
result.isPending = false
result.valueConvertor = valueConvertor
result.metadata = metadata
result.extradata = extradata
result.noAmount = newCurrencyAmount()
result.amountCurrency = valueConvertor(
if metadata.activityType == backend.ActivityType.Receive: metadata.amountIn else: metadata.amountOut,
if metadata.activityType == backend.ActivityType.Receive: mt.toAsset else: mt.fromAsset,
if metadata.activityType == backend.ActivityType.Receive: metadata.symbolIn.get("") else: metadata.symbolOut.get(""),
)
result.setup()
proc newTransactionActivityEntry*(tr: ref TransactionDto, metadata: backend.ActivityEntry, fromAddresses: seq[string], extradata: ExtraData, valueConvertor: AmountToCurrencyConvertor): ActivityEntry =
proc newTransactionActivityEntry*(metadata: backend.ActivityEntry, fromAddresses: seq[string], extradata: ExtraData, valueConvertor: AmountToCurrencyConvertor): ActivityEntry =
new(result, delete)
result.multi_transaction = nil
result.transaction = tr
result.isPending = metadata.payloadType == backend.PayloadType.PendingTransaction
result.valueConvertor = valueConvertor
result.metadata = metadata
result.extradata = extradata
result.amountCurrency = valueConvertor(
if metadata.activityType == backend.ActivityType.Receive: metadata.amountIn else: metadata.amountOut,
tr.symbol
if metadata.activityType == backend.ActivityType.Receive: metadata.symbolIn.get("") else: metadata.symbolOut.get(""),
)
result.noAmount = newCurrencyAmount()
result.setup()
proc isMultiTransaction*(self: ActivityEntry): bool {.slot.} =
return self.multi_transaction != nil
return self.metadata.getPayloadType() == backend.PayloadType.MultiTransaction
QtProperty[bool] isMultiTransaction:
read = isMultiTransaction
proc isPendingTransaction*(self: ActivityEntry): bool {.slot.} =
return (not self.isMultiTransaction()) and self.isPending
return self.metadata.getPayloadType() == backend.PayloadType.PendingTransaction
QtProperty[bool] isPendingTransaction:
read = isPendingTransaction
proc `$`*(self: ActivityEntry): string =
let mtStr = if self.multi_transaction != nil: $(self.multi_transaction.id) else: "0"
let trStr = if self.transaction != nil: $(self.transaction[]) else: "nil"
return fmt"""ActivityEntry(
multi_transaction.id:{mtStr},
transaction:{trStr},
isPending:{self.isPending}
metadata:{$self.metadata},
)"""
proc isInTransactionType(self: ActivityEntry): bool =
return self.metadata.activityType == backend.ActivityType.Receive or self.metadata.activityType == backend.ActivityType.Mint
proc getMultiTransaction*(self: ActivityEntry): MultiTransactionDto =
if not self.isMultiTransaction():
raise newException(Defect, "ActivityEntry is not a MultiTransaction")
return self.multi_transaction
# TODO: is this the right way to pass transaction identity? Why not use the instance?
proc getId*(self: ActivityEntry): string {.slot.} =
if self.isMultiTransaction():
return $self.multi_transaction.id
elif self.transaction != nil:
return self.transaction[].id
return ""
return $(self.metadata.getMultiTransactionId().get())
return $(self.metadata.getTransactionIdentity().get().hash)
QtProperty[string] id:
read = getId
@ -233,20 +202,6 @@ QtObject:
QtProperty[int] txType:
read = getTxType
proc getTokenType*(self: ActivityEntry): string {.slot.} =
let s = if self.transaction != nil: self.transaction[].symbol else: ""
if self.transaction != nil:
return self.transaction[].typeValue
if self.isInTransactionType() and self.metadata.tokenOut.isSome:
return $self.metadata.tokenOut.unsafeGet().tokenType
if self.metadata.tokenIn.isSome:
return $self.metadata.tokenIn.unsafeGet().tokenType
return ""
# TODO: used only in details, move it to a entry_details.nim. See #11598
QtProperty[string] tokenType:
read = getTokenType
proc getTokenInAddress*(self: ActivityEntry): string {.slot.} =
if self.metadata.tokenIn.isSome:
let address = self.metadata.tokenIn.unsafeGet().address
@ -276,7 +231,7 @@ QtObject:
read = getTokenAddress
proc getTokenID*(self: ActivityEntry): string {.slot.} =
if self.metadata.payloadType == backend.PayloadType.MultiTransaction:
if self.metadata.getPayloadType() == backend.PayloadType.MultiTransaction:
error "getTokenID: ActivityEntry is not a transaction"
return ""

View File

@ -1,6 +1,7 @@
import NimQml, json, stint, strutils
import NimQml, json, stint, strutils, logging, options
import backend/activity as backend
import backend/backend as common_backend
import app/modules/shared_models/currency_amount
@ -14,6 +15,10 @@ QtObject:
type
ActivityDetails* = ref object of QObject
id*: string
metadata: backend.ActivityEntry
# TODO use medatada
multiTxId: int
nonce*: int
blockNumber*: int
@ -33,41 +38,57 @@ QtObject:
proc getMaxTotalFees(maxFee: string, gasLimit: string): string =
return (stint.fromHex(Uint256, maxFee) * stint.fromHex(Uint256, gasLimit)).toHex
proc newActivityDetails*(id: string, isMultiTx: bool): ActivityDetails =
proc newActivityDetails*(metadata: backend.ActivityEntry, valueConvertor: AmountToCurrencyConvertor): ActivityDetails =
new(result, delete)
if isMultiTx:
result.multiTxId = parseInt(id)
else:
result.id = id
defer: result.setup()
result.maxTotalFees = newCurrencyAmount()
result.totalFees = newCurrencyAmount()
result.setup()
proc newActivityDetails*(e: JsonNode, valueConvertor: AmountToCurrencyConvertor): ActivityDetails =
new(result, delete)
var e: JsonNode
case metadata.getPayloadType():
of PendingTransaction:
result.id = metadata.getTransactionIdentity().get().hash
return
of MultiTransaction:
result.multiTxId = metadata.getMultiTransactionId.get(0)
let res = backend.getMultiTxDetails(metadata.getMultiTransactionId().get(0))
if res.error != nil:
error "failed to fetch multi tx details: ", metadata.getMultiTransactionId()
return
e = res.result
of SimpleTransaction:
let res = backend.getTxDetails(metadata.getTransactionIdentity().get().hash)
if res.error != nil:
error "failed to fetch tx details: ", metadata.getTransactionIdentity().get().hash
return
e = res.result
const protocolTypeField = "protocolType"
const hashField = "hash"
const contractAddressField = "contractAddress"
const inputField = "input"
const totalFeesField = "totalFees"
result = ActivityDetails(
id: e["id"].getStr(),
multiTxId: e["multiTxId"].getInt(),
nonce: e["nonce"].getInt(),
blockNumber: e["blockNumber"].getInt()
)
result.id = e["id"].getStr()
result.multiTxId = e["multiTxId"].getInt()
result.nonce = e["nonce"].getInt()
result.blockNumber = e["blockNumber"].getInt()
let maxFeePerGas = e["maxFeePerGas"].getStr()
let gasLimit = e["gasLimit"].getStr()
const gweiSymbol = "Gwei"
if len(maxFeePerGas) > 0 and len(gasLimit) > 0:
let maxTotalFees = getMaxTotalFees(maxFeePerGas, gasLimit)
result.maxTotalFees = valueConvertor(stint.fromHex(UInt256, maxTotalFees), "Gwei")
else:
result.maxTotalFees = newCurrencyAmount()
result.maxTotalFees = valueConvertor(stint.fromHex(UInt256, maxTotalFees), gweiSymbol)
if e.hasKey(totalFeesField) and e[totalFeesField].kind != JNull:
let totalFees = e[totalFeesField].getStr()
result.totalFees = valueConvertor(stint.fromHex(UInt256, totalFees), "Gwei")
let resTotalFees = valueConvertor(stint.fromHex(UInt256, totalFees), gweiSymbol)
if resTotalFees != nil:
result.totalFees = resTotalFees
if e.hasKey(hashField) and e[hashField].kind != JNull:
result.txHash = e[hashField].getStr()
@ -79,8 +100,6 @@ QtObject:
var contractAddress: eth.Address
fromJson(e[contractAddressField], contractAddressField, contractAddress)
result.contractAddress = some(contractAddress)
result.setup()
proc getNonce*(self: ActivityDetails): int {.slot.} =
return self.nonce
@ -131,3 +150,14 @@ QtObject:
QtProperty[QVariant] totalFees:
read = getTotalFees
proc getTokenType*(self: ActivityDetails): string {.slot.} =
if self.metadata.tokenIn.isSome:
return $self.metadata.tokenIn.get().tokenType
if self.metadata.tokenOut.isSome:
return $self.metadata.tokenOut.get().tokenType
return ""
QtProperty[string] tokenType:
read = getTokenType

View File

@ -35,6 +35,12 @@ QtObject:
for i in 0 ..< self.entries.len:
result &= fmt"""[{i}]:({$self.entries[i]})"""
proc getEntry*(self: Model, index: int): entry.ActivityEntry =
if index < 0 or index >= self.entries.len:
return nil
return self.entries[index]
proc countChanged(self: Model) {.signal.}
proc getCount*(self: Model): int {.slot.} =
@ -97,13 +103,13 @@ QtObject:
proc sameIdentity(e: entry.ActivityEntry, d: backend.Data): bool =
let m = e.getMetadata()
if m.payloadType != d.payloadType:
if m.getPayloadType() != d.payloadType:
return false
if m.payloadType == MultiTransaction:
return m.id == d.id.get()
if m.getPayloadType() == MultiTransaction:
return m.getMultiTransactionId().get(0) == d.id.get()
return m.transaction.isSome() and d.transaction.isSome() and m.transaction.get() == d.transaction.get()
return m.getTransactionIdentity().isSome() and d.transaction.isSome() and m.getTransactionIdentity().get() == d.transaction.get()
proc updateEntries*(self: Model, updates: seq[backend.Data]) =
for i in countdown(self.entries.high, 0):

View File

@ -253,14 +253,13 @@ proc `%`*(pt: TransferType): JsonNode {.inline.} =
proc fromJson*(jn: JsonNode, T: typedesc[TransferType]): TransferType {.inline.} =
return cast[TransferType](jn.getInt())
# TODO: hide internals behind safe interface
# Mirrors status-go/services/wallet/activity/activity.go Entry
type
ActivityEntry* = object
# Identification
payloadType*: PayloadType
transaction*: Option[TransactionIdentity]
id*: int
payloadType: PayloadType
transaction: Option[TransactionIdentity]
id: int
timestamp*: int
@ -322,6 +321,19 @@ type
hasMore*: bool
errorCode*: ErrorCode
proc getPayloadType*(ae: ActivityEntry): PayloadType =
return ae.payloadType
proc getTransactionIdentity*(ae: ActivityEntry): Option[TransactionIdentity] =
if ae.payloadType == PayloadType.MultiTransaction:
return none(TransactionIdentity)
return ae.transaction
proc getMultiTransactionId*(ae: ActivityEntry): Option[int] =
if ae.payloadType != PayloadType.MultiTransaction:
return none(int)
return some(ae.id)
proc toJson*(ae: ActivityEntry): JsonNode {.inline.} =
return %*(ae)

View File

@ -137,8 +137,10 @@ Item {
HistoryView {
overview: RootStore.overview
showAllAccounts: root.showAllAccounts
onLaunchTransactionDetail: {
transactionDetailView.transaction = transaction
onLaunchTransactionDetail: function (entry, entryIndex) {
transactionDetailView.transactionIndex = entryIndex
transactionDetailView.transaction = entry
stack.currentIndex = 3
}
}

View File

@ -27,23 +27,13 @@ Item {
property var overview: WalletStores.RootStore.overview
property var contactsStore
property var transaction
property int transactionIndex
property var sendModal
property bool showAllAccounts: false
readonly property bool isTransactionValid: transaction !== undefined && !!transaction
onTransactionChanged: {
d.decodedInputData = ""
if (!transaction)
return
RootStore.fetchTxDetails(transaction.id, transaction.isMultiTransaction, transaction.isPending)
d.details = RootStore.getTxDetails()
if (!!d.details && !!d.details.input) {
d.loadingInputDate = true
RootStore.fetchDecodedTxData(d.details.txHash, d.details.input)
}
}
onTransactionChanged: d.updateTransactionDetails()
Component.onCompleted: d.updateTransactionDetails()
QtObject {
id: d
@ -83,7 +73,7 @@ Item {
const formatted = RootStore.formatCurrencyAmount(transaction.outAmount, transaction.outSymbol)
return outSymbol || !transaction.tokenOutAddress ? formatted : "%1 (%2)".arg(formatted).arg(Utils.compactAddress(transaction.tokenOutAddress, 4))
}
readonly property real feeEthValue: root.isTransactionValid ? RootStore.getFeeEthValue(d.details.totalFees) : 0
readonly property real feeEthValue: d.details ? RootStore.getFeeEthValue(d.details.totalFees) : 0
readonly property real feeFiatValue: root.isTransactionValid ? RootStore.getFiatValue(d.feeEthValue, Constants.ethToken, RootStore.currentCurrency) : 0 // TODO use directly?
readonly property int transactionType: root.isTransactionValid ? transaction.txType : Constants.TransactionType.Send
readonly property bool isBridge: d.transactionType === Constants.TransactionType.Bridge
@ -94,6 +84,20 @@ Item {
function retryTransaction() {
// TODO handle failed transaction retry
}
function updateTransactionDetails() {
d.decodedInputData = ""
if (!transaction)
return
RootStore.fetchTxDetails(transactionIndex)
d.details = RootStore.getTxDetails()
if (!!d.details && !!d.details.input) {
d.loadingInputDate = true
RootStore.fetchDecodedTxData(d.details.txHash, d.details.input)
}
}
}
Connections {
@ -459,7 +463,7 @@ Item {
Layout.fillHeight: true
Layout.fillWidth: true
title: qsTr("Token format")
subTitle: root.isTransactionValid ? transaction.tokenType.toUpperCase() : ""
subTitle: root.isTransactionValid ? d.details.tokenType.toUpperCase() : ""
visible: !!subTitle
}
TransactionDataTile {
@ -634,7 +638,7 @@ Item {
case Constants.TransactionType.Send:
case Constants.TransactionType.Swap:
case Constants.TransactionType.Bridge:
return LocaleUtils.currencyAmountToLocaleString(d.details.totalFees)
return d.details ? LocaleUtils.currencyAmountToLocaleString(d.details.totalFees) : ""
default:
return ""
}

View File

@ -170,7 +170,7 @@ StatusListItem {
function getDetailsString(detailsObj) {
if (!detailsObj) {
rootStore.fetchTxDetails(modelData.id, modelData.isMultiTransaction, modelData.isPending)
rootStore.fetchTxDetails(index)
detailsObj = rootStore.getTxDetails()
}

View File

@ -247,8 +247,8 @@ QtObject {
walletSectionInst.fetchDecodedTxData(txHash, input)
}
function fetchTxDetails(id, isMultiTx, isPending) {
walletSectionInst.activityController.fetchTxDetails(id, isMultiTx, isPending)
function fetchTxDetails(modelIndex) {
walletSectionInst.activityController.fetchTxDetails(modelIndex)
}
function getTxDetails() {

View File

@ -29,7 +29,7 @@ ColumnLayout {
property var overview
property bool showAllAccounts: false
signal launchTransactionDetail(var transaction)
signal launchTransactionDetail(var transaction, int entryIndex)
onVisibleChanged: {
if (!visible)
@ -356,7 +356,7 @@ ColumnLayout {
if (mouse.button === Qt.RightButton) {
delegateMenu.openMenu(this, mouse, modelData)
} else {
launchTransactionDetail(modelData)
launchTransactionDetail(modelData, index)
}
}
}