diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml
index dd0c341412..562ceb1cc1 100644
--- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml
+++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml
@@ -137,11 +137,27 @@ Rectangle {
console.log("Failed to get Available Updates", result.data.message);
} else {
root.availableUpdatesReceived = true;
- if (result.data.updates.indexOf(root.itemId) > -1) {
- root.isUpdating = true;
+ for (var i = 0; i < result.data.updates.length; i++) {
+ if (result.data.updates[i].item_id === root.itemId) {
+ root.isUpdating = true;
+ break;
+ }
}
}
}
+
+ onUpdateItemResult: {
+ if (result.status !== 'success') {
+ failureErrorText.text = result.message;
+ root.activeView = "checkoutFailure";
+ } else {
+ root.itemHref = result.data.download_url;
+ if (result.data.categories.indexOf("Wearables") > -1) {
+ root.itemType = "wearable";
+ }
+ root.activeView = "checkoutSuccess";
+ }
+ }
}
onItemIdChanged: {
@@ -447,7 +463,7 @@ Rectangle {
id: itemPriceText;
text: root.isUpdating ? "FREE\nUPGRADE" : ((root.itemPrice === -1) ? "--" : root.itemPrice);
// Text size
- size: 26;
+ size: root.isUpdating ? 20 : 26;
// Anchors
anchors.top: parent.top;
anchors.right: parent.right;
@@ -569,7 +585,9 @@ Rectangle {
text: root.isUpdating ? "CONFIRM UPDATE" : (((root.isCertified) ? ((ownershipStatusReceived && balanceReceived && availableUpdatesReceived) ?
(viewInMyPurchasesButton.visible ? "Buy It Again" : "Confirm Purchase") : "--") : "Get Item"));
onClicked: {
- if (root.isCertified) {
+ if (root.isUpdating) {
+ Commerce.updateItem(root.itemId);
+ } else if (root.isCertified) {
if (!root.shouldBuyWithControlledFailure) {
if (root.itemType === "contentSet" && !Entities.canReplaceContent()) {
lightboxPopup.titleText = "Purchase Content Set";
@@ -1020,12 +1038,12 @@ Rectangle {
switch (message.method) {
case 'updateCheckoutQML':
root.isUpdating = message.params.isUpdating;
- itemId = message.params.itemId;
- itemName = message.params.itemName;
+ root.itemId = message.params.itemId;
+ root.itemName = message.params.itemName.trim();
root.itemPrice = message.params.itemPrice;
- itemHref = message.params.itemHref;
- referrer = message.params.referrer;
- itemAuthor = message.params.itemAuthor;
+ root.itemHref = message.params.itemHref;
+ root.referrer = message.params.referrer;
+ root.itemAuthor = message.params.itemAuthor;
refreshBuyUI();
break;
default:
@@ -1056,11 +1074,9 @@ Rectangle {
}
if (root.isUpdating) {
- buyText.text = "By agreeing to update, you agree to trade in your old item for the update that replaces it.";
- buyTextContainer.color = "#FFC3CD";
- buyTextContainer.border.color = "#F3808F";
- buyGlyph.text = hifi.glyphs.alert;
- buyGlyph.size = 54;
+ buyText.text = "By pressing \"Confirm Update\", you agree to trade in your old item for the updated item that replaces it.";
+ buyTextContainer.color = "#FFFFFF";
+ buyTextContainer.border.color = "#FFFFFF";
} else if (root.itemType === "contentSet" && !Entities.canReplaceContent()) {
buyText.text = "The domain owner must enable 'Replace Content' permissions for you in this " +
"domain's server settings before you can replace this domain's content with " + root.itemName + "";
diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml
index d8e02b08e5..df36bfd753 100644
--- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml
+++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml
@@ -50,11 +50,12 @@ Item {
property bool isInstalled;
property string upgradeUrl;
property string upgradeTitle;
+ property bool isShowingMyItems;
property string originalStatusText;
property string originalStatusColor;
- height: root.upgradeUrl === "" ? 110 : 150;
+ height: (root.upgradeUrl === "" || root.isShowingMyItems) ? 110 : 150;
width: parent.width;
Connections {
@@ -647,7 +648,7 @@ Item {
Rectangle {
id: upgradeAvailableContainer;
- visible: root.upgradeUrl !== "";
+ visible: root.upgradeUrl !== "" && !root.isShowingMyItems;
anchors.top: itemContainer.bottom;
anchors.bottom: parent.bottom;
anchors.left: parent.left;
diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
index 8952aad0cf..485ae81305 100644
--- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
+++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
@@ -400,6 +400,7 @@ Rectangle {
isInstalled: model.isInstalled;
upgradeUrl: model.upgrade_url;
upgradeTitle: model.upgrade_title;
+ isShowingMyItems: root.isShowingMyItems;
itemType: {
if (model.root_file_url.indexOf(".fst") > -1) {
"avatar";
diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp
index 62411a095a..c9b6bf3523 100644
--- a/interface/src/commerce/Ledger.cpp
+++ b/interface/src/commerce/Ledger.cpp
@@ -53,6 +53,7 @@ Handler(transferHfcToNode)
Handler(transferHfcToUsername)
Handler(alreadyOwned)
Handler(availableUpdates)
+Handler(updateItem)
void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request) {
auto accountManager = DependencyManager::get();
@@ -372,3 +373,14 @@ void Ledger::getAvailableUpdates() {
request["public_keys"] = QJsonArray::fromStringList(wallet->listPublicKeys());
send(endpoint, "availableUpdatesSuccess", "availableUpdatesFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, request);
}
+
+void Ledger::updateItem(const QString& hfc_key, const QString& asset_id, const QString& inventory_key) {
+ QJsonObject transaction;
+ transaction["hfc_key"] = hfc_key;
+ transaction["cost"] = 0;
+ transaction["asset_id"] = asset_id;
+ transaction["inventory_key"] = inventory_key;
+ QJsonDocument transactionDoc{ transaction };
+ auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
+ signedSend("transaction", transactionString, hfc_key, "update_item", "updateItemSuccess", "updateItemFailure");
+}
diff --git a/interface/src/commerce/Ledger.h b/interface/src/commerce/Ledger.h
index 04c618d665..c68ed8493b 100644
--- a/interface/src/commerce/Ledger.h
+++ b/interface/src/commerce/Ledger.h
@@ -37,6 +37,7 @@ public:
void transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage);
void alreadyOwned(const QString& marketplaceId);
void getAvailableUpdates();
+ void updateItem(const QString& hfc_key, const QString& asset_id, const QString& inventory_key);
enum CertificateStatus {
CERTIFICATE_STATUS_UNKNOWN = 0,
@@ -59,6 +60,7 @@ signals:
void transferHfcToUsernameResult(QJsonObject result);
void alreadyOwnedResult(QJsonObject result);
void availableUpdatesResult(QJsonObject result);
+ void updateItemResult(QJsonObject result);
void updateCertificateStatus(const QString& certID, uint certStatus);
@@ -87,6 +89,8 @@ public slots:
void alreadyOwnedFailure(QNetworkReply& reply);
void availableUpdatesSuccess(QNetworkReply& reply);
void availableUpdatesFailure(QNetworkReply& reply);
+ void updateItemSuccess(QNetworkReply& reply);
+ void updateItemFailure(QNetworkReply& reply);
private:
QJsonObject apiResponse(const QString& label, QNetworkReply& reply);
diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp
index 57d5e53794..701f2403d4 100644
--- a/interface/src/commerce/QmlCommerce.cpp
+++ b/interface/src/commerce/QmlCommerce.cpp
@@ -39,6 +39,7 @@ QmlCommerce::QmlCommerce() {
connect(ledger.data(), &Ledger::transferHfcToNodeResult, this, &QmlCommerce::transferHfcToNodeResult);
connect(ledger.data(), &Ledger::transferHfcToUsernameResult, this, &QmlCommerce::transferHfcToUsernameResult);
connect(ledger.data(), &Ledger::availableUpdatesResult, this, &QmlCommerce::availableUpdatesResult);
+ connect(ledger.data(), &Ledger::updateItemResult, this, &QmlCommerce::updateItemResult);
auto accountManager = DependencyManager::get();
connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() {
@@ -349,3 +350,16 @@ void QmlCommerce::getAvailableUpdates() {
auto ledger = DependencyManager::get();
ledger->getAvailableUpdates();
}
+
+void QmlCommerce::updateItem(const QString& marketplaceId) {
+ auto ledger = DependencyManager::get();
+ auto wallet = DependencyManager::get();
+ QStringList keys = wallet->listPublicKeys();
+ if (keys.count() == 0) {
+ QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } };
+ return emit updateItemResult(result);
+ }
+ QString key = keys[0];
+ // For now, we receive at the same key that pays for it.
+ ledger->updateItem(key, marketplaceId, key);
+}
diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h
index f3615cc8a5..fdca17e557 100644
--- a/interface/src/commerce/QmlCommerce.h
+++ b/interface/src/commerce/QmlCommerce.h
@@ -44,6 +44,7 @@ signals:
void certificateInfoResult(QJsonObject result);
void alreadyOwnedResult(QJsonObject result);
void availableUpdatesResult(QJsonObject result);
+ void updateItemResult(QJsonObject result);
void updateCertificateStatus(const QString& certID, uint certStatus);
@@ -90,6 +91,7 @@ protected:
Q_INVOKABLE bool openApp(const QString& appHref);
Q_INVOKABLE void getAvailableUpdates();
+ Q_INVOKABLE void updateItem(const QString& marketplaceId);
private:
QString _appsPath;
diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js
index 1546c2e6d5..d033e6988d 100644
--- a/scripts/system/html/js/marketplacesInject.js
+++ b/scripts/system/html/js/marketplacesInject.js
@@ -262,6 +262,7 @@
isUpdating: true,
itemId: id,
itemName: name,
+ itemPrice: 0,
itemHref: href,
referrer: referrer,
itemAuthor: author
@@ -436,7 +437,7 @@
var cost = $('.item-cost').text();
if (availability !== 'available') {
purchaseButton.html('UNAVAILABLE (' + availability + ')');
- } else if (url.indexOf('edition=' != -1)) {
+ } else if (window.location.href.indexOf('edition=' != -1)) {
purchaseButton.html('UPDATE FOR FREE');
} else if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) {
purchaseButton.html('PURCHASE