diff --git a/src/StorageBackend.cpp b/src/StorageBackend.cpp index 0f591d6..8c3d2b1 100644 --- a/src/StorageBackend.cpp +++ b/src/StorageBackend.cpp @@ -145,26 +145,9 @@ LogosResult StorageBackend::init(const QString& configJson) { if (!success) { QString message = data[1].toString(); reportError("Failure during upload progress: " + message); - - m_uploadStatus = "Error: " + message; - emit uploadStatusChanged(); } else { - QString sessionId = data[1].toString(); qint64 len = data[2].toLongLong(); - - m_uploadedBytes += len; - - if (m_uploadTotalBytes > 0) { - m_uploadProgress = (m_uploadedBytes * 100) / m_uploadTotalBytes; - } - - m_uploadStatus = QString("Uploading: %1 / %2 bytes (%3%)") - .arg(m_uploadedBytes) - .arg(m_uploadTotalBytes) - .arg(m_uploadProgress); - - emit uploadProgressChanged(); - emit uploadStatusChanged(); + emit uploadChunk(len); } })) { qWarning() << "StorageWidget: failed to subscribe to storageUploadProgress events"; @@ -175,20 +158,11 @@ LogosResult StorageBackend::init(const QString& configJson) { if (!success) { QString message = data[1].toString(); - debug("Failed to upload: " + message); - m_uploadProgress = 0; - m_uploadStatus = "Upload failed"; - emit uploadProgressChanged(); - emit uploadStatusChanged(); + reportError("Failed to upload: " + message); } else { QString sessionId = data[1].toString(); QString cid = data[2].toString(); debug("Upload completed for session " + sessionId + " with CID " + cid); - - m_uploadProgress = 100; - m_uploadStatus = "Upload completed!"; - emit uploadProgressChanged(); - emit uploadStatusChanged(); emit uploadCompleted(cid); QMetaObject::invokeMethod(this, &StorageBackend::refreshSpace, Qt::QueuedConnection); QMetaObject::invokeMethod(this, &StorageBackend::downloadManifests, Qt::QueuedConnection); @@ -361,16 +335,9 @@ void StorageBackend::uploadFile(const QUrl& url) { return; } - // Reset and initialize progress tracking - m_uploadProgress = 0; - m_uploadedBytes = 0; - m_uploadTotalBytes = QFileInfo(url.toLocalFile()).size(); - m_uploadStatus = "Starting upload..."; - - emit uploadProgressChanged(); - emit uploadStatusChanged(); - - debug(QString("Starting upload of file: %1 bytes").arg(m_uploadTotalBytes)); + qint64 totalBytes = QFileInfo(url.toLocalFile()).size(); + debug(QString("Starting upload of file: %1 bytes").arg(totalBytes)); + emit uploadStarted(totalBytes); LogosResult result = m_logos->storage_module.uploadUrl(url); @@ -836,6 +803,3 @@ QString StorageBackend::configJson() const { return QString::fromUtf8(m_config.t StorageBackend::StorageStatus StorageBackend::status() const { return m_status; } -int StorageBackend::uploadProgress() const { return m_uploadProgress; } - -QString StorageBackend::uploadStatus() const { return m_uploadStatus; } diff --git a/src/StorageBackend.h b/src/StorageBackend.h index acd3356..3113aac 100644 --- a/src/StorageBackend.h +++ b/src/StorageBackend.h @@ -36,8 +36,6 @@ class StorageBackend : public QObject { QML_ELEMENT Q_PROPERTY(QString debugLogs READ debugLogs NOTIFY debugLogsChanged) Q_PROPERTY(StorageStatus status READ status NOTIFY statusChanged) - Q_PROPERTY(int uploadProgress READ uploadProgress NOTIFY uploadProgressChanged) - Q_PROPERTY(QString uploadStatus READ uploadStatus NOTIFY uploadStatusChanged) public: enum StorageStatus { // Stopped means that the context is created but the module is not started @@ -57,8 +55,6 @@ class StorageBackend : public QObject { QString debugLogs() const; StorageStatus status() const; - int uploadProgress() const; - QString uploadStatus() const; Q_INVOKABLE QString configJson() const; // Provide a default config for onboarding @@ -108,8 +104,9 @@ class StorageBackend : public QObject { void fetch(const QString& cid); // Upload a file from the url - // Emit uploadProgressChanged and uploadStatusChanged on storageUploadProgress - // Emit uploadProgressChanged, uploadStatusChanged and uploadCompleted(cid) on storageUploadDone + // Emit uploadStarted(totalBytes) when the upload begins + // Emit uploadChunk(len) on each storageUploadProgress event + // Emit uploadCompleted(cid) on storageUploadDone void uploadFile(const QUrl& url); // Upload a file from the url @@ -202,8 +199,11 @@ class StorageBackend : public QObject { // Used to refresh the disk widgets void spaceUpdated(qlonglong total, qlonglong used); - void uploadProgressChanged(); - void uploadStatusChanged(); + // Emitted when an upload starts, with the total file size + void uploadStarted(qint64 totalBytes); + + // Emitted for each chunk received during upload + void uploadChunk(qint64 len); // Used to refresh the Manifests table void manifestsUpdated(const QVariantList& manifests); @@ -254,14 +254,6 @@ class StorageBackend : public QObject { // List of debug logs displayed to the application. QString m_debugLogs; - // TODO: double check if we need all of this parameters - // We could just have the progress passed using event and - // the error using reportError - int m_uploadProgress = 0; - QString m_uploadStatus = ""; - qint64 m_uploadTotalBytes = 0; - qint64 m_uploadedBytes = 0; - // Internal configuration object. It can be updated by // upnp or port forwarning methods. QJsonDocument m_config; diff --git a/src/qml/StorageView.qml b/src/qml/StorageView.qml index 0739ba1..f9842db 100644 --- a/src/qml/StorageView.qml +++ b/src/qml/StorageView.qml @@ -32,12 +32,12 @@ LogosStorageLayout { id: mockBackend property var status: 0 property var debugLogs: "Hello!" - property string uploadStatus: "" - property int uploadProgress: 0 property var manifests: [] signal nodeIsUp signal nodeIsntUp(string reason) signal peersUpdated(int count) + signal uploadStarted(real totalBytes) + signal uploadChunk(real len) signal uploadCompleted(string cid) signal downloadCompleted(string cid) diff --git a/src/qml/UploadWidget.qml b/src/qml/UploadWidget.qml index 3d5525d..ce3f8f2 100644 --- a/src/qml/UploadWidget.qml +++ b/src/qml/UploadWidget.qml @@ -6,14 +6,40 @@ import Logos.Controls ArcWidget { id: root - property int uploadProgress: 0 // 0–100 + property var backend property bool running: false + property real totalBytes: 0 + property real uploadedBytes: 0 + + readonly property int uploadProgress: { + if (totalBytes <= 0) { + return 0 + } + return Math.min(Math.round(uploadedBytes / totalBytes * 100), 100) + } + + signal uploadRequested readonly property bool isUploading: uploadProgress > 0 && uploadProgress < 100 readonly property bool isDone: uploadProgress >= 100 - signal uploadRequested + Connections { + target: root.backend + + function onUploadStarted(totalBytes) { + root._totalBytes = totalBytes + root._uploadedBytes = 0 + } + + function onUploadChunk(len) { + root.uploadedBytes += len + } + + function onUploadCompleted(cid) { + root._uploadedBytes = root.totalBytes // force 100% + } + } fraction: root.uploadProgress / 100.0 fillColor: root.isDone ? Theme.palette.success : Theme.palette.text diff --git a/src/qml/Widgets.qml b/src/qml/Widgets.qml index d863718..6a0ff90 100644 --- a/src/qml/Widgets.qml +++ b/src/qml/Widgets.qml @@ -44,7 +44,7 @@ ColumnLayout { spacing: Theme.spacing.medium UploadWidget { - uploadProgress: root.backend.uploadProgress + backend: root.backend running: root.running onUploadRequested: uploadDialog.open() }