2026-06-30 11:59:27 -03:00

188 lines
5.2 KiB
QML

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Item {
id: root
property string message: ""
property string detail: ""
property string transactionId: ""
property string status: "success"
property bool copied: false
property bool open: false
property int duration: 7000
height: implicitHeight
implicitHeight: toast.implicitHeight
opacity: root.open ? 1 : 0
visible: root.open || fadeOut.running
z: 30
TextEdit { id: clipboardProxy; visible: false }
function shortTransactionId(value) {
return value.length > 18 ? value.substring(0, 10) + "..." + value.slice(-8) : value;
}
function copyTransactionId() {
if (root.transactionId.length === 0) return;
clipboardProxy.text = root.transactionId;
clipboardProxy.selectAll();
clipboardProxy.copy();
clipboardProxy.deselect();
clipboardProxy.text = "";
root.copied = true;
}
function show(nextMessage, nextDetail, nextTransactionId, nextStatus) {
root.message = nextMessage;
root.detail = nextDetail || "";
root.transactionId = nextTransactionId || "";
root.status = nextStatus || "success";
root.copied = false;
root.open = true;
dismissTimer.restart();
}
Timer {
id: dismissTimer
interval: root.duration
repeat: false
onTriggered: {
if (copyButton.activeFocus || hoverGuard.containsMouse)
restart()
else
root.open = false
}
}
Behavior on opacity {
NumberAnimation {
id: fadeOut
duration: 160
easing.type: Easing.OutCubic
}
}
Rectangle {
id: toast
anchors.fill: parent
color: "#20201F"
implicitHeight: Math.max(50, toastContent.implicitHeight + 18)
radius: 8
border.color: root.status === "error" ? "#6A2E2E" : "#4D3A2E"
border.width: 1
Accessible.role: Accessible.AlertMessage
Accessible.name: root.detail.length > 0
? qsTr("%1. %2").arg(root.message).arg(root.detail)
: root.message
MouseArea {
id: hoverGuard
anchors.fill: parent
acceptedButtons: Qt.NoButton
hoverEnabled: true
}
RowLayout {
id: toastContent
spacing: 8
anchors {
fill: parent
leftMargin: 14
rightMargin: 14
}
Rectangle {
color: root.status === "error" ? "#D75C5C" : "#78C88D"
radius: 6
Layout.alignment: Qt.AlignTop
Layout.topMargin: 3
Layout.preferredHeight: 12
Layout.preferredWidth: 12
}
ColumnLayout {
spacing: 2
Layout.fillWidth: true
Text {
id: toastText
color: "#E7E1D8"
elide: Text.ElideRight
font.bold: true
font.pixelSize: 14
text: root.message
Layout.fillWidth: true
}
Text {
color: "#B8ADA3"
font.pixelSize: 12
maximumLineCount: 3
text: root.detail
visible: root.detail.length > 0
wrapMode: Text.WordWrap
Layout.fillWidth: true
}
Text {
color: "#F2D8C7"
elide: Text.ElideMiddle
font.pixelSize: 12
text: qsTr("Tx %1").arg(root.shortTransactionId(root.transactionId))
visible: root.transactionId.length > 0
Layout.fillWidth: true
}
}
Button {
id: copyButton
Accessible.name: root.copied ? qsTr("Transaction id copied") : qsTr("Copy transaction id")
Accessible.role: Accessible.Button
activeFocusOnTab: true
focusPolicy: Qt.StrongFocus
text: root.copied ? qsTr("Copied") : qsTr("Copy tx")
visible: root.transactionId.length > 0
Layout.alignment: Qt.AlignVCenter
Layout.preferredHeight: 30
Layout.preferredWidth: copyText.implicitWidth + 18
contentItem: Text {
id: copyText
color: "#E7E1D8"
font.bold: true
font.pixelSize: 11
horizontalAlignment: Text.AlignHCenter
text: copyButton.text
verticalAlignment: Text.AlignVCenter
}
background: Rectangle {
border.color: copyButton.activeFocus ? "#F2D8C7" : "transparent"
color: copyButton.hovered ? "#F26A21" : "#2B2724"
radius: 6
}
onClicked: root.copyTransactionId()
}
}
}
}