mirror of
https://github.com/wownero/wowlet.git
synced 2026-10-17 07:11:29 +02:00
wowlet: first-run 'be your own node' welcome + deferred startup + non-blocking node toggle. On first launch a welcome dialog lets the user choose own-node vs remote BEFORE any node starts (gated on firstRun; later launches use the saved choice); node start moved past it in WindowManager. Settings toggle now stops wownerod non-blocking (no UI freeze while it flushes LMDB). Copy: 'many recommended', no em-dash
This commit is contained in:
@@ -176,7 +176,7 @@ void Settings::setupNetworkTab() {
|
|||||||
if (enabled)
|
if (enabled)
|
||||||
daemonManager()->start();
|
daemonManager()->start();
|
||||||
else
|
else
|
||||||
daemonManager()->stop();
|
daemonManager()->stop(false); // non-blocking: don't freeze Settings while wownerod flushes
|
||||||
m_nodes->autoConnect(true);
|
m_nodes->autoConnect(true);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+56
-5
@@ -3,9 +3,15 @@
|
|||||||
|
|
||||||
#include "WindowManager.h"
|
#include "WindowManager.h"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QDialog>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
|
#include <QFont>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
|
#include <QLabel>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QVBoxLayout>
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
@@ -48,16 +54,22 @@ WindowManager::WindowManager(QObject *parent)
|
|||||||
this->buildTrayMenu();
|
this->buildTrayMenu();
|
||||||
m_tray->setVisible(conf()->get(Config::showTrayIcon).toBool());
|
m_tray->setVisible(conf()->get(Config::showTrayIcon).toBool());
|
||||||
|
|
||||||
// wowlet: boot the embedded wownerod node early so it syncs while the user opens their wallet.
|
|
||||||
// No-op if the user disabled the local node (Config::runLocalNode) or no daemon is bundled.
|
|
||||||
daemonManager()->init();
|
|
||||||
daemonManager()->start();
|
|
||||||
|
|
||||||
this->initSkins();
|
this->initSkins();
|
||||||
this->patchMacStylesheet();
|
this->patchMacStylesheet();
|
||||||
|
|
||||||
this->showCrashLogs();
|
this->showCrashLogs();
|
||||||
|
|
||||||
|
// wowlet: on the very first launch, let the user choose their own node vs a remote one BEFORE anything
|
||||||
|
// connects. No node — local or remote — starts until they hit Continue. Later launches use the saved choice.
|
||||||
|
if (conf()->get(Config::firstRun).toBool()) {
|
||||||
|
this->showNodeWelcome();
|
||||||
|
}
|
||||||
|
|
||||||
|
// wowlet: boot the embedded wownerod (shouldStartDaemon() makes this a no-op if the user chose a remote
|
||||||
|
// node), so it syncs while the user opens their wallet.
|
||||||
|
daemonManager()->init();
|
||||||
|
daemonManager()->start();
|
||||||
|
|
||||||
// wowlet: the embedded local node is configured automatically — skip the first-run network wizard.
|
// wowlet: the embedded local node is configured automatically — skip the first-run network wizard.
|
||||||
this->onInitialNetworkConfigured();
|
this->onInitialNetworkConfigured();
|
||||||
|
|
||||||
@@ -68,6 +80,45 @@ WindowManager::WindowManager(QObject *parent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wowlet: first-run "be your own node" welcome. Shown before any node starts; records the user's choice
|
||||||
|
// in Config::runLocalNode, which start()/autoConnect then honour.
|
||||||
|
void WindowManager::showNodeWelcome() {
|
||||||
|
QDialog dlg;
|
||||||
|
dlg.setWindowTitle("Welcome to wowlet");
|
||||||
|
dlg.setMinimumWidth(440);
|
||||||
|
|
||||||
|
auto *title = new QLabel("🐕 Welcome to wowlet", &dlg);
|
||||||
|
QFont tf = title->font();
|
||||||
|
tf.setPointSize(tf.pointSize() + 4);
|
||||||
|
tf.setBold(true);
|
||||||
|
title->setFont(tf);
|
||||||
|
|
||||||
|
auto *intro = new QLabel("wowlet runs your own Wownero node by default: be your own boss and help run the network.", &dlg);
|
||||||
|
intro->setWordWrap(true);
|
||||||
|
|
||||||
|
auto *check = new QCheckBox("Run your own Wownero node (many recommended)", &dlg);
|
||||||
|
check->setChecked(conf()->get(Config::runLocalNode).toBool());
|
||||||
|
|
||||||
|
auto *hint = new QLabel("(untick to use a remote node instead)", &dlg);
|
||||||
|
hint->setStyleSheet("color: gray;");
|
||||||
|
|
||||||
|
auto *btn = new QPushButton("Continue", &dlg);
|
||||||
|
btn->setDefault(true);
|
||||||
|
connect(btn, &QPushButton::clicked, &dlg, &QDialog::accept);
|
||||||
|
|
||||||
|
auto *layout = new QVBoxLayout(&dlg);
|
||||||
|
layout->addWidget(title);
|
||||||
|
layout->addWidget(intro);
|
||||||
|
layout->addSpacing(8);
|
||||||
|
layout->addWidget(check);
|
||||||
|
layout->addWidget(hint);
|
||||||
|
layout->addSpacing(8);
|
||||||
|
layout->addWidget(btn, 0, Qt::AlignRight);
|
||||||
|
|
||||||
|
dlg.exec(); // modal — blocks until Continue
|
||||||
|
conf()->set(Config::runLocalNode, check->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
QPointer<WindowManager> WindowManager::m_instance(nullptr);
|
QPointer<WindowManager> WindowManager::m_instance(nullptr);
|
||||||
|
|
||||||
void WindowManager::setEventFilter(EventFilter *ef) {
|
void WindowManager::setEventFilter(EventFilter *ef) {
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ private:
|
|||||||
bool autoOpenWallet();
|
bool autoOpenWallet();
|
||||||
|
|
||||||
void initWizard();
|
void initWizard();
|
||||||
|
void showNodeWelcome(); // wowlet: first-run "be your own node" choice, before any node starts
|
||||||
WalletWizard* createWizard(WalletWizard::Page startPage);
|
WalletWizard* createWizard(WalletWizard::Page startPage);
|
||||||
|
|
||||||
void handleWalletError(const Utils::Message &message);
|
void handleWalletError(const Utils::Message &message);
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ void DaemonManager::start() {
|
|||||||
m_started = true;
|
m_started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonManager::stop() {
|
void DaemonManager::stop(bool wait) {
|
||||||
m_stopping = true;
|
m_stopping = true;
|
||||||
if (m_process->state() == QProcess::ProcessState::NotRunning) {
|
if (m_process->state() == QProcess::ProcessState::NotRunning) {
|
||||||
m_started = false;
|
m_started = false;
|
||||||
@@ -107,12 +107,14 @@ void DaemonManager::stop() {
|
|||||||
// wownerod owns an LMDB database. Send SIGTERM so it flushes and exits cleanly; only hard-kill
|
// wownerod owns an LMDB database. Send SIGTERM so it flushes and exits cleanly; only hard-kill
|
||||||
// if it refuses to shut down, to avoid blockchain database corruption.
|
// if it refuses to shut down, to avoid blockchain database corruption.
|
||||||
m_process->terminate();
|
m_process->terminate();
|
||||||
|
m_started = false;
|
||||||
|
if (!wait)
|
||||||
|
return; // toggle/live use: let it flush + exit in the background instead of freezing the UI thread.
|
||||||
if (!m_process->waitForFinished(30000)) {
|
if (!m_process->waitForFinished(30000)) {
|
||||||
qWarning() << "wownerod did not exit gracefully within 30s; killing";
|
qWarning() << "wownerod did not exit gracefully within 30s; killing";
|
||||||
m_process->kill();
|
m_process->kill();
|
||||||
m_process->waitForFinished(5000);
|
m_process->waitForFinished(5000);
|
||||||
}
|
}
|
||||||
m_started = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonManager::onStateChanged(QProcess::ProcessState state) {
|
void DaemonManager::onStateChanged(QProcess::ProcessState state) {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public:
|
|||||||
|
|
||||||
void init();
|
void init();
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop(bool wait = true); // wait=false: non-blocking (don't freeze the UI on a settings toggle)
|
||||||
bool unpackBins();
|
bool unpackBins();
|
||||||
|
|
||||||
bool isStarted() const { return m_started; }
|
bool isStarted() const { return m_started; }
|
||||||
|
|||||||
@@ -59,11 +59,11 @@ NodeWidget::NodeWidget(QWidget *parent)
|
|||||||
// wowlet: built-in node toggle + the "why run your own node" messaging. Running your own node is
|
// wowlet: built-in node toggle + the "why run your own node" messaging. Running your own node is
|
||||||
// a privacy win (no remote operator sees your wallet) AND it strengthens the Wownero network by
|
// a privacy win (no remote operator sees your wallet) AND it strengthens the Wownero network by
|
||||||
// adding a peer — a deliberate differentiator we surface clearly here.
|
// adding a peer — a deliberate differentiator we surface clearly here.
|
||||||
m_localNodeCheck = new QCheckBox(tr("Run your own Wownero node (much recommended)"), this);
|
m_localNodeCheck = new QCheckBox(tr("Run your own Wownero node (many recommended)"), this);
|
||||||
m_localNodeCheck->setChecked(conf()->get(Config::runLocalNode).toBool());
|
m_localNodeCheck->setChecked(conf()->get(Config::runLocalNode).toBool());
|
||||||
auto *localNodeInfo = new QLabel(
|
auto *localNodeInfo = new QLabel(
|
||||||
tr("wowlet bundles its own node so you can be your own boss — and every node keeps the Wownero "
|
tr("wowlet runs your own Wownero node by default: be your own boss and help run the network. "
|
||||||
"network strong + decentralized. 🐕 Uncheck to use a remote node instead."), this);
|
"🐕 Uncheck to use a remote node instead."), this);
|
||||||
localNodeInfo->setWordWrap(true);
|
localNodeInfo->setWordWrap(true);
|
||||||
localNodeInfo->setStyleSheet("color: gray;");
|
localNodeInfo->setStyleSheet("color: gray;");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user