mirror of
https://github.com/logos-blockchain/lez-explorer-ui.git
synced 2026-07-30 03:13:25 +00:00
fix: existing ui bugs fixed + polished
This commit is contained in:
parent
e77bf6153c
commit
ec2ba77912
@ -20,7 +20,23 @@ Rectangle {
|
||||
property int histIndex: -1
|
||||
|
||||
// --- Navigation API (pages call these via the injected `explorer`) ---
|
||||
function sameDescriptor(a, b) {
|
||||
if (!a || !b)
|
||||
return false;
|
||||
if (a.type !== b.type)
|
||||
return false;
|
||||
if (a.type === "home")
|
||||
return true;
|
||||
if (a.type === "search")
|
||||
return a.query === b.query;
|
||||
return a.param === b.param;
|
||||
}
|
||||
function navigateTo(desc) {
|
||||
// Navigating to the page we're already on is a no-op — don't grow the
|
||||
// history (so e.g. Home-while-home doesn't wake the Back button).
|
||||
var current = root.histIndex >= 0 ? root.history[root.histIndex] : null;
|
||||
if (root.sameDescriptor(current, desc))
|
||||
return;
|
||||
var h = root.history.slice(0, root.histIndex + 1);
|
||||
h.push(desc);
|
||||
root.history = h;
|
||||
|
||||
55
src/qml/components/CopyButton.qml
Normal file
55
src/qml/components/CopyButton.qml
Normal file
@ -0,0 +1,55 @@
|
||||
import QtQuick
|
||||
import Logos.Theme
|
||||
|
||||
// Tiny copy-to-clipboard button. Self-contained: writes `value` to the system
|
||||
// clipboard via a hidden TextEdit (which runs in the host GUI process, so it
|
||||
// reaches the real desktop clipboard), then flips to a check mark briefly as
|
||||
// confirmation.
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string value: ""
|
||||
property int size: 22
|
||||
implicitWidth: size
|
||||
implicitHeight: size
|
||||
|
||||
// Off-screen helper used purely to push text onto the clipboard.
|
||||
TextEdit { id: clip; visible: false }
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: Theme.spacing.radiusSmall
|
||||
color: hover.hovered ? Theme.palette.backgroundSecondary : "transparent"
|
||||
|
||||
HoverHandler { id: hover }
|
||||
TapHandler {
|
||||
onTapped: {
|
||||
clip.text = root.value;
|
||||
clip.selectAll();
|
||||
clip.copy();
|
||||
clip.text = "";
|
||||
icon.source = icon.checkUrl;
|
||||
resetTimer.restart();
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: icon
|
||||
anchors.centerIn: parent
|
||||
property url copyUrl: Qt.resolvedUrl("../icons/copy.svg")
|
||||
property url checkUrl: Qt.resolvedUrl("../icons/check.svg")
|
||||
source: copyUrl
|
||||
sourceSize.width: Math.round(root.size * 0.72)
|
||||
sourceSize.height: Math.round(root.size * 0.72)
|
||||
width: Math.round(root.size * 0.72)
|
||||
height: Math.round(root.size * 0.72)
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: resetTimer
|
||||
interval: 1200
|
||||
onTriggered: icon.source = icon.copyUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,7 @@ RowLayout {
|
||||
property string label: ""
|
||||
property string value: ""
|
||||
property bool mono: false
|
||||
property bool copyable: false
|
||||
property color valueColor: Theme.palette.text
|
||||
|
||||
spacing: Theme.spacing.medium
|
||||
@ -36,4 +37,10 @@ RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop
|
||||
}
|
||||
|
||||
CopyButton {
|
||||
visible: root.copyable && root.value.length > 0
|
||||
value: root.value
|
||||
Layout.alignment: Qt.AlignTop
|
||||
}
|
||||
}
|
||||
|
||||
3
src/qml/icons/check.svg
Normal file
3
src/qml/icons/check.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#a6e3a1" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polyline points="20 6 9 17 4 12"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 201 B |
4
src/qml/icons/copy.svg
Normal file
4
src/qml/icons/copy.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#cdd6f4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
|
||||
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 290 B |
@ -49,13 +49,13 @@ Item {
|
||||
Layout.fillWidth: true
|
||||
visible: page.loaded && Object.keys(page.account).length > 1
|
||||
|
||||
InfoRow { label: "Account ID"; value: page.account.accountId || ""; mono: true }
|
||||
InfoRow { label: "Account ID"; value: page.account.accountId || ""; mono: true; copyable: true }
|
||||
InfoRow {
|
||||
label: "Balance"
|
||||
value: page.account.balance || "0"
|
||||
valueColor: Theme.palette.success
|
||||
}
|
||||
InfoRow { label: "Program Owner"; value: page.account.programOwner || ""; mono: true }
|
||||
InfoRow { label: "Program Owner"; value: page.account.programOwner || ""; mono: true; copyable: true }
|
||||
InfoRow { label: "Nonce"; value: page.account.nonce || "0" }
|
||||
InfoRow {
|
||||
label: "Data Size"
|
||||
|
||||
@ -49,7 +49,7 @@ Item {
|
||||
visible: page.loaded && Object.keys(page.block).length > 0
|
||||
|
||||
InfoRow { label: "Block ID"; value: String(page.block.blockId !== undefined ? page.block.blockId : "") }
|
||||
InfoRow { label: "Hash"; value: page.block.hash || ""; mono: true }
|
||||
InfoRow { label: "Hash"; value: page.block.hash || ""; mono: true; copyable: true }
|
||||
|
||||
// Previous hash — a clickable link to the previous block when not genesis.
|
||||
RowLayout {
|
||||
@ -68,6 +68,11 @@ Item {
|
||||
onTapped: page.explorer.navigateBlock(Number(page.blockId) - 1)
|
||||
}
|
||||
}
|
||||
CopyButton {
|
||||
visible: (page.block.prevBlockHash || "").length > 0
|
||||
value: page.block.prevBlockHash || ""
|
||||
Layout.alignment: Qt.AlignTop
|
||||
}
|
||||
}
|
||||
|
||||
InfoRow { label: "Timestamp"; value: page.block.timestampText || "" }
|
||||
@ -80,7 +85,7 @@ Item {
|
||||
Item { Layout.fillWidth: true }
|
||||
}
|
||||
|
||||
InfoRow { label: "Signature"; value: page.block.signature || ""; mono: true }
|
||||
InfoRow { label: "Signature"; value: page.block.signature || ""; mono: true; copyable: true }
|
||||
InfoRow { label: "Transactions"; value: String(page.block.txCount !== undefined ? page.block.txCount : 0) }
|
||||
}
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ Item {
|
||||
Layout.fillWidth: true
|
||||
visible: page.loaded && Object.keys(page.tx).length > 0
|
||||
|
||||
InfoRow { label: "Hash"; value: page.tx.hash || ""; mono: true }
|
||||
InfoRow { label: "Hash"; value: page.tx.hash || ""; mono: true; copyable: true }
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Theme.spacing.medium
|
||||
@ -60,7 +60,7 @@ Item {
|
||||
// Public.
|
||||
InfoRow {
|
||||
visible: page.txType === "Public"
|
||||
label: "Program ID"; value: page.tx.programId || ""; mono: true
|
||||
label: "Program ID"; value: page.tx.programId || ""; mono: true; copyable: true
|
||||
}
|
||||
InfoRow {
|
||||
visible: page.txType === "Public"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user