History: display details of transactions with multiple recipients

This commit is contained in:
rating89us 2021-06-03 19:06:12 +02:00 committed by rating89us
parent 2946127ed7
commit 7b2c886ddc
4 changed files with 209 additions and 67 deletions

View File

@ -16,6 +16,7 @@ Text {
property alias tooltipLeft: tooltip.tooltipLeft
property alias tooltipIconVisible: tooltip.tooltipIconVisible
property alias tooltipPopup: tooltip.tooltipPopup
property alias tooltipWrapMode: tooltip.tooltipWrapMode
font.family: MoneroComponents.Style.fontMedium.name
font.bold: false
font.pixelSize: 14

View File

@ -36,6 +36,7 @@ import "." as MoneroComponents
Rectangle {
property alias text: tooltip.text
property alias tooltipPopup: popup
property alias tooltipWrapMode: tooltip.wrapMode
property bool tooltipIconVisible: false
property bool tooltipLeft: false
property bool tooltipBottom: tooltipIconVisible ? false : true

View File

@ -2,13 +2,33 @@ function destinationsToAmount(destinations){
// Gets amount from destinations line
// input: "20.000000000000: 9tLGyK277MnYrDc7Vzi6TB1pJvstFoviziFwsqQNFbwA9rvg5RxYVYjEezFKDjvDHgAzTELJhJHVx6JAaWZKeVqSUZkXeKk"
// returns: 20.000000000000
return destinations.split(" ")[0].split(":")[0];
var numberOfDestinations = (destinations.match(/:/g) || []).length;
var amountList = "";
for (var i = 0; i < numberOfDestinations; i++) {
var destinationAndAmount = destinations.split("<br> ")[i];
var amount = destinationAndAmount.split(":")[0];
if (i+1 != numberOfDestinations) {
amountList += amount + " ";
} else {
amountList += amount;
}
}
return amountList;
}
function destinationsToAddress(destinations){
var address = destinations.split(" ")[1];
if(address === undefined) return ""
return address;
var numberOfDestinations = (destinations.match(/:/g) || []).length;
var addressList = "";
for (var i = 0; i < numberOfDestinations; i++) {
var destinationAndAmount = destinations.split("<br> ")[i];
var address = destinationAndAmount.split(": ")[1];
if (i+1 != numberOfDestinations) {
addressList += address + " ";
} else {
addressList += address;
}
}
return addressList;
}
function addressTruncate(address, range){

View File

@ -573,7 +573,7 @@ Rectangle {
anchors.right: parent ? parent.right : undefined
height: {
if(!collapsed) return 60;
return 320;
return 200 + middleColumn.height;
}
color: {
if(!collapsed) return "transparent"
@ -628,9 +628,10 @@ Rectangle {
Layout.preferredHeight: 60
ColumnLayout {
id: leftColumn
spacing: 0
clip: true
Layout.preferredHeight: 120
Layout.preferredHeight: 100 + amountRectangle.height
Layout.minimumWidth: 180
Rectangle {
@ -656,23 +657,63 @@ Rectangle {
}
Rectangle {
id: amountRectangle
color: "transparent"
Layout.fillWidth: true
Layout.preferredHeight: 20
Layout.preferredHeight: amountColumn.height
Component.onCompleted: {
var amountListArray = [];
amountListArray = amountList.split(" ");
for (var i = 0; i < amountListArray.length; i++) {
amountFieldModel.append({amountArray: amountListArray[i]});
}
}
MoneroComponents.TextPlain {
font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 15
text: (amount == 0 ? qsTr("Unknown amount") : displayAmount) + translationManager.emptyString
color: MoneroComponents.Style.defaultFontColor
anchors.verticalCenter: parent.verticalCenter
ListModel {
id: amountFieldModel
}
MouseArea {
state: "copyable"
anchors.fill: parent
hoverEnabled: true
onEntered: parent.color = MoneroComponents.Style.orange
onExited: parent.color = MoneroComponents.Style.defaultFontColor
ColumnLayout {
id: amountColumn
Repeater {
id: amountFieldRepeater
model: amountFieldModel
MoneroComponents.TextPlain {
id: amountField
font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 15
textFormat: Text.RichText
color: MoneroComponents.Style.defaultFontColor
text: {
if (numberOfDestinations > 1) {
if(!collapsed) {
if (index == 0) {
return displayAmount;
} else {
return "";
}
} else {
return amountFieldModel.get(index).amountArray + " XMR"
}
} else {
if (amount == 0) {
return qsTr("Unknown amount") + translationManager.emptyString
} else {
return displayAmount;
}
}
}
MouseArea {
state: "copyable"
anchors.fill: parent
hoverEnabled: true
onEntered: parent.color = MoneroComponents.Style.orange
onExited: parent.color = MoneroComponents.Style.defaultFontColor
}
}
}
}
}
@ -740,9 +781,10 @@ Rectangle {
}
ColumnLayout {
id: middleColumn
spacing: 0
clip: true
Layout.preferredHeight: 120
Layout.preferredHeight: 100 + addressRectangle.height
Layout.minimumWidth: 230
Rectangle {
@ -768,51 +810,101 @@ Rectangle {
}
Rectangle {
id: addressRectangle
color: "transparent"
Layout.fillWidth: true
Layout.preferredHeight: 20
Layout.preferredHeight: addressColumn.height
Component.onCompleted: {
var addressListArray = [];
addressListArray = addressList.split(" ");
for (var i = 0; i < addressListArray.length; i++) {
addressFieldModel.append({addressArray: addressListArray[i]});
}
}
MoneroComponents.TextPlain {
id: addressField
font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 15
text: {
if (isout) {
if (address) {
return (addressBookName ? FontAwesome.addressBook + " " + addressBookName : TxUtils.addressTruncate(address, 8));
}
if (amount != 0) {
return qsTr("Unknown recipient") + translationManager.emptyString;
} else {
return qsTr("My wallet") + translationManager.emptyString;
}
} else {
if (receivingAddress) {
if (subaddrIndex == 0) {
return qsTr("Address") + " #0" + " (" + qsTr("Primary address") + ")" + translationManager.emptyString;
ListModel {
id: addressFieldModel
}
ColumnLayout {
id: addressColumn
Repeater {
id: addressFieldRepeater
model: addressFieldModel
MoneroComponents.TextPlain {
id: addressField
font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 15
textFormat: Text.RichText
color: MoneroComponents.Style.defaultFontColor
property var addressFromAddressListArray: ""
tooltip: numberOfDestinations > 1 ? (!collapsed ? "" : addressFromAddressListArray)
: address ? address
: receivingAddress ? receivingAddress
: ""
tooltipWrapMode: Text.Wrap
text: {
if (numberOfDestinations > 1) {
if(!collapsed) {
if (index == 0) {
return qsTr("Multiple recipients") + " (" + numberOfDestinations + ")" + translationManager.emptyString;
} else {
return "";
}
} else {
addressFromAddressListArray = addressFieldModel.get(index).addressArray;
var addressOnAddressBook = currentWallet ? currentWallet.addressBook.getDescription(addressFromAddressListArray) : null;
if (addressOnAddressBook) {
return FontAwesome.addressBook + " " + addressOnAddressBook;
} else {
return TxUtils.addressTruncate(addressFieldModel.get(index).addressArray, 8);
}
}
} else {
if (receivingAddressLabel) {
return qsTr("Address") + " #" + subaddrIndex + " (" + receivingAddressLabel + ")" + translationManager.emptyString;
if (isout) {
if (address) {
return (addressBookName ? FontAwesome.addressBook + " " + addressBookName : TxUtils.addressTruncate(address, 8));
}
if (amount != 0) {
return qsTr("Unknown recipient") + translationManager.emptyString;
} else {
return qsTr("My wallet") + translationManager.emptyString;
}
} else {
return qsTr("Address") + " #" + subaddrIndex + " (" + TxUtils.addressTruncate(receivingAddress, 4) + ")" + translationManager.emptyString;
if (receivingAddress) {
if (subaddrIndex == 0) {
return qsTr("Address") + " #0" + " (" + qsTr("Primary address") + ")" + translationManager.emptyString;
} else {
if (receivingAddressLabel) {
return qsTr("Address") + " #" + subaddrIndex + " (" + receivingAddressLabel + ")" + translationManager.emptyString;
} else {
return qsTr("Address") + " #" + subaddrIndex + " (" + TxUtils.addressTruncate(receivingAddress, 4) + ")" + translationManager.emptyString;
}
}
} else {
return qsTr("Unknown address") + translationManager.emptyString;
}
}
}
} else {
return qsTr("Unknown address") + translationManager.emptyString;
}
MouseArea {
state: isout ? "copyable_address" : "copyable_receiving_address"
anchors.fill: parent
hoverEnabled: true
onEntered: {
parent.color = MoneroComponents.Style.orange
tooltip ? parent.tooltipPopup.open() : ""
}
onExited: {
parent.color = MoneroComponents.Style.defaultFontColor
tooltip ? parent.tooltipPopup.close() : ""
}
}
}
}
color: MoneroComponents.Style.defaultFontColor
anchors.verticalCenter: parent.verticalCenter
MouseArea {
state: isout ? "copyable_address" : "copyable_receiving_address"
anchors.fill: parent
hoverEnabled: true
onEntered: parent.color = MoneroComponents.Style.orange
onExited: parent.color = MoneroComponents.Style.defaultFontColor
}
}
}
@ -875,10 +967,12 @@ Rectangle {
}
ColumnLayout {
id: rightColumn
spacing: 0
clip: true
Layout.preferredHeight: 120
Layout.minimumWidth: 130
Layout.alignment: Qt.AlignTop
Rectangle {
color: "transparent"
@ -1245,7 +1339,9 @@ Rectangle {
for(var i = 0; i < res.length; i+=1){
if(res[i].containsMouse === true){
if(res[i].state === 'copyable' && res[i].parent.hasOwnProperty('text')) toClipboard(res[i].parent.text);
if(res[i].state === 'copyable_address') (address ? root.toClipboard(address) : root.toClipboard(addressField.text));
if(res[i].state === 'copyable_address') (address ? root.toClipboard(address)
: res[i].parent.addressFromAddressListArray ? root.toClipboard(res[i].parent.addressFromAddressListArray)
: root.toClipboard(res[i].parent.text));
if(res[i].state === 'copyable_receiving_address') root.toClipboard(currentWallet.address(subaddrAccount, subaddrIndex));
if(res[i].state === 'copyable_txkey') root.getTxKey(hash, res[i]);
if(res[i].state === 'set_tx_note') root.editDescription(hash, tx_note);
@ -1434,7 +1530,11 @@ Rectangle {
}
if(root.sortSearchString.length >= 1){
if(item.amount && item.amount.toString().startsWith(root.sortSearchString)){
if(item.displayAmount && item.displayAmount.startsWith(root.sortSearchString)){
txs.push(item);
} else if(item.amountList != "" && item.amountList.toLowerCase().includes(root.sortSearchString.toLowerCase())){
txs.push(item);
} else if(item.addressList != "" && item.addressList.toLowerCase().includes(root.sortSearchString.toLowerCase())){
txs.push(item);
} else if(item.address !== "" && item.address.toLowerCase().startsWith(root.sortSearchString.toLowerCase())){
txs.push(item);
@ -1538,26 +1638,43 @@ Rectangle {
var subaddrIndex = model.data(idx, TransactionHistoryModel.TransactionSubaddrIndexRole);
var timestamp = new Date(date + " " + time).getTime() / 1000;
var dateHuman = Utils.ago(timestamp);
var numberOfDestinations = (destinations.match(/:/g) || []).length;
var amountList = TxUtils.destinationsToAmount(destinations);
if (amount === 0) {
// transactions to the same account have amount === 0, while the 'destinations string'
// has the correct amount, so we try to fetch it from that instead.
amount = Number(TxUtils.destinationsToAmount(destinations));
if (numberOfDestinations >1) {
var totalAmount = 0;
for (var i = 0; i < numberOfDestinations; i++) {
var amountFromAmountList = amountList.split(" ")[i];
var amountAsNumber = Number(amountFromAmountList);
totalAmount += amountAsNumber;
}
var displayAmount = Utils.removeTrailingZeros(totalAmount.toFixed(12)) + " XMR";
} else {
if (amount === 0) {
// transactions to the same account have amount === 0, while the 'destinations string'
// has the correct amount, so we try to fetch it from that instead.
amount = Number(TxUtils.destinationsToAmount(destinations));
}
var displayAmount = Utils.removeTrailingZeros(amount.toFixed(12)) + " XMR";
}
var displayAmount = Utils.removeTrailingZeros(amount.toFixed(12)) + " XMR";
var tx_note = currentWallet.getUserNote(hash);
var address = "";
var addressBookName = "";
var receivingAddress = "";
var receivingAddressLabel = "";
var addressList = "";
if (isout) {
address = TxUtils.destinationsToAddress(destinations);
addressBookName = currentWallet ? currentWallet.addressBook.getDescription(address) : null;
if (numberOfDestinations >1) {
addressList = TxUtils.destinationsToAddress(destinations);
} else {
receivingAddress = currentWallet ? currentWallet.address(subaddrAccount, subaddrIndex) : null;
receivingAddressLabel = currentWallet ? appWindow.currentWallet.getSubaddressLabel(subaddrAccount, subaddrIndex) : null;
if (isout) {
address = TxUtils.destinationsToAddress(destinations);
addressBookName = currentWallet ? currentWallet.addressBook.getDescription(address) : null;
} else {
receivingAddress = currentWallet ? currentWallet.address(subaddrAccount, subaddrIndex) : null;
receivingAddressLabel = currentWallet ? appWindow.currentWallet.getSubaddressLabel(subaddrAccount, subaddrIndex) : null;
}
}
if (isout)
@ -1572,11 +1689,14 @@ Rectangle {
"isout": isout,
"amount": amount,
"displayAmount": displayAmount,
"amountList": amountList,
"hash": hash,
"paymentId": paymentId,
"address": address,
"addressList": addressList,
"addressBookName": addressBookName,
"destinations": destinations,
"numberOfDestinations": numberOfDestinations,
"tx_note": tx_note,
"dateHuman": dateHuman,
"dateTime": date + " " + time,