Skip to content

Introduce Tooltip for the BlockClock navbar button #400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,9 @@ QML_RES_ICONS = \
qml/res/icons/shutdown.png \
qml/res/icons/singlesig-wallet.png \
qml/res/icons/storage-dark.png \
qml/res/icons/storage-light.png
qml/res/icons/storage-light.png \
qml/res/icons/tooltip-arrow-dark.png \
qml/res/icons/tooltip-arrow-light.png

QML_QRC_CPP = qml/qrc_bitcoin.cpp
QML_QRC = qml/bitcoin_qml.qrc
Expand All @@ -360,6 +362,7 @@ QML_RES_QML = \
qml/components/StorageSettings.qml \
qml/components/ThemeSettings.qml \
qml/components/TotalBytesIndicator.qml \
qml/components/Tooltip.qml \
qml/controls/ContinueButton.qml \
qml/controls/CoreText.qml \
qml/controls/ExternalLink.qml \
Expand All @@ -381,6 +384,7 @@ QML_RES_QML = \
qml/controls/TextButton.qml \
qml/controls/Theme.qml \
qml/controls/ToggleButton.qml \
qml/controls/utils.js \
qml/controls/ValueInput.qml \
qml/pages/initerrormessage.qml \
qml/pages/main.qml \
Expand Down
4 changes: 4 additions & 0 deletions src/qml/bitcoin_qml.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<file>components/StorageSettings.qml</file>
<file>components/ThemeSettings.qml</file>
<file>components/TotalBytesIndicator.qml</file>
<file>components/Tooltip.qml</file>
<file>controls/ContinueButton.qml</file>
<file>controls/CoreText.qml</file>
<file>controls/ExternalLink.qml</file>
Expand All @@ -41,6 +42,7 @@
<file>controls/TextButton.qml</file>
<file>controls/Theme.qml</file>
<file>controls/ToggleButton.qml</file>
<file>controls/utils.js</file>
<file>controls/ValueInput.qml</file>
<file>pages/initerrormessage.qml</file>
<file>pages/main.qml</file>
Expand Down Expand Up @@ -88,6 +90,8 @@
<file alias="singlesig-wallet">res/icons/singlesig-wallet.png</file>
<file alias="storage-dark">res/icons/storage-dark.png</file>
<file alias="storage-light">res/icons/storage-light.png</file>
<file alias="tooltip-arrow-dark">res/icons/tooltip-arrow-dark.png</file>
<file alias="tooltip-arrow-light">res/icons/tooltip-arrow-light.png</file>
</qresource>
<qresource prefix="/fonts">
<file alias="inter/regular">res/fonts/Inter-Regular.otf</file>
Expand Down
64 changes: 2 additions & 62 deletions src/qml/components/BlockClock.qml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Qt.labs.settings 1.0
import org.bitcoincore.qt 1.0

import "../controls"
import "../controls/utils.js" as Utils

Item {
id: root
Expand All @@ -28,7 +29,7 @@ Item {
property bool synced: nodeModel.verificationProgress > 0.999
property string syncProgress: formatProgressPercentage(nodeModel.verificationProgress * 100)
property bool paused: false
property var syncState: formatRemainingSyncTime(nodeModel.remainingSyncTime)
property var syncState: Utils.formatRemainingSyncTime(nodeModel.remainingSyncTime)
property string syncTime: syncState.text
property bool estimating: syncState.estimating

Expand Down Expand Up @@ -234,65 +235,4 @@ Item {
return "0%"
}
}

function formatRemainingSyncTime(milliseconds) {
var minutes = Math.floor(milliseconds / 60000);
var seconds = Math.floor((milliseconds % 60000) / 1000);
var weeks = Math.floor(minutes / 10080);
minutes %= 10080;
var days = Math.floor(minutes / 1440);
minutes %= 1440;
var hours = Math.floor(minutes / 60);
minutes %= 60;
var result = "";
var estimatingStatus = false;

if (weeks > 0) {
return {
text: "~" + weeks + (weeks === 1 ? " week" : " weeks") + " left",
estimating: false
};
}
if (days > 0) {
return {
text: "~" + days + (days === 1 ? " day" : " days") + " left",
estimating: false
};
}
if (hours >= 5) {
return {
text: "~" + hours + (hours === 1 ? " hour" : " hours") + " left",
estimating: false
};
}
if (hours > 0) {
return {
text: "~" + hours + "h " + minutes + "m" + " left",
estimating: false
};
}
if (minutes >= 5) {
return {
text: "~" + minutes + (minutes === 1 ? " minute" : " minutes") + " left",
estimating: false
};
}
if (minutes > 0) {
return {
text: "~" + minutes + "m " + seconds + "s" + " left",
estimating: false
};
}
if (seconds > 0) {
return {
text: "~" + seconds + (seconds === 1 ? " second" : " seconds") + " left",
estimating: false
};
} else {
return {
text: "Estimating",
estimating: true
};
}
}
}
44 changes: 44 additions & 0 deletions src/qml/components/Tooltip.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2024 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

import QtQuick 2.15
import QtQuick.Controls 2.15

import "../controls"

Item {
id: root

property alias text: tooltipText.text

Rectangle {
id: tooltipBg
color: Theme.color.neutral0
border.color: Theme.color.neutral4
radius: 5
border.width: 1
width: tooltipText.width + 30
height: tooltipText.height + 20
anchors.top: arrow.bottom
anchors.right: arrow.right
anchors.rightMargin: -10
anchors.topMargin: -1
}

Image {
id: arrow
source: Theme.image.tooltipArrow
width: 22
height: 10
anchors.horizontalCenter: root.horizontalCenter
anchors.top: root.top
}

CoreText {
id: tooltipText
text: ""
wrapMode: Text.NoWrap
anchors.centerIn: tooltipBg
}
}
2 changes: 1 addition & 1 deletion src/qml/controls/CoreText.qml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import QtQuick.Controls 2.15
Text {
property bool bold: false
property bool wrap: true
color: Theme.color.white
color: Theme.color.neutral9
font.family: "Inter"
font.styleName: bold ? "Semi Bold" : "Regular"
font.pixelSize: 13
Expand Down
3 changes: 3 additions & 0 deletions src/qml/controls/Theme.qml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Control {
required property url blocktime
required property url network
required property url storage
required property url tooltipArrow
}

ColorSet {
Expand Down Expand Up @@ -115,13 +116,15 @@ Control {
blocktime: "image://images/blocktime-dark"
network: "image://images/network-dark"
storage: "image://images/storage-dark"
tooltipArrow: "qrc:/icons/tooltip-arrow-dark"
}

ImageSet {
id: lightImageSet
blocktime: "image://images/blocktime-light"
network: "image://images/network-light"
storage: "image://images/storage-light"
tooltipArrow: "qrc:/icons/tooltip-arrow-light"
}

function toggleDark() {
Expand Down
66 changes: 66 additions & 0 deletions src/qml/controls/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) 2024 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

// utils.js

function formatRemainingSyncTime(milliseconds) {
var minutes = Math.floor(milliseconds / 60000);
var seconds = Math.floor((milliseconds % 60000) / 1000);
var weeks = Math.floor(minutes / 10080);
minutes %= 10080;
var days = Math.floor(minutes / 1440);
minutes %= 1440;
var hours = Math.floor(minutes / 60);
minutes %= 60;
var result = "";
var estimatingStatus = false;

if (weeks > 0) {
return {
text: "~" + weeks + (weeks === 1 ? " week" : " weeks") + " left",
estimating: false
};
}
if (days > 0) {
return {
text: "~" + days + (days === 1 ? " day" : " days") + " left",
estimating: false
};
}
if (hours >= 5) {
return {
text: "~" + hours + (hours === 1 ? " hour" : " hours") + " left",
estimating: false
};
}
if (hours > 0) {
return {
text: "~" + hours + "h " + minutes + "m" + " left",
estimating: false
};
}
if (minutes >= 5) {
return {
text: "~" + minutes + (minutes === 1 ? " minute" : " minutes") + " left",
estimating: false
};
}
if (minutes > 0) {
return {
text: "~" + minutes + "m " + seconds + "s" + " left",
estimating: false
};
}
if (seconds > 0) {
return {
text: "~" + seconds + (seconds === 1 ? " second" : " seconds") + " left",
estimating: false
};
} else {
return {
text: "Estimating",
estimating: true
};
}
}
10 changes: 10 additions & 0 deletions src/qml/imageprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,15 @@ QPixmap ImageProvider::requestPixmap(const QString& id, QSize* size, const QSize
return QIcon(":/icons/storage-light").pixmap(requested_size);
}

if (id == "tooltip-arrow-dark") {
*size = requested_size;
return QIcon(":/icons/tooltip-arrow-dark").pixmap(requested_size);
}

if (id == "tooltip-arrow-light") {
*size = requested_size;
return QIcon(":/icons/tooltip-arrow-light").pixmap(requested_size);
}

return {};
}
29 changes: 29 additions & 0 deletions src/qml/pages/wallet/DesktopWallets.qml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

import org.bitcoincore.qt 1.0

import "../../controls"
import "../../controls/utils.js" as Utils
import "../../components"
import "../node"

Expand Down Expand Up @@ -67,10 +70,36 @@ Page {
shorten: true
}
NavigationTab {
id: blockClockTabButton
Layout.preferredWidth: 30
Layout.rightMargin: 10
property int index: 3
ButtonGroup.group: navigationTabs

Tooltip {
id: blockClockTooltip
property var syncState: Utils.formatRemainingSyncTime(nodeModel.remainingSyncTime)
property bool synced: nodeModel.verificationProgress > 0.9999
property bool paused: nodeModel.pause
property bool connected: nodeModel.numOutboundPeers > 0

anchors.top: blockClockTabButton.bottom
anchors.topMargin: -5
anchors.horizontalCenter: blockClockTabButton.horizontalCenter

visible: blockClockTabButton.hovered
text: {
if (paused) {
qsTr("Paused")
} else if (connected && synced) {
qsTr("Blocktime\n" + Number(nodeModel.blockTipHeight).toLocaleString(Qt.locale(), 'f', 0))
} else if (connected){
qsTr("Downloading blocks\n" + syncState.text)
} else {
qsTr("Connecting")
}
}
}
}
NavigationTab {
iconSource: "image://images/gear-outline"
Expand Down
Binary file added src/qml/res/icons/tooltip-arrow-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/qml/res/icons/tooltip-arrow-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/qml/res/src/tooltip-arrow-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/qml/res/src/tooltip-arrow-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading