diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml
index 3c0577532a..dbe4235cdd 100644
--- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml
+++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml
@@ -96,7 +96,7 @@ Item {
topMargin: hifi.dimensions.contentSpacing.y
}
- text: qsTr("Sign in to High Fidelity to make friends, get HFC, and buy interesting things on the Marketplace!")
+ text: qsTr("Sign in to High Fidelity to make friends, get HFC, and get interesting things on the Marketplace!")
width: parent.width
wrapMode: Text.WordWrap
lineHeight: 1
diff --git a/interface/resources/qml/controls-uit/FilterBar.qml b/interface/resources/qml/controls-uit/FilterBar.qml
index ecae790b22..3d4e18ed48 100644
--- a/interface/resources/qml/controls-uit/FilterBar.qml
+++ b/interface/resources/qml/controls-uit/FilterBar.qml
@@ -260,38 +260,50 @@ Item {
interactive: false;
anchors.fill: parent;
model: filterBarModel;
- delegate: Rectangle {
- id: dropDownButton;
- color: hifi.colors.white;
+ delegate: Item {
width: parent.width;
height: 50;
+ Rectangle {
+ id: dropDownButton;
+ color: hifi.colors.white;
+ width: parent.width;
+ height: 50;
+ visible: true;
- RalewaySemiBold {
- id: dropDownButtonText;
- text: model.displayName;
- anchors.fill: parent;
- anchors.leftMargin: 12;
- color: hifi.colors.baseGray;
- horizontalAlignment: Text.AlignLeft;
- verticalAlignment: Text.AlignVCenter;
- size: 18;
+ RalewaySemiBold {
+ id: dropDownButtonText;
+ text: model.displayName;
+ anchors.fill: parent;
+ anchors.topMargin: 2;
+ anchors.leftMargin: 12;
+ color: hifi.colors.baseGray;
+ horizontalAlignment: Text.AlignLeft;
+ verticalAlignment: Text.AlignVCenter;
+ size: 18;
+ }
+
+ MouseArea {
+ anchors.fill: parent;
+ hoverEnabled: true;
+ propagateComposedEvents: false;
+ onEntered: {
+ dropDownButton.color = hifi.colors.blueHighlight;
+ }
+ onExited: {
+ dropDownButton.color = hifi.colors.white;
+ }
+ onClicked: {
+ textField.forceActiveFocus();
+ root.primaryFilter_index = index;
+ dropdownContainer.visible = false;
+ }
+ }
}
-
- MouseArea {
- anchors.fill: parent;
- hoverEnabled: true;
- propagateComposedEvents: false;
- onEntered: {
- dropDownButton.color = hifi.colors.blueHighlight;
- }
- onExited: {
- dropDownButton.color = hifi.colors.white;
- }
- onClicked: {
- textField.forceActiveFocus();
- root.primaryFilter_index = index;
- dropdownContainer.visible = false;
- }
+ Rectangle {
+ height: 2;
+ width: parent.width;
+ color: hifi.colors.lightGray;
+ visible: model.separator
}
}
}
diff --git a/interface/resources/qml/hifi/avatarapp/MessageBoxes.qml b/interface/resources/qml/hifi/avatarapp/MessageBoxes.qml
index b7782c697d..89a8eff025 100644
--- a/interface/resources/qml/hifi/avatarapp/MessageBoxes.qml
+++ b/interface/resources/qml/hifi/avatarapp/MessageBoxes.qml
@@ -63,8 +63,8 @@ MessageBox {
popup.dialogButtons.yesButton.fontCapitalization = Font.MixedCase;
popup.button1text = 'CANCEL'
popup.titleText = 'Get Wearables'
- popup.bodyText = 'Buy wearables from Marketplace.' + ' ' +
- 'Wear wearable from My Purchases.' + ' ' + ' ' +
+ popup.bodyText = 'Get wearables from Marketplace.' + ' ' +
+ 'Wear wearable from Inventory.' + ' ' + ' ' +
'Visit “AvatarIsland” to get wearables'
popup.imageSource = getWearablesUrl;
@@ -89,7 +89,7 @@ MessageBox {
function showDeleteFavorite(favoriteName, callback) {
popup.titleText = 'Delete Favorite: {AvatarName}'.replace('{AvatarName}', favoriteName)
- popup.bodyText = 'This will delete your favorite. You will retain access to the wearables and avatar that made up the favorite from My Purchases.'
+ popup.bodyText = 'This will delete your favorite. You will retain access to the wearables and avatar that made up the favorite from Inventory.'
popup.imageSource = null;
popup.button1text = 'CANCEL'
popup.button2text = 'DELETE'
@@ -128,8 +128,8 @@ MessageBox {
popup.button1text = 'CANCEL'
popup.titleText = 'Get Avatars'
- popup.bodyText = 'Buy avatars from Marketplace.' + ' ' +
- 'Wear avatars in My Purchases.' + ' ' + ' ' +
+ popup.bodyText = 'Get avatars from Marketplace.' + ' ' +
+ 'Wear avatars in Inventory.' + ' ' + ' ' +
'Visit “BodyMart” to get free avatars.'
popup.imageSource = getAvatarsUrl;
diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml
index b13f23f17d..271aab87d1 100644
--- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml
+++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml
@@ -240,11 +240,6 @@ Rectangle {
lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
- lightboxPopup.button2text = "GO TO WALLET";
- lightboxPopup.button2method = function() {
- lightboxPopup.visible = false;
- sendToScript({method: 'checkout_openWallet'});
- };
lightboxPopup.visible = true;
} else {
sendToScript(msg);
@@ -383,7 +378,7 @@ Rectangle {
anchors.leftMargin: 16;
width: paintedWidth;
height: paintedHeight;
- text: "Review Purchase:";
+ text: "Review:";
color: hifi.colors.black;
size: 28;
}
@@ -448,7 +443,7 @@ Rectangle {
// "HFC" balance label
HiFiGlyphs {
id: itemPriceTextLabel;
- visible: !(root.isUpdating && root.itemEdition > 0);
+ visible: !(root.isUpdating && root.itemEdition > 0) && (root.itemPrice > 0);
text: hifi.glyphs.hfc;
// Size
size: 30;
@@ -464,7 +459,7 @@ Rectangle {
}
FiraSansSemiBold {
id: itemPriceText;
- text: (root.isUpdating && root.itemEdition > 0) ? "FREE\nUPDATE" : ((root.itemPrice === -1) ? "--" : root.itemPrice);
+ text: (root.isUpdating && root.itemEdition > 0) ? "FREE\nUPDATE" : ((root.itemPrice === -1) ? "--" : ((root.itemPrice > 0) ? root.itemPrice : "FREE"));
// Text size
size: (root.isUpdating && root.itemEdition > 0) ? 20 : 26;
// Anchors
@@ -559,7 +554,7 @@ Rectangle {
}
}
- // "View in My Purchases" button
+ // "View in Inventory" button
HifiControlsUit.Button {
id: viewInMyPurchasesButton;
visible: false;
@@ -570,7 +565,7 @@ Rectangle {
height: 50;
anchors.left: parent.left;
anchors.right: parent.right;
- text: root.isUpdating ? "UPDATE TO THIS ITEM FOR FREE" : "VIEW THIS ITEM IN MY PURCHASES";
+ text: root.isUpdating ? "UPDATE TO THIS ITEM FOR FREE" : "VIEW THIS ITEM IN YOUR INVENTORY";
onClicked: {
if (root.isUpdating) {
sendToScript({method: 'checkout_goToPurchases', filterText: root.baseItemName});
@@ -594,7 +589,7 @@ Rectangle {
anchors.left: parent.left;
anchors.right: parent.right;
text: (root.isUpdating && root.itemEdition > 0) ? "CONFIRM UPDATE" : (((root.isCertified) ? ((ownershipStatusReceived && balanceReceived && availableUpdatesReceived) ?
- ((viewInMyPurchasesButton.visible && !root.isUpdating) ? "Buy It Again" : "Confirm Purchase") : "--") : "Get Item"));
+ ((viewInMyPurchasesButton.visible && !root.isUpdating) ? "Get It Again" : "Confirm") : "--") : "Get Item"));
onClicked: {
if (root.isUpdating && root.itemEdition > 0) {
// If we're updating an app, the existing app needs to be uninstalled.
@@ -608,9 +603,9 @@ Rectangle {
} else if (root.isCertified) {
if (!root.shouldBuyWithControlledFailure) {
if (root.itemType === "contentSet" && !Entities.canReplaceContent()) {
- lightboxPopup.titleText = "Purchase Content Set";
+ lightboxPopup.titleText = "Get Content Set";
lightboxPopup.bodyText = "You will not be able to replace this domain's content with " + root.itemName +
- " until the server owner gives you 'Replace Content' permissions.
Are you sure you want to purchase this content set?";
+ " until the server owner gives you 'Replace Content' permissions.
Are you sure you want to get this content set?";
lightboxPopup.button1text = "CANCEL";
lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
@@ -694,7 +689,7 @@ Rectangle {
id: completeText2;
text: "The " + (root.itemTypesText)[itemTypesArray.indexOf(root.itemType)] +
' ' + root.itemName + '' +
- " has been added to your Purchases and a receipt will appear in your Wallet's transaction history.";
+ " has been added to your Inventory.";
// Text size
size: 18;
// Anchors
@@ -833,7 +828,7 @@ Rectangle {
}
lightboxPopup.button2text = "OPEN GOTO";
lightboxPopup.button2method = function() {
- sendToScript({method: 'purchases_openGoTo'});
+ sendToScript({method: 'checkout_openGoTo'});
lightboxPopup.visible = false;
};
lightboxPopup.visible = true;
@@ -864,7 +859,7 @@ Rectangle {
RalewaySemiBold {
id: myPurchasesLink;
- text: 'View this item in My Purchases';
+ text: 'View this item in your Inventory';
// Text size
size: 18;
// Anchors
@@ -886,7 +881,8 @@ Rectangle {
RalewaySemiBold {
id: walletLink;
- text: 'View receipt in Wallet';
+ visible: !WalletScriptingInterface.limitedCommerce;
+ text: 'View receipt in Recent Activity';
// Text size
size: 18;
// Anchors
@@ -902,18 +898,18 @@ Rectangle {
horizontalAlignment: Text.AlignLeft;
verticalAlignment: Text.AlignVCenter;
onLinkActivated: {
- sendToScript({method: 'purchases_openWallet'});
+ sendToScript({method: 'checkout_openRecentActivity'});
}
}
RalewayRegular {
id: pendingText;
- text: 'Your item is marked "pending" while your purchase is being confirmed. ' +
+ text: 'Your item is marked "pending" while the transfer is being confirmed. ' +
'Learn More';
// Text size
size: 18;
// Anchors
- anchors.top: walletLink.bottom;
+ anchors.top: walletLink.visible ? walletLink.bottom : myPurchasesLink.bottom;
anchors.topMargin: 32;
height: paintedHeight;
anchors.left: parent.left;
@@ -925,8 +921,8 @@ Rectangle {
horizontalAlignment: Text.AlignLeft;
verticalAlignment: Text.AlignVCenter;
onLinkActivated: {
- lightboxPopup.titleText = "Purchase Confirmations";
- lightboxPopup.bodyText = 'Your item is marked "pending" while your purchase is being confirmed.
' +
+ lightboxPopup.titleText = "Confirmations";
+ lightboxPopup.bodyText = 'Your item is marked "pending" while the transfer is being confirmed.
' +
'Confirmations usually take about 90 seconds.';
lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = function() {
@@ -936,9 +932,9 @@ Rectangle {
}
}
- // "Continue Shopping" button
+ // "Continue" button
HifiControlsUit.Button {
- id: continueShoppingButton;
+ id: continueButton;
color: hifi.buttons.noneBorderlessGray;
colorScheme: hifi.colorSchemes.light;
anchors.bottom: parent.bottom;
@@ -946,9 +942,9 @@ Rectangle {
anchors.right: parent.right;
width: 193;
height: 44;
- text: "Continue Shopping";
+ text: "Continue";
onClicked: {
- sendToScript({method: 'checkout_continueShopping', itemId: itemId});
+ sendToScript({method: 'checkout_continue', itemId: itemId});
}
}
}
@@ -971,7 +967,7 @@ Rectangle {
RalewayRegular {
id: failureHeaderText;
- text: "Purchase Failed. Your Purchases and HFC balance haven't changed.";
+ text: "Purchase Failed. Your Inventory and HFC balance haven't changed.";
// Text size
size: 24;
// Anchors
@@ -1037,7 +1033,7 @@ Rectangle {
width: parent.width/2 - anchors.leftMargin*2;
text: "Back to Marketplace";
onClicked: {
- sendToScript({method: 'checkout_continueShopping', itemId: itemId});
+ sendToScript({method: 'checkout_continue', itemId: itemId});
}
}
}
@@ -1122,10 +1118,10 @@ Rectangle {
if (root.balanceAfterPurchase < 0) {
// If you already own the item...
if (!root.alreadyOwned) {
- buyText.text = "Your Wallet does not have sufficient funds to purchase this item.";
+ buyText.text = "You do not have sufficient funds to purchase this item.";
// Else if you don't already own the item...
} else if (canBuyAgain()) {
- buyText.text = "Your Wallet does not have sufficient funds to purchase this item again.";
+ buyText.text = "You do not have sufficient funds to purchase this item again.";
} else {
buyText.text = "While you do not have sufficient funds to buy this, you already have this item."
}
@@ -1171,7 +1167,7 @@ Rectangle {
buyText.text = "";
}
} else {
- buyText.text = 'This type of item cannot currently be certified, so it will not show up in "My Purchases". You can access it again for free from the Marketplace.';
+ buyText.text = 'This type of item cannot currently be certified, so it will not show up in "Inventory". You can access it again for free from the Marketplace.';
buyTextContainer.color = hifi.colors.white;
buyTextContainer.border.color = hifi.colors.white;
buyGlyph.text = "";
diff --git a/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml b/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml
index 1b77dcd3e9..99c2d89da8 100644
--- a/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml
+++ b/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml
@@ -27,7 +27,6 @@ Item {
property string referrerURL: (Account.metaverseServerURL + "/marketplace?");
readonly property int additionalDropdownHeight: usernameDropdown.height - myUsernameButton.anchors.bottomMargin;
property alias usernameDropdownVisible: usernameDropdown.visible;
- property bool messagesWaiting: false;
height: mainContainer.height + additionalDropdownHeight;
@@ -38,7 +37,6 @@ Item {
if (walletStatus === 0) {
sendToParent({method: "needsLogIn"});
} else if (walletStatus === 5) {
- Commerce.getAvailableUpdates();
Commerce.getSecurityImage();
} else if (walletStatus > 5) {
console.log("ERROR in EmulatedMarketplaceHeader.qml: Unknown wallet status: " + walletStatus);
@@ -59,14 +57,6 @@ Item {
securityImage.source = "image://security/securityImage";
}
}
-
- onAvailableUpdatesResult: {
- if (result.status !== 'success') {
- console.log("Failed to get Available Updates", result.data.message);
- } else {
- root.messagesWaiting = result.data.updates.length > 0;
- }
- }
}
Component.onCompleted: {
@@ -118,50 +108,6 @@ Item {
anchors.right: securityImage.left;
anchors.rightMargin: 6;
- Rectangle {
- id: myPurchasesLink;
- anchors.right: myUsernameButton.left;
- anchors.rightMargin: 8;
- anchors.verticalCenter: parent.verticalCenter;
- height: 40;
- width: myPurchasesText.paintedWidth + 10;
-
- RalewaySemiBold {
- id: myPurchasesText;
- text: "My Purchases";
- // Text size
- size: 18;
- // Style
- color: hifi.colors.blueAccent;
- horizontalAlignment: Text.AlignHCenter;
- verticalAlignment: Text.AlignVCenter;
- // Anchors
- anchors.centerIn: parent;
- }
-
- MouseArea {
- anchors.fill: parent;
- hoverEnabled: enabled;
- onClicked: {
- sendToParent({ method: 'header_goToPurchases', hasUpdates: root.messagesWaiting });
- }
- onEntered: myPurchasesText.color = hifi.colors.blueHighlight;
- onExited: myPurchasesText.color = hifi.colors.blueAccent;
- }
- }
-
- Rectangle {
- id: messagesWaitingLight;
- visible: root.messagesWaiting;
- anchors.right: myPurchasesLink.left;
- anchors.rightMargin: -2;
- anchors.verticalCenter: parent.verticalCenter;
- height: 10;
- width: height;
- radius: height/2;
- color: "red";
- }
-
TextMetrics {
id: textMetrics;
font.family: "Raleway"
@@ -267,7 +213,7 @@ Item {
anchors.topMargin: -buttonAndUsernameContainer.anchors.bottomMargin;
anchors.right: buttonAndUsernameContainer.right;
height: childrenRect.height;
- width: 100;
+ width: 150;
Rectangle {
id: myItemsButton;
@@ -279,7 +225,7 @@ Item {
RalewaySemiBold {
anchors.fill: parent;
- text: "My Items"
+ text: "My Submissions"
color: hifi.colors.baseGray;
horizontalAlignment: Text.AlignHCenter;
verticalAlignment: Text.AlignVCenter;
diff --git a/interface/resources/qml/hifi/commerce/common/FirstUseTutorial.qml b/interface/resources/qml/hifi/commerce/common/FirstUseTutorial.qml
index 5f874d3f04..0b982893f1 100644
--- a/interface/resources/qml/hifi/commerce/common/FirstUseTutorial.qml
+++ b/interface/resources/qml/hifi/commerce/common/FirstUseTutorial.qml
@@ -87,7 +87,7 @@ Rectangle {
}
RalewayRegular {
id: introText2;
- text: "My Purchases";
+ text: "Inventory";
// Text size
size: 22;
// Anchors
@@ -116,7 +116,7 @@ Rectangle {
RalewayRegular {
id: step1text;
- text: "The 'REZ IT' button makes your purchase appear in front of you.";
+ text: "The 'REZ IT' button makes your item appear in front of you.";
// Text size
size: 20;
// Anchors
diff --git a/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml b/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml
index 0a5c3e8053..bb4bb624bc 100644
--- a/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml
+++ b/interface/resources/qml/hifi/commerce/common/sendAsset/SendAsset.qml
@@ -73,6 +73,10 @@ Item {
}
onTransferAssetToNodeResult: {
+ if (!root.visible) {
+ return;
+ }
+
root.isCurrentlySendingAsset = false;
if (result.status === 'success') {
@@ -92,6 +96,10 @@ Item {
}
onTransferAssetToUsernameResult: {
+ if (!root.visible) {
+ return;
+ }
+
root.isCurrentlySendingAsset = false;
if (result.status === 'success') {
@@ -1309,13 +1317,13 @@ Item {
Rectangle {
anchors.top: parent.top;
- anchors.topMargin: root.assetName === "" ? 15 : 150;
+ anchors.topMargin: root.assetName === "" ? 15 : 125;
anchors.left: parent.left;
anchors.leftMargin: root.assetName === "" ? 15 : 50;
anchors.right: parent.right;
anchors.rightMargin: root.assetName === "" ? 15 : 50;
anchors.bottom: parent.bottom;
- anchors.bottomMargin: root.assetName === "" ? 15 : 240;
+ anchors.bottomMargin: root.assetName === "" ? 15 : 125;
color: "#FFFFFF";
RalewaySemiBold {
diff --git a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml
index d24344b40a..885838a26e 100644
--- a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml
+++ b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml
@@ -28,7 +28,7 @@ Rectangle {
property string itemName: "--";
property string itemOwner: "--";
property string itemEdition: "--";
- property string dateOfPurchase: "--";
+ property string dateAcquired: "--";
property string itemCost: "--";
property string certTitleTextColor: hifi.colors.darkGray;
property string certTextColor: hifi.colors.white;
@@ -64,7 +64,7 @@ Rectangle {
root.itemName = "";
root.itemEdition = "";
root.itemOwner = "";
- root.dateOfPurchase = "";
+ root.dateAcquired = "";
root.itemCost = "";
errorText.text = "Information about this certificate is currently unavailable. Please try again later.";
}
@@ -77,8 +77,9 @@ Rectangle {
// "\u2022" is the Unicode character 'BULLET' - it's what's used in password fields on the web, etc
root.itemOwner = root.isMyCert ? Account.username :
"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
- root.dateOfPurchase = root.isMyCert ? getFormattedDate(result.data.transfer_created_at * 1000) : "Undisclosed";
- root.itemCost = (root.isMyCert && result.data.cost !== undefined) ? result.data.cost : "Undisclosed";
+ root.dateAcquired = root.isMyCert ? getFormattedDate(result.data.transfer_created_at * 1000) : "Undisclosed";
+ root.itemCost = (root.isMyCert && result.data.cost !== undefined) ?
+ (parseInt(result.data.cost) > 0 ? result.data.cost : "Free") : "Undisclosed";
}
if (root.certInfoReplaceMode > 4) {
root.itemEdition = result.data.edition_number + "/" + (result.data.limited_run === -1 ? "\u221e" : result.data.limited_run);
@@ -86,7 +87,7 @@ Rectangle {
if (root.certificateStatus === 4) { // CERTIFICATE_STATUS_OWNER_VERIFICATION_FAILED
if (root.isMyCert) {
- errorText.text = "This item is an uncertified copy of an item you purchased.";
+ errorText.text = "This item is an uncertified copy of an item you acquired.";
} else {
errorText.text = "The person who placed this item doesn't own it.";
}
@@ -102,8 +103,8 @@ Rectangle {
showInMarketplaceButton.visible = false;
// "Edition" text previously set above in this function
// "Owner" text previously set above in this function
- // "Purchase Date" text previously set above in this function
- // "Purchase Price" text previously set above in this function
+ // "Acquisition Date" text previously set above in this function
+ // "Acquisition Price" text previously set above in this function
if (result.data.invalid_reason) {
errorText.text = result.data.invalid_reason;
}
@@ -117,8 +118,8 @@ Rectangle {
showInMarketplaceButton.visible = true;
// "Edition" text previously set above in this function
// "Owner" text previously set above in this function
- // "Purchase Date" text previously set above in this function
- // "Purchase Price" text previously set above in this function
+ // "Acquisition Date" text previously set above in this function
+ // "Acquisition Price" text previously set above in this function
errorText.text = "The status of this item is still pending confirmation. If the purchase is not confirmed, " +
"this entity will be cleaned up by the domain.";
}
@@ -145,8 +146,8 @@ Rectangle {
// "Item Name" text will be set in "onCertificateInfoResult()"
// "Edition" text will be set in "onCertificateInfoResult()"
// "Owner" text will be set in "onCertificateInfoResult()"
- // "Purchase Date" text will be set in "onCertificateInfoResult()"
- // "Purchase Price" text will be set in "onCertificateInfoResult()"
+ // "Acquisition Date" text will be set in "onCertificateInfoResult()"
+ // "Acquisition Price" text will be set in "onCertificateInfoResult()"
errorText.text = "";
} else if (root.certificateStatus === 2) { // CERTIFICATE_STATUS_VERIFICATION_TIMEOUT
root.useGoldCert = false;
@@ -160,7 +161,7 @@ Rectangle {
root.itemName = "";
root.itemEdition = "";
root.itemOwner = "";
- root.dateOfPurchase = "";
+ root.dateAcquired = "";
root.itemCost = "";
errorText.text = "Your request to inspect this item timed out. Please try again later.";
} else if (root.certificateStatus === 3) { // CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED
@@ -175,8 +176,8 @@ Rectangle {
// "Item Name" text will be set in "onCertificateInfoResult()"
// "Edition" text will be set in "onCertificateInfoResult()"
// "Owner" text will be set in "onCertificateInfoResult()"
- // "Purchase Date" text will be set in "onCertificateInfoResult()"
- // "Purchase Price" text will be set in "onCertificateInfoResult()"
+ // "Acquisition Date" text will be set in "onCertificateInfoResult()"
+ // "Acquisition Price" text will be set in "onCertificateInfoResult()"
errorText.text = "The information associated with this item has been modified and it no longer matches the original certified item.";
} else if (root.certificateStatus === 4) { // CERTIFICATE_STATUS_OWNER_VERIFICATION_FAILED
root.useGoldCert = false;
@@ -190,8 +191,8 @@ Rectangle {
// "Item Name" text will be set in "onCertificateInfoResult()"
root.itemEdition = "Uncertified Copy"
// "Owner" text will be set in "onCertificateInfoResult()"
- // "Purchase Date" text will be set in "onCertificateInfoResult()"
- // "Purchase Price" text will be set in "onCertificateInfoResult()"
+ // "Acquisition Date" text will be set in "onCertificateInfoResult()"
+ // "Acquisition Price" text will be set in "onCertificateInfoResult()"
// "Error Text" text will be set in "onCertificateInfoResult()"
} else {
console.log("Unknown certificate status received from ledger signal!");
@@ -485,8 +486,8 @@ Rectangle {
}
RalewayRegular {
- id: dateOfPurchaseHeader;
- text: "PURCHASE DATE";
+ id: dateAcquiredHeader;
+ text: "ACQUISITION DATE";
// Text size
size: 16;
// Anchors
@@ -500,15 +501,15 @@ Rectangle {
color: hifi.colors.darkGray;
}
AnonymousProRegular {
- id: dateOfPurchase;
- text: root.dateOfPurchase;
+ id: dateAcquired;
+ text: root.dateAcquired;
// Text size
size: 18;
// Anchors
- anchors.top: dateOfPurchaseHeader.bottom;
+ anchors.top: dateAcquiredHeader.bottom;
anchors.topMargin: 8;
- anchors.left: dateOfPurchaseHeader.left;
- anchors.right: dateOfPurchaseHeader.right;
+ anchors.left: dateAcquiredHeader.left;
+ anchors.right: dateAcquiredHeader.right;
height: paintedHeight;
// Style
color: root.infoTextColor;
@@ -516,7 +517,7 @@ Rectangle {
RalewayRegular {
id: priceHeader;
- text: "PURCHASE PRICE";
+ text: "ACQUISITION PRICE";
// Text size
size: 16;
// Anchors
@@ -530,7 +531,7 @@ Rectangle {
}
HiFiGlyphs {
id: hfcGlyph;
- visible: priceText.text !== "Undisclosed" && priceText.text !== "";
+ visible: priceText.text !== "Undisclosed" && priceText.text !== "" && priceText.text !== "Free";
text: hifi.glyphs.hfc;
// Size
size: 24;
@@ -618,7 +619,7 @@ Rectangle {
root.itemName = "--";
root.itemOwner = "--";
root.itemEdition = "--";
- root.dateOfPurchase = "--";
+ root.dateAcquired = "--";
root.marketplaceUrl = "";
root.itemCost = "--";
root.isMyCert = false;
diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml
index eeb9ac3c54..0828d86eff 100644
--- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml
+++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml
@@ -47,8 +47,7 @@ Item {
property string wornEntityID;
property string upgradeUrl;
property string upgradeTitle;
- property bool updateAvailable: root.upgradeUrl !== "" && !root.isShowingMyItems;
- property bool isShowingMyItems;
+ property bool updateAvailable: root.upgradeUrl !== "";
property bool valid;
property string originalStatusText;
@@ -231,7 +230,7 @@ Item {
Loader {
id: giftButton;
- visible: !root.isShowingMyItems;
+ visible: root.itemEdition > 0;
sourceComponent: contextCardButton;
anchors.right: parent.right;
anchors.top: parent.top;
@@ -345,6 +344,7 @@ Item {
Rectangle {
id: permissionExplanationCard;
+ visible: false;
anchors.left: parent.left;
anchors.leftMargin: 30;
anchors.top: parent.top;
diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
index 015ec3a172..df4d7f6175 100644
--- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
+++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
@@ -19,7 +19,6 @@ import "../../../controls" as HifiControls
import "qrc:////qml//hifi//models" as HifiModels // Absolute path so the same code works everywhere.
import "../wallet" as HifiWallet
import "../common" as HifiCommerceCommon
-import "../inspectionCertificate" as HifiInspectionCertificate
import "../common/sendAsset" as HifiSendAsset
import "../.." as HifiCommon
@@ -34,7 +33,6 @@ Rectangle {
property bool securityImageResultReceived: false;
property bool purchasesReceived: false;
property bool punctuationMode: false;
- property bool isShowingMyItems: false;
property bool isDebuggingFirstUseTutorial: false;
property string installedApps;
property bool keyboardRaised: false;
@@ -92,7 +90,6 @@ Rectangle {
if (result.status !== 'success') {
console.log("Failed to get Available Updates", result.data.message);
} else {
- sendToScript({method: 'purchases_availableUpdatesReceived', numUpdates: result.data.updates.length });
root.numUpdatesAvailable = result.total_entries;
}
}
@@ -106,10 +103,6 @@ Rectangle {
}
}
- onIsShowingMyItemsChanged: {
- getPurchases();
- }
-
Timer {
id: notSetUpTimer;
interval: 200;
@@ -118,19 +111,6 @@ Rectangle {
}
}
- HifiInspectionCertificate.InspectionCertificate {
- id: inspectionCertificate;
- z: 998;
- visible: false;
- anchors.fill: parent;
-
- Connections {
- onSendToScript: {
- sendToScript(message);
- }
- }
- }
-
HifiCommerceCommon.CommerceLightbox {
id: lightboxPopup;
z: 999;
@@ -180,7 +160,8 @@ Rectangle {
HifiCommerceCommon.EmulatedMarketplaceHeader {
id: titleBarContainer;
z: 997;
- visible: !needsLogIn.visible;
+ visible: false;
+ height: 100;
// Size
width: parent.width;
// Anchors
@@ -199,11 +180,6 @@ Rectangle {
lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
- lightboxPopup.button2text = "GO TO WALLET";
- lightboxPopup.button2method = function() {
- sendToScript({method: 'purchases_openWallet'});
- lightboxPopup.visible = false;
- };
lightboxPopup.visible = true;
} else {
sendToScript(msg);
@@ -475,7 +451,7 @@ Rectangle {
anchors.left: parent.left;
anchors.leftMargin: 16;
width: paintedWidth;
- text: isShowingMyItems ? "My Items" : "My Purchases";
+ text: "Inventory";
color: hifi.colors.black;
size: 22;
}
@@ -517,8 +493,13 @@ Rectangle {
"filterName": "wearable"
},
{
+ "separator" : true,
"displayName": "Updatable",
"filterName": "updated"
+ },
+ {
+ "displayName": "My Submissions",
+ "filterName": "proofs"
}
]
filterBar.primaryFilterChoices.clear();
@@ -533,6 +514,7 @@ Rectangle {
onTextChanged: {
purchasesModel.searchFilter = filterBar.text;
filterBar.previousText = filterBar.text;
+
}
}
}
@@ -556,10 +538,18 @@ Rectangle {
listModelName: 'purchases';
listView: purchasesContentsList;
getPage: function () {
- console.debug('getPage', purchasesModel.listModelName, root.isShowingMyItems, filterBar.primaryFilter_filterName, purchasesModel.currentPageToRetrieve, purchasesModel.itemsPerPage);
+ console.debug('getPage', purchasesModel.listModelName, filterBar.primaryFilter_filterName, purchasesModel.currentPageToRetrieve, purchasesModel.itemsPerPage);
+ var editionFilter = "";
+ var primaryFilter = "";
+
+ if (filterBar.primaryFilter_filterName === "proofs") {
+ editionFilter = "proofs";
+ } else {
+ primaryFilter = filterBar.primaryFilter_filterName;
+ }
Commerce.inventory(
- root.isShowingMyItems ? "proofs" : "purchased",
- filterBar.primaryFilter_filterName,
+ editionFilter,
+ primaryFilter,
filterBar.text,
purchasesModel.currentPageToRetrieve,
purchasesModel.itemsPerPage
@@ -609,7 +599,6 @@ Rectangle {
upgradeUrl: model.upgrade_url;
upgradeTitle: model.upgrade_title;
itemType: model.item_type;
- isShowingMyItems: root.isShowingMyItems;
valid: model.valid;
anchors.topMargin: 10;
anchors.bottomMargin: 10;
@@ -626,8 +615,6 @@ Rectangle {
sendToScript({ method: 'purchases_updateWearables' });
}
} else if (msg.method === 'purchases_itemCertificateClicked') {
- inspectionCertificate.visible = true;
- inspectionCertificate.isLightbox = true;
sendToScript(msg);
} else if (msg.method === "showInvalidatedLightbox") {
lightboxPopup.titleText = "Item Invalidated";
@@ -640,7 +627,7 @@ Rectangle {
lightboxPopup.visible = true;
} else if (msg.method === "showPendingLightbox") {
lightboxPopup.titleText = "Item Pending";
- lightboxPopup.bodyText = 'Your item is marked "pending" while your purchase is being confirmed. ' +
+ lightboxPopup.bodyText = 'Your item is marked "pending" while the transfer is being confirmed. ' +
"Usually, purchases take about 90 seconds to confirm.";
lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = function() {
@@ -822,7 +809,8 @@ Rectangle {
Rectangle {
id: updatesAvailableBanner;
- visible: root.numUpdatesAvailable > 0 && !root.isShowingMyItems;
+ visible: root.numUpdatesAvailable > 0 &&
+ filterBar.primaryFilter_filterName !== "proofs";
anchors.bottom: parent.bottom;
anchors.left: parent.left;
anchors.right: parent.right;
@@ -883,9 +871,8 @@ Rectangle {
id: noItemsAlertContainer;
visible: !purchasesContentsList.visible &&
root.purchasesReceived &&
- root.isShowingMyItems &&
filterBar.text === "" &&
- filterBar.primaryFilter_displayName === "";
+ filterBar.primaryFilter_filterName === "proofs";
anchors.top: filterBarContainer.bottom;
anchors.topMargin: 12;
anchors.left: parent.left;
@@ -895,7 +882,7 @@ Rectangle {
// Explanitory text
RalewayRegular {
id: noItemsYet;
- text: "You haven't submitted anything to the Marketplace yet!
Submit an item to the Marketplace to add it to My Items.";
+ text: "You haven't submitted anything to the Marketplace yet!
Submit an item to the Marketplace to add it to My Submissions.";
// Text size
size: 22;
// Anchors
@@ -933,7 +920,6 @@ Rectangle {
id: noPurchasesAlertContainer;
visible: !purchasesContentsList.visible &&
root.purchasesReceived &&
- !root.isShowingMyItems &&
filterBar.text === "" &&
filterBar.primaryFilter_displayName === "";
anchors.top: filterBarContainer.bottom;
@@ -945,7 +931,7 @@ Rectangle {
// Explanitory text
RalewayRegular {
id: haventPurchasedYet;
- text: "You haven't purchased anything yet!
Get an item from Marketplace to add it to My Purchases.";
+ text: "You haven't gotten anything yet!
Get an item from Marketplace to add it to your Inventory.";
// Text size
size: 22;
// Anchors
@@ -1065,11 +1051,10 @@ Rectangle {
titleBarContainer.referrerURL = message.referrerURL || "";
filterBar.text = message.filterText ? message.filterText : "";
break;
- case 'inspectionCertificate_setCertificateId':
- inspectionCertificate.fromScript(message);
- break;
case 'purchases_showMyItems':
- root.isShowingMyItems = true;
+ filterBar.primaryFilter_filterName = "proofs";
+ filterBar.primaryFilter_displayName = "Proofs";
+ filterBar.primaryFilter_index = 6;
break;
case 'updateConnections':
sendAsset.updateConnections(message.connections);
diff --git a/interface/resources/qml/hifi/commerce/wallet/Help.qml b/interface/resources/qml/hifi/commerce/wallet/Help.qml
index 6cf00f78eb..575edfc34d 100644
--- a/interface/resources/qml/hifi/commerce/wallet/Help.qml
+++ b/interface/resources/qml/hifi/commerce/wallet/Help.qml
@@ -62,7 +62,7 @@ Item {
isExpanded: false;
question: "How can I get HFC?";
answer: "High Fidelity commerce is in open beta right now. Want more HFC? \
-Get it by going to
BankOfHighFidelity. and meeting with the banker!";
+Get it by going to BankOfHighFidelity and meeting with the banker!";
}
ListElement {
isExpanded: false;
diff --git a/interface/resources/qml/hifi/commerce/wallet/NeedsLogIn.qml b/interface/resources/qml/hifi/commerce/wallet/NeedsLogIn.qml
index eadf1ca8a2..03af964830 100644
--- a/interface/resources/qml/hifi/commerce/wallet/NeedsLogIn.qml
+++ b/interface/resources/qml/hifi/commerce/wallet/NeedsLogIn.qml
@@ -93,7 +93,7 @@ Item {
// Text below helper text
RalewayRegular {
id: loginDetailText;
- text: "To buy/sell items on the Marketplace, or to use your Wallet, you must first log in to High Fidelity.";
+ text: "To get items on the Marketplace, or to use your Assets, you must first log in to High Fidelity.";
// Text size
size: 18;
// Anchors
diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml
index d032f060e2..76c2484f0b 100644
--- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml
+++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml
@@ -20,6 +20,8 @@ import "../../../controls" as HifiControls
import "../common" as HifiCommerceCommon
import "../common/sendAsset"
import "../.." as HifiCommon
+import "../purchases" as HifiPurchases
+import "../inspectionCertificate" as HifiInspectionCertificate
Rectangle {
HifiConstants { id: hifi; }
@@ -27,6 +29,7 @@ Rectangle {
id: root;
property string activeView: "initialize";
+ property string initialActiveViewAfterStatus5: "walletInventory";
property bool keyboardRaised: false;
property bool isPassword: false;
@@ -64,7 +67,8 @@ Rectangle {
}
} else if (walletStatus === 5) {
if (root.activeView !== "walletSetup") {
- root.activeView = "walletHome";
+ root.activeView = root.initialActiveViewAfterStatus5;
+ Commerce.getAvailableUpdates();
Commerce.getSecurityImage();
}
} else {
@@ -86,6 +90,21 @@ Rectangle {
titleBarSecurityImage.source = "image://security/securityImage";
}
}
+
+ onAvailableUpdatesResult: {
+ if (result.status !== 'success') {
+ console.log("Failed to get Available Updates", result.data.message);
+ } else {
+ exchangeMoneyButtonContainer.messagesWaiting = result.data.updates.length > 0;
+ }
+ }
+ }
+
+ onActiveViewChanged: {
+ if (activeView === "walletHome") {
+ walletHomeButtonContainer.messagesWaiting = false;
+ sendToScript({method: 'clearShouldShowDotHistory'});
+ }
}
HifiCommerceCommon.CommerceLightbox {
@@ -124,7 +143,7 @@ Rectangle {
// Title Bar text
RalewaySemiBold {
id: titleBarText;
- text: "WALLET";
+ text: "ASSETS";
// Text size
size: hifi.fontSizes.overlayTitle;
// Anchors
@@ -319,6 +338,39 @@ Rectangle {
}
}
+ HifiInspectionCertificate.InspectionCertificate {
+ id: inspectionCertificate;
+ z: 998;
+ visible: false;
+ anchors.fill: parent;
+
+ Connections {
+ onSendToScript: {
+ sendToScript(message);
+ }
+ }
+ }
+
+ HifiPurchases.Purchases {
+ id: walletInventory;
+ visible: root.activeView === "walletInventory";
+ anchors.top: titleBarContainer.bottom;
+ anchors.bottom: tabButtonsContainer.top;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ Connections {
+ onSendToScript: {
+ if (message.method === 'purchases_itemCertificateClicked') {
+ inspectionCertificate.visible = true;
+ inspectionCertificate.isLightbox = true;
+ sendToScript(message);
+ } else {
+ sendToScript(message);
+ }
+ }
+ }
+ }
+
HifiCommon.RootHttpRequest {
id: http;
}
@@ -380,16 +432,17 @@ Rectangle {
// "WALLET HOME" tab button
Rectangle {
id: walletHomeButtonContainer;
+ property bool messagesWaiting: false;
visible: !walletSetup.visible;
color: root.activeView === "walletHome" ? hifi.colors.blueAccent : hifi.colors.black;
anchors.top: parent.top;
- anchors.left: parent.left;
+ anchors.left: exchangeMoneyButtonContainer.right;
anchors.bottom: parent.bottom;
width: parent.width / tabButtonsContainer.numTabs;
-
+
HiFiGlyphs {
id: homeTabIcon;
- text: hifi.glyphs.home2;
+ text: hifi.glyphs.leftRightArrows;
// Size
size: 50;
// Anchors
@@ -397,11 +450,24 @@ Rectangle {
anchors.top: parent.top;
anchors.topMargin: -2;
// Style
- color: root.activeView === "walletHome" || walletHomeTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
+ color: WalletScriptingInterface.limitedCommerce ? hifi.colors.lightGray50 : ((root.activeView === "walletHome" || walletHomeTabMouseArea.containsMouse) ? hifi.colors.white : hifi.colors.blueHighlight);
+ }
+
+ Rectangle {
+ id: recentActivityMessagesWaitingLight;
+ visible: parent.messagesWaiting;
+ anchors.right: homeTabIcon.left;
+ anchors.rightMargin: -4;
+ anchors.top: homeTabIcon.top;
+ anchors.topMargin: 16;
+ height: 10;
+ width: height;
+ radius: height/2;
+ color: "red";
}
RalewaySemiBold {
- text: "WALLET HOME";
+ text: "RECENT ACTIVITY";
// Text size
size: 16;
// Anchors
@@ -412,7 +478,7 @@ Rectangle {
anchors.right: parent.right;
anchors.rightMargin: 4;
// Style
- color: root.activeView === "walletHome" || walletHomeTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
+ color: WalletScriptingInterface.limitedCommerce ? hifi.colors.lightGray50 : ((root.activeView === "walletHome" || walletHomeTabMouseArea.containsMouse) ? hifi.colors.white : hifi.colors.blueHighlight);
wrapMode: Text.WordWrap;
// Alignment
horizontalAlignment: Text.AlignHCenter;
@@ -421,6 +487,7 @@ Rectangle {
MouseArea {
id: walletHomeTabMouseArea;
anchors.fill: parent;
+ enabled: !WalletScriptingInterface.limitedCommerce;
hoverEnabled: enabled;
onClicked: {
root.activeView = "walletHome";
@@ -434,16 +501,18 @@ Rectangle {
// "EXCHANGE MONEY" tab button
Rectangle {
id: exchangeMoneyButtonContainer;
+ property bool messagesWaiting: false;
+
visible: !walletSetup.visible;
- color: hifi.colors.black;
+ color: root.activeView === "walletInventory" ? hifi.colors.blueAccent : hifi.colors.black;
anchors.top: parent.top;
- anchors.left: walletHomeButtonContainer.right;
+ anchors.left: parent.left;
anchors.bottom: parent.bottom;
width: parent.width / tabButtonsContainer.numTabs;
-
+
HiFiGlyphs {
id: exchangeMoneyTabIcon;
- text: hifi.glyphs.leftRightArrows;
+ text: hifi.glyphs.home2;
// Size
size: 50;
// Anchors
@@ -451,11 +520,24 @@ Rectangle {
anchors.top: parent.top;
anchors.topMargin: -2;
// Style
- color: hifi.colors.lightGray50;
+ color: root.activeView === "walletInventory" || inventoryTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
+ }
+
+ Rectangle {
+ id: exchangeMoneyMessagesWaitingLight;
+ visible: parent.messagesWaiting;
+ anchors.right: exchangeMoneyTabIcon.left;
+ anchors.rightMargin: 9;
+ anchors.top: exchangeMoneyTabIcon.top;
+ anchors.topMargin: 16;
+ height: 10;
+ width: height;
+ radius: height/2;
+ color: "red";
}
RalewaySemiBold {
- text: "EXCHANGE MONEY";
+ text: "INVENTORY";
// Text size
size: 16;
// Anchors
@@ -466,12 +548,24 @@ Rectangle {
anchors.right: parent.right;
anchors.rightMargin: 4;
// Style
- color: hifi.colors.lightGray50;
+ color: root.activeView === "walletInventory" || inventoryTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
wrapMode: Text.WordWrap;
// Alignment
horizontalAlignment: Text.AlignHCenter;
verticalAlignment: Text.AlignTop;
}
+
+ MouseArea {
+ id: inventoryTabMouseArea;
+ anchors.fill: parent;
+ hoverEnabled: enabled;
+ onClicked: {
+ root.activeView = "walletInventory";
+ tabButtonsContainer.resetTabButtonColors();
+ }
+ onEntered: parent.color = hifi.colors.blueHighlight;
+ onExited: parent.color = root.activeView === "walletInventory" ? hifi.colors.blueAccent : hifi.colors.black;
+ }
}
@@ -481,10 +575,10 @@ Rectangle {
visible: !walletSetup.visible;
color: root.activeView === "sendMoney" ? hifi.colors.blueAccent : hifi.colors.black;
anchors.top: parent.top;
- anchors.left: exchangeMoneyButtonContainer.right;
+ anchors.left: walletHomeButtonContainer.right;
anchors.bottom: parent.bottom;
width: parent.width / tabButtonsContainer.numTabs;
-
+
HiFiGlyphs {
id: sendMoneyTabIcon;
text: hifi.glyphs.paperPlane;
@@ -495,7 +589,7 @@ Rectangle {
anchors.top: parent.top;
anchors.topMargin: -2;
// Style
- color: root.activeView === "sendMoney" || sendMoneyTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
+ color: WalletScriptingInterface.limitedCommerce ? hifi.colors.lightGray50 : ((root.activeView === "sendMoney" || sendMoneyTabMouseArea.containsMouse) ? hifi.colors.white : hifi.colors.blueHighlight);
}
RalewaySemiBold {
@@ -510,7 +604,7 @@ Rectangle {
anchors.right: parent.right;
anchors.rightMargin: 4;
// Style
- color: root.activeView === "sendMoney" || sendMoneyTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
+ color: WalletScriptingInterface.limitedCommerce ? hifi.colors.lightGray50 : ((root.activeView === "sendMoney" || sendMoneyTabMouseArea.containsMouse) ? hifi.colors.white : hifi.colors.blueHighlight);
wrapMode: Text.WordWrap;
// Alignment
horizontalAlignment: Text.AlignHCenter;
@@ -520,6 +614,7 @@ Rectangle {
MouseArea {
id: sendMoneyTabMouseArea;
anchors.fill: parent;
+ enabled: !WalletScriptingInterface.limitedCommerce;
hoverEnabled: enabled;
onClicked: {
root.activeView = "sendMoney";
@@ -539,7 +634,7 @@ Rectangle {
anchors.left: sendMoneyButtonContainer.right;
anchors.bottom: parent.bottom;
width: parent.width / tabButtonsContainer.numTabs;
-
+
HiFiGlyphs {
id: helpTabIcon;
text: hifi.glyphs.question;
@@ -588,16 +683,16 @@ Rectangle {
function resetTabButtonColors() {
walletHomeButtonContainer.color = hifi.colors.black;
sendMoneyButtonContainer.color = hifi.colors.black;
- securityButtonContainer.color = hifi.colors.black;
helpButtonContainer.color = hifi.colors.black;
+ exchangeMoneyButtonContainer.color = hifi.colors.black;
if (root.activeView === "walletHome") {
walletHomeButtonContainer.color = hifi.colors.blueAccent;
} else if (root.activeView === "sendMoney") {
sendMoneyButtonContainer.color = hifi.colors.blueAccent;
- } else if (root.activeView === "security") {
- securityButtonContainer.color = hifi.colors.blueAccent;
} else if (root.activeView === "help") {
helpButtonContainer.color = hifi.colors.blueAccent;
+ } else if (root.activeView == "walletInventory") {
+ exchangeMoneyButtonContainer.color = hifi.colors.blueAccent;
}
}
}
@@ -663,18 +758,40 @@ Rectangle {
break;
case 'updateConnections':
sendMoney.updateConnections(message.connections);
+ walletInventory.fromScript(message);
break;
case 'selectRecipient':
case 'updateSelectedRecipientUsername':
sendMoney.fromScript(message);
+ walletInventory.fromScript(message);
break;
case 'http.response':
http.handleHttpResponse(message);
+ // Duplicate handler is required because we don't track referrer for `http`
+ walletInventory.fromScript(message);
break;
case 'palIsStale':
case 'avatarDisconnected':
// Because we don't have "channels" for sending messages to a specific QML object, the messages are broadcast to all QML Items. If an Item of yours happens to be visible when some script sends a message with a method you don't expect, you'll get "Unrecognized message..." logs.
break;
+ case 'inspectionCertificate_setCertificateId':
+ inspectionCertificate.fromScript(message);
+ break;
+ case 'updatePurchases':
+ case 'purchases_showMyItems':
+ case 'updateWearables':
+ walletInventory.fromScript(message);
+ break;
+ case 'updateRecentActivityMessageLight':
+ walletHomeButtonContainer.messagesWaiting = message.messagesWaiting;
+ break;
+ case 'checkout_openRecentActivity':
+ if (root.activeView === "initialize") {
+ root.initialActiveViewAfterStatus5 = "walletHome";
+ } else {
+ root.activeView = "walletHome";
+ }
+ break;
default:
console.log('Unrecognized message from wallet.js:', JSON.stringify(message));
}
@@ -722,7 +839,8 @@ Rectangle {
root.activeView = "initialize";
Commerce.getWalletStatus();
} else if (msg.referrer === 'purchases') {
- sendToScript({method: 'goToPurchases'});
+ root.activeView = "walletInventory";
+ tabButtonsContainer.resetTabButtonColors();
} else if (msg.referrer === 'marketplace cta' || msg.referrer === 'mainPage') {
sendToScript({method: 'goToMarketplaceMainPage', itemId: msg.referrer});
} else {
diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml
index 627da1d43f..d32017189e 100644
--- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml
+++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml
@@ -179,28 +179,6 @@ Item {
color: hifi.colors.baseGrayHighlight;
}
- RalewaySemiBold {
- id: myPurchasesLink;
- text: 'My Purchases';
- // Anchors
- anchors.top: parent.top;
- anchors.topMargin: 26;
- anchors.right: parent.right;
- anchors.rightMargin: 20;
- width: paintedWidth;
- height: 30;
- y: 4;
- // Text size
- size: 18;
- // Style
- color: hifi.colors.baseGrayHighlight;
- horizontalAlignment: Text.AlignRight;
-
- onLinkActivated: {
- sendSignalToWallet({method: 'goToPurchases_fromWalletHome'});
- }
- }
-
HifiModels.PSFListModel {
id: transactionHistoryModel;
property int lastPendingCount: 0;
diff --git a/interface/resources/qml/hifi/dialogs/security/Security.qml b/interface/resources/qml/hifi/dialogs/security/Security.qml
index 8baff0ac13..96a554838f 100644
--- a/interface/resources/qml/hifi/dialogs/security/Security.qml
+++ b/interface/resources/qml/hifi/dialogs/security/Security.qml
@@ -328,7 +328,7 @@ Rectangle {
HifiStylesUit.RalewayRegular {
text: "Your wallet is not set up.\n" +
- "Open the WALLET app to get started.";
+ "Open the ASSETS app to get started.";
// Anchors
anchors.fill: parent;
// Text size
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index 245e6c0017..c2faf8494a 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -1148,7 +1148,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
// set the OCULUS_STORE property so the oculus plugin can know if we ran from the Oculus Store
static const QString OCULUS_STORE_ARG = "--oculus-store";
- setProperty(hifi::properties::OCULUS_STORE, arguments().indexOf(OCULUS_STORE_ARG) != -1);
+ bool isStore = arguments().indexOf(OCULUS_STORE_ARG) != -1;
+ setProperty(hifi::properties::OCULUS_STORE, isStore);
+ DependencyManager::get()->setLimitedCommerce(isStore); // Or we could make it a separate arg, or if either arg is set, etc. And should this instead by a hifi::properties?
updateHeartbeat();
@@ -3152,7 +3154,7 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance());
surfaceContext->setContextProperty("Selection", DependencyManager::get().data());
surfaceContext->setContextProperty("ContextOverlay", DependencyManager::get().data());
- surfaceContext->setContextProperty("Wallet", DependencyManager::get().data());
+ surfaceContext->setContextProperty("WalletScriptingInterface", DependencyManager::get().data());
surfaceContext->setContextProperty("HiFiAbout", AboutUtil::getInstance());
surfaceContext->setContextProperty("ResourceRequestObserver", DependencyManager::get().data());
@@ -6874,7 +6876,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
scriptEngine->registerGlobalObject("AvatarInputs", AvatarInputs::getInstance());
scriptEngine->registerGlobalObject("Selection", DependencyManager::get().data());
scriptEngine->registerGlobalObject("ContextOverlay", DependencyManager::get().data());
- scriptEngine->registerGlobalObject("Wallet", DependencyManager::get().data());
+ scriptEngine->registerGlobalObject("WalletScriptingInterface", DependencyManager::get().data());
scriptEngine->registerGlobalObject("AddressManager", DependencyManager::get().data());
scriptEngine->registerGlobalObject("HifiAbout", AboutUtil::getInstance());
scriptEngine->registerGlobalObject("ResourceRequestObserver", DependencyManager::get().data());
@@ -7879,6 +7881,7 @@ void Application::loadAvatarBrowser() const {
auto tablet = dynamic_cast(DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"));
// construct the url to the marketplace item
QString url = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/marketplace?category=avatars";
+
QString MARKETPLACES_INJECT_SCRIPT_PATH = "file:///" + qApp->applicationDirPath() + "/scripts/system/html/js/marketplacesInject.js";
tablet->gotoWebScreen(url, MARKETPLACES_INJECT_SCRIPT_PATH);
DependencyManager::get()->openTablet();
diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp
index 60cd96c0ca..0c59fbc6d0 100644
--- a/interface/src/commerce/Ledger.cpp
+++ b/interface/src/commerce/Ledger.cpp
@@ -244,7 +244,6 @@ QString transactionString(const QJsonObject& valueObject) {
return result;
}
-static const QString MARKETPLACE_ITEMS_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/marketplace/items/";
void Ledger::historySuccess(QNetworkReply* reply) {
// here we send a historyResult with some extra stuff in it
// Namely, the styled text we'd like to show. The issue is the
diff --git a/interface/src/scripting/WalletScriptingInterface.cpp b/interface/src/scripting/WalletScriptingInterface.cpp
index e2158b9fd7..93ee60ba5b 100644
--- a/interface/src/scripting/WalletScriptingInterface.cpp
+++ b/interface/src/scripting/WalletScriptingInterface.cpp
@@ -10,13 +10,15 @@
//
#include "WalletScriptingInterface.h"
+#include
CheckoutProxy::CheckoutProxy(QObject* qmlObject, QObject* parent) : QmlWrapper(qmlObject, parent) {
Q_ASSERT(QThread::currentThread() == qApp->thread());
}
WalletScriptingInterface::WalletScriptingInterface() {
-
+ connect(DependencyManager::get().data(),
+ &AccountManager::limitedCommerceChanged, this, &WalletScriptingInterface::limitedCommerceChanged);
}
void WalletScriptingInterface::refreshWalletStatus() {
@@ -42,4 +44,4 @@ void WalletScriptingInterface::proveAvatarEntityOwnershipVerification(const QUui
} else {
qCDebug(entities) << "Failed to prove ownership of:" << entityID << "is not an avatar entity";
}
-}
\ No newline at end of file
+}
diff --git a/interface/src/scripting/WalletScriptingInterface.h b/interface/src/scripting/WalletScriptingInterface.h
index 25955ca7a3..36ee021b29 100644
--- a/interface/src/scripting/WalletScriptingInterface.h
+++ b/interface/src/scripting/WalletScriptingInterface.h
@@ -15,13 +15,13 @@
#include
#include
-#include "scripting/HMDScriptingInterface.h"
#include
#include
#include
#include "Application.h"
#include "commerce/Wallet.h"
#include "ui/overlays/ContextOverlayInterface.h"
+#include
class CheckoutProxy : public QmlWrapper {
Q_OBJECT
@@ -29,7 +29,6 @@ public:
CheckoutProxy(QObject* qmlObject, QObject* parent = nullptr);
};
-
/**jsdoc
* @namespace Wallet
*
@@ -37,28 +36,31 @@ public:
* @hifi-client-entity
*
* @property {number} walletStatus
+ * @property {bool} limitedCommerce
*/
class WalletScriptingInterface : public QObject, public Dependency {
Q_OBJECT
-
+ SINGLETON_DEPENDENCY
Q_PROPERTY(uint walletStatus READ getWalletStatus WRITE setWalletStatus NOTIFY walletStatusChanged)
+ Q_PROPERTY(bool limitedCommerce READ getLimitedCommerce WRITE setLimitedCommerce NOTIFY limitedCommerceChanged)
public:
+
WalletScriptingInterface();
/**jsdoc
- * @function Wallet.refreshWalletStatus
+ * @function WalletScriptingInterface.refreshWalletStatus
*/
Q_INVOKABLE void refreshWalletStatus();
/**jsdoc
- * @function Wallet.getWalletStatus
+ * @function WalletScriptingInterface.getWalletStatus
* @returns {number}
*/
Q_INVOKABLE uint getWalletStatus() { return _walletStatus; }
/**jsdoc
- * @function Wallet.proveAvatarEntityOwnershipVerification
+ * @function WalletScriptingInterface.proveAvatarEntityOwnershipVerification
* @param {Uuid} entityID
*/
Q_INVOKABLE void proveAvatarEntityOwnershipVerification(const QUuid& entityID);
@@ -67,29 +69,38 @@ public:
// scripts could cause the Wallet to incorrectly report its status.
void setWalletStatus(const uint& status);
+ bool getLimitedCommerce() { return DependencyManager::get()->getLimitedCommerce(); }
+ void setLimitedCommerce(bool isLimited) { DependencyManager::get()->setLimitedCommerce(isLimited); };
+
signals:
/**jsdoc
- * @function Wallet.walletStatusChanged
+ * @function WalletScriptingInterface.walletStatusChanged
* @returns {Signal}
*/
void walletStatusChanged();
/**jsdoc
- * @function Wallet.walletNotSetup
+ * @function WalletScriptingInterface.limitedCommerceChanged
+ * @returns {Signal}
+ */
+ void limitedCommerceChanged();
+
+ /**jsdoc
+ * @function WalletScriptingInterface.walletNotSetup
* @returns {Signal}
*/
void walletNotSetup();
/**jsdoc
- * @function Wallet.ownershipVerificationSuccess
+ * @function WalletScriptingInterface.ownershipVerificationSuccess
* @param {Uuid} entityID
* @returns {Signal}
*/
void ownershipVerificationSuccess(const QUuid& entityID);
/**jsdoc
- * @function Wallet.ownershipVerificationFailed
+ * @function WalletScriptingInterface.ownershipVerificationFailed
* @param {Uuid} entityID
* @returns {Signal}
*/
diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp
index 9f1018f6c7..11c268dd48 100644
--- a/interface/src/ui/overlays/ContextOverlayInterface.cpp
+++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp
@@ -223,12 +223,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID&
bool ContextOverlayInterface::contextOverlayFilterPassed(const EntityItemID& entityItemID) {
EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags);
- Setting::Handle _settingSwitch{ "commerce", true };
- if (_settingSwitch.get()) {
- return (entityProperties.getCertificateID().length() != 0);
- } else {
- return (entityProperties.getMarketplaceID().length() != 0);
- }
+ return (entityProperties.getCertificateID().length() != 0);
}
bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event) {
diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp
index 084615cae2..f13d25f22c 100644
--- a/interface/src/ui/overlays/Web3DOverlay.cpp
+++ b/interface/src/ui/overlays/Web3DOverlay.cpp
@@ -53,6 +53,7 @@
#include "ui/AvatarInputs.h"
#include "avatar/AvatarManager.h"
#include "scripting/AccountServicesScriptingInterface.h"
+#include "scripting/WalletScriptingInterface.h"
#include
#include "ui/Snapshot.h"
#include "SoundCacheScriptingInterface.h"
@@ -270,6 +271,7 @@ void Web3DOverlay::setupQmlSurface(bool isTablet) {
_webSurface->getSurfaceContext()->setContextProperty("Window", DependencyManager::get().data());
_webSurface->getSurfaceContext()->setContextProperty("Reticle", qApp->getApplicationCompositor().getReticleInterface());
_webSurface->getSurfaceContext()->setContextProperty("HiFiAbout", AboutUtil::getInstance());
+ _webSurface->getSurfaceContext()->setContextProperty("WalletScriptingInterface", DependencyManager::get().data());
_webSurface->getSurfaceContext()->setContextProperty("ResourceRequestObserver", DependencyManager::get().data());
// Override min fps for tablet UI, for silky smooth scrolling
diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp
index d99c0020da..2d1a0c0afb 100644
--- a/libraries/networking/src/AccountManager.cpp
+++ b/libraries/networking/src/AccountManager.cpp
@@ -837,3 +837,7 @@ void AccountManager::handleKeypairGenerationError() {
// reset our waiting state for keypair response
_isWaitingForKeypairResponse = false;
}
+
+void AccountManager::setLimitedCommerce(bool isLimited) {
+ _limitedCommerce = isLimited;
+}
diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h
index f3b81cf1c9..093ac9a27c 100644
--- a/libraries/networking/src/AccountManager.h
+++ b/libraries/networking/src/AccountManager.h
@@ -98,6 +98,9 @@ public:
void removeAccountFromFile();
+ bool getLimitedCommerce() { return _limitedCommerce; }
+ void setLimitedCommerce(bool isLimited);
+
public slots:
void requestAccessToken(const QString& login, const QString& password);
void requestAccessTokenWithSteam(QByteArray authSessionTicket);
@@ -121,6 +124,7 @@ signals:
void loginFailed();
void logoutComplete();
void newKeypair();
+ void limitedCommerceChanged();
private slots:
void handleKeypairGenerationError();
@@ -150,6 +154,8 @@ private:
QByteArray _pendingPrivateKey;
QUuid _sessionID { QUuid::createUuid() };
+
+ bool _limitedCommerce { false };
};
#endif // hifi_AccountManager_h
diff --git a/libraries/ui/src/ui/types/RequestFilters.cpp b/libraries/ui/src/ui/types/RequestFilters.cpp
index 7f192d6e52..a3b3b7dc57 100644
--- a/libraries/ui/src/ui/types/RequestFilters.cpp
+++ b/libraries/ui/src/ui/types/RequestFilters.cpp
@@ -70,9 +70,9 @@ void RequestFilters::interceptHFWebEngineRequest(QWebEngineUrlRequestInfo& info,
// check if this is a request to a highfidelity URL
bool isAuthable = isAuthableHighFidelityURL(info.requestUrl());
+ auto accountManager = DependencyManager::get();
if (isAuthable) {
// if we have an access token, add it to the right HTTP header for authorization
- auto accountManager = DependencyManager::get();
if (accountManager->hasValidAccessToken()) {
static const QString OAUTH_AUTHORIZATION_HEADER = "Authorization";
@@ -84,13 +84,9 @@ void RequestFilters::interceptHFWebEngineRequest(QWebEngineUrlRequestInfo& info,
static const QString USER_AGENT = "User-Agent";
const QString tokenStringMobile{ "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36" };
const QString tokenStringMetaverse{ "Chrome/48.0 (HighFidelityInterface)" };
+ const QString tokenStringLimitedCommerce{ "Chrome/48.0 (HighFidelityInterface limitedCommerce)" };
- // During the period in which we have HFC commerce in the system, but not applied everywhere:
- const QString tokenStringCommerce{ "Chrome/48.0 (HighFidelityInterface WithHFC)" };
- Setting::Handle _settingSwitch{ "commerce", true };
- bool isMoney = _settingSwitch.get();
-
- const QString tokenString = !isAuthable ? tokenStringMobile : (isMoney ? tokenStringCommerce : tokenStringMetaverse);
+ const QString tokenString = !isAuthable ? tokenStringMobile : (accountManager->getLimitedCommerce() ? tokenStringLimitedCommerce : tokenStringMetaverse);
info.setHttpHeader(USER_AGENT.toLocal8Bit(), tokenString.toLocal8Bit());
}
diff --git a/scripts/modules/appUi.js b/scripts/modules/appUi.js
index efb842a9bb..e267293977 100644
--- a/scripts/modules/appUi.js
+++ b/scripts/modules/appUi.js
@@ -95,16 +95,16 @@ function AppUi(properties) {
activeIcon: isWaiting ? that.activeMessagesButton : that.activeButton
});
};
- that.notificationPollTimeout = false;
- that.notificationPollTimeoutMs = 60000;
- that.notificationPollEndpoint = false;
- that.notificationPollStopPaginatingConditionMet = false;
+ that.notificationPollTimeout = [false];
+ that.notificationPollTimeoutMs = [60000];
+ that.notificationPollEndpoint = [false];
+ that.notificationPollStopPaginatingConditionMet = [false];
that.notificationDataProcessPage = function (data) {
return data;
};
- that.notificationPollCallback = that.ignore;
- that.notificationPollCaresAboutSince = false;
- that.notificationInitialCallbackMade = false;
+ that.notificationPollCallback = [that.ignore];
+ that.notificationPollCaresAboutSince = [false];
+ that.notificationInitialCallbackMade = [false];
that.notificationDisplayBanner = function (message) {
if (!that.isOpen) {
Window.displayAnnouncement(message);
@@ -129,7 +129,9 @@ function AppUi(properties) {
}
that.isOpen = true;
}
- } else { // Not us. Should we do something for type Home, Menu, and particularly Closed (meaning tablet hidden?
+ } else {
+ // A different screen is now visible, or the tablet has been closed.
+ // Tablet visibility is controlled separately by `tabletShownChanged()`
that.wireEventBridge(false);
if (that.isOpen) {
that.buttonActive(false);
@@ -139,83 +141,124 @@ function AppUi(properties) {
that.isOpen = false;
}
}
- // console.debug(that.buttonName + " app reports: Tablet screen changed.\nNew screen type: " + type +
- // "\nNew screen URL: " + url + "\nCurrent app open status: " + that.isOpen + "\n");
};
// Overwrite with the given properties:
- Object.keys(properties).forEach(function (key) { that[key] = properties[key]; });
+ Object.keys(properties).forEach(function (key) {
+ that[key] = properties[key];
+ });
//
// START Notification Handling
//
+
+ var currentDataPageToRetrieve = [];
+ var concatenatedServerResponse = [];
+ for (var i = 0; i < that.notificationPollEndpoint.length; i++) {
+ currentDataPageToRetrieve[i] = 1;
+ concatenatedServerResponse[i] = new Array();
+ }
+
+ var MAX_LOG_LENGTH_CHARACTERS = 300;
+ function requestCallback(error, response, optionalParams) {
+ var indexOfRequest = optionalParams.indexOfRequest;
+ var urlOfRequest = optionalParams.urlOfRequest;
+
+ if (error || (response.status !== 'success')) {
+ print("Error: unable to get", urlOfRequest, error || response.status);
+ startNotificationTimer(indexOfRequest);
+ return;
+ }
+
+ if (!that.notificationPollStopPaginatingConditionMet[indexOfRequest] ||
+ that.notificationPollStopPaginatingConditionMet[indexOfRequest](response)) {
+ startNotificationTimer(indexOfRequest);
+
+ var notificationData;
+ if (concatenatedServerResponse[indexOfRequest].length) {
+ notificationData = concatenatedServerResponse[indexOfRequest];
+ } else {
+ notificationData = that.notificationDataProcessPage[indexOfRequest](response);
+ }
+ console.debug(that.buttonName, that.notificationPollEndpoint[indexOfRequest],
+ 'truncated notification data for processing:',
+ JSON.stringify(notificationData).substring(0, MAX_LOG_LENGTH_CHARACTERS));
+ that.notificationPollCallback[indexOfRequest](notificationData);
+ that.notificationInitialCallbackMade[indexOfRequest] = true;
+ currentDataPageToRetrieve[indexOfRequest] = 1;
+ concatenatedServerResponse[indexOfRequest] = new Array();
+ } else {
+ concatenatedServerResponse[indexOfRequest] =
+ concatenatedServerResponse[indexOfRequest].concat(that.notificationDataProcessPage[indexOfRequest](response));
+ currentDataPageToRetrieve[indexOfRequest]++;
+ request({
+ json: true,
+ uri: (urlOfRequest + "&page=" + currentDataPageToRetrieve[indexOfRequest])
+ }, requestCallback, optionalParams);
+ }
+ }
+
+
var METAVERSE_BASE = Account.metaverseServerURL;
- var currentDataPageToRetrieve = 1;
- var concatenatedServerResponse = new Array();
- that.notificationPoll = function () {
- if (!that.notificationPollEndpoint) {
+ var MS_IN_SEC = 1000;
+ that.notificationPoll = function (i) {
+ if (!that.notificationPollEndpoint[i]) {
return;
}
- // User is "appearing offline" or is offline
- if (GlobalServices.findableBy === "none" || Account.username === "") {
- that.notificationPollTimeout = Script.setTimeout(that.notificationPoll, that.notificationPollTimeoutMs);
+ // User is "appearing offline" or is not logged in
+ if (GlobalServices.findableBy === "none" || Account.username === "Unknown user") {
+ // The notification polling will restart when the user changes their availability
+ // or when they log in, so it's not necessary to restart a timer here.
+ console.debug(that.buttonName + " Notifications: User is appearing offline or not logged in. " +
+ that.buttonName + " will poll for notifications when user logs in and has their availability " +
+ "set to not appear offline.");
return;
}
- var url = METAVERSE_BASE + that.notificationPollEndpoint;
+ var url = METAVERSE_BASE + that.notificationPollEndpoint[i];
- var settingsKey = "notifications/" + that.buttonName + "/lastPoll";
+ var settingsKey = "notifications/" + that.notificationPollEndpoint[i] + "/lastPoll";
var currentTimestamp = new Date().getTime();
var lastPollTimestamp = Settings.getValue(settingsKey, currentTimestamp);
- if (that.notificationPollCaresAboutSince) {
- url = url + "&since=" + lastPollTimestamp/1000;
+ if (that.notificationPollCaresAboutSince[i]) {
+ url = url + "&since=" + lastPollTimestamp / MS_IN_SEC;
}
Settings.setValue(settingsKey, currentTimestamp);
console.debug(that.buttonName, 'polling for notifications at endpoint', url);
- function requestCallback(error, response) {
- if (error || (response.status !== 'success')) {
- print("Error: unable to get", url, error || response.status);
- that.notificationPollTimeout = Script.setTimeout(that.notificationPoll, that.notificationPollTimeoutMs);
- return;
- }
-
- if (!that.notificationPollStopPaginatingConditionMet || that.notificationPollStopPaginatingConditionMet(response)) {
- that.notificationPollTimeout = Script.setTimeout(that.notificationPoll, that.notificationPollTimeoutMs);
-
- var notificationData;
- if (concatenatedServerResponse.length) {
- notificationData = concatenatedServerResponse;
- } else {
- notificationData = that.notificationDataProcessPage(response);
- }
- console.debug(that.buttonName, 'notification data for processing:', JSON.stringify(notificationData));
- that.notificationPollCallback(notificationData);
- that.notificationInitialCallbackMade = true;
- currentDataPageToRetrieve = 1;
- concatenatedServerResponse = new Array();
- } else {
- concatenatedServerResponse = concatenatedServerResponse.concat(that.notificationDataProcessPage(response));
- currentDataPageToRetrieve++;
- request({ json: true, uri: (url + "&page=" + currentDataPageToRetrieve) }, requestCallback);
- }
- }
-
- request({ json: true, uri: url }, requestCallback);
+ request({
+ json: true,
+ uri: url
+ },
+ requestCallback,
+ {
+ indexOfRequest: i,
+ urlOfRequest: url
+ });
};
// This won't do anything if there isn't a notification endpoint set
- that.notificationPoll();
+ for (i = 0; i < that.notificationPollEndpoint.length; i++) {
+ that.notificationPoll(i);
+ }
+
+ function startNotificationTimer(indexOfRequest) {
+ that.notificationPollTimeout[indexOfRequest] = Script.setTimeout(function () {
+ that.notificationPoll(indexOfRequest);
+ }, that.notificationPollTimeoutMs[indexOfRequest]);
+ }
function restartNotificationPoll() {
- that.notificationInitialCallbackMade = false;
- if (that.notificationPollTimeout) {
- Script.clearTimeout(that.notificationPollTimeout);
- that.notificationPollTimeout = false;
+ for (var j = 0; j < that.notificationPollEndpoint.length; j++) {
+ that.notificationInitialCallbackMade[j] = false;
+ if (that.notificationPollTimeout[j]) {
+ Script.clearTimeout(that.notificationPollTimeout[j]);
+ that.notificationPollTimeout[j] = false;
+ }
+ that.notificationPoll(j);
}
- that.notificationPoll();
}
//
// END Notification Handling
@@ -322,9 +365,11 @@ function AppUi(properties) {
}
that.tablet.removeButton(that.button);
}
- if (that.notificationPollTimeout) {
- Script.clearInterval(that.notificationPollTimeout);
- that.notificationPollTimeout = false;
+ for (var i = 0; i < that.notificationPollTimeout.length; i++) {
+ if (that.notificationPollTimeout[i]) {
+ Script.clearInterval(that.notificationPollTimeout[i]);
+ that.notificationPollTimeout[i] = false;
+ }
}
};
// Set up the handlers.
@@ -333,7 +378,7 @@ function AppUi(properties) {
Script.scriptEnding.connect(that.onScriptEnding);
GlobalServices.findableByChanged.connect(restartNotificationPoll);
GlobalServices.myUsernameChanged.connect(restartNotificationPoll);
- if (that.buttonName == Settings.getValue("startUpApp")) {
+ if (that.buttonName === Settings.getValue("startUpApp")) {
Settings.setValue("startUpApp", "");
Script.setTimeout(function () {
that.open();
diff --git a/scripts/modules/request.js b/scripts/modules/request.js
index d0037f9b43..37f3ac0d7b 100644
--- a/scripts/modules/request.js
+++ b/scripts/modules/request.js
@@ -18,7 +18,8 @@
module.exports = {
// ------------------------------------------------------------------
- request: function (options, callback) { // cb(error, responseOfCorrectContentType) of url. A subset of npm request.
+ // cb(error, responseOfCorrectContentType, optionalCallbackParameter) of url. A subset of npm request.
+ request: function (options, callback, optionalCallbackParameter) {
var httpRequest = new XMLHttpRequest(), key;
// QT bug: apparently doesn't handle onload. Workaround using readyState.
httpRequest.onreadystatechange = function () {
@@ -38,7 +39,7 @@ module.exports = {
if (error) {
response = { statusCode: httpRequest.status };
}
- callback(error, response);
+ callback(error, response, optionalCallbackParameter);
}
};
if (typeof options === 'string') {
diff --git a/scripts/system/avatarapp.js b/scripts/system/avatarapp.js
index ece35acce7..44f10396ca 100644
--- a/scripts/system/avatarapp.js
+++ b/scripts/system/avatarapp.js
@@ -159,7 +159,7 @@ var selectedAvatarEntityGrabbable = false;
var selectedAvatarEntityID = null;
var grabbedAvatarEntityChangeNotifier = null;
-var MARKETPLACE_PURCHASES_QML_PATH = "hifi/commerce/purchases/Purchases.qml";
+var MARKETPLACE_PURCHASES_QML_PATH = "hifi/commerce/wallet/Wallet.qml";
var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace";
var MARKETPLACES_INJECT_SCRIPT_URL = Script.resolvePath("html/js/marketplacesInject.js");
@@ -285,9 +285,9 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
case 'navigate':
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system")
if(message.url.indexOf('app://') === 0) {
- if(message.url === 'app://marketplace') {
+ if (message.url === 'app://marketplace') {
tablet.gotoWebScreen(MARKETPLACE_URL, MARKETPLACES_INJECT_SCRIPT_URL);
- } else if(message.url === 'app://purchases') {
+ } else if (message.url === 'app://purchases') {
tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH);
}
diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js
index 2d44650d9c..033ca638e4 100644
--- a/scripts/system/commerce/wallet.js
+++ b/scripts/system/commerce/wallet.js
@@ -11,7 +11,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
-/* global getConnectionData */
+/* global getConnectionData getControllerWorldLocation openLoginWindow WalletScriptingInterface */
(function () { // BEGIN LOCAL_SCOPE
Script.include("/~/system/libraries/accountUtils.js");
@@ -20,7 +20,6 @@ var AppUi = Script.require('appUi');
var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace";
-
// BEGIN AVATAR SELECTOR LOGIC
var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6 };
var SELECTED_COLOR = { red: 0xF3, green: 0x91, blue: 0x29 };
@@ -48,7 +47,6 @@ ExtendedOverlay.prototype.editOverlay = function (properties) { // change displa
function color(selected, hovering) {
var base = hovering ? HOVER_COLOR : selected ? SELECTED_COLOR : UNSELECTED_COLOR;
function scale(component) {
- var delta = 0xFF - component;
return component;
}
return { red: scale(base.red), green: scale(base.green), blue: scale(base.blue) };
@@ -105,7 +103,8 @@ ExtendedOverlay.unHover = function () { // calls hover(false) on lastHoveringId
// hit(overlay) on the one overlay intersected by pickRay, if any.
// noHit() if no ExtendedOverlay was intersected (helps with hover)
ExtendedOverlay.applyPickRay = function (pickRay, hit, noHit) {
- var pickedOverlay = Overlays.findRayIntersection(pickRay); // Depends on nearer coverOverlays to extend closer to us than farther ones.
+ // Depends on nearer coverOverlays to extend closer to us than farther ones.
+ var pickedOverlay = Overlays.findRayIntersection(pickRay);
if (!pickedOverlay.intersects) {
if (noHit) {
return noHit();
@@ -131,6 +130,7 @@ function addAvatarNode(id) {
}
var pingPong = true;
+var OVERLAY_SCALE = 0.032;
function updateOverlays() {
var eye = Camera.position;
AvatarList.getAvatarIdentifiers().forEach(function (id) {
@@ -148,7 +148,8 @@ function updateOverlays() {
var target = avatar.position;
var distance = Vec3.distance(target, eye);
var offset = 0.2;
- var diff = Vec3.subtract(target, eye); // get diff between target and eye (a vector pointing to the eye from avatar position)
+ // get diff between target and eye (a vector pointing to the eye from avatar position)
+ var diff = Vec3.subtract(target, eye);
var headIndex = avatar.getJointIndex("Head"); // base offset on 1/2 distance from hips to head if we can
if (headIndex > 0) {
offset = avatar.getAbsoluteJointTranslationInObjectFrame(headIndex).y / 2;
@@ -164,7 +165,7 @@ function updateOverlays() {
overlay.editOverlay({
color: color(ExtendedOverlay.isSelected(id), overlay.hovering),
position: target,
- dimensions: 0.032 * distance
+ dimensions: OVERLAY_SCALE * distance
});
});
pingPong = !pingPong;
@@ -380,6 +381,31 @@ function onUsernameChanged() {
Settings.setValue("keepMeLoggedIn", false);
Settings.setValue("keepMeLoggedIn/savedUsername", "");
}
+}
+
+var MARKETPLACES_INJECT_SCRIPT_URL = Script.resolvePath("../html/js/marketplacesInject.js");
+var METAVERSE_SERVER_URL = Account.metaverseServerURL;
+var MARKETPLACE_URL_INITIAL = MARKETPLACE_URL + "?"; // Append "?" to signal injected script that it's the initial page.
+function openMarketplace(optionalItemOrUrl) {
+ // This is a bit of a kluge, but so is the whole file.
+ // If given a whole path, use it with no cta.
+ // If given an id, build the appropriate url and use the id as the cta.
+ // Otherwise, use home and 'marketplace cta'.
+ // AND... if call onMarketplaceOpen to setupWallet if we need to.
+ var url = optionalItemOrUrl || MARKETPLACE_URL_INITIAL;
+ // If optionalItemOrUrl contains the metaverse base, then it's a url, not an item id.
+ if (optionalItemOrUrl && optionalItemOrUrl.indexOf(METAVERSE_SERVER_URL) === -1) {
+ url = MARKETPLACE_URL + '/items/' + optionalItemOrUrl;
+ }
+ ui.open(url, MARKETPLACES_INJECT_SCRIPT_URL);
+}
+
+function setCertificateInfo(itemCertificateId) {
+ ui.tablet.sendToQml({
+ method: 'inspectionCertificate_setCertificateId',
+ entityId: "",
+ certificateId: itemCertificateId
+ });
}
// Function Name: fromQml()
@@ -387,8 +413,6 @@ function onUsernameChanged() {
// Description:
// -Called when a message is received from SpectatorCamera.qml. The "message" argument is what is sent from the QML
// in the format "{method, params}", like json-rpc. See also sendToQml().
-var MARKETPLACE_PURCHASES_QML_PATH = "hifi/commerce/purchases/Purchases.qml";
-var MARKETPLACES_INJECT_SCRIPT_URL = Script.resolvePath("../html/js/marketplacesInject.js");
function fromQml(message) {
switch (message.method) {
case 'passphrasePopup_cancelClicked':
@@ -413,6 +437,7 @@ function fromQml(message) {
}
break;
case 'needsLogIn_loginClicked':
+ ui.close();
openLoginWindow();
break;
case 'disableHmdPreview':
@@ -422,10 +447,6 @@ function fromQml(message) {
case 'transactionHistory_linkClicked':
ui.open(message.marketplaceLink, MARKETPLACES_INJECT_SCRIPT_URL);
break;
- case 'goToPurchases_fromWalletHome':
- case 'goToPurchases':
- ui.open(MARKETPLACE_PURCHASES_QML_PATH);
- break;
case 'goToMarketplaceMainPage':
ui.open(MARKETPLACE_URL, MARKETPLACES_INJECT_SCRIPT_URL);
break;
@@ -450,22 +471,20 @@ function fromQml(message) {
removeOverlays();
break;
case 'sendAsset_sendPublicly':
- if (message.assetName === "") {
- deleteSendMoneyParticleEffect();
- sendMoneyRecipient = message.recipient;
- var amount = message.amount;
- var props = SEND_MONEY_PARTICLE_PROPERTIES;
- props.parentID = MyAvatar.sessionUUID;
- props.position = MyAvatar.position;
- props.position.y += 0.2;
- if (message.effectImage) {
- props.textures = message.effectImage;
- }
- sendMoneyParticleEffect = Entities.addEntity(props, true);
- particleEffectTimestamp = Date.now();
- updateSendMoneyParticleEffect();
- sendMoneyParticleEffectUpdateTimer = Script.setInterval(updateSendMoneyParticleEffect, SEND_MONEY_PARTICLE_TIMER_UPDATE);
+ deleteSendMoneyParticleEffect();
+ sendMoneyRecipient = message.recipient;
+ var props = SEND_MONEY_PARTICLE_PROPERTIES;
+ props.parentID = MyAvatar.sessionUUID;
+ props.position = MyAvatar.position;
+ props.position.y += 0.2;
+ if (message.effectImage) {
+ props.textures = message.effectImage;
}
+ sendMoneyParticleEffect = Entities.addEntity(props, true);
+ particleEffectTimestamp = Date.now();
+ updateSendMoneyParticleEffect();
+ sendMoneyParticleEffectUpdateTimer =
+ Script.setInterval(updateSendMoneyParticleEffect, SEND_MONEY_PARTICLE_TIMER_UPDATE);
break;
case 'transactionHistory_goToBank':
if (Account.metaverseServerURL.indexOf("staging") >= 0) {
@@ -474,6 +493,49 @@ function fromQml(message) {
Window.location = "hifi://BankOfHighFidelity";
}
break;
+ case 'purchases_updateWearables':
+ var currentlyWornWearables = [];
+ var ATTACHMENT_SEARCH_RADIUS = 100; // meters (just in case)
+
+ var nearbyEntities = Entities.findEntitiesByType('Model', MyAvatar.position, ATTACHMENT_SEARCH_RADIUS);
+
+ for (var i = 0; i < nearbyEntities.length; i++) {
+ var currentProperties = Entities.getEntityProperties(
+ nearbyEntities[i], ['certificateID', 'editionNumber', 'parentID']
+ );
+ if (currentProperties.parentID === MyAvatar.sessionUUID) {
+ currentlyWornWearables.push({
+ entityID: nearbyEntities[i],
+ entityCertID: currentProperties.certificateID,
+ entityEdition: currentProperties.editionNumber
+ });
+ }
+ }
+
+ ui.tablet.sendToQml({ method: 'updateWearables', wornWearables: currentlyWornWearables });
+ break;
+ case 'purchases_walletNotSetUp':
+ ui.tablet.sendToQml({
+ method: 'updateWalletReferrer',
+ referrer: "purchases"
+ });
+ break;
+ case 'purchases_openGoTo':
+ ui.open("hifi/tablet/TabletAddressDialog.qml");
+ break;
+ case 'purchases_itemInfoClicked':
+ var itemId = message.itemId;
+ if (itemId && itemId !== "") {
+ openMarketplace(itemId);
+ }
+ break;
+ case 'purchases_itemCertificateClicked':
+ setCertificateInfo(message.itemCertificateId);
+ break;
+ case 'clearShouldShowDotHistory':
+ shouldShowDotHistory = false;
+ ui.messagesWaiting(shouldShowDotUpdates || shouldShowDotHistory);
+ break;
case 'http.request':
// Handled elsewhere, don't log.
break;
@@ -482,41 +544,76 @@ function fromQml(message) {
}
}
+var isWired = false;
function walletOpened() {
Users.usernameFromIDReply.connect(usernameFromIDReply);
Controller.mousePressEvent.connect(handleMouseEvent);
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
triggerMapping.enable();
triggerPressMapping.enable();
- shouldShowDot = false;
- ui.messagesWaiting(shouldShowDot);
+ isWired = true;
+
+ if (shouldShowDotHistory) {
+ ui.sendMessage({
+ method: 'updateRecentActivityMessageLight',
+ messagesWaiting: shouldShowDotHistory
+ });
+ }
}
function walletClosed() {
off();
}
-function notificationDataProcessPage(data) {
+function notificationDataProcessPageUpdates(data) {
+ return data.data.updates;
+}
+
+function notificationDataProcessPageHistory(data) {
return data.data.history;
}
-var shouldShowDot = false;
-function notificationPollCallback(historyArray) {
+var shouldShowDotUpdates = false;
+function notificationPollCallbackUpdates(updatesArray) {
+ shouldShowDotUpdates = shouldShowDotUpdates || updatesArray.length > 0;
+ ui.messagesWaiting(shouldShowDotUpdates || shouldShowDotHistory);
+
+ if (updatesArray.length > 0) {
+ var message;
+ if (!ui.notificationInitialCallbackMade[0]) {
+ message = updatesArray.length + " of your purchased items " +
+ (updatesArray.length === 1 ? "has an update " : "have updates ") +
+ "available. Open ASSETS to update.";
+ ui.notificationDisplayBanner(message);
+
+ ui.notificationPollCaresAboutSince[0] = true;
+ } else {
+ for (var i = 0; i < updatesArray.length; i++) {
+ message = "Update available for \"" +
+ updatesArray[i].base_item_title + "\"." +
+ "Open ASSETS to update.";
+ ui.notificationDisplayBanner(message);
+ }
+ }
+ }
+}
+var shouldShowDotHistory = false;
+function notificationPollCallbackHistory(historyArray) {
if (!ui.isOpen) {
var notificationCount = historyArray.length;
- shouldShowDot = shouldShowDot || notificationCount > 0;
- ui.messagesWaiting(shouldShowDot);
+ shouldShowDotHistory = shouldShowDotHistory || notificationCount > 0;
+ ui.messagesWaiting(shouldShowDotUpdates || shouldShowDotHistory);
if (notificationCount > 0) {
var message;
- if (!ui.notificationInitialCallbackMade) {
- message = "You have " + notificationCount + " unread wallet " +
- "transaction" + (notificationCount === 1 ? "" : "s") + ". Open WALLET to see all activity.";
+ if (!ui.notificationInitialCallbackMade[1]) {
+ message = "You have " + notificationCount + " unread recent " +
+ "transaction" + (notificationCount === 1 ? "" : "s") + ". Open ASSETS to see all activity.";
ui.notificationDisplayBanner(message);
} else {
for (var i = 0; i < notificationCount; i++) {
message = '"' + (historyArray[i].message) + '" ' +
- "Open WALLET to see all activity.";
+ "Open ASSETS to see all activity.";
ui.notificationDisplayBanner(message);
}
}
@@ -524,7 +621,12 @@ function notificationPollCallback(historyArray) {
}
}
-function isReturnedDataEmpty(data) {
+function isReturnedDataEmptyUpdates(data) {
+ var updatesArray = data.data.updates;
+ return updatesArray.length === 0;
+}
+
+function isReturnedDataEmptyHistory(data) {
var historyArray = data.data.history;
return historyArray.length === 0;
}
@@ -559,23 +661,41 @@ function uninstallMarketplaceItemTester() {
}
}
-var BUTTON_NAME = "WALLET";
+var BUTTON_NAME = "ASSETS";
var WALLET_QML_SOURCE = "hifi/commerce/wallet/Wallet.qml";
+var NOTIFICATION_POLL_TIMEOUT = 300000;
var ui;
function startup() {
+ var notificationPollEndpointArray = ["/api/v1/commerce/available_updates?per_page=10"];
+ var notificationPollTimeoutMsArray = [NOTIFICATION_POLL_TIMEOUT];
+ var notificationDataProcessPageArray = [notificationDataProcessPageUpdates];
+ var notificationPollCallbackArray = [notificationPollCallbackUpdates];
+ var notificationPollStopPaginatingConditionMetArray = [isReturnedDataEmptyUpdates];
+ var notificationPollCaresAboutSinceArray = [false];
+
+ if (!WalletScriptingInterface.limitedCommerce) {
+ notificationPollEndpointArray[1] = "/api/v1/commerce/history?per_page=10";
+ notificationPollTimeoutMsArray[1] = NOTIFICATION_POLL_TIMEOUT;
+ notificationDataProcessPageArray[1] = notificationDataProcessPageHistory;
+ notificationPollCallbackArray[1] = notificationPollCallbackHistory;
+ notificationPollStopPaginatingConditionMetArray[1] = isReturnedDataEmptyHistory;
+ notificationPollCaresAboutSinceArray[1] = true;
+ }
+
ui = new AppUi({
buttonName: BUTTON_NAME,
+ buttonPrefix: "wallet-",
sortOrder: 10,
home: WALLET_QML_SOURCE,
onOpened: walletOpened,
onClosed: walletClosed,
onMessage: fromQml,
- notificationPollEndpoint: "/api/v1/commerce/history?per_page=10",
- notificationPollTimeoutMs: 300000,
- notificationDataProcessPage: notificationDataProcessPage,
- notificationPollCallback: notificationPollCallback,
- notificationPollStopPaginatingConditionMet: isReturnedDataEmpty,
- notificationPollCaresAboutSince: true
+ notificationPollEndpoint: notificationPollEndpointArray,
+ notificationPollTimeoutMs: notificationPollTimeoutMsArray,
+ notificationDataProcessPage: notificationDataProcessPageArray,
+ notificationPollCallback: notificationPollCallbackArray,
+ notificationPollStopPaginatingConditionMet: notificationPollStopPaginatingConditionMetArray,
+ notificationPollCaresAboutSince: notificationPollCaresAboutSinceArray
});
GlobalServices.myUsernameChanged.connect(onUsernameChanged);
installMarketplaceItemTester();
@@ -583,11 +703,14 @@ function startup() {
var isUpdateOverlaysWired = false;
function off() {
- Users.usernameFromIDReply.disconnect(usernameFromIDReply);
- Controller.mousePressEvent.disconnect(handleMouseEvent);
- Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent);
- triggerMapping.disable();
- triggerPressMapping.disable();
+ if (isWired) {
+ Users.usernameFromIDReply.disconnect(usernameFromIDReply);
+ Controller.mousePressEvent.disconnect(handleMouseEvent);
+ Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent);
+ triggerMapping.disable();
+ triggerPressMapping.disable();
+ isWired = false;
+ }
if (isUpdateOverlaysWired) {
Script.update.disconnect(updateOverlays);
diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js
index 24a96023da..c4a4adebdf 100644
--- a/scripts/system/html/js/marketplacesInject.js
+++ b/scripts/system/html/js/marketplacesInject.js
@@ -27,6 +27,7 @@
var xmlHttpRequest = null;
var isPreparing = false; // Explicitly track download request status.
+ var limitedCommerce = false;
var commerceMode = false;
var userIsLoggedIn = false;
var walletNeedsSetup = false;
@@ -59,7 +60,7 @@
);
// Footer.
- var isInitialHiFiPage = location.href === marketplaceBaseURL + "/marketplace?";
+ var isInitialHiFiPage = location.href === (marketplaceBaseURL + "/marketplace?");
$("body").append(
'