Skip to content

Commit 0233931

Browse files
committed
Merge #465: Show "Select Wallet" or "Add Wallet" in the Wallet selector if a wallet isn't loaded
03b568d qml: Add Context to CreateWalletWizard (johnny9) 5b9b484 qml: Show Add Wallet in WalletBadge if none are found (johnny9) 7af55d5 qml: Hide tabs and show Select Wallet if no wallet is loaded (johnny9) Pull request description: In addition to changing the component in the top left corner, the navigation tabs will be hidden if no wallet is loaded until a wallet is created/selected. ![Screenshot from 2025-06-05 00-05-47](https://github.com/user-attachments/assets/6d7b7990-7472-45b7-ac65-9d334be2d9a5) ![Screenshot from 2025-06-05 00-08-48](https://github.com/user-attachments/assets/3c23e764-2650-4193-8067-6d04ed46c694) ![Screenshot from 2025-06-05 00-06-08](https://github.com/user-attachments/assets/526903d5-6fb6-4b44-b243-3109c8a69755) ACKs for top commit: GBKS: ACK 03b568d Tree-SHA512: 33c6621af2b0d83a16b115369a10a094c395e4b252c3ab58f47384772654621a11084384bbdc0b245a28270ef46d09387c91d0c1b0f1d48ef0c78ad15941a381
2 parents 7af5708 + 03b568d commit 0233931

File tree

7 files changed

+111
-8
lines changed

7 files changed

+111
-8
lines changed

src/qml/models/walletqmlmodel.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class WalletQmlModel : public QObject
2929
Q_PROPERTY(SendRecipient* sendRecipient READ sendRecipient CONSTANT)
3030
Q_PROPERTY(WalletQmlModelTransaction* currentTransaction READ currentTransaction NOTIFY currentTransactionChanged)
3131
Q_PROPERTY(unsigned int targetBlocks READ feeTargetBlocks WRITE setFeeTargetBlocks NOTIFY feeTargetBlocksChanged)
32+
Q_PROPERTY(bool isWalletLoaded READ isWalletLoaded NOTIFY walletIsLoadedChanged)
3233

3334
public:
3435
WalletQmlModel(std::unique_ptr<interfaces::Wallet> wallet, QObject* parent = nullptr);
@@ -67,11 +68,15 @@ class WalletQmlModel : public QObject
6768
unsigned int feeTargetBlocks() const;
6869
void setFeeTargetBlocks(unsigned int target_blocks);
6970

71+
bool isWalletLoaded() const { return m_is_wallet_loaded; }
72+
void setWalletLoaded(bool loaded);
73+
7074
Q_SIGNALS:
7175
void nameChanged();
7276
void balanceChanged();
7377
void currentTransactionChanged();
7478
void feeTargetBlocksChanged();
79+
void walletIsLoadedChanged();
7580

7681
private:
7782
std::unique_ptr<interfaces::Wallet> m_wallet;
@@ -80,6 +85,7 @@ class WalletQmlModel : public QObject
8085
SendRecipient* m_current_recipient{nullptr};
8186
WalletQmlModelTransaction* m_current_transaction{nullptr};
8287
wallet::CCoinControl m_coin_control;
88+
bool m_is_wallet_loaded{false};
8389
};
8490

8591
#endif // BITCOIN_QML_MODELS_WALLETQMLMODEL_H

src/qml/pages/main.qml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,10 @@ ApplicationWindow {
6969
onFinished: {
7070
optionsModel.onboard()
7171
if (AppMode.walletEnabled && AppMode.isDesktop) {
72-
main.push(desktopWallets)
73-
main.push(createWalletWizard)
72+
main.push([
73+
desktopWallets, {},
74+
createWalletWizard, { "launchContext": CreateWalletWizard.Context.Onboarding }
75+
])
7476
} else {
7577
main.push(node)
7678
}
@@ -82,7 +84,7 @@ ApplicationWindow {
8284
id: desktopWallets
8385
DesktopWallets {
8486
onAddWallet: {
85-
main.push(createWalletWizard)
87+
main.push(createWalletWizard, { "launchContext": CreateWalletWizard.Context.Main })
8688
}
8789
onSendTransaction: {
8890
main.push(sendReviewPage)

src/qml/pages/wallet/CreateWalletWizard.qml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,27 @@ import "../wallet"
1313
PageStack {
1414
id: root
1515

16+
enum Context { Onboarding, Main }
17+
1618
signal finished()
1719
property string walletName: ""
20+
property int launchContext: CreateWalletWizard.Context.Onboarding
1821

1922
initialItem: Page {
2023
background: null
2124

2225
header: NavigationBar2 {
2326
id: navbar
2427
rightItem: NavButton {
25-
text: qsTr("Skip")
28+
text: {
29+
switch (root.launchContext) {
30+
case CreateWalletWizard.Context.Main:
31+
return qsTr("Cancel");
32+
case CreateWalletWizard.Context.Onboarding:
33+
default:
34+
return qsTr("Skip");
35+
}
36+
}
2637
onClicked: {
2738
root.finished()
2839
}

src/qml/pages/wallet/DesktopWallets.qml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,20 @@ Page {
3030
text: walletController.selectedWallet.name
3131
balance: walletController.selectedWallet.balance
3232
loading: !walletController.initialized
33+
noWalletLoaded: !walletController.isWalletLoaded
34+
noWalletsFound: walletController.noWalletsFound
3335

3436
MouseArea {
3537
anchors.fill: parent
3638
onClicked: {
37-
walletListModel.listWalletDir()
38-
walletSelect.opened ? walletSelect.close() : walletSelect.open()
39+
if (walletController.initialized) {
40+
walletListModel.listWalletDir()
41+
if (walletController.noWalletsFound) {
42+
root.addWallet()
43+
} else {
44+
walletSelect.opened ? walletSelect.close() : walletSelect.open()
45+
}
46+
}
3947
}
4048
}
4149

@@ -52,9 +60,9 @@ Page {
5260
}
5361
}
5462
centerItem: RowLayout {
63+
visible: walletController.isWalletLoaded
5564
NavigationTab {
5665
id: activityTabButton
57-
checked: true
5866
text: qsTr("Activity")
5967
property int index: 0
6068
ButtonGroup.group: navigationTabs
@@ -79,6 +87,7 @@ Page {
7987
}
8088
NavigationTab {
8189
id: blockClockTabButton
90+
checked: true
8291
Layout.preferredWidth: 30
8392
Layout.rightMargin: 10
8493
property int index: 3

src/qml/pages/wallet/WalletBadge.qml

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Button {
2323
property bool showIcon: true
2424
property string balance: "0.0 000 000"
2525
property bool loading: false
26+
property bool noWalletLoaded: false
27+
property bool noWalletsFound: false
2628

2729
checkable: true
2830
hoverEnabled: AppMode.isDesktop
@@ -32,6 +34,10 @@ Button {
3234
topPadding: 0
3335
clip: true
3436

37+
HoverHandler{
38+
cursorShape: Qt.PointingHandCursor
39+
}
40+
3541
contentItem: Item {
3642
RowLayout {
3743
visible: root.loading
@@ -65,7 +71,40 @@ Button {
6571
}
6672

6773
RowLayout {
68-
visible: !root.loading
74+
visible: !root.loading && root.noWalletLoaded
75+
76+
opacity: visible ? 1 : 0
77+
78+
Behavior on opacity {
79+
NumberAnimation { duration: 400 }
80+
}
81+
82+
anchors.leftMargin: 5
83+
anchors.rightMargin: 5
84+
anchors.centerIn: parent
85+
clip: true
86+
spacing: 5
87+
Icon {
88+
visible: root.showIcon
89+
source: root.noWalletsFound ? "image://images/plus" : "image://images/caret-down-medium-filled"
90+
color: Theme.color.neutral8
91+
size: 30
92+
Layout.minimumWidth: 25
93+
Layout.preferredWidth: 25
94+
Layout.maximumWidth: 25
95+
}
96+
CoreText {
97+
horizontalAlignment: Text.AlignLeft
98+
Layout.fillWidth: true
99+
wrap: false
100+
font.pixelSize: 15
101+
text: root.noWalletsFound ? qsTr("Add Wallet") : qsTr("Select Wallet")
102+
color: root.textColor
103+
}
104+
}
105+
106+
RowLayout {
107+
visible: !root.loading && !root.noWalletLoaded
69108

70109
opacity: visible ? 1 : 0
71110

src/qml/walletqmlcontroller.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ void WalletQmlController::createSingleSigWallet(const QString &name, const QStri
7979
if (wallet) {
8080
m_selected_wallet = new WalletQmlModel(std::move(*wallet));
8181
m_wallets.push_back(m_selected_wallet);
82+
setNoWalletsFound(false);
8283
Q_EMIT selectedWalletChanged();
8384
} else {
8485
m_error_message = util::ErrorString(wallet);
@@ -94,6 +95,7 @@ void WalletQmlController::handleLoadWallet(std::unique_ptr<interfaces::Wallet> w
9495
if (wallet_model->name() == name) {
9596
m_selected_wallet = wallet_model;
9697
Q_EMIT selectedWalletChanged();
98+
setWalletLoaded(true);
9799
return;
98100
}
99101
}
@@ -104,6 +106,7 @@ void WalletQmlController::handleLoadWallet(std::unique_ptr<interfaces::Wallet> w
104106
m_selected_wallet = wallet_model;
105107
m_wallets.push_back(m_selected_wallet);
106108
Q_EMIT selectedWalletChanged();
109+
setWalletLoaded(true);
107110
}
108111

109112
void WalletQmlController::initialize()
@@ -118,9 +121,32 @@ void WalletQmlController::initialize()
118121
}
119122
if (!m_wallets.empty()) {
120123
m_selected_wallet = m_wallets.front();
124+
setWalletLoaded(true);
121125
Q_EMIT selectedWalletChanged();
122126
}
123127

128+
if (m_node.walletLoader().listWalletDir().size() == 0) {
129+
setNoWalletsFound(true);
130+
} else {
131+
setNoWalletsFound(false);
132+
}
133+
124134
m_initialized = true;
125135
Q_EMIT initializedChanged();
126136
}
137+
138+
void WalletQmlController::setWalletLoaded(bool loaded)
139+
{
140+
if (m_is_wallet_loaded != loaded) {
141+
m_is_wallet_loaded = loaded;
142+
Q_EMIT isWalletLoadedChanged();
143+
}
144+
}
145+
146+
void WalletQmlController::setNoWalletsFound(bool no_wallets_found)
147+
{
148+
if (m_no_wallets_found != no_wallets_found) {
149+
m_no_wallets_found = no_wallets_found;
150+
Q_EMIT noWalletsFoundChanged();
151+
}
152+
}

src/qml/walletqmlcontroller.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class WalletQmlController : public QObject
2222
Q_OBJECT
2323
Q_PROPERTY(WalletQmlModel* selectedWallet READ selectedWallet NOTIFY selectedWalletChanged)
2424
Q_PROPERTY(bool initialized READ initialized NOTIFY initializedChanged)
25+
Q_PROPERTY(bool isWalletLoaded READ isWalletLoaded NOTIFY isWalletLoadedChanged)
26+
Q_PROPERTY(bool noWalletsFound READ noWalletsFound NOTIFY noWalletsFoundChanged)
2527

2628
public:
2729
explicit WalletQmlController(interfaces::Node& node, QObject *parent = nullptr);
@@ -33,10 +35,16 @@ class WalletQmlController : public QObject
3335
WalletQmlModel* selectedWallet() const;
3436
void unloadWallets();
3537
bool initialized() const { return m_initialized; }
38+
bool isWalletLoaded() const { return m_is_wallet_loaded; }
39+
void setWalletLoaded(bool loaded);
40+
bool noWalletsFound() const { return m_no_wallets_found; }
41+
void setNoWalletsFound(bool no_wallets_found);
3642

3743
Q_SIGNALS:
3844
void selectedWalletChanged();
3945
void initializedChanged();
46+
void isWalletLoadedChanged();
47+
void noWalletsFoundChanged();
4048

4149
public Q_SLOTS:
4250
void initialize();
@@ -52,6 +60,8 @@ public Q_SLOTS:
5260
QMutex m_wallets_mutex;
5361
std::vector<WalletQmlModel*> m_wallets;
5462
std::unique_ptr<interfaces::Handler> m_handler_load_wallet;
63+
bool m_is_wallet_loaded{false};
64+
bool m_no_wallets_found{false};
5565

5666
bilingual_str m_error_message;
5767
std::vector<bilingual_str> m_warning_messages;

0 commit comments

Comments
 (0)