Files
pay/guis/desktop/Transaction.qml
T
tomFlowee 5cce0ad32f Make values line up.
On the desktop activity view the prices are right aligned but due to
adding fiat prices this means that the bch amounts are not lining up.
This adds a little space between the two in order to make them much more
readable.
2025-01-29 14:25:36 +01:00

223 lines
6.9 KiB
QML

/*
* This file is part of the Flowee project
* Copyright (C) 2020-2025 Tom Zander <tom@flowee.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick
import QtQuick.Controls as QQC2
import "../Flowee" as Flowee
import "../Utils.js" as Utils
Rectangle {
id: txRoot
height: {
var rc = mainLabel.height + 10 + date.height
if (detailsPane.item != null)
rc += detailsPane.item.height;
return rc;
}
width: mainLabel.width + bitcoinAmountLabel.width + 30
property int minedHeight: model.height
property bool isRejected: minedHeight === -2 // -2 is the magic block-height indicating 'rejected'
property bool isMoved: Utils.isMoved(model);
/*
we have
model.fundsIn the amount of satoshis consumed by inputs we own
model.fundsOut the amout of satoshis locked up in outputs we own
model.txid
model.height
model.date
model.isCoinbase
model.isFused
model.comment
*/
// overlay that indicates the transactions is new since last sync.
Rectangle {
id: isNewIndicator
anchors.verticalCenter: mainLabel.verticalCenter
width: model.isNew ? 5 : 0 // avoid taking space
height: width
radius: width
color: Pay.useDarkSkin ? mainWindow.floweeSalmon : mainWindow.floweeBlue
}
Flowee.Label {
id: mainLabel
anchors.left: isNewIndicator.right
anchors.leftMargin: model.isNew ? 3 : 0
text: {
if (model.isCoinbase)
return qsTr("Miner Reward")
if (model.isFused)
return qsTr("Fused")
if (model.fundsIn === 0)
return qsTr("Received")
if (isMoved)
return qsTr("Moved");
return qsTr("Sent")
}
}
Flowee.Label {
id: date
anchors.top: mainLabel.bottom
function updateText() {
if (txRoot.isRejected)
text = qsTr("rejected")
else
text = Pay.formatDateTime(model.date);
}
opacity: detailsPane.item === null ? 0.8 : 1;
font.pointSize: mainLabel.font.pointSize * 0.9
color: txRoot.isRejected ? (Pay.useDarkSkin ? "#ec2327" : "#b41214") : palette.windowText
Component.onCompleted: date.updateText()
Timer {
interval: 60000
running: !txRoot.isRejected
repeat: true
onTriggered: date.updateText()
}
}
Flowee.CFIcon {
id: fusedIcon
visible: model.isFused
anchors.right: userComment.left
anchors.rightMargin: 6
anchors.verticalCenter: userComment.verticalCenter
width: 16
height: 16
}
Flowee.Label {
id: userComment
y: (date.y + date.height - height) / 2
anchors {
// Pick the widest label to be aligned to
left: date.width > mainLabel.width ? date.right : mainLabel.right
right: bitcoinAmountLabel.left
leftMargin: fusedIcon.visible ? 25 : 6
rightMargin: 10
}
text: model.comment
elide: Text.ElideRight
Connections {
target: date
function onTextChanged() {
if (date.width > mainLabel.width) {
userComment.anchors.left = date.right
} else {
userComment.anchors.left = mainLabel.right
}
}
}
}
Flowee.BitcoinAmountLabel {
id: bitcoinAmountLabel
visible: Pay.activityShowsBch || !Pay.isMainChain
fiatTimestamp: model.date
fiatWidth: 90
value: {
let inputs = model.fundsIn
let outputs = model.fundsOut
let diff = model.fundsOut - model.fundsIn
if (!model.isFused
&& diff < 0 && diff > -1000) // then the diff is likely just fees.
return inputs;
return diff;
}
anchors.top: mainLabel.top
anchors.right: parent.right
colorize: !isMoved
}
Flowee.Label {
anchors.top: mainLabel.top
anchors.right: parent.right
visible: bitcoinAmountLabel.visible === false
text: {
if (isRejected)
return "";
var fiatPrice = Fiat.historicalPrice(model.date);
return Fiat.formattedPrice(bitcoinAmountLabel.value, fiatPrice)
}
color: {
var num = bitcoinAmountLabel.value
if (num > 0) // positive value
return Pay.useDarkSkin ? "#86ffa8" : "green";
else if (num < 0) // negative
return Pay.useDarkSkin ? "#ffdede" : "#444446";
// zero is shown without normally
return palette.windowText
}
}
Item {
id: checks
width: row.width
height: 18
anchors.right: parent.right
anchors.top: mainLabel.bottom
property int txHeight: model.height
property int confirmations: Pay.chainHeight - txHeight
visible: txHeight === -1 || confirmations < 5
Row {
id: row
height: parent.height
spacing: -3
Flowee.Label {
text: "?"
font.bold: true
font.pixelSize: 14
color: Pay.useDarkSkin ? "#5d94c7" : mainWindow.floweeBlue
visible: checks.txHeight === -1
}
Repeater {
model: {
if (checks.txHeight < 0)
return 0;
var c = checks.confirmations;
return c < 5 ? c : 0;
}
Flowee.Label {
text: "✓"
font.pixelSize: 18
color: Pay.useDarkSkin ? "#86ffa8" : "green";
}
}
}
}
MouseArea {
anchors.fill: parent
onClicked: detailsPane.source = (detailsPane.source == "") ? "./TransactionInfoSmall.qml" : ""
}
Loader {
id: detailsPane
anchors.bottom: parent.bottom
anchors.bottomMargin: 6
width: parent.width
onLoaded: item.infoObject = portfolio.current.txInfo(model.walletIndex, item)
}
Behavior on height { NumberAnimation { duration: 100 } }
}