Skip to content

Commit

Permalink
qml: Introduce UI Flow for Loading Snapshot
Browse files Browse the repository at this point in the history
This introduce the UI flow to load a AssumeUTXO snapshot
into the Bitcoin Core App. It modifies the connection seetings
and adds a SnapshotSettings file, Icon, and modified profress
bar.

It has been rebased
  • Loading branch information
D33r-Gee committed Nov 1, 2024
1 parent 15c1f39 commit c97d2a1
Show file tree
Hide file tree
Showing 17 changed files with 383 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -337,11 +337,14 @@ QML_RES_ICONS = \
qml/res/icons/caret-left.png \
qml/res/icons/caret-right.png \
qml/res/icons/check.png \
qml/res/icons/circle-file.png \
qml/res/icons/circle-green-check.png \
qml/res/icons/cross.png \
qml/res/icons/error.png \
qml/res/icons/export.png \
qml/res/icons/gear.png \
qml/res/icons/gear-outline.png \
qml/res/icons/green-check.png \
qml/res/icons/hidden.png \
qml/res/icons/info.png \
qml/res/icons/minus.png \
Expand Down Expand Up @@ -373,6 +376,7 @@ QML_RES_QML = \
qml/components/NetworkIndicator.qml \
qml/components/ProxySettings.qml \
qml/components/Separator.qml \
qml/components/SnapshotSettings.qml \
qml/components/StorageLocations.qml \
qml/components/StorageOptions.qml \
qml/components/StorageSettings.qml \
Expand Down Expand Up @@ -426,6 +430,7 @@ QML_RES_QML = \
qml/pages/settings/SettingsDeveloper.qml \
qml/pages/settings/SettingsDisplay.qml \
qml/pages/settings/SettingsProxy.qml \
qml/pages/settings/SettingsSnapshot.qml \
qml/pages/settings/SettingsStorage.qml \
qml/pages/settings/SettingsTheme.qml \
qml/pages/wallet/CreateBackup.qml \
Expand Down
6 changes: 6 additions & 0 deletions src/qml/bitcoin_qml.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<file>components/ProxySettings.qml</file>
<file>components/StorageLocations.qml</file>
<file>components/Separator.qml</file>
<file>components/SnapshotSettings.qml</file>
<file>components/StorageOptions.qml</file>
<file>components/StorageSettings.qml</file>
<file>components/ThemeSettings.qml</file>
Expand All @@ -25,6 +26,7 @@
<file>controls/CoreTextField.qml</file>
<file>controls/ExternalLink.qml</file>
<file>controls/FocusBorder.qml</file>
<file>controls/GreenCheckIcon.qml</file>
<file>controls/Header.qml</file>
<file>controls/Icon.qml</file>
<file>controls/InformationPage.qml</file>
Expand Down Expand Up @@ -66,6 +68,7 @@
<file>pages/settings/SettingsDeveloper.qml</file>
<file>pages/settings/SettingsDisplay.qml</file>
<file>pages/settings/SettingsProxy.qml</file>
<file>pages/settings/SettingsSnapshot.qml</file>
<file>pages/settings/SettingsStorage.qml</file>
<file>pages/settings/SettingsTheme.qml</file>
<file>pages/wallet/CreateBackup.qml</file>
Expand All @@ -91,11 +94,14 @@
<file alias="caret-left">res/icons/caret-left.png</file>
<file alias="caret-right">res/icons/caret-right.png</file>
<file alias="check">res/icons/check.png</file>
<file alias="circle-file">res/icons/circle-file.png</file>
<file alias="circle-green-check">res/icons/circle-green-check.png</file>
<file alias="cross">res/icons/cross.png</file>
<file alias="error">res/icons/error.png</file>
<file alias="export">res/icons/export.png</file>
<file alias="gear">res/icons/gear.png</file>
<file alias="gear-outline">res/icons/gear-outline.png</file>
<file alias="green-check">res/icons/green-check.png</file>
<file alias="hidden">res/icons/hidden.png</file>
<file alias="info">res/icons/info.png</file>
<file alias="minus">res/icons/minus.png</file>
Expand Down
30 changes: 30 additions & 0 deletions src/qml/components/ConnectionSettings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,37 @@ import "../controls"
ColumnLayout {
id: root
signal next
property bool snapshotImported: false
function setSnapshotImported(imported) {
snapshotImported = imported
}
spacing: 4
Setting {
id: gotoSnapshot
Layout.fillWidth: true
header: qsTr("Load snapshot")
description: qsTr("Instant use with background sync")
actionItem: Item {
width: 26
height: 26
CaretRightIcon {
anchors.centerIn: parent
visible: !snapshotImported
color: gotoSnapshot.stateColor
}
GreenCheckIcon {
anchors.centerIn: parent
visible: snapshotImported
color: Theme.color.transparent
size: 30
}
}
onClicked: {
connectionSwipe.incrementCurrentIndex()
connectionSwipe.incrementCurrentIndex()
}
}
Separator { Layout.fillWidth: true }
Setting {
Layout.fillWidth: true
header: qsTr("Enable listening")
Expand Down
204 changes: 204 additions & 0 deletions src/qml/components/SnapshotSettings.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
// Copyright (c) 2023-present 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 QtQuick.Layouts 1.15

import "../controls"

ColumnLayout {
signal snapshotImportCompleted()
property int snapshotVerificationCycles: 0
property real snapshotVerificationProgress: 0
property bool snapshotVerified: false

id: columnLayout
width: Math.min(parent.width, 450)
anchors.horizontalCenter: parent.horizontalCenter


Timer {
id: snapshotSimulationTimer
interval: 50 // Update every 50ms
running: false
repeat: true
onTriggered: {
if (snapshotVerificationProgress < 1) {
snapshotVerificationProgress += 0.01
} else {
snapshotVerificationCycles++
if (snapshotVerificationCycles < 1) {
snapshotVerificationProgress = 0
} else {
running = false
snapshotVerified = true
settingsStack.currentIndex = 2
}
}
}
}

StackLayout {
id: settingsStack
currentIndex: 0

ColumnLayout {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: Math.min(parent.width, 450)

Image {
Layout.alignment: Qt.AlignCenter
source: "image://images/circle-file"

sourceSize.width: 200
sourceSize.height: 200
}

Header {
Layout.fillWidth: true
Layout.topMargin: 20
headerBold: true
header: qsTr("Load snapshot")
descriptionBold: false
descriptionColor: Theme.color.neutral6
descriptionSize: 17
descriptionLineHeight: 1.1
description: qsTr("You can start using the application more quickly by loading a recent transaction snapshot." +
" It will be automatically verified in the background.")
}

ContinueButton {
Layout.preferredWidth: Math.min(300, columnLayout.width - 2 * Layout.leftMargin)
Layout.topMargin: 40
Layout.leftMargin: 20
Layout.rightMargin: Layout.leftMargin
Layout.bottomMargin: 20
Layout.alignment: Qt.AlignCenter
text: qsTr("Choose snapshot file")
onClicked: {
settingsStack.currentIndex = 1
snapshotSimulationTimer.start()
}
}
}

ColumnLayout {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: Math.min(parent.width, 450)

Image {
Layout.alignment: Qt.AlignCenter
source: "image://images/circle-file"

sourceSize.width: 200
sourceSize.height: 200
}

Header {
Layout.fillWidth: true
Layout.topMargin: 20
Layout.leftMargin: 20
Layout.rightMargin: 20
header: qsTr("Loading Snapshot")
}

ProgressIndicator {
id: progressIndicator
Layout.topMargin: 20
width: 200
height: 20
progress: snapshotVerificationProgress
Layout.alignment: Qt.AlignCenter
progressColor: Theme.color.blue
}
}

ColumnLayout {
id: loadedSnapshotColumn
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: Math.min(parent.width, 450)

Image {
Layout.alignment: Qt.AlignCenter
source: "image://images/circle-green-check"

sourceSize.width: 60
sourceSize.height: 60
}

Header {
Layout.fillWidth: true
Layout.topMargin: 20
headerBold: true
header: qsTr("Snapshot Loaded")
descriptionBold: false
descriptionColor: Theme.color.neutral6
descriptionSize: 17
descriptionLineHeight: 1.1
description: qsTr("It contains transactions up to January 12, 2024. Newer transactions still need to be downloaded." +
" The data will be verified in the background.")
}

ContinueButton {
Layout.preferredWidth: Math.min(300, columnLayout.width - 2 * Layout.leftMargin)
Layout.topMargin: 40
Layout.alignment: Qt.AlignCenter
text: qsTr("Done")
onClicked: {
snapshotImportCompleted()
connectionSwipe.decrementCurrentIndex()
connectionSwipe.decrementCurrentIndex()
}
}

Setting {
id: viewDetails
Layout.alignment: Qt.AlignCenter
header: qsTr("View details")
actionItem: CaretRightIcon {
id: caretIcon
color: viewDetails.stateColor
rotation: viewDetails.expanded ? 90 : 0
Behavior on rotation { NumberAnimation { duration: 200 } }
}

property bool expanded: false

onClicked: {
expanded = !expanded
}
}

ColumnLayout {
id: detailsContent
visible: viewDetails.expanded
Layout.preferredWidth: Math.min(300, parent.width - 2 * Layout.leftMargin)
Layout.alignment: Qt.AlignCenter
Layout.leftMargin: 80
Layout.rightMargin: 80
Layout.topMargin: 10
spacing: 10
// TODO: make sure the block height number aligns right
RowLayout {
CoreText {
text: qsTr("Block Height:")
Layout.alignment: Qt.AlignLeft
font.pixelSize: 14
}
CoreText {
text: qsTr("200,000")
Layout.alignment: Qt.AlignRight
font.pixelSize: 14
}
}
Separator { Layout.fillWidth: true }
CoreText {
text: qsTr("Hash: 0x1234567890abcdef...")
font.pixelSize: 14
}
}
}
}
}
11 changes: 11 additions & 0 deletions src/qml/controls/GreenCheckIcon.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) 2023 - present 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

Icon {
source: "image://images/green-check"
size: 30
}
2 changes: 2 additions & 0 deletions src/qml/controls/Header.qml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ ColumnLayout {
property int subtextSize: 15
property color subtextColor: Theme.color.neutral9
property bool wrap: true
property real descriptionLineHeight: 1

spacing: 0
Loader {
Expand Down Expand Up @@ -60,6 +61,7 @@ ColumnLayout {
text: root.description
horizontalAlignment: root.center ? Text.AlignHCenter : Text.AlignLeft
wrapMode: wrap ? Text.WordWrap : Text.NoWrap
lineHeight: root.descriptionLineHeight

Behavior on color {
ColorAnimation { duration: 150 }
Expand Down
3 changes: 2 additions & 1 deletion src/qml/controls/ProgressIndicator.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import QtQuick.Controls 2.15

Control {
property real progress: 0
property color progressColor: Theme.color.orange
Behavior on progress {
NumberAnimation {
easing.type: Easing.Bezier
Expand All @@ -26,7 +27,7 @@ Control {
width: contentItem.width
height: contentItem.height
radius: contentItem.radius
color: Theme.color.orange
color: progressColor
}
}
}
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 @@ -27,6 +27,7 @@ Control {
required property color blue
required property color amber
required property color purple
required property color transparent
required property color neutral0
required property color neutral1
required property color neutral2
Expand Down Expand Up @@ -59,6 +60,7 @@ Control {
blue: "#3CA3DE"
amber: "#C9B500"
purple: "#C075DC"
transparent: "#00000000"
neutral0: "#000000"
neutral1: "#1A1A1A"
neutral2: "#2D2D2D"
Expand Down Expand Up @@ -91,6 +93,7 @@ Control {
blue: "#2D9CDB"
amber: "#C9B500"
purple: "#BB6BD9"
transparent: "#00000000"
neutral0: "#FFFFFF"
neutral1: "#F8F8F8"
neutral2: "#F4F4F4"
Expand Down
Loading

0 comments on commit c97d2a1

Please sign in to comment.