Skip to content

Commit b29d499

Browse files
committed
Merge #259: Introduce the Peers page
c9aaeae qml: add Looking for peers footer to Peers (johnny9) cc1da00 qml: Introduce the Peers page (johnny9) Pull request description: Adds a new page under Node settings that shows a list of connected peers. A ProxyModel is added to translate the original PeerTableModel into a model that the ListView can handle. [![Windows](https://img.shields.io/badge/OS-Windows-green)](https://api.cirrus-ci.com/v1/artifact/github/bitcoin-core/gui-qml/win64/insecure_win_gui.zip?branch=pull/259) [![Intel macOS](https://img.shields.io/badge/OS-Intel%20macOS-green)](https://api.cirrus-ci.com/v1/artifact/github/bitcoin-core/gui-qml/macos/insecure_mac_gui.zip?branch=pull/259) [![Apple Silicon macOS](https://img.shields.io/badge/OS-Apple%20Silicon%20macOS-green)](https://api.cirrus-ci.com/v1/artifact/github/bitcoin-core/gui-qml/macos_arm64/insecure_mac_arm64_gui.zip?branch=pull/259) [![ARM64 Android](https://img.shields.io/badge/OS-Android-green)](https://api.cirrus-ci.com/v1/artifact/github/bitcoin-core/gui-qml/android/insecure_android_apk.zip?branch=pull/259) ![Screenshot from 2023-02-12 22-38-10](https://user-images.githubusercontent.com/985648/218367663-54a31931-cd25-49b6-80b6-2b17a99edd76.png) ![Screenshot from 2023-02-12 22-38-30](https://user-images.githubusercontent.com/985648/218367593-f8b693d7-0f37-48f7-a7f0-996566697a9d.png) ACKs for top commit: jarolrod: ACK c9aaeae Tree-SHA512: 127a36da2428b8bc1bac23d02c7d5be775f5475355b044a1ec4a86b3ab077e76f611c3a9a8d9b0cd533e8adca2441fd84b6ec0d38be31f0f7380d17c5f3c7a70
2 parents 3bf58b2 + c9aaeae commit b29d499

File tree

8 files changed

+229
-2
lines changed

8 files changed

+229
-2
lines changed

src/Makefile.qt.include

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ QT_MOC_CPP = \
4040
qml/moc_chainmodel.cpp \
4141
qml/moc_nodemodel.cpp \
4242
qml/moc_options_model.cpp \
43+
qml/moc_peerlistsortproxy.cpp \
4344
qt/moc_addressbookpage.cpp \
4445
qt/moc_addresstablemodel.cpp \
4546
qt/moc_askpassphrasedialog.cpp \
@@ -118,6 +119,7 @@ BITCOIN_QT_H = \
118119
qml/imageprovider.h \
119120
qml/nodemodel.h \
120121
qml/options_model.h \
122+
qml/peerlistsortproxy.h \
121123
qml/util.h \
122124
qt/addressbookpage.h \
123125
qt/addresstablemodel.h \
@@ -300,6 +302,7 @@ BITCOIN_QML_BASE_CPP = \
300302
qml/imageprovider.cpp \
301303
qml/nodemodel.cpp \
302304
qml/options_model.cpp \
305+
qml/peerlistsortproxy.cpp \
303306
qml/util.cpp
304307

305308
QML_RES_FONTS = \
@@ -360,6 +363,7 @@ QML_RES_QML = \
360363
qml/pages/main.qml \
361364
qml/pages/node/NodeRunner.qml \
362365
qml/pages/node/NodeSettings.qml \
366+
qml/pages/node/Peers.qml \
363367
qml/pages/onboarding/OnboardingBlockclock.qml \
364368
qml/pages/onboarding/OnboardingConnection.qml \
365369
qml/pages/onboarding/OnboardingCover.qml \

src/qml/bitcoin.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
#include <qml/imageprovider.h>
1919
#include <qml/nodemodel.h>
2020
#include <qml/options_model.h>
21+
#include <qml/peerlistsortproxy.h>
2122
#include <qml/util.h>
2223
#include <qt/guiconstants.h>
2324
#include <qt/guiutil.h>
2425
#include <qt/initexecutor.h>
2526
#include <qt/networkstyle.h>
27+
#include <qt/peertablemodel.h>
2628
#include <util/system.h>
2729
#include <util/threadnames.h>
2830
#include <util/translation.h>
@@ -185,6 +187,10 @@ int QmlGuiMain(int argc, char* argv[])
185187
node->startShutdown();
186188
});
187189

190+
PeerTableModel peer_model{*node, nullptr};
191+
PeerListSortProxy peer_model_sort_proxy{nullptr};
192+
peer_model_sort_proxy.setSourceModel(&peer_model);
193+
188194
GUIUtil::LoadFont(":/fonts/inter/regular");
189195
GUIUtil::LoadFont(":/fonts/inter/semibold");
190196

@@ -196,6 +202,8 @@ int QmlGuiMain(int argc, char* argv[])
196202

197203
engine.rootContext()->setContextProperty("nodeModel", &node_model);
198204
engine.rootContext()->setContextProperty("chainModel", &chain_model);
205+
engine.rootContext()->setContextProperty("peerTableModel", &peer_model);
206+
engine.rootContext()->setContextProperty("peerListModelProxy", &peer_model_sort_proxy);
199207

200208
OptionsQmlModel options_model{*node};
201209
engine.rootContext()->setContextProperty("optionsModel", &options_model);

src/qml/bitcoin_qml.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<file>pages/main.qml</file>
3434
<file>pages/node/NodeRunner.qml</file>
3535
<file>pages/node/NodeSettings.qml</file>
36+
<file>pages/node/Peers.qml</file>
3637
<file>pages/onboarding/OnboardingBlockclock.qml</file>
3738
<file>pages/onboarding/OnboardingConnection.qml</file>
3839
<file>pages/onboarding/OnboardingCover.qml</file>

src/qml/pages/node/NodeSettings.qml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ Item {
8585
}
8686
onClicked: loadedItem.clicked()
8787
}
88+
Separator { Layout.fillWidth: true }
89+
Setting {
90+
id: gotoPeers
91+
Layout.fillWidth: true
92+
header: qsTr("Peers")
93+
actionItem: CaretRightButton {
94+
stateColor: gotoPeers.stateColor
95+
onClicked: {
96+
peerTableModel.startAutoRefresh();
97+
nodeSettingsView.push(peers_page)
98+
}
99+
}
100+
onClicked: loadedItem.clicked()
101+
}
88102
}
89103
}
90104
}
@@ -124,4 +138,17 @@ Item {
124138
}
125139
}
126140
}
141+
Component {
142+
id: peers_page
143+
Peers {
144+
navLeftDetail: NavButton {
145+
iconSource: "image://images/caret-left"
146+
text: qsTr("Back")
147+
onClicked: {
148+
nodeSettingsView.pop()
149+
peerTableModel.stopAutoRefresh();
150+
}
151+
}
152+
}
153+
}
127154
}

src/qml/pages/node/Peers.qml

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// Copyright (c) 2023 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
import QtQuick 2.15
6+
import QtQuick.Controls 2.15
7+
import QtQuick.Layouts 1.15
8+
import "../../controls"
9+
import "../../components"
10+
11+
Page {
12+
background: null
13+
property alias navLeftDetail: navbar.leftDetail
14+
15+
header: NavigationBar {
16+
id: navbar
17+
}
18+
19+
Text {
20+
anchors.top: parent.top
21+
anchors.horizontalCenter: parent.horizontalCenter
22+
id: description
23+
height: 75
24+
width: Math.min(parent.width - 40, 450)
25+
wrapMode: Text.WordWrap
26+
text: qsTr("Peers are nodes you are connected to. You want to ensure that you are connected to x, y and z, but not a, b, and c. Learn more.")
27+
font.family: "Inter"
28+
font.styleName: "Regular"
29+
font.pixelSize: 13
30+
color: Theme.color.neutral7
31+
horizontalAlignment: Text.AlignHCenter
32+
}
33+
34+
ListView {
35+
id: listView
36+
clip: true
37+
width: Math.min(parent.width - 40, 450)
38+
anchors.top: description.bottom
39+
anchors.bottom: parent.bottom
40+
anchors.horizontalCenter: parent.horizontalCenter
41+
model: peerListModelProxy
42+
spacing: 15
43+
44+
footer: Loader {
45+
anchors.centerIn: parent
46+
height: 75
47+
active: nodeModel.numOutboundPeers < nodeModel.maxNumOutboundPeers
48+
visible: active
49+
sourceComponent: RowLayout {
50+
spacing: 20
51+
PeersIndicator {
52+
Layout.alignment: Qt.AlignHCenter
53+
numOutboundPeers: nodeModel.numOutboundPeers
54+
maxNumOutboundPeers: nodeModel.maxNumOutboundPeers
55+
}
56+
Text {
57+
Layout.alignment: Qt.AlignHCenter
58+
text: qsTr("Looking for %1 more peer(s)").arg(
59+
nodeModel.maxNumOutboundPeers - nodeModel.numOutboundPeers)
60+
font.family: "Inter"
61+
font.styleName: "Regular"
62+
font.pixelSize: 15
63+
color: Theme.color.neutral7
64+
}
65+
}
66+
}
67+
68+
delegate: Item {
69+
required property int nodeId;
70+
required property string address;
71+
required property string subversion;
72+
required property string direction;
73+
implicitHeight: 65
74+
implicitWidth: listView.width
75+
76+
ColumnLayout {
77+
anchors.left: parent.left
78+
Label {
79+
Layout.alignment: Qt.AlignLeft
80+
id: primary
81+
text: "#" + nodeId
82+
font.family: "Inter"
83+
font.styleName: "Regular"
84+
font.pixelSize: 18
85+
color: Theme.color.neutral9
86+
}
87+
Label {
88+
Layout.alignment: Qt.AlignLeft
89+
id: tertiary
90+
text: address
91+
font.family: "Inter"
92+
font.styleName: "Regular"
93+
font.pixelSize: 15
94+
color: Theme.color.neutral7
95+
}
96+
}
97+
ColumnLayout {
98+
anchors.right: parent.right
99+
Label {
100+
Layout.alignment: Qt.AlignRight
101+
id:secondary
102+
text: direction
103+
font.family: "Inter"
104+
font.styleName: "Regular"
105+
font.pixelSize: 18
106+
color: Theme.color.neutral9
107+
}
108+
Label {
109+
Layout.alignment: Qt.AlignRight
110+
id: quaternary
111+
text: subversion
112+
font.family: "Inter"
113+
font.styleName: "Regular"
114+
font.pixelSize: 15
115+
color: Theme.color.neutral7
116+
}
117+
}
118+
Separator {
119+
anchors.bottom: parent.bottom
120+
width: parent.width
121+
}
122+
}
123+
}
124+
}

src/qml/peerlistsortproxy.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) 2023 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <qml/peerlistsortproxy.h>
6+
#include <qt/peertablemodel.h>
7+
8+
PeerListSortProxy::PeerListSortProxy(QObject* parent)
9+
: PeerTableSortProxy(parent)
10+
{
11+
}
12+
13+
QHash<int, QByteArray> PeerListSortProxy::roleNames() const
14+
{
15+
QHash<int, QByteArray> roles;
16+
roles[PeerTableModel::NetNodeId] = "nodeId";
17+
roles[PeerTableModel::Age] = "age";
18+
roles[PeerTableModel::Address] = "address";
19+
roles[PeerTableModel::Direction] = "direction";
20+
roles[PeerTableModel::ConnectionType] = "connectionType";
21+
roles[PeerTableModel::Network] = "network";
22+
roles[PeerTableModel::Ping] = "ping";
23+
roles[PeerTableModel::Sent] = "sent";
24+
roles[PeerTableModel::Received] = "received";
25+
roles[PeerTableModel::Subversion] = "subversion";
26+
return roles;
27+
}
28+
29+
QVariant PeerListSortProxy::data(const QModelIndex& index, int role) const
30+
{
31+
if (role == PeerTableModel::StatsRole) {
32+
return PeerTableSortProxy::data(index, role);
33+
}
34+
35+
QModelIndex converted_index = PeerTableSortProxy::index(index.row(), role);
36+
return PeerTableSortProxy::data(converted_index, Qt::DisplayRole);
37+
}

src/qml/peerlistsortproxy.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) 2023 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_QML_PEERLISTSORTPROXY_H
6+
#define BITCOIN_QML_PEERLISTSORTPROXY_H
7+
8+
#include <qt/peertablesortproxy.h>
9+
#include <QByteArray>
10+
#include <QHash>
11+
#include <QModelIndex>
12+
#include <QVariant>
13+
14+
class PeerListSortProxy : public PeerTableSortProxy
15+
{
16+
Q_OBJECT
17+
18+
public:
19+
explicit PeerListSortProxy(QObject* parent);
20+
~PeerListSortProxy() = default;
21+
22+
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
23+
QHash<int, QByteArray> roleNames() const override;
24+
};
25+
26+
#endif // BITCOIN_QML_PEERLISTSORTPROXY_H

src/qt/peertablemodel.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ class PeerTableModel : public QAbstractTableModel
4242
public:
4343
explicit PeerTableModel(interfaces::Node& node, QObject* parent);
4444
~PeerTableModel();
45-
void startAutoRefresh();
46-
void stopAutoRefresh();
45+
Q_INVOKABLE void startAutoRefresh();
46+
Q_INVOKABLE void stopAutoRefresh();
4747

4848
enum ColumnIndex {
4949
NetNodeId = 0,

0 commit comments

Comments
 (0)