diff --git a/src/StorageBackend.cpp b/src/StorageBackend.cpp
index 34393e9..d534e7c 100644
--- a/src/StorageBackend.cpp
+++ b/src/StorageBackend.cpp
@@ -47,7 +47,7 @@ LogosResult StorageBackend::init(const QString& configJson) {
m_config = QJsonDocument::fromJson(configJson.toUtf8());
if (m_config.isNull()) {
qDebug() << "StorageBackend::initStorage invalid json config" << configJson;
- emit initFailed();
+ reportError("Failed to create the storage: invalid JSON config");
return {false, "", "Failed to create the storage, invalid json config"};
}
@@ -57,9 +57,8 @@ LogosResult StorageBackend::init(const QString& configJson) {
if (!result) {
setStatus(Destroyed);
- debug("Failed to init storage");
- emit initFailed();
- return {false, "", "Filed to init storage"};
+ reportError("Failed to init storage");
+ return {false, "", "Failed to init storage"};
}
setStatus(Stopped);
@@ -72,6 +71,7 @@ LogosResult StorageBackend::init(const QString& configJson) {
setStatus(Stopped);
debug("Failed to start Storage module:" + message);
emit startFailed(message);
+ reportError("Failed to start: " + message);
} else {
setStatus(Running);
debug("Storage module started.");
@@ -237,6 +237,8 @@ LogosResult StorageBackend::start(const QString& newConfigJson) {
setStatus(Starting);
debug("Starting Storage module...");
+ // TODO trach the start attempts in a file
+
auto result = m_logos->storage_module.start();
if (!result) {
@@ -295,6 +297,11 @@ void StorageBackend::destroy() {
QString StorageBackend::debugLogs() const { return m_debugLogs; };
+void StorageBackend::reportError(const QString& message) {
+ debug(message);
+ emit error(message);
+}
+
void StorageBackend::debug(const QString& log) {
if (!m_debugLogs.isEmpty()) {
m_debugLogs += "\n";
@@ -866,36 +873,38 @@ void StorageBackend::enableNatExtConfig(int tcpPort) {
QJsonArray listenAddrs = {QString("/ip4/0.0.0.0/tcp/%1").arg(tcpPort)};
obj["listen-addrs"] = listenAddrs;
+ reloadIfChanged(QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact)));
+
qDebug() << "StorageBackend::enableNatExtConfig Retrieving the public IP";
-
+ emit natExtConfigCompleted();
// Create the network manager
- QNetworkAccessManager* manager = new QNetworkAccessManager(this);
- QNetworkRequest request(QUrl("https://echo.codex.storage/"));
- request.setRawHeader("Accept", "text/plain");
- QNetworkReply* reply = manager->get(request);
+ // QNetworkAccessManager* manager = new QNetworkAccessManager(this);
+ // QNetworkRequest request(QUrl("https://echo.codex.storage/"));
+ // request.setRawHeader("Accept", "text/plain");
+ // QNetworkReply* reply = manager->get(request);
- connect(reply, &QNetworkReply::finished, this, [this, reply, manager, obj]() {
- reply->deleteLater();
- manager->deleteLater();
+ // connect(reply, &QNetworkReply::finished, this, [this, reply, manager, obj]() {
+ // reply->deleteLater();
+ // manager->deleteLater();
- if (reply->error() != QNetworkReply::NoError) {
- emit natExtConfigFailed(reply->errorString());
- return;
- }
+ // if (reply->error() != QNetworkReply::NoError) {
+ // reportError("NAT config failed: " + reply->errorString());
+ // return;
+ // }
- QString ip = reply->readAll().trimmed();
+ // QString ip = reply->readAll().trimmed();
- qDebug() << "StorageBackend::enableNatExtConfig ip=" << ip;
+ // qDebug() << "StorageBackend::enableNatExtConfig ip=" << ip;
- obj["nat"] = "extip:" + ip;
+ // obj["nat"] = "extip:" + ip;
- qDebug() << "StorageBackend::enableNatExtConfig config="
- << QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact));
+ // qDebug() << "StorageBackend::enableNatExtConfig config="
+ // << QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact));
- reloadIfChanged(QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact)));
+ // reloadIfChanged(QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact)));
- emit natExtConfigCompleted();
- });
+ // emit natExtConfigCompleted();
+ // });
}
void StorageBackend::status(StorageStatus status) { m_status = status; }
diff --git a/src/StorageBackend.h b/src/StorageBackend.h
index 39db7f7..8442ea1 100644
--- a/src/StorageBackend.h
+++ b/src/StorageBackend.h
@@ -133,6 +133,25 @@ class StorageBackend : public QObject {
// and re-create a context with the new configuration
void enableNatExtConfig(int tcpPort);
+ // This method try to get guidance about the resolution
+ // of the misconfiguration for the node.
+ // The idea is to check if:
+ //
+ // 1- upnp is enabled. In this case, the user should go back
+ // and try to configure the port forwarding
+ // 2- port forwarning is enabled. Indicate that the port has to
+ // be free and open to remote connection.
+ void guessResolution();
+
+ // This method will ensure that the node is ready to be used.
+ // 1- Make a call to debug function in the storage module and
+ // make sure that the node has peer. If not, the UI should suggest
+ // to modifiy the discovery port (8090) in the advance settings (to come).
+ // 2- Ensure that the tcp port is open to remote connection. If not,
+ // the UI should suggest to change go back and try another port and double
+ // check that the port forwarding is enabled on the router.
+ void checkNodeIsUp();
+
signals:
void ready();
void startCompleted();
@@ -146,9 +165,8 @@ class StorageBackend : public QObject {
void manifestsChanged();
void quotaChanged();
void initCompleted();
- void initFailed();
- void natExtConfigFailed(const QString& error);
void natExtConfigCompleted();
+ void error(const QString& message);
private slots:
@@ -156,6 +174,7 @@ class StorageBackend : public QObject {
void setStatus(StorageStatus newStatus);
void peerConnect(const QString& peerId);
void debug(const QString& log);
+ void reportError(const QString& message);
LogosAPI* m_logosAPI;
LogosModules* m_logos;
diff --git a/src/StorageUIPlugin.cpp b/src/StorageUIPlugin.cpp
index 622a6a3..0513c92 100644
--- a/src/StorageUIPlugin.cpp
+++ b/src/StorageUIPlugin.cpp
@@ -102,13 +102,13 @@ void StorageUIPlugin::destroyWidget(QWidget* widget) {
return;
}
- if (backend->status() != StorageBackend::StorageStatus::Destroyed) {
- qDebug() << "StorageUIPlugin::destroyWidget: backend is not initialised so let's detroy it.";
+ if (backend->status() == StorageBackend::StorageStatus::Destroyed) {
+ qDebug() << "StorageUIPlugin::destroyWidget: backend is not initialised so let's delete the widget.";
quickWidget->deleteLater();
return;
}
- if (backend->status() == StorageBackend::StorageStatus::Running) {
+ if (backend->status() != StorageBackend::StorageStatus::Running) {
qDebug() << "StorageUIPlugin::destroyWidget: backend is not running so let's detroy it.";
backend->destroy();
diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt
index a373110..b7e8697 100644
--- a/src/qml/CMakeLists.txt
+++ b/src/qml/CMakeLists.txt
@@ -134,6 +134,7 @@ qt_add_qml_module(appqml
LogosStorageButton.qml
LogosStorageLayout.qml
PortForwarding.qml
+ ErrorToast.qml
)
# Set up QML module directory for runtime
diff --git a/src/qml/ErrorToast.qml b/src/qml/ErrorToast.qml
index 7b996e2..0a5c30f 100644
--- a/src/qml/ErrorToast.qml
+++ b/src/qml/ErrorToast.qml
@@ -9,26 +9,53 @@ Rectangle {
property alias title: titleText.text
property alias message: messageText.text
- function show(t, msg) {
- root.title = t
- root.message = msg
+ function show(title, message) {
+ root.title = title
+ root.message = message
root.visible = true
slideAnim.restart()
}
function hide() {
- root.visible = false
+ hideAnim.restart()
}
visible: false
opacity: 0
width: 500
radius: Theme.spacing.tiny
- color: "#1e1e1e"
+ color: "#3D2020"
implicitHeight: content.implicitHeight + Theme.spacing.medium * 2
- transform: Translate { id: slideTranslate; y: 20 }
+ transform: Translate {
+ id: slideTranslate
+ y: 20
+ }
+
+ ParallelAnimation {
+ id: hideAnim
+
+ NumberAnimation {
+ target: slideTranslate
+ property: "y"
+ from: 0
+ to: 20
+ duration: 300
+ easing.type: Easing.InCubic
+ }
+
+ NumberAnimation {
+ target: root
+ property: "opacity"
+ from: 1
+ to: 0
+ duration: 300
+ easing.type: Easing.InCubic
+ }
+
+ onFinished: root.visible = false
+ }
ParallelAnimation {
id: slideAnim
@@ -52,6 +79,23 @@ Rectangle {
}
}
+ // Close button top right
+ LogosText {
+ text: "x"
+ font.pixelSize: Theme.typography.primaryText
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.margins: Theme.spacing.small
+ z: 1
+ color: Theme.palette.text
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ onClicked: root.hide()
+ }
+ }
+
ColumnLayout {
id: content
anchors {
@@ -62,28 +106,12 @@ Rectangle {
}
spacing: Theme.spacing.tiny
- RowLayout {
+ LogosText {
+ id: titleText
Layout.fillWidth: true
-
- LogosText {
- id: titleText
- Layout.fillWidth: true
- color: Theme.palette.error
- font.pixelSize: Theme.typography.primaryText
- font.bold: true
- }
-
- LogosText {
- text: "✕"
- color: Theme.palette.textMuted
- font.pixelSize: Theme.typography.primaryText
-
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onClicked: root.hide()
- }
- }
+ color: Theme.palette.error
+ font.pixelSize: Theme.typography.primaryText
+ font.bold: true
}
LogosText {
diff --git a/src/qml/Main.qml b/src/qml/Main.qml
index 83fa598..bdef8bc 100644
--- a/src/qml/Main.qml
+++ b/src/qml/Main.qml
@@ -1,6 +1,7 @@
import QtQuick
import QtQuick.Controls
import QtCore
+import Logos.Theme
// qmllint disable unqualified
Item {
@@ -20,6 +21,9 @@ Item {
signal startFailed
signal stopCompleted
signal initCompleted
+ signal ready
+ signal error
+ signal natExtConfigCompleted
function start() {
console.log("mock start called")
@@ -38,6 +42,8 @@ Item {
function saveCurrentConfig() {}
function stop() {}
+
+ function guessResolution() {}
}
Settings {
@@ -61,13 +67,23 @@ Item {
initialItem: onboardingComponent
}
+ ErrorToast {
+ id: errorToast
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: Theme.spacing.medium
+ }
+
Component {
id: onboardingComponent
OnBoarding {
onCompleted: function (upnpEnabled) {
+ console.info("onboarding completed")
if (upnpEnabled) {
root.backend.enableUpnpConfig()
+ root.backend.start()
+ stackView.push(startNodeComponent)
} else {
stackView.push(portForwardingComponent)
}
@@ -122,16 +138,16 @@ Item {
function onInitCompleted() {}
function onReady() {
- console.info("i am ready")
if (settings.onboardingCompleted) {
- console.info("onboardingCompleted completed")
root.backend.loadUserConfig()
root.backend.start()
stackView.replace(storageComponent, StackView.Immediate)
}
}
- function onNatExtConfigFailed(error) {}
+ function onError(message) {
+ errorToast.show("Error", message)
+ }
function onNatExtConfigCompleted(error) {
root.backend.start()
diff --git a/src/qml/StartNode.qml b/src/qml/StartNode.qml
index 2ee5499..c92d345 100644
--- a/src/qml/StartNode.qml
+++ b/src/qml/StartNode.qml
@@ -10,6 +10,7 @@ LogosStorageLayout {
property var backend: mockBackend
property string status: ""
property string title: "Starting your node...."
+ property string resolution: ""
property bool starting: true
property bool success: false
@@ -56,6 +57,8 @@ LogosStorageLayout {
root.title = "Error"
root.status = "Failed to start: " + error
}
+
+ function guessResolution() {}
}
ColumnLayout {
@@ -76,6 +79,13 @@ LogosStorageLayout {
text: root.status
Layout.alignment: Qt.AlignHCenter
}
+
+ LogosText {
+ id: suggestionText
+ font.pixelSize: Theme.typography.primaryText
+ text: root.suggestion
+ Layout.alignment: Qt.AlignHCenter
+ }
}
LogosStorageButton {
@@ -97,4 +107,14 @@ LogosStorageLayout {
onClicked: root.next()
enabled: root.success == true
}
+
+ Connections {
+ target: root.backend
+
+ function onStartFailed(error) {
+ root.title = "Erreur"
+ root.status = "Your node failed to start with this error: " + error
+ root.method = root.backend.guessResolution()
+ }
+ }
}
diff --git a/src/qml/main.cpp b/src/qml/main.cpp
index 5666f0b..6c9f90a 100644
--- a/src/qml/main.cpp
+++ b/src/qml/main.cpp
@@ -19,7 +19,7 @@ int main(int argc, char* argv[]) {
Qt::QueuedConnection);
engine.addImportPath(QCoreApplication::applicationDirPath() + "/qml");
- engine.loadFromModule("StorageBackend", "OnBoarding");
+ engine.loadFromModule("StorageBackend", "Main");
return app.exec();
}
diff --git a/src/storage_resources.qrc b/src/storage_resources.qrc
index fff4020..a43bd09 100644
--- a/src/storage_resources.qrc
+++ b/src/storage_resources.qrc
@@ -8,5 +8,6 @@
qml/LogosStorageButton.qml
qml/LogosStorageLayout.qml
qml/PortForwarding.qml
+ qml/ErrorToast.qml