diff --git a/interface/resources/icons/tablet-icons/market-msg-a.svg b/interface/resources/icons/tablet-icons/market-msg-a.svg
new file mode 100644
index 0000000000..bf9aa9335f
--- /dev/null
+++ b/interface/resources/icons/tablet-icons/market-msg-a.svg
@@ -0,0 +1,23 @@
+
+
+
diff --git a/interface/resources/icons/tablet-icons/market-msg-i.svg b/interface/resources/icons/tablet-icons/market-msg-i.svg
new file mode 100644
index 0000000000..bf9aa9335f
--- /dev/null
+++ b/interface/resources/icons/tablet-icons/market-msg-i.svg
@@ -0,0 +1,23 @@
+
+
+
diff --git a/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml b/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml
index 8a7e809b3d..f6fb28b08a 100644
--- a/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml
+++ b/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml
@@ -28,6 +28,7 @@ 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,6 +39,7 @@ 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);
@@ -58,6 +60,14 @@ 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: {
@@ -109,6 +119,17 @@ Item {
anchors.right: securityImage.left;
anchors.rightMargin: 6;
+ Rectangle {
+ id: messagesWaitingLight;
+ visible: root.messagesWaiting;
+ anchors.right: myPurchasesLink.left;
+ anchors.rightMargin: 4;
+ anchors.verticalCenter: parent.verticalCenter;
+ height: 10;
+ width: height;
+ radius: height/2;
+ }
+
Rectangle {
id: myPurchasesLink;
anchors.right: myUsernameButton.left;
diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
index 8089818ba6..31c0ba73c0 100644
--- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
+++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
@@ -64,6 +64,7 @@ Rectangle {
root.activeView = "purchasesMain";
root.installedApps = Commerce.getInstalledApps();
Commerce.inventory();
+ Commerce.getAvailableUpdates();
}
} else {
console.log("ERROR in Purchases.qml: Unknown wallet status: " + walletStatus);
@@ -119,6 +120,14 @@ Rectangle {
root.pendingInventoryReply = false;
}
+
+ onAvailableUpdatesResult: {
+ if (result.status !== 'success') {
+ console.log("Failed to get Available Updates", result.data.message);
+ } else {
+ sendToScript({method: 'purchases_availableUpdatesReceived', numUpdates: result.data.updates.length });
+ }
+ }
}
Timer {
@@ -273,6 +282,7 @@ Rectangle {
root.activeView = "purchasesMain";
root.installedApps = Commerce.getInstalledApps();
Commerce.inventory();
+ Commerce.getAvailableUpdates();
break;
}
}
@@ -617,6 +627,7 @@ Rectangle {
console.log("Refreshing Purchases...");
root.pendingInventoryReply = true;
Commerce.inventory();
+ Commerce.getAvailableUpdates();
}
}
}
diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml
index 27660b5e9e..7a14ee060f 100644
--- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml
+++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml
@@ -39,6 +39,7 @@ Item {
root.noMoreHistoryData = false;
root.historyRequestPending = true;
Commerce.history(root.currentHistoryPage);
+ Commerce.getAvailableUpdates();
} else {
refreshTimer.stop();
}
@@ -133,6 +134,14 @@ Item {
refreshTimer.start();
}
}
+
+ onAvailableUpdatesResult: {
+ if (result.status !== 'success') {
+ console.log("Failed to get Available Updates", result.data.message);
+ } else {
+ sendToScript({method: 'wallet_availableUpdatesReceived', numUpdates: result.data.updates.length });
+ }
+ }
}
Connections {
diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js
index 2565a998f1..9376ed9823 100644
--- a/scripts/system/html/js/marketplacesInject.js
+++ b/scripts/system/html/js/marketplacesInject.js
@@ -30,6 +30,7 @@
var userIsLoggedIn = false;
var walletNeedsSetup = false;
var marketplaceBaseURL = "https://highfidelity.com";
+ var messagesWaiting = false;
function injectCommonCode(isDirectoryPage) {
@@ -205,7 +206,11 @@
purchasesElement.id = "purchasesButton";
purchasesElement.setAttribute('href', "#");
- purchasesElement.innerHTML = "My Purchases";
+ purchasesElement.innerHTML = "";
+ if (messagesWaiting) {
+ purchasesElement.innerHTML += " ";
+ }
+ purchasesElement.innerHTML += "My Purchases";
// FRONTEND WEBDEV RANT: The username dropdown should REALLY not be programmed to be on the same
// line as the search bar, overlaid on top of the search bar, floated right, and then relatively bumped up using "top:-50px".
purchasesElement.style = "height:100%;margin-top:18px;font-weight:bold;float:right;margin-right:" + (dropDownElement.offsetWidth + 30) +
@@ -705,6 +710,7 @@
if (marketplaceBaseURL.indexOf('metaverse.') !== -1) {
marketplaceBaseURL = marketplaceBaseURL.replace('metaverse.', '');
}
+ messagesWaiting = parsedJsonMessage.data.messagesWaiting;
injectCode();
}
}
diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js
index d3620968c7..3d878ef948 100644
--- a/scripts/system/marketplaces/marketplaces.js
+++ b/scripts/system/marketplaces/marketplaces.js
@@ -86,13 +86,24 @@ var selectionDisplay = null; // for gridTool.js to ignore
}
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
+ var NORMAL_ICON = "icons/tablet-icons/market-i.svg";
+ var NORMAL_ACTIVE = "icons/tablet-icons/market-a.svg";
+ var WAITING_ICON = "icons/tablet-icons/market-msg-i.svg";
+ var WAITING_ACTIVE = "icons/tablet-icons/market-msg-a.svg";
var marketplaceButton = tablet.addButton({
- icon: "icons/tablet-icons/market-i.svg",
- activeIcon: "icons/tablet-icons/market-a.svg",
+ icon: NORMAL_ICON,
+ activeIcon: NORMAL_ACTIVE,
text: "MARKET",
sortOrder: 9
});
+ function messagesWaiting(isWaiting) {
+ button.editProperties({
+ icon: (isWaiting ? WAITING_ICON : NORMAL_ICON),
+ activeIcon: (isWaiting ? WAITING_ACTIVE : NORMAL_ACTIVE)
+ });
+ }
+
function onCanWriteAssetsChanged() {
var message = CAN_WRITE_ASSETS + " " + Entities.canWriteAssets();
tablet.emitScriptEvent(message);
@@ -178,6 +189,7 @@ var selectionDisplay = null; // for gridTool.js to ignore
}
}
+ var userHasUpdates = false;
function sendCommerceSettings() {
tablet.emitScriptEvent(JSON.stringify({
type: "marketplaces",
@@ -186,7 +198,8 @@ var selectionDisplay = null; // for gridTool.js to ignore
commerceMode: Settings.getValue("commerce", true),
userIsLoggedIn: Account.loggedIn,
walletNeedsSetup: Wallet.walletStatus === 1,
- metaverseServerURL: Account.metaverseServerURL
+ metaverseServerURL: Account.metaverseServerURL,
+ messagesWaiting: userHasUpdates
}
}));
}
@@ -619,6 +632,11 @@ var selectionDisplay = null; // for gridTool.js to ignore
case 'sendMoney_sendPublicly':
// NOP
break;
+ case 'wallet_availableUpdatesReceived':
+ case 'purchases_availableUpdatesReceived':
+ userHasUpdates = message.numUpdates > 0;
+ messagesWaiting(userHasUpdates);
+ break;
default:
print('Unrecognized message from Checkout.qml or Purchases.qml: ' + JSON.stringify(message));
}