mirror of
https://github.com/wownero/wowlet.git
synced 2026-10-28 03:38:53 +01:00
Allow opening multiple windows
This commit is contained in:
+106
-64
@@ -5,7 +5,83 @@
|
||||
|
||||
#include "nodes.h"
|
||||
#include "utils/utils.h"
|
||||
#include "utils/tails.h"
|
||||
#include "appcontext.h"
|
||||
#include "constants.h"
|
||||
#include "utils/WebsocketNotifier.h"
|
||||
#include "utils/TorManager.h"
|
||||
|
||||
bool NodeList::addNode(const QString &node, NetworkType::Type networkType, NodeList::Type source) {
|
||||
// We can't obtain references to QJsonObjects...
|
||||
|
||||
QJsonObject obj = config()->get(Config::nodes).toJsonObject();
|
||||
this->ensureStructure(obj, networkType);
|
||||
|
||||
QString networkTypeStr = QString::number(networkType);
|
||||
QJsonObject netTypeObj = obj.value(networkTypeStr).toObject();
|
||||
|
||||
QString sourceStr = Utils::QtEnumToString(source);
|
||||
QJsonArray sourceArray = netTypeObj.value(sourceStr).toArray();
|
||||
|
||||
if (sourceArray.contains(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sourceArray.append(node);
|
||||
|
||||
netTypeObj[sourceStr] = sourceArray;
|
||||
obj[networkTypeStr] = netTypeObj;
|
||||
|
||||
config()->set(Config::nodes, obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
void NodeList::setNodes(const QStringList &nodes, NetworkType::Type networkType, NodeList::Type source) {
|
||||
QJsonObject obj = config()->get(Config::nodes).toJsonObject();
|
||||
this->ensureStructure(obj, networkType);
|
||||
|
||||
QString networkTypeStr = QString::number(networkType);
|
||||
QJsonObject netTypeObj = obj.value(networkTypeStr).toObject();
|
||||
|
||||
QString sourceStr = Utils::QtEnumToString(source);
|
||||
QJsonArray sourceArray = QJsonArray::fromStringList(nodes);
|
||||
|
||||
netTypeObj[sourceStr] = sourceArray;
|
||||
obj[networkTypeStr] = netTypeObj;
|
||||
|
||||
config()->set(Config::nodes, obj);
|
||||
}
|
||||
|
||||
QStringList NodeList::getNodes(NetworkType::Type networkType, NodeList::Type source) {
|
||||
QJsonObject obj = config()->get(Config::nodes).toJsonObject();
|
||||
|
||||
QString networkTypeStr = QString::number(networkType);
|
||||
QJsonObject netTypeObj = obj.value(networkTypeStr).toObject();
|
||||
|
||||
QString sourceStr = Utils::QtEnumToString(source);
|
||||
QJsonArray sourceArray = netTypeObj.value(sourceStr).toArray();
|
||||
|
||||
QStringList nodes;
|
||||
for (const auto &node : sourceArray) {
|
||||
nodes << node.toString();
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
void NodeList::ensureStructure(QJsonObject &obj, NetworkType::Type networkType) {
|
||||
QString networkTypeStr = QString::number(networkType);
|
||||
|
||||
if (!obj.contains(networkTypeStr))
|
||||
obj[networkTypeStr] = QJsonObject();
|
||||
|
||||
QJsonObject netTypeObj = obj.value(networkTypeStr).toObject();
|
||||
if (!netTypeObj.contains("ws"))
|
||||
netTypeObj["ws"] = QJsonArray();
|
||||
if (!netTypeObj.contains("custom"))
|
||||
netTypeObj["custom"] = QJsonArray();
|
||||
|
||||
obj[networkTypeStr] = netTypeObj;
|
||||
}
|
||||
|
||||
Nodes::Nodes(AppContext *ctx, QObject *parent)
|
||||
: QObject(parent)
|
||||
@@ -16,50 +92,30 @@ Nodes::Nodes(AppContext *ctx, QObject *parent)
|
||||
{
|
||||
this->loadConfig();
|
||||
connect(m_ctx, &AppContext::walletRefreshed, this, &Nodes::onWalletRefreshed);
|
||||
connect(websocketNotifier(), &WebsocketNotifier::NodesReceived, this, &Nodes::onWSNodesReceived);
|
||||
}
|
||||
|
||||
void Nodes::loadConfig() {
|
||||
auto configNodes = config()->get(Config::nodes).toByteArray();
|
||||
auto key = QString::number(m_ctx->networkType);
|
||||
if (!Utils::validateJSON(configNodes)) {
|
||||
m_configJson[key] = QJsonObject();
|
||||
qCritical() << "Fixed malformed config key \"nodes\"";
|
||||
}
|
||||
|
||||
QJsonDocument doc = QJsonDocument::fromJson(configNodes);
|
||||
m_configJson = doc.object();
|
||||
|
||||
if (!m_configJson.contains(key))
|
||||
m_configJson[key] = QJsonObject();
|
||||
|
||||
auto obj = m_configJson.value(key).toObject();
|
||||
if (!obj.contains("custom"))
|
||||
obj["custom"] = QJsonArray();
|
||||
if (!obj.contains("ws"))
|
||||
obj["ws"] = QJsonArray();
|
||||
|
||||
// load custom nodes
|
||||
auto nodes = obj.value("custom").toArray();
|
||||
for (auto value: nodes) {
|
||||
auto customNode = FeatherNode(value.toString());
|
||||
QStringList customNodes = m_nodes.getNodes(constants::networkType, NodeList::custom);
|
||||
for (const auto &node : customNodes) {
|
||||
FeatherNode customNode{node};
|
||||
customNode.custom = true;
|
||||
|
||||
if(m_connection == customNode) {
|
||||
if(m_connection.isActive)
|
||||
if (m_connection == customNode) {
|
||||
if (m_connection.isActive)
|
||||
customNode.isActive = true;
|
||||
else if(m_connection.isConnecting)
|
||||
else if (m_connection.isConnecting)
|
||||
customNode.isConnecting = true;
|
||||
}
|
||||
|
||||
m_customNodes.append(customNode);
|
||||
}
|
||||
|
||||
// load cached websocket nodes
|
||||
auto ws = obj.value("ws").toArray();
|
||||
for (auto value: ws) {
|
||||
auto wsNode = FeatherNode(value.toString());
|
||||
QStringList websocketNodes = m_nodes.getNodes(constants::networkType, NodeList::ws);
|
||||
for (const auto &node : websocketNodes) {
|
||||
FeatherNode wsNode{node};
|
||||
wsNode.custom = false;
|
||||
wsNode.online = true; // assume online
|
||||
wsNode.online = true; // assume online
|
||||
|
||||
if (m_connection == wsNode) {
|
||||
if (m_connection.isActive)
|
||||
@@ -86,9 +142,9 @@ void Nodes::loadConfig() {
|
||||
QJsonObject nodes_obj = nodes_json.object();
|
||||
|
||||
QString netKey;
|
||||
if (m_ctx->networkType == NetworkType::MAINNET) {
|
||||
if (constants::networkType == NetworkType::MAINNET) {
|
||||
netKey = "mainnet";
|
||||
} else if (m_ctx->networkType == NetworkType::STAGENET) {
|
||||
} else if (constants::networkType == NetworkType::STAGENET) {
|
||||
netKey = "stagenet";
|
||||
}
|
||||
|
||||
@@ -96,30 +152,22 @@ void Nodes::loadConfig() {
|
||||
QJsonArray nodes_list;
|
||||
nodes_list = nodes_json[netKey].toObject()["tor"].toArray();
|
||||
nodes_list.append(nodes_list = nodes_json[netKey].toObject()["clearnet"].toArray());
|
||||
|
||||
for (auto node: nodes_list) {
|
||||
auto wsNode = FeatherNode(node.toString());
|
||||
FeatherNode wsNode(node.toString());
|
||||
wsNode.custom = false;
|
||||
wsNode.online = true;
|
||||
m_websocketNodes.append(wsNode);
|
||||
m_nodes.addNode(node.toString(), constants::networkType, NodeList::Type::ws);
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << QString("Loaded %1 nodes from hardcoded list").arg(m_websocketNodes.count());
|
||||
}
|
||||
|
||||
m_configJson[key] = obj;
|
||||
this->writeConfig();
|
||||
this->updateModels();
|
||||
}
|
||||
|
||||
void Nodes::writeConfig() {
|
||||
QJsonDocument doc(m_configJson);
|
||||
QString output(doc.toJson(QJsonDocument::Compact));
|
||||
config()->set(Config::nodes, output);
|
||||
|
||||
qDebug() << "Saved node config.";
|
||||
}
|
||||
|
||||
void Nodes::connectToNode() {
|
||||
// auto connect
|
||||
m_wsExhaustedWarningEmitted = false;
|
||||
@@ -135,10 +183,10 @@ void Nodes::connectToNode(const FeatherNode &node) {
|
||||
qInfo() << QString("Attempting to connect to %1 (%2)").arg(node.toAddress()).arg(node.custom ? "custom" : "ws");
|
||||
|
||||
if (!node.url.userName().isEmpty() && !node.url.password().isEmpty())
|
||||
m_ctx->currentWallet->setDaemonLogin(node.url.userName(), node.url.password());
|
||||
m_ctx->wallet->setDaemonLogin(node.url.userName(), node.url.password());
|
||||
|
||||
// Don't use SSL over Tor
|
||||
m_ctx->currentWallet->setUseSSL(!node.isOnion());
|
||||
m_ctx->wallet->setUseSSL(!node.isOnion());
|
||||
|
||||
QString proxyAddress;
|
||||
if (useTorProxy(node)) {
|
||||
@@ -150,7 +198,7 @@ void Nodes::connectToNode(const FeatherNode &node) {
|
||||
}
|
||||
}
|
||||
|
||||
m_ctx->currentWallet->initAsync(node.toAddress(), true, 0, false, false, 0, proxyAddress);
|
||||
m_ctx->wallet->initAsync(node.toAddress(), true, 0, false, false, 0, proxyAddress);
|
||||
|
||||
m_connection = node;
|
||||
m_connection.isActive = false;
|
||||
@@ -162,11 +210,11 @@ void Nodes::connectToNode(const FeatherNode &node) {
|
||||
|
||||
void Nodes::autoConnect(bool forceReconnect) {
|
||||
// this function is responsible for automatically connecting to a daemon.
|
||||
if (m_ctx->currentWallet == nullptr || !m_enableAutoconnect) {
|
||||
if (m_ctx->wallet == nullptr || !m_enableAutoconnect) {
|
||||
return;
|
||||
}
|
||||
|
||||
Wallet::ConnectionStatus status = m_ctx->currentWallet->connectionStatus();
|
||||
Wallet::ConnectionStatus status = m_ctx->wallet->connectionStatus();
|
||||
bool wsMode = (this->source() == NodeSource::websocket);
|
||||
|
||||
if (wsMode && !m_wsNodesReceived && websocketNodes().count() == 0) {
|
||||
@@ -276,15 +324,12 @@ void Nodes::onWSNodesReceived(QList<FeatherNode> &nodes) {
|
||||
}
|
||||
|
||||
// cache into config
|
||||
auto key = QString::number(m_ctx->networkType);
|
||||
auto obj = m_configJson.value(key).toObject();
|
||||
auto ws = QJsonArray();
|
||||
for (auto const &node: m_websocketNodes)
|
||||
ws.push_back(node.toAddress());
|
||||
QStringList wsNodeList;
|
||||
for (const auto &node : m_websocketNodes) {
|
||||
wsNodeList << node.toAddress();
|
||||
}
|
||||
m_nodes.setNodes(wsNodeList, constants::networkType, NodeList::ws);
|
||||
|
||||
obj["ws"] = ws;
|
||||
m_configJson[key] = obj;
|
||||
this->writeConfig();
|
||||
this->resetLocalState();
|
||||
this->updateModels();
|
||||
}
|
||||
@@ -297,20 +342,17 @@ void Nodes::onNodeSourceChanged(NodeSource nodeSource) {
|
||||
|
||||
void Nodes::setCustomNodes(const QList<FeatherNode> &nodes) {
|
||||
m_customNodes.clear();
|
||||
auto key = QString::number(m_ctx->networkType);
|
||||
auto obj = m_configJson.value(key).toObject();
|
||||
|
||||
QStringList nodesList;
|
||||
for (auto const &node: nodes) {
|
||||
if (nodesList.contains(node.toAddress())) continue;
|
||||
if (nodesList.contains(node.toAddress())) // skip duplicates
|
||||
continue;
|
||||
nodesList.append(node.toAddress());
|
||||
m_customNodes.append(node);
|
||||
}
|
||||
|
||||
auto arr = QJsonArray::fromStringList(nodesList);
|
||||
obj["custom"] = arr;
|
||||
m_configJson[key] = obj;
|
||||
this->writeConfig();
|
||||
m_nodes.setNodes(nodesList, constants::networkType, NodeList::Type::custom);
|
||||
|
||||
this->resetLocalState();
|
||||
this->updateModels();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user