diff --git a/interface/resources/qml/hifi/commerce/Checkout.qml b/interface/resources/qml/hifi/commerce/Checkout.qml
deleted file mode 100644
index d9b0072917..0000000000
--- a/interface/resources/qml/hifi/commerce/Checkout.qml
+++ /dev/null
@@ -1,463 +0,0 @@
-//
-// Checkout.qml
-// qml/hifi/commerce
-//
-// Checkout
-//
-// Created by Zach Fox on 2017-08-07
-// Copyright 2017 High Fidelity, Inc.
-//
-// Distributed under the Apache License, Version 2.0.
-// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
-//
-
-import Hifi 1.0 as Hifi
-import QtQuick 2.5
-import QtQuick.Controls 1.4
-import "../../styles-uit"
-import "../../controls-uit" as HifiControlsUit
-import "../../controls" as HifiControls
-import "./wallet" as HifiWallet
-
-// references XXX from root context
-
-Rectangle {
- HifiConstants { id: hifi; }
-
- id: checkoutRoot;
- property bool inventoryReceived: false;
- property bool balanceReceived: false;
- property string itemId: "";
- property string itemHref: "";
- property int balanceAfterPurchase: 0;
- property bool alreadyOwned: false;
- property int itemPriceFull: 0;
- // Style
- color: hifi.colors.baseGray;
- Hifi.QmlCommerce {
- id: commerce;
- onBuyResult: {
- if (result.status !== 'success') {
- buyButton.text = result.message;
- buyButton.enabled = false;
- } else {
- if (urlHandler.canHandleUrl(itemHref)) {
- urlHandler.handleUrl(itemHref);
- }
- sendToScript({method: 'checkout_buySuccess', itemId: itemId});
- }
- }
- onBalanceResult: {
- if (result.status !== 'success') {
- console.log("Failed to get balance", result.message);
- } else {
- balanceReceived = true;
- hfcBalanceText.text = parseFloat(result.data.balance/100).toFixed(2);
- balanceAfterPurchase = parseFloat(result.data.balance/100) - parseFloat(checkoutRoot.itemPriceFull/100).toFixed(2);
- }
- }
- onInventoryResult: {
- if (result.status !== 'success') {
- console.log("Failed to get inventory", result.message);
- } else {
- inventoryReceived = true;
- console.log('inventory fixme', JSON.stringify(result));
- if (inventoryContains(result.data.assets, itemId)) {
- alreadyOwned = true;
- } else {
- alreadyOwned = false;
- }
- }
- }
- }
-
- //
- // TITLE BAR START
- //
- Item {
- id: titleBarContainer;
- // Size
- width: checkoutRoot.width;
- height: 50;
- // Anchors
- anchors.left: parent.left;
- anchors.top: parent.top;
-
- // Title Bar text
- RalewaySemiBold {
- id: titleBarText;
- text: "Checkout";
- // Text size
- size: hifi.fontSizes.overlayTitle;
- // Anchors
- anchors.top: parent.top;
- anchors.left: parent.left;
- anchors.leftMargin: 16;
- anchors.bottom: parent.bottom;
- width: paintedWidth;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
-
- // Separator
- HifiControlsUit.Separator {
- anchors.left: parent.left;
- anchors.right: parent.right;
- anchors.bottom: parent.bottom;
- }
- }
- //
- // TITLE BAR END
- //
-
- //
- // ITEM DESCRIPTION START
- //
- Item {
- id: itemDescriptionContainer;
- // Size
- width: checkoutRoot.width;
- height: childrenRect.height + 20;
- // Anchors
- anchors.left: parent.left;
- anchors.top: titleBarContainer.bottom;
-
- // Item Name text
- Item {
- id: itemNameContainer;
- // Anchors
- anchors.top: parent.top;
- anchors.topMargin: 4;
- anchors.left: parent.left;
- anchors.leftMargin: 16;
- anchors.right: parent.right;
- anchors.rightMargin: 16;
- height: childrenRect.height;
-
- RalewaySemiBold {
- id: itemNameTextLabel;
- text: "Item Name:";
- // Anchors
- anchors.top: parent.top;
- anchors.left: parent.left;
- width: paintedWidth;
- // Text size
- size: 16;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- RalewayRegular {
- id: itemNameText;
- // Text size
- size: itemNameTextLabel.size;
- // Anchors
- anchors.top: parent.top;
- anchors.left: itemNameTextLabel.right;
- anchors.leftMargin: 16;
- width: paintedWidth;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- }
-
-
- // Item Author text
- Item {
- id: itemAuthorContainer;
- // Anchors
- anchors.top: itemNameContainer.bottom;
- anchors.topMargin: 4;
- anchors.left: parent.left;
- anchors.leftMargin: 16;
- anchors.right: parent.right;
- anchors.rightMargin: 16;
- height: childrenRect.height;
-
- RalewaySemiBold {
- id: itemAuthorTextLabel;
- text: "Item Author:";
- // Anchors
- anchors.top: parent.top;
- anchors.left: parent.left;
- width: paintedWidth;
- // Text size
- size: 16;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- RalewayRegular {
- id: itemAuthorText;
- // Text size
- size: itemAuthorTextLabel.size;
- // Anchors
- anchors.top: parent.top;
- anchors.left: itemAuthorTextLabel.right;
- anchors.leftMargin: 16;
- width: paintedWidth;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- }
-
- // HFC Balance text
- Item {
- id: hfcBalanceContainer;
- // Anchors
- anchors.top: itemAuthorContainer.bottom;
- anchors.topMargin: 16;
- anchors.left: parent.left;
- anchors.leftMargin: 16;
- anchors.right: parent.right;
- anchors.rightMargin: 16;
- height: childrenRect.height;
-
- RalewaySemiBold {
- id: hfcBalanceTextLabel;
- text: "HFC Balance:";
- // Anchors
- anchors.top: parent.top;
- anchors.left: parent.left;
- width: paintedWidth;
- // Text size
- size: 20;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- RalewayRegular {
- id: hfcBalanceText;
- text: "--";
- // Text size
- size: hfcBalanceTextLabel.size;
- // Anchors
- anchors.top: parent.top;
- anchors.left: hfcBalanceTextLabel.right;
- anchors.leftMargin: 16;
- width: paintedWidth;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- }
-
- // Item Price text
- Item {
- id: itemPriceContainer;
- // Anchors
- anchors.top: hfcBalanceContainer.bottom;
- anchors.topMargin: 4;
- anchors.left: parent.left;
- anchors.leftMargin: 16;
- anchors.right: parent.right;
- anchors.rightMargin: 16;
- height: childrenRect.height;
-
- RalewaySemiBold {
- id: itemPriceTextLabel;
- text: "Item Price:";
- // Anchors
- anchors.top: parent.top;
- anchors.left: parent.left;
- width: paintedWidth;
- // Text size
- size: 20;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- RalewayRegular {
- id: itemPriceText;
- // Text size
- size: itemPriceTextLabel.size;
- // Anchors
- anchors.top: parent.top;
- anchors.left: itemPriceTextLabel.right;
- anchors.leftMargin: 16;
- width: paintedWidth;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- }
-
- // HFC "Balance After Purchase" text
- Item {
- id: hfcBalanceAfterPurchaseContainer;
- // Anchors
- anchors.top: itemPriceContainer.bottom;
- anchors.topMargin: 4;
- anchors.left: parent.left;
- anchors.leftMargin: 16;
- anchors.right: parent.right;
- anchors.rightMargin: 16;
- height: childrenRect.height;
-
- RalewaySemiBold {
- id: hfcBalanceAfterPurchaseTextLabel;
- text: "HFC Balance After Purchase:";
- // Anchors
- anchors.top: parent.top;
- anchors.left: parent.left;
- width: paintedWidth;
- // Text size
- size: 20;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- RalewayRegular {
- id: hfcBalanceAfterPurchaseText;
- text: balanceAfterPurchase;
- // Text size
- size: hfcBalanceAfterPurchaseTextLabel.size;
- // Anchors
- anchors.top: parent.top;
- anchors.left: hfcBalanceAfterPurchaseTextLabel.right;
- anchors.leftMargin: 16;
- width: paintedWidth;
- // Style
- color: (balanceAfterPurchase >= 0) ? hifi.colors.lightGrayText : hifi.colors.redHighlight;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- }
- }
- //
- // ITEM DESCRIPTION END
- //
-
-
- //
- // ACTION BUTTONS START
- //
- Item {
- id: actionButtonsContainer;
- // Size
- width: checkoutRoot.width;
- height: 40;
- // Anchors
- anchors.left: parent.left;
- anchors.bottom: parent.bottom;
- anchors.bottomMargin: 8;
-
- // "Cancel" button
- HifiControlsUit.Button {
- id: cancelButton;
- color: hifi.buttons.black;
- colorScheme: hifi.colorSchemes.dark;
- anchors.top: parent.top;
- anchors.topMargin: 3;
- anchors.bottom: parent.bottom;
- anchors.bottomMargin: 3;
- anchors.left: parent.left;
- anchors.leftMargin: 20;
- width: parent.width/2 - anchors.leftMargin*2;
- text: "Cancel"
- onClicked: {
- sendToScript({method: 'checkout_cancelClicked', params: itemId});
- }
- }
-
- // "Buy" button
- HifiControlsUit.Button {
- id: buyButton;
- enabled: balanceAfterPurchase >= 0 && inventoryReceived && balanceReceived;
- color: hifi.buttons.black;
- colorScheme: hifi.colorSchemes.dark;
- anchors.top: parent.top;
- anchors.topMargin: 3;
- anchors.bottom: parent.bottom;
- anchors.bottomMargin: 3;
- anchors.right: parent.right;
- anchors.rightMargin: 20;
- width: parent.width/2 - anchors.rightMargin*2;
- text: (inventoryReceived && balanceReceived) ? (alreadyOwned ? "Already Owned: Get Item" : "Buy") : "--";
- onClicked: {
- if (!alreadyOwned) {
- commerce.buy(itemId, parseFloat(itemPriceText.text*100));
- } else {
- if (urlHandler.canHandleUrl(itemHref)) {
- urlHandler.handleUrl(itemHref);
- }
- sendToScript({method: 'checkout_buySuccess', itemId: itemId});
- }
- }
- }
- }
- //
- // ACTION BUTTONS END
- //
-
- //
- // FUNCTION DEFINITIONS START
- //
- //
- // Function Name: fromScript()
- //
- // Relevant Variables:
- // None
- //
- // Arguments:
- // message: The message sent from the JavaScript, in this case the Marketplaces JavaScript.
- // Messages are in format "{method, params}", like json-rpc.
- //
- // Description:
- // Called when a message is received from a script.
- //
- function fromScript(message) {
- switch (message.method) {
- case 'updateCheckoutQML':
- itemId = message.params.itemId;
- itemNameText.text = message.params.itemName;
- itemAuthorText.text = message.params.itemAuthor;
- checkoutRoot.itemPriceFull = message.params.itemPrice;
- itemPriceText.text = parseFloat(checkoutRoot.itemPriceFull/100).toFixed(2);
- itemHref = message.params.itemHref;
- commerce.balance();
- commerce.inventory();
- break;
- default:
- console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
- }
- }
- signal sendToScript(var message);
-
- function inventoryContains(inventoryJson, id) {
- for (var idx = 0; idx < inventoryJson.length; idx++) {
- if(inventoryJson[idx].id === id) {
- return true;
- }
- }
- return false;
- }
-
- //
- // FUNCTION DEFINITIONS END
- //
-}
diff --git a/interface/resources/qml/hifi/commerce/Inventory.qml b/interface/resources/qml/hifi/commerce/Inventory.qml
deleted file mode 100644
index 20458f9f16..0000000000
--- a/interface/resources/qml/hifi/commerce/Inventory.qml
+++ /dev/null
@@ -1,280 +0,0 @@
-//
-// Inventory.qml
-// qml/hifi/commerce
-//
-// Inventory
-//
-// Created by Zach Fox on 2017-08-10
-// Copyright 2017 High Fidelity, Inc.
-//
-// Distributed under the Apache License, Version 2.0.
-// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
-//
-
-import Hifi 1.0 as Hifi
-import QtQuick 2.5
-import QtQuick.Controls 1.4
-import "../../styles-uit"
-import "../../controls-uit" as HifiControlsUit
-import "../../controls" as HifiControls
-import "./wallet" as HifiWallet
-
-// references XXX from root context
-
-Rectangle {
- HifiConstants { id: hifi; }
-
- id: inventoryRoot;
- property string referrerURL: "";
- // Style
- color: hifi.colors.baseGray;
- Hifi.QmlCommerce {
- id: commerce;
- onBalanceResult: {
- if (result.status !== 'success') {
- console.log("Failed to get balance", result.message);
- } else {
- hfcBalanceText.text = parseFloat(result.data.balance/100).toFixed(2);
- }
- }
- onInventoryResult: {
- if (result.status !== 'success') {
- console.log("Failed to get inventory", result.message);
- } else {
- inventoryContentsList.model = result.data.assets;
- }
- }
- }
-
- //
- // TITLE BAR START
- //
- Item {
- id: titleBarContainer;
- // Size
- width: parent.width;
- height: 50;
- // Anchors
- anchors.left: parent.left;
- anchors.top: parent.top;
-
- // Title Bar text
- RalewaySemiBold {
- id: titleBarText;
- text: "Inventory";
- // Text size
- size: hifi.fontSizes.overlayTitle;
- // Anchors
- anchors.top: parent.top;
- anchors.left: parent.left;
- anchors.leftMargin: 16;
- anchors.bottom: parent.bottom;
- width: paintedWidth;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
-
- // Separator
- HifiControlsUit.Separator {
- anchors.left: parent.left;
- anchors.right: parent.right;
- anchors.bottom: parent.bottom;
- }
- }
- //
- // TITLE BAR END
- //
-
- //
- // HFC BALANCE START
- //
- Item {
- id: hfcBalanceContainer;
- // Size
- width: inventoryRoot.width;
- height: childrenRect.height + 20;
- // Anchors
- anchors.left: parent.left;
- anchors.leftMargin: 16;
- anchors.top: titleBarContainer.bottom;
- anchors.topMargin: 4;
-
- RalewaySemiBold {
- id: hfcBalanceTextLabel;
- text: "HFC Balance:";
- // Anchors
- anchors.top: parent.top;
- anchors.left: parent.left;
- width: paintedWidth;
- // Text size
- size: 20;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- RalewayRegular {
- id: hfcBalanceText;
- text: "--";
- // Text size
- size: hfcBalanceTextLabel.size;
- // Anchors
- anchors.top: parent.top;
- anchors.left: hfcBalanceTextLabel.right;
- anchors.leftMargin: 16;
- width: paintedWidth;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- }
- //
- // HFC BALANCE END
- //
-
- //
- // INVENTORY CONTENTS START
- //
- Item {
- id: inventoryContentsContainer;
- // Anchors
- anchors.left: parent.left;
- anchors.leftMargin: 16;
- anchors.right: parent.right;
- anchors.rightMargin: 16;
- anchors.top: hfcBalanceContainer.bottom;
- anchors.topMargin: 8;
- anchors.bottom: actionButtonsContainer.top;
- anchors.bottomMargin: 8;
-
- RalewaySemiBold {
- id: inventoryContentsLabel;
- text: "Inventory:";
- // Anchors
- anchors.top: parent.top;
- anchors.left: parent.left;
- width: paintedWidth;
- // Text size
- size: 24;
- // Style
- color: hifi.colors.lightGrayText;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- verticalAlignment: Text.AlignVCenter;
- }
- ListView {
- id: inventoryContentsList;
- clip: true;
- // Anchors
- anchors.top: inventoryContentsLabel.bottom;
- anchors.topMargin: 8;
- anchors.left: parent.left;
- anchors.bottom: parent.bottom;
- width: parent.width;
- delegate: Item {
- width: parent.width;
- height: 30;
- RalewayRegular {
- id: thisItemId;
- // Text size
- size: 20;
- // Style
- color: hifi.colors.blueAccent;
- text: modelData.title;
- // Alignment
- horizontalAlignment: Text.AlignHLeft;
- }
- MouseArea {
- anchors.fill: parent;
- hoverEnabled: enabled;
- onClicked: {
- sendToScript({method: 'inventory_itemClicked', itemId: modelData.id});
- }
- onEntered: {
- thisItemId.color = hifi.colors.blueHighlight;
- }
- onExited: {
- thisItemId.color = hifi.colors.blueAccent;
- }
- }
- }
- }
- }
- //
- // INVENTORY CONTENTS END
- //
-
- //
- // ACTION BUTTONS START
- //
- Item {
- id: actionButtonsContainer;
- // Size
- width: inventoryRoot.width;
- height: 40;
- // Anchors
- anchors.left: parent.left;
- anchors.bottom: parent.bottom;
- anchors.bottomMargin: 8;
-
- // "Back" button
- HifiControlsUit.Button {
- id: backButton;
- color: hifi.buttons.black;
- colorScheme: hifi.colorSchemes.dark;
- anchors.top: parent.top;
- anchors.topMargin: 3;
- anchors.bottom: parent.bottom;
- anchors.bottomMargin: 3;
- anchors.left: parent.left;
- anchors.leftMargin: 20;
- width: parent.width/2 - anchors.leftMargin*2;
- text: "Back"
- onClicked: {
- sendToScript({method: 'inventory_backClicked', referrerURL: referrerURL});
- }
- }
- }
- //
- // ACTION BUTTONS END
- //
-
- //
- // FUNCTION DEFINITIONS START
- //
- //
- // Function Name: fromScript()
- //
- // Relevant Variables:
- // None
- //
- // Arguments:
- // message: The message sent from the JavaScript, in this case the Marketplaces JavaScript.
- // Messages are in format "{method, params}", like json-rpc.
- //
- // Description:
- // Called when a message is received from a script.
- //
- function fromScript(message) {
- switch (message.method) {
- case 'updateInventory':
- referrerURL = message.referrerURL;
- commerce.balance();
- commerce.inventory();
- break;
- default:
- console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
- }
- }
- signal sendToScript(var message);
-
- //
- // FUNCTION DEFINITIONS END
- //
-}
diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml
new file mode 100644
index 0000000000..5329099df5
--- /dev/null
+++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml
@@ -0,0 +1,902 @@
+//
+// Checkout.qml
+// qml/hifi/commerce/checkout
+//
+// Checkout
+//
+// Created by Zach Fox on 2017-08-25
+// Copyright 2017 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+import Hifi 1.0 as Hifi
+import QtQuick 2.5
+import QtQuick.Controls 1.4
+import "../../../styles-uit"
+import "../../../controls-uit" as HifiControlsUit
+import "../../../controls" as HifiControls
+import "../wallet" as HifiWallet
+
+// references XXX from root context
+
+Rectangle {
+ HifiConstants { id: hifi; }
+
+ id: root;
+ property string activeView: "initialize";
+ property bool purchasesReceived: false;
+ property bool balanceReceived: false;
+ property string itemId: "";
+ property string itemHref: "";
+ property double balanceAfterPurchase: 0;
+ property bool alreadyOwned: false;
+ property int itemPriceFull: 0;
+ property bool itemIsJson: true;
+ property bool securityImageResultReceived: false;
+ property bool keyFilePathIfExistsResultReceived: false;
+ // Style
+ color: hifi.colors.baseGray;
+ Hifi.QmlCommerce {
+ id: commerce;
+
+ onSecurityImageResult: {
+ securityImageResultReceived = true;
+ if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up"
+ root.activeView = "notSetUp";
+ } else if (root.securityImageResultReceived && exists && root.keyFilePathIfExistsResultReceived && root.activeView === "initialize") {
+ root.activeView = "checkoutMain";
+ } else if (exists) {
+ // just set the source again (to be sure the change was noticed)
+ securityImage.source = "";
+ securityImage.source = "image://security/securityImage";
+ }
+ }
+
+ onKeyFilePathIfExistsResult: {
+ keyFilePathIfExistsResultReceived = true;
+ if (path === "" && root.activeView !== "notSetUp") {
+ root.activeView = "notSetUp";
+ } else if (root.securityImageResultReceived && root.keyFilePathIfExistsResultReceived && path !== "" && root.activeView === "initialize") {
+ root.activeView = "checkoutMain";
+ }
+ }
+
+ onBuyResult: {
+ if (result.status !== 'success') {
+ failureErrorText.text = "Here's some more info about the error:
" + (result.message);
+ root.activeView = "checkoutFailure";
+ } else {
+ root.activeView = "checkoutSuccess";
+ }
+ }
+
+ onBalanceResult: {
+ if (result.status !== 'success') {
+ console.log("Failed to get balance", result.data.message);
+ } else {
+ root.balanceReceived = true;
+ hfcBalanceText.text = (parseFloat(result.data.balance/100).toFixed(2)) + " HFC";
+ balanceAfterPurchase = parseFloat(result.data.balance/100) - root.itemPriceFull/100;
+ root.setBuyText();
+ }
+ }
+
+ onInventoryResult: {
+ if (result.status !== 'success') {
+ console.log("Failed to get purchases", result.data.message);
+ } else {
+ root.purchasesReceived = true;
+ if (purchasesContains(result.data.assets, itemId)) {
+ root.alreadyOwned = true;
+ } else {
+ root.alreadyOwned = false;
+ }
+ root.setBuyText();
+ }
+ }
+ }
+
+ HifiWallet.SecurityImageModel {
+ id: securityImageModel;
+ }
+
+ //
+ // TITLE BAR START
+ //
+ Item {
+ id: titleBarContainer;
+ // Size
+ width: parent.width;
+ height: 50;
+ // Anchors
+ anchors.left: parent.left;
+ anchors.top: parent.top;
+
+ // Title Bar text
+ RalewaySemiBold {
+ id: titleBarText;
+ text: "MARKETPLACE";
+ // Text size
+ size: hifi.fontSizes.overlayTitle;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.left: parent.left;
+ anchors.leftMargin: 16;
+ anchors.bottom: parent.bottom;
+ width: paintedWidth;
+ // Style
+ color: hifi.colors.faintGray;
+ // Alignment
+ horizontalAlignment: Text.AlignHLeft;
+ verticalAlignment: Text.AlignVCenter;
+ }
+
+ // Security Image (TEMPORARY!)
+ Image {
+ id: securityImage;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.right: parent.right;
+ anchors.verticalCenter: parent.verticalCenter;
+ height: parent.height - 10;
+ width: height;
+ fillMode: Image.PreserveAspectFit;
+ mipmap: true;
+ cache: false;
+ source: "image://security/securityImage";
+ }
+
+ // Separator
+ HifiControlsUit.Separator {
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ anchors.bottom: parent.bottom;
+ }
+ }
+ //
+ // TITLE BAR END
+ //
+
+ Rectangle {
+ id: initialize;
+ visible: root.activeView === "initialize";
+ anchors.top: titleBarContainer.bottom;
+ anchors.bottom: parent.top;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ color: hifi.colors.baseGray;
+
+ Component.onCompleted: {
+ commerce.getSecurityImage();
+ commerce.getKeyFilePathIfExists();
+ }
+ }
+
+ //
+ // "WALLET NOT SET UP" START
+ //
+ Item {
+ id: notSetUp;
+ visible: root.activeView === "notSetUp";
+ anchors.top: titleBarContainer.bottom;
+ anchors.bottom: parent.bottom;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+
+ RalewayRegular {
+ id: notSetUpText;
+ text: "Your wallet isn't set up.
Set up your Wallet (no credit card necessary) to claim your free HFC " +
+ "and get items from the Marketplace.";
+ // Text size
+ size: 24;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.bottom: notSetUpActionButtonsContainer.top;
+ anchors.left: parent.left;
+ anchors.leftMargin: 16;
+ anchors.right: parent.right;
+ anchors.rightMargin: 16;
+ // Style
+ color: hifi.colors.faintGray;
+ wrapMode: Text.WordWrap;
+ // Alignment
+ horizontalAlignment: Text.AlignHCenter;
+ verticalAlignment: Text.AlignVCenter;
+ }
+
+ Item {
+ id: notSetUpActionButtonsContainer;
+ // Size
+ width: root.width;
+ height: 70;
+ // Anchors
+ anchors.left: parent.left;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 24;
+
+ // "Cancel" button
+ HifiControlsUit.Button {
+ id: cancelButton;
+ color: hifi.buttons.black;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: parent.top;
+ anchors.topMargin: 3;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 3;
+ anchors.left: parent.left;
+ anchors.leftMargin: 20;
+ width: parent.width/2 - anchors.leftMargin*2;
+ text: "Cancel"
+ onClicked: {
+ sendToScript({method: 'checkout_cancelClicked', params: itemId});
+ }
+ }
+
+ // "Set Up" button
+ HifiControlsUit.Button {
+ id: setUpButton;
+ color: hifi.buttons.blue;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: parent.top;
+ anchors.topMargin: 3;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 3;
+ anchors.right: parent.right;
+ anchors.rightMargin: 20;
+ width: parent.width/2 - anchors.rightMargin*2;
+ text: "Set Up Wallet"
+ onClicked: {
+ sendToScript({method: 'checkout_setUpClicked'});
+ }
+ }
+ }
+ }
+ //
+ // "WALLET NOT SET UP" END
+ //
+
+ //
+ // CHECKOUT CONTENTS START
+ //
+ Item {
+ id: checkoutContents;
+ visible: root.activeView === "checkoutMain";
+ anchors.top: titleBarContainer.bottom;
+ anchors.bottom: parent.bottom;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+
+ onVisibleChanged: {
+ if (visible) {
+ commerce.balance();
+ commerce.inventory();
+ }
+ }
+
+ //
+ // ITEM DESCRIPTION START
+ //
+ Item {
+ id: itemDescriptionContainer;
+ // Anchors
+ anchors.left: parent.left;
+ anchors.leftMargin: 32;
+ anchors.right: parent.right;
+ anchors.rightMargin: 32;
+ anchors.top: parent.top;
+ anchors.bottom: checkoutActionButtonsContainer.top;
+
+ // HFC Balance text
+ Item {
+ id: hfcBalanceContainer;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.topMargin: 30;
+ anchors.left: parent.left;
+ anchors.leftMargin: 16;
+ anchors.right: parent.right;
+ anchors.rightMargin: 16;
+ height: childrenRect.height;
+
+ RalewaySemiBold {
+ id: hfcBalanceTextLabel;
+ text: "Balance:";
+ // Anchors
+ anchors.top: parent.top;
+ anchors.left: parent.left;
+ width: paintedWidth;
+ height: paintedHeight;
+ // Text size
+ size: 30;
+ // Style
+ color: hifi.colors.lightGrayText;
+ // Alignment
+ horizontalAlignment: Text.AlignLeft;
+ verticalAlignment: Text.AlignVCenter;
+ }
+ RalewayRegular {
+ id: hfcBalanceText;
+ text: "-- HFC";
+ // Text size
+ size: hfcBalanceTextLabel.size;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.left: hfcBalanceTextLabel.right;
+ anchors.leftMargin: 16;
+ anchors.right: parent.right;
+ anchors.rightMargin: 16;
+ height: paintedHeight;
+ // Style
+ color: hifi.colors.lightGrayText;
+ // Alignment
+ horizontalAlignment: Text.AlignRight;
+ verticalAlignment: Text.AlignVCenter;
+ }
+ }
+
+ // Item Name text
+ Item {
+ id: itemNameContainer;
+ // Anchors
+ anchors.top: hfcBalanceContainer.bottom;
+ anchors.topMargin: 32;
+ anchors.left: parent.left;
+ anchors.leftMargin: 16;
+ anchors.right: parent.right;
+ anchors.rightMargin: 16;
+ height: childrenRect.height;
+
+ RalewaySemiBold {
+ id: itemNameTextLabel;
+ text: "Item:";
+ // Anchors
+ anchors.top: parent.top;
+ anchors.left: parent.left;
+ width: paintedWidth;
+ height: paintedHeight;
+ // Text size
+ size: 20;
+ // Style
+ color: hifi.colors.lightGrayText;
+ // Alignment
+ horizontalAlignment: Text.AlignLeft;
+ verticalAlignment: Text.AlignVCenter;
+ }
+ RalewayRegular {
+ id: itemNameText;
+ // Text size
+ size: itemNameTextLabel.size;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.left: itemNameTextLabel.right;
+ anchors.leftMargin: 16;
+ anchors.right: parent.right;
+ anchors.rightMargin: 16;
+ height: paintedHeight;
+ // Style
+ color: hifi.colors.lightGrayText;
+ elide: Text.ElideRight;
+ // Alignment
+ horizontalAlignment: Text.AlignRight;
+ verticalAlignment: Text.AlignVCenter;
+ }
+ }
+
+
+ // Item Author text
+ Item {
+ id: itemAuthorContainer;
+ // Anchors
+ anchors.top: itemNameContainer.bottom;
+ anchors.topMargin: 4;
+ anchors.left: parent.left;
+ anchors.leftMargin: 16;
+ anchors.right: parent.right;
+ anchors.rightMargin: 16;
+ height: childrenRect.height;
+
+ RalewaySemiBold {
+ id: itemAuthorTextLabel;
+ text: "Author:";
+ // Anchors
+ anchors.top: parent.top;
+ anchors.left: parent.left;
+ width: paintedWidth;
+ height: paintedHeight;
+ // Text size
+ size: 20;
+ // Style
+ color: hifi.colors.lightGrayText;
+ // Alignment
+ horizontalAlignment: Text.AlignLeft;
+ verticalAlignment: Text.AlignVCenter;
+ }
+ RalewayRegular {
+ id: itemAuthorText;
+ // Text size
+ size: itemAuthorTextLabel.size;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.left: itemAuthorTextLabel.right;
+ anchors.leftMargin: 16;
+ anchors.right: parent.right;
+ anchors.rightMargin: 16;
+ height: paintedHeight;
+ // Style
+ color: hifi.colors.lightGrayText;
+ elide: Text.ElideRight;
+ // Alignment
+ horizontalAlignment: Text.AlignRight;
+ verticalAlignment: Text.AlignVCenter;
+ }
+ }
+
+ // "Item Price" container
+ Item {
+ id: itemPriceContainer;
+ // Anchors
+ anchors.top: itemAuthorContainer.bottom;
+ anchors.topMargin: 32;
+ anchors.left: parent.left;
+ anchors.leftMargin: 16;
+ anchors.right: parent.right;
+ anchors.rightMargin: 16;
+ height: childrenRect.height;
+
+ RalewaySemiBold {
+ id: itemPriceTextLabel;
+ text: "Item Price:";
+ // Anchors
+ anchors.top: parent.top;
+ anchors.left: parent.left;
+ width: paintedWidth;
+ height: paintedHeight;
+ // Text size
+ size: 30;
+ // Style
+ color: hifi.colors.lightGrayText;
+ // Alignment
+ horizontalAlignment: Text.AlignLeft;
+ verticalAlignment: Text.AlignVCenter;
+ }
+ RalewayRegular {
+ id: itemPriceText;
+ text: "-- HFC";
+ // Text size
+ size: itemPriceTextLabel.size;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.left: itemPriceTextLabel.right;
+ anchors.leftMargin: 16;
+ anchors.right: parent.right;
+ anchors.rightMargin: 16;
+ height: paintedHeight;
+ // Style
+ color: (balanceAfterPurchase >= 0) ? hifi.colors.lightGrayText : hifi.colors.redHighlight;
+ // Alignment
+ horizontalAlignment: Text.AlignRight;
+ verticalAlignment: Text.AlignVCenter;
+ }
+ }
+
+ // "Balance After Purchase" container
+ Item {
+ id: balanceAfterPurchaseContainer;
+ // Anchors
+ anchors.top: itemPriceContainer.bottom;
+ anchors.topMargin: 16;
+ anchors.left: parent.left;
+ anchors.leftMargin: 16;
+ anchors.right: parent.right;
+ anchors.rightMargin: 16;
+ height: childrenRect.height;
+
+ RalewaySemiBold {
+ id: balanceAfterPurchaseTextLabel;
+ text: "Balance After Purchase:";
+ // Anchors
+ anchors.top: parent.top;
+ anchors.left: parent.left;
+ width: paintedWidth;
+ height: paintedHeight;
+ // Text size
+ size: 20;
+ // Style
+ color: hifi.colors.lightGrayText;
+ // Alignment
+ horizontalAlignment: Text.AlignLeft;
+ verticalAlignment: Text.AlignVCenter;
+ }
+ RalewayRegular {
+ id: balanceAfterPurchaseText;
+ text: balanceAfterPurchase.toFixed(2) + " HFC";
+ // Text size
+ size: balanceAfterPurchaseTextLabel.size;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.left: balanceAfterPurchaseTextLabel.right;
+ anchors.leftMargin: 16;
+ anchors.right: parent.right;
+ anchors.rightMargin: 16;
+ height: paintedHeight;
+ // Style
+ color: (balanceAfterPurchase >= 0) ? hifi.colors.lightGrayText : hifi.colors.redHighlight;
+ // Alignment
+ horizontalAlignment: Text.AlignRight;
+ verticalAlignment: Text.AlignVCenter;
+ }
+ }
+ }
+ //
+ // ITEM DESCRIPTION END
+ //
+
+
+ //
+ // ACTION BUTTONS AND TEXT START
+ //
+ Item {
+ id: checkoutActionButtonsContainer;
+ // Size
+ width: root.width;
+ height: 200;
+ // Anchors
+ anchors.left: parent.left;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 8;
+
+ // "Cancel" button
+ HifiControlsUit.Button {
+ id: cancelPurchaseButton;
+ color: hifi.buttons.black;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: parent.top;
+ anchors.topMargin: 3;
+ height: 40;
+ anchors.left: parent.left;
+ anchors.leftMargin: 20;
+ width: parent.width/2 - anchors.leftMargin*2;
+ text: "Cancel"
+ onClicked: {
+ sendToScript({method: 'checkout_cancelClicked', params: itemId});
+ }
+ }
+
+ // "Buy" button
+ HifiControlsUit.Button {
+ id: buyButton;
+ enabled: (balanceAfterPurchase >= 0 && purchasesReceived && balanceReceived) || !itemIsJson;
+ color: hifi.buttons.blue;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: parent.top;
+ anchors.topMargin: 3;
+ height: 40;
+ anchors.right: parent.right;
+ anchors.rightMargin: 20;
+ width: parent.width/2 - anchors.rightMargin*2;
+ text: (itemIsJson ? ((purchasesReceived && balanceReceived) ? (root.alreadyOwned ? "Buy Another" : "Buy"): "--") : "Get Item");
+ onClicked: {
+ if (itemIsJson) {
+ buyButton.enabled = false;
+ commerce.buy(itemId, itemPriceFull);
+ } else {
+ if (urlHandler.canHandleUrl(itemHref)) {
+ urlHandler.handleUrl(itemHref);
+ }
+ }
+ }
+ }
+
+ // "Purchases" button
+ HifiControlsUit.Button {
+ id: goToPurchasesButton;
+ color: hifi.buttons.black;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: buyButton.bottom;
+ anchors.topMargin: 20;
+ anchors.bottomMargin: 7;
+ height: 40;
+ anchors.left: parent.left;
+ anchors.leftMargin: 20;
+ width: parent.width - anchors.leftMargin*2;
+ text: "View Purchases"
+ onClicked: {
+ sendToScript({method: 'checkout_goToPurchases'});
+ }
+ }
+
+ RalewayRegular {
+ id: buyText;
+ // Text size
+ size: 20;
+ // Anchors
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 10;
+ height: paintedHeight;
+ anchors.left: parent.left;
+ anchors.leftMargin: 10;
+ anchors.right: parent.right;
+ anchors.rightMargin: 10;
+ // Style
+ color: hifi.colors.faintGray;
+ wrapMode: Text.WordWrap;
+ // Alignment
+ horizontalAlignment: Text.AlignHCenter;
+ verticalAlignment: Text.AlignVCenter;
+ }
+ }
+ //
+ // ACTION BUTTONS END
+ //
+ }
+ //
+ // CHECKOUT CONTENTS END
+ //
+
+ //
+ // CHECKOUT SUCCESS START
+ //
+ Item {
+ id: checkoutSuccess;
+ visible: root.activeView === "checkoutSuccess";
+ anchors.top: titleBarContainer.bottom;
+ anchors.bottom: root.bottom;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+
+ RalewayRegular {
+ id: completeText;
+ text: "Purchase Complete!
You bought " + (itemNameText.text) + " by " + (itemAuthorText.text) + "";
+ // Text size
+ size: 24;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.topMargin: 40;
+ height: paintedHeight;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ // Style
+ color: hifi.colors.faintGray;
+ wrapMode: Text.WordWrap;
+ // Alignment
+ horizontalAlignment: Text.AlignHCenter;
+ verticalAlignment: Text.AlignVCenter;
+ }
+
+ Item {
+ id: checkoutSuccessActionButtonsContainer;
+ // Size
+ width: root.width;
+ height: 70;
+ // Anchors
+ anchors.top: completeText.bottom;
+ anchors.topMargin: 30;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+
+ // "Purchases" button
+ HifiControlsUit.Button {
+ id: purchasesButton;
+ color: hifi.buttons.black;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: parent.top;
+ anchors.topMargin: 3;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 3;
+ anchors.left: parent.left;
+ anchors.leftMargin: 20;
+ width: parent.width/2 - anchors.leftMargin*2;
+ text: "View Purchases";
+ onClicked: {
+ sendToScript({method: 'checkout_goToPurchases'});
+ }
+ }
+
+ // "Rez Now!" button
+ HifiControlsUit.Button {
+ id: rezNowButton;
+ color: hifi.buttons.blue;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: parent.top;
+ anchors.topMargin: 3;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 3;
+ anchors.right: parent.right;
+ anchors.rightMargin: 20;
+ width: parent.width/2 - anchors.rightMargin*2;
+ text: "Rez Now!"
+ onClicked: {
+ if (urlHandler.canHandleUrl(itemHref)) {
+ urlHandler.handleUrl(itemHref);
+ }
+ }
+ }
+ }
+
+ Item {
+ id: continueShoppingButtonContainer;
+ // Size
+ width: root.width;
+ height: 70;
+ // Anchors
+ anchors.left: parent.left;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 8;
+ // "Continue Shopping" button
+ HifiControlsUit.Button {
+ id: continueShoppingButton;
+ color: hifi.buttons.black;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: parent.top;
+ anchors.topMargin: 3;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 3;
+ anchors.left: parent.left;
+ anchors.leftMargin: 20;
+ width: parent.width/2 - anchors.rightMargin*2;
+ text: "Continue Shopping";
+ onClicked: {
+ sendToScript({method: 'checkout_continueShopping', itemId: itemId});
+ }
+ }
+ }
+ }
+ //
+ // CHECKOUT SUCCESS END
+ //
+
+ //
+ // CHECKOUT FAILURE START
+ //
+ Item {
+ id: checkoutFailure;
+ visible: root.activeView === "checkoutFailure";
+ anchors.top: titleBarContainer.bottom;
+ anchors.bottom: root.bottom;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+
+ RalewayRegular {
+ id: failureHeaderText;
+ text: "Purchase Failed.
Your Purchases and HFC balance haven't changed.";
+ // Text size
+ size: 24;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.topMargin: 80;
+ height: paintedHeight;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ // Style
+ color: hifi.colors.faintGray;
+ wrapMode: Text.WordWrap;
+ // Alignment
+ horizontalAlignment: Text.AlignHCenter;
+ verticalAlignment: Text.AlignVCenter;
+ }
+
+ RalewayRegular {
+ id: failureErrorText;
+ // Text size
+ size: 16;
+ // Anchors
+ anchors.top: failureHeaderText.bottom;
+ anchors.topMargin: 35;
+ height: paintedHeight;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ // Style
+ color: hifi.colors.faintGray;
+ wrapMode: Text.WordWrap;
+ // Alignment
+ horizontalAlignment: Text.AlignHCenter;
+ verticalAlignment: Text.AlignVCenter;
+ }
+
+ Item {
+ id: backToMarketplaceButtonContainer;
+ // Size
+ width: root.width;
+ height: 130;
+ // Anchors
+ anchors.left: parent.left;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 8;
+ // "Back to Marketplace" button
+ HifiControlsUit.Button {
+ id: backToMarketplaceButton;
+ color: hifi.buttons.black;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: parent.top;
+ anchors.topMargin: 3;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 3;
+ anchors.right: parent.right;
+ anchors.rightMargin: 20;
+ width: parent.width/2 - anchors.rightMargin*2;
+ text: "Back to Marketplace";
+ onClicked: {
+ sendToScript({method: 'checkout_continueShopping', itemId: itemId});
+ }
+ }
+ }
+ }
+ //
+ // CHECKOUT FAILURE END
+ //
+
+ //
+ // FUNCTION DEFINITIONS START
+ //
+ //
+ // Function Name: fromScript()
+ //
+ // Relevant Variables:
+ // None
+ //
+ // Arguments:
+ // message: The message sent from the JavaScript, in this case the Marketplaces JavaScript.
+ // Messages are in format "{method, params}", like json-rpc.
+ //
+ // Description:
+ // Called when a message is received from a script.
+ //
+ function fromScript(message) {
+ switch (message.method) {
+ case 'updateCheckoutQML':
+ itemId = message.params.itemId;
+ itemNameText.text = message.params.itemName;
+ itemAuthorText.text = message.params.itemAuthor;
+ root.itemPriceFull = message.params.itemPrice;
+ itemPriceText.text = root.itemPriceFull === 0 ? "Free" : "" + (parseFloat(root.itemPriceFull/100).toFixed(2)) + " HFC";
+ itemHref = message.params.itemHref;
+ if (itemHref.indexOf('.json') === -1) {
+ root.itemIsJson = false;
+ }
+ setBuyText();
+ break;
+ default:
+ console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
+ }
+ }
+ signal sendToScript(var message);
+
+ function purchasesContains(purchasesJson, id) {
+ for (var idx = 0; idx < purchasesJson.length; idx++) {
+ if(purchasesJson[idx].id === id) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function setBuyText() {
+ if (root.itemIsJson) {
+ if (root.purchasesReceived && root.balanceReceived) {
+ if (root.balanceAfterPurchase < 0) {
+ if (root.alreadyOwned) {
+ buyText.text = "You do not have enough HFC to purchase this item again. Go to your Purchases to view the copy you own.";
+ } else {
+ buyText.text = "You do not have enough HFC to purchase this item.";
+ }
+ } else {
+ if (root.alreadyOwned) {
+ buyText.text = "You already own this item. If you buy it again, you'll be able to use multiple copies of it at once.";
+ } else {
+ buyText.text = "This item will be added to your Purchases, which can be accessed from Marketplace.";
+ }
+ }
+ } else {
+ buyText.text = "";
+ }
+ } else {
+ buyText.text = "This Marketplace item isn't an entity. It will not be added to your Purchases.";
+ }
+ }
+
+ //
+ // FUNCTION DEFINITIONS END
+ //
+}
diff --git a/interface/resources/qml/hifi/commerce/images/01cat.jpg b/interface/resources/qml/hifi/commerce/images/01cat.jpg
deleted file mode 100644
index 6e7897cb82..0000000000
Binary files a/interface/resources/qml/hifi/commerce/images/01cat.jpg and /dev/null differ
diff --git a/interface/resources/qml/hifi/commerce/images/02car.jpg b/interface/resources/qml/hifi/commerce/images/02car.jpg
deleted file mode 100644
index 5dd8091e57..0000000000
Binary files a/interface/resources/qml/hifi/commerce/images/02car.jpg and /dev/null differ
diff --git a/interface/resources/qml/hifi/commerce/images/03dog.jpg b/interface/resources/qml/hifi/commerce/images/03dog.jpg
deleted file mode 100644
index 4a85b80c0c..0000000000
Binary files a/interface/resources/qml/hifi/commerce/images/03dog.jpg and /dev/null differ
diff --git a/interface/resources/qml/hifi/commerce/images/04stars.jpg b/interface/resources/qml/hifi/commerce/images/04stars.jpg
deleted file mode 100644
index 8f2bf62f83..0000000000
Binary files a/interface/resources/qml/hifi/commerce/images/04stars.jpg and /dev/null differ
diff --git a/interface/resources/qml/hifi/commerce/images/05plane.jpg b/interface/resources/qml/hifi/commerce/images/05plane.jpg
deleted file mode 100644
index 6504459d8b..0000000000
Binary files a/interface/resources/qml/hifi/commerce/images/05plane.jpg and /dev/null differ
diff --git a/interface/resources/qml/hifi/commerce/images/06gingerbread.jpg b/interface/resources/qml/hifi/commerce/images/06gingerbread.jpg
deleted file mode 100644
index 54c37faa2f..0000000000
Binary files a/interface/resources/qml/hifi/commerce/images/06gingerbread.jpg and /dev/null differ
diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml
new file mode 100644
index 0000000000..af32f5cfb7
--- /dev/null
+++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml
@@ -0,0 +1,143 @@
+//
+// PurchasedItem.qml
+// qml/hifi/commerce/purchases
+//
+// PurchasedItem
+//
+// Created by Zach Fox on 2017-08-25
+// Copyright 2017 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+import Hifi 1.0 as Hifi
+import QtQuick 2.5
+import QtQuick.Controls 1.4
+import "../../../styles-uit"
+import "../../../controls-uit" as HifiControlsUit
+import "../../../controls" as HifiControls
+import "../wallet" as HifiWallet
+
+// references XXX from root context
+
+Rectangle {
+ HifiConstants { id: hifi; }
+
+ id: root;
+ property string itemName: "";
+ property string itemId: "";
+ property string itemPreviewImageUrl: "";
+ property string itemHref: "";
+ // Style
+ color: hifi.colors.white;
+ // Size
+ width: parent.width;
+ height: 120;
+
+ Image {
+ id: itemPreviewImage;
+ source: root.itemPreviewImageUrl;
+ anchors.left: parent.left;
+ anchors.leftMargin: 8;
+ anchors.top: parent.top;
+ anchors.topMargin: 8;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 8;
+ width: 180;
+ fillMode: Image.PreserveAspectFit;
+
+ MouseArea {
+ anchors.fill: parent;
+ onClicked: {
+ sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
+ }
+ }
+ }
+
+
+ RalewayRegular {
+ id: itemName;
+ anchors.top: itemPreviewImage.top;
+ anchors.left: itemPreviewImage.right;
+ anchors.leftMargin: 8;
+ anchors.right: parent.right;
+ anchors.rightMargin: 8;
+ height: 30;
+ // Text size
+ size: 20;
+ // Style
+ color: hifi.colors.blueAccent;
+ text: root.itemName;
+ elide: Text.ElideRight;
+ // Alignment
+ horizontalAlignment: Text.AlignLeft;
+ verticalAlignment: Text.AlignVCenter;
+
+ MouseArea {
+ anchors.fill: parent;
+ hoverEnabled: enabled;
+ onClicked: {
+ sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
+ }
+ onEntered: {
+ itemName.color = hifi.colors.blueHighlight;
+ }
+ onExited: {
+ itemName.color = hifi.colors.blueAccent;
+ }
+ }
+ }
+
+ Item {
+ id: buttonContainer;
+ anchors.top: itemName.bottom;
+ anchors.topMargin: 8;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 8;
+ anchors.left: itemPreviewImage.right;
+ anchors.leftMargin: 8;
+ anchors.right: parent.right;
+ anchors.rightMargin: 8;
+
+ // "Rez" button
+ HifiControlsUit.Button {
+ id: rezButton;
+ color: hifi.buttons.blue;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: parent.top;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ height: parent.height/2 - 4;
+ text: "Rez Item"
+ onClicked: {
+ if (urlHandler.canHandleUrl(root.itemHref)) {
+ urlHandler.handleUrl(root.itemHref);
+ }
+ }
+ }
+
+ // "More Info" button
+ HifiControlsUit.Button {
+ id: moreInfoButton;
+ color: hifi.buttons.black;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.bottom: parent.bottom;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ height: parent.height/2 - 4;
+ text: "More Info"
+ onClicked: {
+ sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
+ }
+ }
+ }
+
+ //
+ // FUNCTION DEFINITIONS START
+ //
+ signal sendToPurchases(var msg);
+ //
+ // FUNCTION DEFINITIONS END
+ //
+}
diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
new file mode 100644
index 0000000000..5060b65e0b
--- /dev/null
+++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
@@ -0,0 +1,414 @@
+//
+// Purchases.qml
+// qml/hifi/commerce/purchases
+//
+// Purchases
+//
+// Created by Zach Fox on 2017-08-25
+// Copyright 2017 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+import Hifi 1.0 as Hifi
+import QtQuick 2.5
+import QtQuick.Controls 1.4
+import "../../../styles-uit"
+import "../../../controls-uit" as HifiControlsUit
+import "../../../controls" as HifiControls
+import "../wallet" as HifiWallet
+
+// references XXX from root context
+
+Rectangle {
+ HifiConstants { id: hifi; }
+
+ id: root;
+ property string activeView: "initialize";
+ property string referrerURL: "";
+ property bool securityImageResultReceived: false;
+ property bool keyFilePathIfExistsResultReceived: false;
+ property bool punctuationMode: false;
+ // Style
+ color: hifi.colors.baseGray;
+ Hifi.QmlCommerce {
+ id: commerce;
+
+ onSecurityImageResult: {
+ securityImageResultReceived = true;
+ if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up"
+ root.activeView = "notSetUp";
+ } else if (root.securityImageResultReceived && exists && root.keyFilePathIfExistsResultReceived && root.activeView === "initialize") {
+ root.activeView = "purchasesMain";
+ } else if (exists) {
+ // just set the source again (to be sure the change was noticed)
+ securityImage.source = "";
+ securityImage.source = "image://security/securityImage";
+ }
+ }
+
+ onKeyFilePathIfExistsResult: {
+ keyFilePathIfExistsResultReceived = true;
+ if (path === "" && root.activeView !== "notSetUp") {
+ root.activeView = "notSetUp";
+ } else if (root.securityImageResultReceived && root.keyFilePathIfExistsResultReceived && path !== "" && root.activeView === "initialize") {
+ root.activeView = "purchasesMain";
+ }
+ }
+
+ onInventoryResult: {
+ if (result.status !== 'success') {
+ console.log("Failed to get purchases", result.message);
+ } else {
+ purchasesModel.append(result.data.assets);
+ filteredPurchasesModel.append(result.data.assets);
+ }
+ }
+ }
+
+ HifiWallet.SecurityImageModel {
+ id: securityImageModel;
+ }
+
+ //
+ // TITLE BAR START
+ //
+ Item {
+ id: titleBarContainer;
+ // Size
+ height: 50;
+ // Anchors
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ anchors.top: parent.top;
+
+ // Title Bar text
+ RalewaySemiBold {
+ id: titleBarText;
+ text: "PURCHASES";
+ // Text size
+ size: hifi.fontSizes.overlayTitle;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.left: parent.left;
+ anchors.leftMargin: 16;
+ anchors.bottom: parent.bottom;
+ width: paintedWidth;
+ // Style
+ color: hifi.colors.faintGray;
+ // Alignment
+ horizontalAlignment: Text.AlignHLeft;
+ verticalAlignment: Text.AlignVCenter;
+ }
+
+ // Security Image (TEMPORARY!)
+ Image {
+ id: securityImage;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.right: parent.right;
+ anchors.verticalCenter: parent.verticalCenter;
+ height: parent.height - 10;
+ width: height;
+ fillMode: Image.PreserveAspectFit;
+ mipmap: true;
+ cache: false;
+ source: "image://security/securityImage";
+ }
+
+ // Separator
+ HifiControlsUit.Separator {
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ anchors.bottom: parent.bottom;
+ }
+ }
+ //
+ // TITLE BAR END
+ //
+
+ Rectangle {
+ id: initialize;
+ visible: root.activeView === "initialize";
+ anchors.top: titleBarContainer.bottom;
+ anchors.bottom: parent.bottom;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ color: hifi.colors.baseGray;
+
+ Component.onCompleted: {
+ commerce.getSecurityImage();
+ commerce.getKeyFilePathIfExists();
+ }
+ }
+
+ //
+ // "WALLET NOT SET UP" START
+ //
+ Item {
+ id: notSetUp;
+ visible: root.activeView === "notSetUp";
+ anchors.top: titleBarContainer.bottom;
+ anchors.bottom: parent.bottom;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+
+ RalewayRegular {
+ id: notSetUpText;
+ text: "Your wallet isn't set up.
Set up your Wallet (no credit card necessary) to claim your free HFC " +
+ "and get items from the Marketplace.";
+ // Text size
+ size: 24;
+ // Anchors
+ anchors.top: parent.top;
+ anchors.bottom: notSetUpActionButtonsContainer.top;
+ anchors.left: parent.left;
+ anchors.leftMargin: 16;
+ anchors.right: parent.right;
+ anchors.rightMargin: 16;
+ // Style
+ color: hifi.colors.faintGray;
+ wrapMode: Text.WordWrap;
+ // Alignment
+ horizontalAlignment: Text.AlignHCenter;
+ verticalAlignment: Text.AlignVCenter;
+ }
+
+ Item {
+ id: notSetUpActionButtonsContainer;
+ // Size
+ width: root.width;
+ height: 70;
+ // Anchors
+ anchors.left: parent.left;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 24;
+
+ // "Cancel" button
+ HifiControlsUit.Button {
+ id: cancelButton;
+ color: hifi.buttons.black;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: parent.top;
+ anchors.topMargin: 3;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 3;
+ anchors.left: parent.left;
+ anchors.leftMargin: 20;
+ width: parent.width/2 - anchors.leftMargin*2;
+ text: "Cancel"
+ onClicked: {
+ sendToScript({method: 'purchases_backClicked', referrerURL: referrerURL});
+ }
+ }
+
+ // "Set Up" button
+ HifiControlsUit.Button {
+ id: setUpButton;
+ color: hifi.buttons.blue;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: parent.top;
+ anchors.topMargin: 3;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 3;
+ anchors.right: parent.right;
+ anchors.rightMargin: 20;
+ width: parent.width/2 - anchors.rightMargin*2;
+ text: "Set Up Wallet"
+ onClicked: {
+ sendToScript({method: 'checkout_setUpClicked'});
+ }
+ }
+ }
+ }
+ //
+ // "WALLET NOT SET UP" END
+ //
+
+ //
+ // PURCHASES CONTENTS START
+ //
+ Item {
+ id: purchasesContentsContainer;
+ visible: root.activeView === "purchasesMain";
+ // Anchors
+ anchors.left: parent.left;
+ anchors.leftMargin: 4;
+ anchors.right: parent.right;
+ anchors.rightMargin: 4;
+ anchors.top: titleBarContainer.bottom;
+ anchors.topMargin: 8;
+ anchors.bottom: actionButtonsContainer.top;
+ anchors.bottomMargin: 8;
+
+ onVisibleChanged: {
+ if (visible) {
+ commerce.balance();
+ commerce.inventory();
+ }
+ }
+
+ //
+ // FILTER BAR START
+ //
+ Item {
+ id: filterBarContainer;
+ // Size
+ height: 40;
+ // Anchors
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ anchors.top: parent.top;
+ anchors.topMargin: 4;
+
+ HifiControlsUit.TextField {
+ id: filterBar;
+ property int previousLength: 0;
+ anchors.fill: parent;
+ placeholderText: "Filter";
+
+ onTextChanged: {
+ if (filterBar.text.length < previousLength) {
+ filteredPurchasesModel.clear();
+
+ for (var i = 0; i < purchasesModel.count; i++) {
+ filteredPurchasesModel.append(purchasesModel.get(i));
+ }
+ }
+
+ for (var i = 0; i < filteredPurchasesModel.count; i++) {
+ if (filteredPurchasesModel.get(i).title.toLowerCase().indexOf(filterBar.text.toLowerCase()) === -1) {
+ filteredPurchasesModel.remove(i);
+ i--;
+ }
+ }
+ previousLength = filterBar.text.length;
+ }
+
+ onAccepted: {
+ focus = false;
+ }
+ }
+ }
+ //
+ // FILTER BAR END
+ //
+
+ ListModel {
+ id: purchasesModel;
+ }
+ ListModel {
+ id: filteredPurchasesModel;
+ }
+
+ ListView {
+ id: purchasesContentsList;
+ clip: true;
+ model: filteredPurchasesModel;
+ // Anchors
+ anchors.top: filterBarContainer.bottom;
+ anchors.topMargin: 12;
+ anchors.left: parent.left;
+ anchors.bottom: parent.bottom;
+ width: parent.width;
+ delegate: PurchasedItem {
+ itemName: title;
+ itemId: id;
+ itemPreviewImageUrl: preview;
+ itemHref: root_file_url;
+ anchors.topMargin: 12;
+ anchors.bottomMargin: 12;
+
+ Connections {
+ onSendToPurchases: {
+ if (msg.method === 'purchases_itemInfoClicked') {
+ sendToScript({method: 'purchases_itemInfoClicked', itemId: itemId});
+ }
+ }
+ }
+ }
+ }
+ }
+ //
+ // PURCHASES CONTENTS END
+ //
+
+ //
+ // ACTION BUTTONS START
+ //
+ Item {
+ id: actionButtonsContainer;
+ visible: purchasesContentsContainer.visible;
+ // Size
+ width: parent.width;
+ height: 40;
+ // Anchors
+ anchors.left: parent.left;
+ anchors.bottom: keyboard.top;
+ anchors.bottomMargin: 8;
+
+ // "Back" button
+ HifiControlsUit.Button {
+ id: backButton;
+ color: hifi.buttons.black;
+ colorScheme: hifi.colorSchemes.dark;
+ anchors.top: parent.top;
+ anchors.topMargin: 3;
+ anchors.bottom: parent.bottom;
+ anchors.bottomMargin: 3;
+ anchors.left: parent.left;
+ anchors.leftMargin: 20;
+ width: parent.width/2 - anchors.leftMargin*2;
+ text: "Back"
+ onClicked: {
+ sendToScript({method: 'purchases_backClicked', referrerURL: referrerURL});
+ }
+ }
+ }
+ //
+ // ACTION BUTTONS END
+ //
+
+ HifiControlsUit.Keyboard {
+ id: keyboard;
+ raised: HMD.mounted && filterBar.focus;
+ numeric: parent.punctuationMode;
+ anchors {
+ bottom: parent.bottom;
+ left: parent.left;
+ right: parent.right;
+ }
+ }
+
+ //
+ // FUNCTION DEFINITIONS START
+ //
+ //
+ // Function Name: fromScript()
+ //
+ // Relevant Variables:
+ // None
+ //
+ // Arguments:
+ // message: The message sent from the JavaScript, in this case the Marketplaces JavaScript.
+ // Messages are in format "{method, params}", like json-rpc.
+ //
+ // Description:
+ // Called when a message is received from a script.
+ //
+ function fromScript(message) {
+ switch (message.method) {
+ case 'updatePurchases':
+ referrerURL = message.referrerURL;
+ break;
+ default:
+ console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
+ }
+ }
+ signal sendToScript(var message);
+
+ //
+ // FUNCTION DEFINITIONS END
+ //
+}
diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml
index 88f939d393..33faacd0ab 100644
--- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml
+++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml
@@ -39,6 +39,13 @@ Item {
onBalanceResult : {
balanceText.text = parseFloat(result.data.balance/100).toFixed(2);
}
+
+ onHistoryResult : {
+ if (result.status === 'success') {
+ var txt = result.data.history.map(function (h) { return h.text; }).join("