diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 328b662564..dd0c341412 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -30,6 +30,7 @@ Rectangle { property string activeView: "initialize"; property bool ownershipStatusReceived: false; property bool balanceReceived: false; + property bool availableUpdatesReceived: false; property string itemName; property string itemId; property string itemHref; @@ -130,11 +131,24 @@ Rectangle { root.isInstalled = true; } } + + onAvailableUpdatesResult: { + if (result.status !== 'success') { + 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; + } + } + } } onItemIdChanged: { root.ownershipStatusReceived = false; Commerce.alreadyOwned(root.itemId); + root.availableUpdatesReceived = false; + Commerce.getAvailableUpdates(); itemPreviewImage.source = "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/previews/" + itemId + "/thumbnail/hifi-mp-" + itemId + ".jpg"; } @@ -242,6 +256,7 @@ Rectangle { Component.onCompleted: { ownershipStatusReceived = false; balanceReceived = false; + availableUpdatesReceived = false; Commerce.getWalletStatus(); } } @@ -318,7 +333,7 @@ Rectangle { Rectangle { id: loading; z: 997; - visible: !root.ownershipStatusReceived || !root.balanceReceived; + visible: !root.ownershipStatusReceived || !root.balanceReceived || !root.availableUpdatesReceived; anchors.fill: parent; color: hifi.colors.white; @@ -542,7 +557,7 @@ Rectangle { HifiControlsUit.Button { id: buyButton; visible: !((root.itemType === "avatar" || root.itemType === "app") && viewInMyPurchasesButton.visible) - enabled: (root.balanceAfterPurchase >= 0 && ownershipStatusReceived && balanceReceived) || (!root.isCertified); + enabled: (root.balanceAfterPurchase >= 0 && ownershipStatusReceived && balanceReceived && availableUpdatesReceived) || (!root.isCertified); color: viewInMyPurchasesButton.visible ? hifi.buttons.white : hifi.buttons.blue; colorScheme: hifi.colorSchemes.light; anchors.top: viewInMyPurchasesButton.visible ? viewInMyPurchasesButton.bottom : @@ -551,7 +566,7 @@ Rectangle { height: 50; anchors.left: parent.left; anchors.right: parent.right; - text: root.isUpdating ? "CONFIRM UPDATE" : (((root.isCertified) ? ((ownershipStatusReceived && balanceReceived) ? + text: root.isUpdating ? "CONFIRM UPDATE" : (((root.isCertified) ? ((ownershipStatusReceived && balanceReceived && availableUpdatesReceived) ? (viewInMyPurchasesButton.visible ? "Buy It Again" : "Confirm Purchase") : "--") : "Get Item")); onClicked: { if (root.isCertified) { @@ -978,7 +993,7 @@ Rectangle { buyButton.color = hifi.buttons.red; root.shouldBuyWithControlledFailure = true; } else { - buyButton.text = (root.isCertified ? ((ownershipStatusReceived && balanceReceived) ? (root.alreadyOwned ? "Buy Another" : "Buy"): "--") : "Get Item"); + buyButton.text = (root.isCertified ? ((ownershipStatusReceived && balanceReceived && availableUpdatesReceived) ? (root.alreadyOwned ? "Buy Another" : "Buy"): "--") : "Get Item"); buyButton.color = hifi.buttons.blue; root.shouldBuyWithControlledFailure = false; } @@ -1021,7 +1036,7 @@ Rectangle { function refreshBuyUI() { if (root.isCertified) { - if (root.ownershipStatusReceived && root.balanceReceived) { + if (root.ownershipStatusReceived && root.balanceReceived && root.availableUpdatesReceived) { if (root.balanceAfterPurchase < 0 && !root.isUpdating) { if (root.alreadyOwned) { buyText.text = "Your Wallet does not have sufficient funds to purchase this item again."; @@ -1075,8 +1090,10 @@ Rectangle { } root.balanceReceived = false; root.ownershipStatusReceived = false; + root.availableUpdatesReceived = false; Commerce.alreadyOwned(root.itemId); Commerce.balance(); + Commerce.getAvailableUpdates(); } // diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 712c505e8a..62411a095a 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -52,6 +52,7 @@ Handler(inventory) Handler(transferHfcToNode) Handler(transferHfcToUsername) Handler(alreadyOwned) +Handler(availableUpdates) void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request) { auto accountManager = DependencyManager::get(); @@ -363,3 +364,11 @@ void Ledger::alreadyOwned(const QString& marketplaceId) { request["marketplace_item_id"] = marketplaceId; send(endpoint, "alreadyOwnedSuccess", "alreadyOwnedFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, request); } + +void Ledger::getAvailableUpdates() { + auto wallet = DependencyManager::get(); + QString endpoint = "available_updates"; + QJsonObject request; + request["public_keys"] = QJsonArray::fromStringList(wallet->listPublicKeys()); + send(endpoint, "availableUpdatesSuccess", "availableUpdatesFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, request); +} diff --git a/interface/src/commerce/Ledger.h b/interface/src/commerce/Ledger.h index 703ebda2dc..04c618d665 100644 --- a/interface/src/commerce/Ledger.h +++ b/interface/src/commerce/Ledger.h @@ -36,6 +36,7 @@ public: void transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage); void transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage); void alreadyOwned(const QString& marketplaceId); + void getAvailableUpdates(); enum CertificateStatus { CERTIFICATE_STATUS_UNKNOWN = 0, @@ -57,6 +58,7 @@ signals: void transferHfcToNodeResult(QJsonObject result); void transferHfcToUsernameResult(QJsonObject result); void alreadyOwnedResult(QJsonObject result); + void availableUpdatesResult(QJsonObject result); void updateCertificateStatus(const QString& certID, uint certStatus); @@ -83,6 +85,8 @@ public slots: void transferHfcToUsernameFailure(QNetworkReply& reply); void alreadyOwnedSuccess(QNetworkReply& reply); void alreadyOwnedFailure(QNetworkReply& reply); + void availableUpdatesSuccess(QNetworkReply& reply); + void availableUpdatesFailure(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 557193c074..57d5e53794 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -38,7 +38,7 @@ QmlCommerce::QmlCommerce() { connect(ledger.data(), &Ledger::updateCertificateStatus, this, &QmlCommerce::updateCertificateStatus); connect(ledger.data(), &Ledger::transferHfcToNodeResult, this, &QmlCommerce::transferHfcToNodeResult); connect(ledger.data(), &Ledger::transferHfcToUsernameResult, this, &QmlCommerce::transferHfcToUsernameResult); - connect(ledger.data(), &Ledger::transferHfcToUsernameResult, this, &QmlCommerce::transferHfcToUsernameResult); + connect(ledger.data(), &Ledger::availableUpdatesResult, this, &QmlCommerce::availableUpdatesResult); auto accountManager = DependencyManager::get(); connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() { @@ -344,3 +344,8 @@ bool QmlCommerce::openApp(const QString& itemHref) { return true; } + +void QmlCommerce::getAvailableUpdates() { + auto ledger = DependencyManager::get(); + ledger->getAvailableUpdates(); +} diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index 6a4eaa2be2..f3615cc8a5 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -43,6 +43,7 @@ signals: void accountResult(QJsonObject result); void certificateInfoResult(QJsonObject result); void alreadyOwnedResult(QJsonObject result); + void availableUpdatesResult(QJsonObject result); void updateCertificateStatus(const QString& certID, uint certStatus); @@ -88,6 +89,8 @@ protected: Q_INVOKABLE bool uninstallApp(const QString& appHref); Q_INVOKABLE bool openApp(const QString& appHref); + Q_INVOKABLE void getAvailableUpdates(); + private: QString _appsPath; }; diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index 35f89a4a19..1546c2e6d5 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -445,15 +445,11 @@ purchaseButton.on('click', function () { if (url.indexOf('edition=' != -1)) { - if (url.indexOf('upgradeUrl=' === -1)) { - console.log("ERROR! Item is an upgrade, but no upgradeUrl was specified."); - } else { - updateButtonClicked(window.location.pathname.split("/")[3], - $('#top-center').find('h1').text(), - $('#creator').find('.value').text(), - getParameterByName('upgradeUrl'), - "itemPage"); - } + updateButtonClicked(window.location.pathname.split("/")[3], + $('#top-center').find('h1').text(), + $('#creator').find('.value').text(), + href, + "itemPage"); } else if ('available' === availability) { buyButtonClicked(window.location.pathname.split("/")[3], $('#top-center').find('h1').text(), diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index dafd3e525d..514f6dd975 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -561,7 +561,7 @@ var selectionDisplay = null; // for gridTool.js to ignore tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL); break; case 'updateItemClicked': - tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.itemId + "?edition=" + message.itemEdition + "&upgradeUrl=" + message.upgradeUrl, + tablet.gotoWebScreen(message.upgradeUrl + "?edition=" + message.itemEdition + "&upgradeUrl=" + message.upgradeUrl, MARKETPLACES_INJECT_SCRIPT_URL); break; case 'passphrasePopup_cancelClicked':