From 8c56e35f69f71d0d648cb8b313b2b7407307da1c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Sun, 23 Dec 2018 00:13:01 -0800 Subject: [PATCH] Add granular status to avatar upload --- .../qml/hifi/avatarPackager/AvatarProject.qml | 4 +- .../avatarPackager/AvatarProjectUpload.qml | 163 +++++++----------- .../src/avatar/MarketplaceItemUploader.cpp | 29 ++-- .../src/avatar/MarketplaceItemUploader.h | 10 +- 4 files changed, 93 insertions(+), 113 deletions(-) diff --git a/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml b/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml index 669748e7c9..81afacf28c 100644 --- a/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml +++ b/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml @@ -25,8 +25,10 @@ Item { property var footer: Item { id: uploadFooter + anchors.fill: parent anchors.rightMargin: 17 + HifiControls.Button { id: uploadButton enabled: Account.loggedIn @@ -64,7 +66,7 @@ Item { root.uploader.uploadProgress.connect(function(uploaded, total) { console.log("Uploader progress: " + uploaded + " / " + total); }); - root.uploader.completed.connect(function() { + root.uploader.finished.connect(function() { try { var response = JSON.parse(root.uploader.responseData); console.log("Uploader complete! " + response); diff --git a/interface/resources/qml/hifi/avatarPackager/AvatarProjectUpload.qml b/interface/resources/qml/hifi/avatarPackager/AvatarProjectUpload.qml index bbeca6ab3b..6e011b1ec7 100644 --- a/interface/resources/qml/hifi/avatarPackager/AvatarProjectUpload.qml +++ b/interface/resources/qml/hifi/avatarPackager/AvatarProjectUpload.qml @@ -28,7 +28,7 @@ Item { onVisibleChanged: { console.log("Visibility changed"); if (visible) { - root.uploader.completed.connect(function() { + root.uploader.finished.connect(function() { console.log("Did complete"); backToProjectTimer.start(); }); @@ -36,127 +36,94 @@ Item { } Item { - visible: !!root.uploader && !root.uploader.complete + id: uploadStatus + + visible: !!root.uploader anchors.fill: parent - AnimatedImage { - id: uploadSpinner + Item { + id: statusItem - anchors { - horizontalCenter: parent.horizontalCenter - verticalCenter: parent.verticalCenter + width: parent.width + height: 128 + + AnimatedImage { + id: uploadSpinner + + visible: !!root.uploader && !root.uploader.complete + + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } + + source: "../../../icons/loader-snake-64-w.gif" + playing: true + z: 10000 } - source: "../../../icons/loader-snake-64-w.gif" - playing: true - z: 10000 - } - } + HiFiGlyphs { + id: errorIcon + visible: !!root.uploader && root.uploader.complete && root.uploader.error !== 0 - Item { - id: failureScreen + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } - visible: !!root.uploader && root.uploader.complete && root.uploader.error !== 0 - - anchors.fill: parent - - HiFiGlyphs { - id: errorIcon - - anchors { - horizontalCenter: parent.horizontalCenter - verticalCenter: parent.verticalCenter + size: 128 + text: "w" + color: "red" } - size: 128 - text: "w" - color: "red" - } + HiFiGlyphs { + id: successIcon - Column { - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: errorIcon.bottom - Text { - anchors.horizontalCenter: parent.horizontalCenter + visible: !!root.uploader && root.uploader.complete && root.uploader.error === 0 - text: "Error" - font.pointSize: 24 + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } - color: "white" - } - Text { - text: "Your avatar has not been uploaded." - font.pointSize: 16 - - anchors.horizontalCenter: parent.horizontalCenter - - color: "white" + size: 128 + text: "\ue01a" + color: "#1FC6A6" } } - } + Item { + id: statusRows - Item { - id: successScreen + anchors.top: statusItem.bottom - visible: !!root.uploader && root.uploader.complete && root.uploader.error === 0 + AvatarUploadStatusItem { + id: statusCategories + text: "Retreiving categories" - anchors.fill: parent - - HiFiGlyphs { - id: successIcon - - anchors { - horizontalCenter: parent.horizontalCenter - verticalCenter: parent.verticalCenter + state: root.uploader.state == 1 ? "running" : (root.uploader.state > 1 ? "success" : (root.uploader.error ? "fail" : "")) } + AvatarUploadStatusItem { + id: statusUploading + anchors.top: statusCategories.bottom + text: "Uploading data" - size: 128 - text: "\ue01a" - color: "#1FC6A6" - } - - Column { - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: successIcon.bottom - - Text { - id: successText - - anchors.horizontalCenter: parent.horizontalCenter - - text: "Congratulations!" - font.pointSize: 24 - - color: "white" + state: root.uploader.state == 2 ? "running" : (root.uploader.state > 2 ? "success" : (root.uploader.error ? "fail" : "")) } - Text { - text: "Your avatar has been uploaded." - font.pointSize: 16 + // TODO add waiting for response + //AvatarUploadStatusItem { + //id: statusResponse + //text: "Waiting for completion" + //} + AvatarUploadStatusItem { + id: statusInventory + anchors.top: statusUploading.bottom + text: "Waiting for inventory" - anchors.horizontalCenter: parent.horizontalCenter - - color: "white" + state: root.uploader.state == 3 ? "running" : (root.uploader.state > 3 ? "success" : (root.uploader.error ? "fail" : "")) } } - HifiControls.Button { - width: implicitWidth - height: implicitHeight - - anchors.bottom: parent.bottom - anchors.right: parent.right - - text: "View in Inventory" - - color: hifi.buttons.blue - colorScheme: root.colorScheme - onClicked: function() { - console.log("Opening in inventory"); - - AvatarPackagerCore.currentAvatarProject.openInInventory(); - } - } } Column { @@ -165,8 +132,6 @@ Item { visible: false Text { - id: uploadStatus - text: "Uploading" color: "white" diff --git a/interface/src/avatar/MarketplaceItemUploader.cpp b/interface/src/avatar/MarketplaceItemUploader.cpp index 1559f359a7..0a14ea9af4 100644 --- a/interface/src/avatar/MarketplaceItemUploader.cpp +++ b/interface/src/avatar/MarketplaceItemUploader.cpp @@ -39,15 +39,25 @@ MarketplaceItemUploader::MarketplaceItemUploader(QString title, } void MarketplaceItemUploader::setState(State newState) { + Q_ASSERT(newState != _state); qDebug() << "Setting uploader state to: " << newState; _state = newState; emit stateChanged(newState); if (newState == State::Complete) { emit completed(); + emit finished(); } } +void MarketplaceItemUploader::setError(Error error) { + Q_ASSERT(_error == Error::None); + + _error = error; + emit errorChanged(error); + emit finished(); +} + void MarketplaceItemUploader::send() { doGetCategories(); } @@ -105,14 +115,12 @@ void MarketplaceItemUploader::doGetCategories() { qDebug() << "Done " << success << id; if (!success) { qWarning() << "Failed to find marketplace category id"; - _error = Error::Unknown; - setState(State::Complete); + setError(Error::Unknown); } else { doUploadAvatar(); } } else { - _error = Error::Unknown; - setState(State::Complete); + setError(Error::Unknown); } }); } @@ -132,8 +140,7 @@ void MarketplaceItemUploader::doUploadAvatar() { QuaZipFile zipFile{ &zip }; if (!zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileInfo.fileName()))) { qWarning() << "Could not open zip file:" << zipFile.getZipError(); - _error = Error::Unknown; - setState(State::Complete); + setError(Error::Unknown); return; } QFile file{ filePath }; @@ -204,14 +211,13 @@ void MarketplaceItemUploader::doUploadAvatar() { if (status == "success") { _marketplaceID = QUuid::fromString(doc["data"].toObject()["marketplace_id"].toString()); _itemVersion = doc["data"].toObject()["version"].toDouble(); + setState(State::WaitingForInventory); doWaitForInventory(); } else { - _error = Error::Unknown; - setState(State::Complete); + setError(Error::Unknown); } } else { - _error = Error::Unknown; - setState(State::Complete); + setError(Error::Unknown); } }); @@ -282,8 +288,7 @@ void MarketplaceItemUploader::doWaitForInventory() { } else { qDebug() << "Failed to find item in inventory"; if (_numRequestsForInventory > 8) { - _error = Error::Unknown; - setState(State::Complete); + setError(Error::Unknown); } else { QTimer::singleShot(5000, [this]() { doWaitForInventory(); }); } diff --git a/interface/src/avatar/MarketplaceItemUploader.h b/interface/src/avatar/MarketplaceItemUploader.h index 9cfd531aca..1b1589af96 100644 --- a/interface/src/avatar/MarketplaceItemUploader.h +++ b/interface/src/avatar/MarketplaceItemUploader.h @@ -23,7 +23,7 @@ class MarketplaceItemUploader : public QObject { Q_PROPERTY(bool complete READ getComplete NOTIFY stateChanged) Q_PROPERTY(State state READ getState NOTIFY stateChanged) - Q_PROPERTY(Error error READ getError) + Q_PROPERTY(Error error READ getError NOTIFY errorChanged) Q_PROPERTY(QString responseData READ getResponseData) public: enum class Error @@ -51,11 +51,14 @@ public: Q_INVOKABLE void send(); + void setError(Error error); + QString getResponseData() const { return _responseData; } void setState(State newState); State getState() const { return _state; } bool getComplete() const { return _state == State::Complete; } + QUuid getMarketplaceID() const { return _marketplaceID; } Error getError() const { return _error; } @@ -63,7 +66,12 @@ public: signals: void uploadProgress(qint64 bytesSent, qint64 bytesTotal); void completed(); + void stateChanged(State newState); + void errorChanged(Error error); + + // Triggered when the upload has finished, either succesfully completing, or stopping with an error + void finished(); private: void doGetCategories();