From 95e9eb8e4abebbbaa919224a8f638a78fc91482a Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 12 Feb 2018 17:06:57 -0800 Subject: [PATCH] Lots of progress --- interface/resources/fonts/hifi-glyphs.ttf | Bin 31232 -> 32536 bytes .../qml/hifi/commerce/checkout/Checkout.qml | 69 +++++++++++++----- .../hifi/commerce/purchases/PurchasedItem.qml | 57 +++++++++++---- .../qml/hifi/commerce/purchases/Purchases.qml | 16 +++- .../qml/styles-uit/HifiConstants.qml | 4 + interface/src/Application.cpp | 34 +++++---- interface/src/Application.h | 2 + interface/src/commerce/QmlCommerce.cpp | 13 ++++ interface/src/commerce/QmlCommerce.h | 4 + .../entities/src/EntityScriptingInterface.cpp | 5 ++ .../entities/src/EntityScriptingInterface.h | 6 ++ scripts/system/marketplaces/marketplaces.js | 17 +++-- 12 files changed, 174 insertions(+), 53 deletions(-) diff --git a/interface/resources/fonts/hifi-glyphs.ttf b/interface/resources/fonts/hifi-glyphs.ttf index 4cc5a0fe4f098a287c1df067c8bff37695f96d34..8db0377f88864810e7f893132449ad8e258e68cd 100644 GIT binary patch delta 1778 zcmX|BYit}>6+Y+AoqK2QJl2nSB>S*;W_D-2b{(&GXJ_2H>o!qq1dW}@Z9){4lvT5h zqu7p>-KGvdyya2)h89Z*g%o}O?VnUUtN=f%mWR~PN+2OYkx)Sq5&Ym!Bm`1H$U(EI zxYE7fxku-Gy65UU=jngqH}7dS0U-a02OeC6w}Am{ ze+U4@BM;BikGyrb2Y@F4;P~U~?ahl1e$WOW9|Dk#Gwtr??b{#$Z2t}blrw9Wp0Lk- z?+O6h1lW9TwbMRrK2iK70Hl2J>T0LorZv0)fEEChR@Zx5#n0{g5&-@H04LYZKi+=l zzCWD;kPic3X}!I*3AgYR0M4Zk+GwwL{yul@IKah^0C0Ene79$>Tz&{(>nZ@77!-#9 z<3CKEc`S49zd$39t`EL*>*gIKw{Ct7TlnhE0)7T(cCTO)kG0@#ScG|49K=chgPk9c z0j`2Hu<}6ha9SlOaEEpK#?0;8gBJt$^ znvmp2b9C;3-4pEExjusyJc7T#t6)GGns5-7;5Yy_>bAqJ!1J5KQ3G2Tg@Na@0*RA& z9GzqUa@}co^(3x@m5?*eDhrr|l`t^TwGxK~EUZLvQg=e1*_K<6Bg89Z#LC`#l`0;h z#@=uBzN{(xM>AZvI$0~X_cy8%oG>J&S1V%3xyDQ}sVTa|T^*mr{OD+IaFj<3TNrq? z{N-oE3FOtif1AHCsI0%KQ&}I$2qqeal{<}0(JNJr>nEuzTZ{{dkGS~8Xby8$$|UJ( z-zK`1>hW$!@H)N=8sx!;DVT*A=HY($BpiWba1u5Ez-N}zaGML*jCe~9D{$s_9_tW&CAU7uQ@i9 z%?_9DEe)>)_Q(RF@H4i%-x2t3@AV!c_EsJ~AtNH8L0%S8c!sU#R&MhlsSyhF4MDS(ChHj+vx|Y|pyrw&rWeM?l zbwU;4@6~<^B_a!Xh;e2rjC1MR5>p7HgfWG4E~`|buMwt5hC+oRs~JU32gE#lAK%9> z!W7KFJpkpj0|Va| zMi2?-dZ8eX>=)2VCq~@DD76F6f3$^(eMb&XqkbPQVC4X2 zuo?NE&DthbO*^aZ{Xu=r(-c*UWr;~KMJj2un7wH%o3?E(8^*G#F8}nKIaO%9CP_6( zqZDcGvazdQ&~bPcYA_A;!LGq9%{Kk4`qt~TRwKq=Fr#kHm{Om@z*IrxOdFxUE RU)lNNrJVNvNq_6+{{ZQFEu#Pc delta 506 zcmX|-Pe>GT6vsbrW?a_PN=#T{p%p?1S=w31NpL;s+9A-lJ#L?N1OHfx?@7&K_$jRKEZ}fzEtBH)|UysezmWF6K*xFSHt&=rbf$Ti>;Q8YrX zncAgVM-V91wi+jx!~?YvL%)~ zq-iG8DbuR-xJ$C&e|BTy|Mj+vesu*20yIT_8i=W3*y}t;FhB|8So(HmEqr(Ac;|op E2i!<=3IG5A diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 809f48361d..c141b48d32 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -37,11 +37,14 @@ Rectangle { property double balanceAfterPurchase; property bool alreadyOwned: false; property int itemPrice: -1; - property bool itemIsJson: true; + property bool isCertified; + property string itemType; + property var itemTypesArray: ["entity", "wearable", "contentSet", "app", "avatar"]; + property var buttonTextNormal: ["REZ IT", "WEAR IT", "SWAP CONTENT SET", "INSTALL IT", "WEAR IT"]; + property var buttonTextClicked: ["REZZED", "WORN", "SWAPPED", "INSTALLED", "WORN"] property bool shouldBuyWithControlledFailure: false; property bool debugCheckoutSuccess: false; property bool canRezCertifiedItems: Entities.canRezCertified() || Entities.canRezTmpCertified(); - property bool isWearable; property string referrer; // Style color: hifi.colors.white; @@ -85,7 +88,9 @@ Rectangle { UserActivityLogger.commercePurchaseFailure(root.itemId, root.itemAuthor, root.itemPrice, !root.alreadyOwned, result.message); } else { root.itemHref = result.data.download_url; - root.isWearable = result.data.categories.indexOf("Wearables") > -1; + if (result.data.categories.indexOf("Wearables") > -1) { + root.itemType = "wearable"; + } root.activeView = "checkoutSuccess"; UserActivityLogger.commercePurchaseSuccess(root.itemId, root.itemAuthor, root.itemPrice, !root.alreadyOwned); } @@ -122,7 +127,25 @@ Rectangle { } onItemHrefChanged: { - itemIsJson = root.itemHref.endsWith('.json'); + if (root.itemHref.indexOf(".fst") > -1) { + root.itemType = "avatar"; + } else if (root.itemHref.endsWith('.json.gz')) { + root.itemType = "contentSet"; + } else if (root.itemHref.endsWith('.json')) { + root.itemType = "entity"; // "wearable" type handled later + } else if (root.itemHref.endsWith('.js')) { + root.itemType = "app"; + } else { + root.itemType = "entity"; + } + } + + onItemTypeChanged: { + if (root.itemType === "entity" || root.itemType === "wearable" || root.itemType === "contentSet") { + root.isCertified = true; + } else { + root.isCertified = false; + } } onItemPriceChanged: { @@ -464,7 +487,7 @@ Rectangle { // "Buy" button HifiControlsUit.Button { id: buyButton; - enabled: (root.balanceAfterPurchase >= 0 && purchasesReceived && balanceReceived) || !itemIsJson; + enabled: (root.balanceAfterPurchase >= 0 && purchasesReceived && balanceReceived) || (!root.isCertified); color: hifi.buttons.blue; colorScheme: hifi.colorSchemes.light; anchors.top: checkoutActionButtonsContainer.top; @@ -472,9 +495,9 @@ Rectangle { height: 40; anchors.left: parent.left; anchors.right: parent.right; - text: (itemIsJson ? ((purchasesReceived && balanceReceived) ? "Confirm Purchase" : "--") : "Get Item"); + text: ((root.isCertified) ? ((purchasesReceived && balanceReceived) ? "Confirm Purchase" : "--") : "Get Item"); onClicked: { - if (itemIsJson) { + if (root.isCertified) { buyButton.enabled = false; if (!root.shouldBuyWithControlledFailure) { Commerce.buy(itemId, itemPrice); @@ -576,7 +599,7 @@ Rectangle { RalewayBold { anchors.fill: parent; - text: "REZZED"; + text: (root.buttonTextClicked)[itemTypesArray.indexOf(root.itemType)]; size: 18; color: hifi.colors.white; verticalAlignment: Text.AlignVCenter; @@ -592,7 +615,7 @@ Rectangle { // "Rez" button HifiControlsUit.Button { id: rezNowButton; - enabled: root.canRezCertifiedItems || root.isWearable; + enabled: root.canRezCertifiedItems || root.itemType === "wearable"; buttonGlyph: hifi.glyphs.lightning; color: hifi.buttons.red; colorScheme: hifi.colorSchemes.light; @@ -601,17 +624,27 @@ Rectangle { height: 50; anchors.left: parent.left; anchors.right: parent.right; - text: root.isWearable ? "Wear It" : "Rez It" + text: (root.buttonTextNormal)[itemTypesArray.indexOf(root.itemType)]; onClicked: { - sendToScript({method: 'checkout_rezClicked', itemHref: root.itemHref, isWearable: root.isWearable}); - rezzedNotifContainer.visible = true; - rezzedNotifContainerTimer.start(); - UserActivityLogger.commerceEntityRezzed(root.itemId, "checkout", root.isWearable ? "rez" : "wear"); + if (root.itemType === "contentSet") { + lightboxPopup.titleText = "Replace Content"; + lightboxPopup.bodyText = "Rezzing this content set will replace the existing environment and all of the items in this domain."; + lightboxPopup.button1text = "CANCEL"; + lightboxPopup.button1method = "root.visible = false;" + lightboxPopup.button2text = "CONFIRM"; + lightboxPopup.button2method = "sendToScript({method: 'checkout_rezClicked', itemHref: " + root.itemHref + ", itemType: " + root.itemType + "});"; + lightboxPopup.visible = true; + } else { + sendToScript({method: 'checkout_rezClicked', itemHref: root.itemHref, itemType: root.itemType}); + rezzedNotifContainer.visible = true; + rezzedNotifContainerTimer.start(); + UserActivityLogger.commerceEntityRezzed(root.itemId, "checkout", root.itemType); + } } } RalewaySemiBold { id: noPermissionText; - visible: !root.canRezCertifiedItems && !root.isWearable; + visible: !root.canRezCertifiedItems && root.itemType !== "wearable"; text: 'You do not have Certified Rez permissions in this domain.' // Text size size: 16; @@ -640,7 +673,7 @@ Rectangle { } RalewaySemiBold { id: explainRezText; - visible: !root.isWearable; + visible: root.itemType === "entity"; text: 'What does "Rez" mean?' // Text size size: 16; @@ -851,7 +884,7 @@ Rectangle { buyButton.color = hifi.buttons.red; root.shouldBuyWithControlledFailure = true; } else { - buyButton.text = (itemIsJson ? ((purchasesReceived && balanceReceived) ? (root.alreadyOwned ? "Buy Another" : "Buy"): "--") : "Get Item"); + buyButton.text = (root.isCertified ? ((purchasesReceived && balanceReceived) ? (root.alreadyOwned ? "Buy Another" : "Buy"): "--") : "Get Item"); buyButton.color = hifi.buttons.blue; root.shouldBuyWithControlledFailure = false; } @@ -901,7 +934,7 @@ Rectangle { } function setBuyText() { - if (root.itemIsJson) { + if (root.isCertified) { if (root.purchasesReceived && root.balanceReceived) { if (root.balanceAfterPurchase < 0) { if (root.alreadyOwned) { diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml index 361b9931a4..41f2d919cd 100644 --- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml +++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml @@ -41,8 +41,11 @@ Item { property int limitedRun; property string itemType; property var itemTypesArray: ["entity", "wearable", "contentSet", "app", "avatar"]; - property var buttonTextNormal: ["REZ", "WEAR", "SWAP", "INSTALL", "WEAR"]; - property var buttonTextClicked: ["REZZED", "WORN", "SWAPPED", "INSTALLED", "WORN"] + property var buttonTextNormal: ["REZ", "WEAR", "REPLACE", "INSTALL", "WEAR"]; + property var buttonTextClicked: ["REZZED", "WORN", "REPLACED", "INSTALLED", "WORN"] + property var buttonGlyph: [hifi.glyphs.wand, hifi.glyphs.hat, hifi.glyphs.globe, hifi.glyphs.install, hifi.glyphs.avatar]; + property bool showConfirmation: false; + property bool hasPermissionToRezThis; property string originalStatusText; property string originalStatusColor; @@ -50,6 +53,23 @@ Item { height: 110; width: parent.width; + Connections { + target: Commerce; + + onContentSetChanged: { + if (contentSetMarketplaceID === root.itemId) { + showConfirmation = true; + } + } + } + + onItemTypeChanged: { + if ((itemType === "entity" && (!Entities.canRezCertified() && !Entities.canRezTmpCertified())) || + (itemType === "contentSet" && !Entities.canReplaceContent())) { + root.hasPermissionToRezThis = false; + } + } + onPurchaseStatusChangedChanged: { if (root.purchaseStatusChanged === true && root.purchaseStatus === "confirmed") { root.originalStatusText = statusText.text; @@ -60,6 +80,15 @@ Item { } } + onShowConfirmationChanged: { + if (root.showConfirmation) { + rezzedNotifContainer.visible = true; + rezzedNotifContainerTimer.start(); + UserActivityLogger.commerceEntityRezzed(root.itemId, "purchases", root.itemType); + root.showConfirmation = false; + } + } + Timer { id: confirmedTimer; interval: 3000; @@ -325,7 +354,7 @@ Item { RalewayBold { anchors.fill: parent; text: (root.buttonTextClicked)[itemTypesArray.indexOf(root.itemType)]; - size: 18; + size: 15; color: hifi.colors.white; verticalAlignment: Text.AlignVCenter; horizontalAlignment: Text.AlignHCenter; @@ -353,10 +382,12 @@ Item { enabled: (root.canRezCertifiedItems || root.itemType === "wearable") && root.purchaseStatus !== "invalidated"; onClicked: { - sendToPurchases({method: 'purchases_rezClicked', itemHref: root.itemHref, itemType: root.itemType}); - rezzedNotifContainer.visible = true; - rezzedNotifContainerTimer.start(); - UserActivityLogger.commerceEntityRezzed(root.itemId, "purchases", root.itemType === "wearable" ? "rez" : "wear"); + if (root.itemType === "contentSet") { + sendToPurchases({method: 'showReplaceContentLightbox', itemId: root.itemId, itemHref: root.itemHref}); + } else { + sendToPurchases({method: 'purchases_rezClicked', itemHref: root.itemHref, itemType: root.itemType}); + root.showConfirmation = true; + } } style: ButtonStyle { @@ -396,13 +427,13 @@ Item { label: Item { HiFiGlyphs { - id: lightningIcon; - text: hifi.glyphs.lightning; + id: rezIcon; + text: (root.buttonGlyph)[itemTypesArray.indexOf(root.itemType)]; // Size - size: 32; + size: 60; // Anchors anchors.top: parent.top; - anchors.topMargin: 12; + anchors.topMargin: 0; anchors.left: parent.left; anchors.right: parent.right; horizontalAlignment: Text.AlignHCenter; @@ -411,8 +442,8 @@ Item { : hifi.buttons.disabledTextColor[control.colorScheme] } RalewayBold { - anchors.top: lightningIcon.bottom; - anchors.topMargin: -20; + anchors.top: rezIcon.bottom; + anchors.topMargin: -4; anchors.right: parent.right; anchors.left: parent.left; anchors.bottom: parent.bottom; diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index 922ba54822..956bfa7c26 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -455,10 +455,16 @@ Rectangle { limitedRun: model.limited_run; displayedItemCount: model.displayedItemCount; itemType: { - if (model.download_url.indexOf(".fst") > -1) { + if (model.root_file_url.indexOf(".fst") > -1) { "avatar"; } else if (model.categories.indexOf("Wearables") > -1) { "wearable"; + } else if (model.root_file_url.endsWith('.json.gz')) { + "contentSet"; + } else if (model.root_file_url.endsWith('.json')) { + "entity"; + } else if (model.root_file_url.endsWith('.js')) { + "app"; } else { "entity"; } @@ -490,6 +496,14 @@ Rectangle { lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1method = "root.visible = false;" lightboxPopup.visible = true; + } else if (msg.method === "showReplaceContentLightbox") { + lightboxPopup.titleText = "Replace Content"; + lightboxPopup.bodyText = "Rezzing this content set will replace the existing environment and all of the items in this domain."; + lightboxPopup.button1text = "CANCEL"; + lightboxPopup.button1method = "root.visible = false;" + lightboxPopup.button2text = "CONFIRM"; + lightboxPopup.button2method = "Commerce.replaceContentSet('" + msg.itemId + "', '" + msg.itemHref + "'); root.visible = false;"; + lightboxPopup.visible = true; } else if (msg.method === "setFilterText") { filterBar.text = msg.filterText; } diff --git a/interface/resources/qml/styles-uit/HifiConstants.qml b/interface/resources/qml/styles-uit/HifiConstants.qml index 5da587ea57..16b74f6b54 100644 --- a/interface/resources/qml/styles-uit/HifiConstants.qml +++ b/interface/resources/qml/styles-uit/HifiConstants.qml @@ -354,5 +354,9 @@ Item { readonly property string wallet: "\ue027" readonly property string paperPlane: "\ue028" readonly property string passphrase: "\ue029" + readonly property string globe: "\ue02c" + readonly property string wand: "\ue02d" + readonly property string hat: "\ue02e" + readonly property string install: "\ue02f" } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index be2a54b8e9..576d080947 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6176,6 +6176,24 @@ bool Application::askToWearAvatarAttachmentUrl(const QString& url) { return true; } +void Application::replaceDomainContent(const QString& url) { + qCDebug(interfaceapp) << "Attempting to replace domain content: " << url; + QByteArray urlData(url.toUtf8()); + auto limitedNodeList = DependencyManager::get(); + limitedNodeList->eachMatchingNode([](const SharedNodePointer& node) { + return node->getType() == NodeType::EntityServer && node->getActiveSocket(); + }, [&urlData, limitedNodeList](const SharedNodePointer& octreeNode) { + auto octreeFilePacket = NLPacket::create(PacketType::OctreeFileReplacementFromUrl, urlData.size(), true); + octreeFilePacket->write(urlData); + limitedNodeList->sendPacket(std::move(octreeFilePacket), *octreeNode); + }); + auto addressManager = DependencyManager::get(); + addressManager->handleLookupString(DOMAIN_SPAWNING_POINT); + QString newHomeAddress = addressManager->getHost() + DOMAIN_SPAWNING_POINT; + qCDebug(interfaceapp) << "Setting new home bookmark to: " << newHomeAddress; + DependencyManager::get()->setHomeLocationToAddress(newHomeAddress); +} + bool Application::askToReplaceDomainContent(const QString& url) { QString methodDetails; const int MAX_CHARACTERS_PER_LINE = 90; @@ -6195,21 +6213,7 @@ bool Application::askToReplaceDomainContent(const QString& url) { QString details; if (static_cast(answer.toInt()) == QMessageBox::Yes) { // Given confirmation, send request to domain server to replace content - qCDebug(interfaceapp) << "Attempting to replace domain content: " << url; - QByteArray urlData(url.toUtf8()); - auto limitedNodeList = DependencyManager::get(); - limitedNodeList->eachMatchingNode([](const SharedNodePointer& node) { - return node->getType() == NodeType::EntityServer && node->getActiveSocket(); - }, [&urlData, limitedNodeList](const SharedNodePointer& octreeNode) { - auto octreeFilePacket = NLPacket::create(PacketType::OctreeFileReplacementFromUrl, urlData.size(), true); - octreeFilePacket->write(urlData); - limitedNodeList->sendPacket(std::move(octreeFilePacket), *octreeNode); - }); - auto addressManager = DependencyManager::get(); - addressManager->handleLookupString(DOMAIN_SPAWNING_POINT); - QString newHomeAddress = addressManager->getHost() + DOMAIN_SPAWNING_POINT; - qCDebug(interfaceapp) << "Setting new home bookmark to: " << newHomeAddress; - DependencyManager::get()->setHomeLocationToAddress(newHomeAddress); + replaceDomainContent(url); details = "SuccessfulRequestToReplaceContent"; } else { details = "UserDeclinedToReplaceContent"; diff --git a/interface/src/Application.h b/interface/src/Application.h index ddb8ce11e5..2dd83f39eb 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -284,6 +284,8 @@ public: bool getSaveAvatarOverrideUrl() { return _saveAvatarOverrideUrl; } void saveNextPhysicsStats(QString filename); + void replaceDomainContent(const QString& url); + signals: void svoImportRequested(const QString& url); diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index c9caa393ce..ba52edba4f 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -15,6 +15,8 @@ #include "Ledger.h" #include "Wallet.h" #include +#include +#include QmlCommerce::QmlCommerce() { auto ledger = DependencyManager::get(); @@ -163,3 +165,14 @@ void QmlCommerce::transferHfcToUsername(const QString& username, const int& amou QString key = keys[0]; ledger->transferHfcToUsername(key, username, amount, optionalMessage); } + +void QmlCommerce::replaceContentSet(const QString& id, const QString& url) { + qApp->replaceDomainContent(url); + QJsonObject messageProperties = { + { "status", "SuccessfulRequestToReplaceContent" }, + { "content_set_url", url } + }; + UserActivityLogger::getInstance().logAction("replace_domain_content", messageProperties); + + emit contentSetChanged(id); +} diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index b261ee6de6..aa939a439d 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -48,6 +48,8 @@ signals: void transferHfcToNodeResult(QJsonObject result); void transferHfcToUsernameResult(QJsonObject result); + void contentSetChanged(const QString& contentSetMarketplaceID); + protected: Q_INVOKABLE void getWalletStatus(); @@ -71,6 +73,8 @@ protected: Q_INVOKABLE void transferHfcToNode(const QString& nodeID, const int& amount, const QString& optionalMessage); Q_INVOKABLE void transferHfcToUsername(const QString& username, const int& amount, const QString& optionalMessage); + + Q_INVOKABLE void replaceContentSet(const QString& id, const QString& url); }; #endif // hifi_QmlCommerce_h diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 4342f0e683..f9449cca34 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -101,6 +101,11 @@ bool EntityScriptingInterface::canWriteAssets() { return nodeList->getThisNodeCanWriteAssets(); } +bool EntityScriptingInterface::canReplaceContent() { + auto nodeList = DependencyManager::get(); + return nodeList->getThisNodeCanReplaceContent(); +} + void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) { if (_entityTree) { disconnect(_entityTree.get(), &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity); diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index d1b321dbca..30e1e6ce1c 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -144,6 +144,12 @@ public slots: */ Q_INVOKABLE bool canWriteAssets(); + /**jsdoc + * @function Entities.canReplaceContent + * @return {bool} `true` if the DomainServer will allow this Node/Avatar to replace the domain's content set + */ + Q_INVOKABLE bool canReplaceContent(); + /**jsdoc * Add a new entity with the specified properties. If `clientOnly` is true, the entity will * not be sent to the server and will only be visible/accessible on the local client. diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index b43fe545fa..95d9294063 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -65,7 +65,7 @@ var selectionDisplay = null; // for gridTool.js to ignore var onMarketplaceScreen = false; var onCommerceScreen = false; - var debugCheckout = false; + var debugCheckout = true; var debugError = false; function showMarketplace() { if (!debugCheckout) { @@ -75,11 +75,11 @@ var selectionDisplay = null; // for gridTool.js to ignore tablet.pushOntoStack(MARKETPLACE_CHECKOUT_QML_PATH); tablet.sendToQml({ method: 'updateCheckoutQML', params: { - itemId: '0d90d21c-ce7a-4990-ad18-e9d2cf991027', - itemName: 'Test Flaregun', - itemPrice: (debugError ? 10 : 17), - itemHref: 'http://mpassets.highfidelity.com/0d90d21c-ce7a-4990-ad18-e9d2cf991027-v1/flaregun.json', - categories: ["Wearables", "Miscellaneous"] + itemId: 'e197e3d7-eafc-4aa5-9341-acee57174fe9', + itemName: 'Oasis', + itemPrice: (debugError ? 10 : 11), + itemHref: 'http://mpassets-staging.highfidelity.com/e197e3d7-eafc-4aa5-9341-acee57174fe9-v1/oasis_Aug15.json.gz', + categories: ["Miscellaneous"] } }); } @@ -240,6 +240,11 @@ var selectionDisplay = null; // for gridTool.js to ignore var wearableLocalDimensions = null; var wearableDimensions = null; + if (itemType === "contentSet") { + console.log("Item is a content set; codepath shouldn't go here.") + return; + } + if (isWearable) { var wearableTransforms = Settings.getValue("io.highfidelity.avatarStore.checkOut.transforms"); if (!wearableTransforms) {