mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 05:24:35 +02:00
Merge pull request #14261 from howard-stearns/oculus-store-commerce
Oculus store commerce
This commit is contained in:
commit
a99facb793
33 changed files with 702 additions and 987 deletions
|
@ -96,7 +96,7 @@ Item {
|
||||||
topMargin: hifi.dimensions.contentSpacing.y
|
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
|
width: parent.width
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
lineHeight: 1
|
lineHeight: 1
|
||||||
|
|
|
@ -260,16 +260,21 @@ Item {
|
||||||
interactive: false;
|
interactive: false;
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
model: filterBarModel;
|
model: filterBarModel;
|
||||||
delegate: Rectangle {
|
delegate: Item {
|
||||||
|
width: parent.width;
|
||||||
|
height: 50;
|
||||||
|
Rectangle {
|
||||||
id: dropDownButton;
|
id: dropDownButton;
|
||||||
color: hifi.colors.white;
|
color: hifi.colors.white;
|
||||||
width: parent.width;
|
width: parent.width;
|
||||||
height: 50;
|
height: 50;
|
||||||
|
visible: true;
|
||||||
|
|
||||||
RalewaySemiBold {
|
RalewaySemiBold {
|
||||||
id: dropDownButtonText;
|
id: dropDownButtonText;
|
||||||
text: model.displayName;
|
text: model.displayName;
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
|
anchors.topMargin: 2;
|
||||||
anchors.leftMargin: 12;
|
anchors.leftMargin: 12;
|
||||||
color: hifi.colors.baseGray;
|
color: hifi.colors.baseGray;
|
||||||
horizontalAlignment: Text.AlignLeft;
|
horizontalAlignment: Text.AlignLeft;
|
||||||
|
@ -294,6 +299,13 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Rectangle {
|
||||||
|
height: 2;
|
||||||
|
width: parent.width;
|
||||||
|
color: hifi.colors.lightGray;
|
||||||
|
visible: model.separator
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,8 +63,8 @@ MessageBox {
|
||||||
popup.dialogButtons.yesButton.fontCapitalization = Font.MixedCase;
|
popup.dialogButtons.yesButton.fontCapitalization = Font.MixedCase;
|
||||||
popup.button1text = 'CANCEL'
|
popup.button1text = 'CANCEL'
|
||||||
popup.titleText = 'Get Wearables'
|
popup.titleText = 'Get Wearables'
|
||||||
popup.bodyText = 'Buy wearables from <b><a href="app://marketplace">Marketplace.</a></b>' + '<br/>' +
|
popup.bodyText = 'Get wearables from <b><a href="app://marketplace">Marketplace.</a></b>' + '<br/>' +
|
||||||
'Wear wearable from <b><a href="app://purchases">My Purchases.</a></b>' + '<br/>' + '<br/>' +
|
'Wear wearable from <b><a href="app://purchases">Inventory.</a></b>' + '<br/>' + '<br/>' +
|
||||||
'Visit “AvatarIsland” to get wearables'
|
'Visit “AvatarIsland” to get wearables'
|
||||||
|
|
||||||
popup.imageSource = getWearablesUrl;
|
popup.imageSource = getWearablesUrl;
|
||||||
|
@ -89,7 +89,7 @@ MessageBox {
|
||||||
|
|
||||||
function showDeleteFavorite(favoriteName, callback) {
|
function showDeleteFavorite(favoriteName, callback) {
|
||||||
popup.titleText = 'Delete Favorite: {AvatarName}'.replace('{AvatarName}', favoriteName)
|
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.imageSource = null;
|
||||||
popup.button1text = 'CANCEL'
|
popup.button1text = 'CANCEL'
|
||||||
popup.button2text = 'DELETE'
|
popup.button2text = 'DELETE'
|
||||||
|
@ -128,8 +128,8 @@ MessageBox {
|
||||||
popup.button1text = 'CANCEL'
|
popup.button1text = 'CANCEL'
|
||||||
popup.titleText = 'Get Avatars'
|
popup.titleText = 'Get Avatars'
|
||||||
|
|
||||||
popup.bodyText = 'Buy avatars from <b><a href="app://marketplace">Marketplace.</a></b>' + '<br/>' +
|
popup.bodyText = 'Get avatars from <b><a href="app://marketplace">Marketplace.</a></b>' + '<br/>' +
|
||||||
'Wear avatars in <b><a href="app://purchases">My Purchases.</a></b>' + '<br/>' + '<br/>' +
|
'Wear avatars in <b><a href="app://purchases">Inventory.</a></b>' + '<br/>' + '<br/>' +
|
||||||
'Visit “BodyMart” to get free avatars.'
|
'Visit “BodyMart” to get free avatars.'
|
||||||
|
|
||||||
popup.imageSource = getAvatarsUrl;
|
popup.imageSource = getAvatarsUrl;
|
||||||
|
|
|
@ -240,11 +240,6 @@ Rectangle {
|
||||||
lightboxPopup.button1method = function() {
|
lightboxPopup.button1method = function() {
|
||||||
lightboxPopup.visible = false;
|
lightboxPopup.visible = false;
|
||||||
}
|
}
|
||||||
lightboxPopup.button2text = "GO TO WALLET";
|
|
||||||
lightboxPopup.button2method = function() {
|
|
||||||
lightboxPopup.visible = false;
|
|
||||||
sendToScript({method: 'checkout_openWallet'});
|
|
||||||
};
|
|
||||||
lightboxPopup.visible = true;
|
lightboxPopup.visible = true;
|
||||||
} else {
|
} else {
|
||||||
sendToScript(msg);
|
sendToScript(msg);
|
||||||
|
@ -383,7 +378,7 @@ Rectangle {
|
||||||
anchors.leftMargin: 16;
|
anchors.leftMargin: 16;
|
||||||
width: paintedWidth;
|
width: paintedWidth;
|
||||||
height: paintedHeight;
|
height: paintedHeight;
|
||||||
text: "Review Purchase:";
|
text: "Review:";
|
||||||
color: hifi.colors.black;
|
color: hifi.colors.black;
|
||||||
size: 28;
|
size: 28;
|
||||||
}
|
}
|
||||||
|
@ -448,7 +443,7 @@ Rectangle {
|
||||||
// "HFC" balance label
|
// "HFC" balance label
|
||||||
HiFiGlyphs {
|
HiFiGlyphs {
|
||||||
id: itemPriceTextLabel;
|
id: itemPriceTextLabel;
|
||||||
visible: !(root.isUpdating && root.itemEdition > 0);
|
visible: !(root.isUpdating && root.itemEdition > 0) && (root.itemPrice > 0);
|
||||||
text: hifi.glyphs.hfc;
|
text: hifi.glyphs.hfc;
|
||||||
// Size
|
// Size
|
||||||
size: 30;
|
size: 30;
|
||||||
|
@ -464,7 +459,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
FiraSansSemiBold {
|
FiraSansSemiBold {
|
||||||
id: itemPriceText;
|
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
|
// Text size
|
||||||
size: (root.isUpdating && root.itemEdition > 0) ? 20 : 26;
|
size: (root.isUpdating && root.itemEdition > 0) ? 20 : 26;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -559,7 +554,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// "View in My Purchases" button
|
// "View in Inventory" button
|
||||||
HifiControlsUit.Button {
|
HifiControlsUit.Button {
|
||||||
id: viewInMyPurchasesButton;
|
id: viewInMyPurchasesButton;
|
||||||
visible: false;
|
visible: false;
|
||||||
|
@ -570,7 +565,7 @@ Rectangle {
|
||||||
height: 50;
|
height: 50;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.right: parent.right;
|
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: {
|
onClicked: {
|
||||||
if (root.isUpdating) {
|
if (root.isUpdating) {
|
||||||
sendToScript({method: 'checkout_goToPurchases', filterText: root.baseItemName});
|
sendToScript({method: 'checkout_goToPurchases', filterText: root.baseItemName});
|
||||||
|
@ -594,7 +589,7 @@ Rectangle {
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
text: (root.isUpdating && root.itemEdition > 0) ? "CONFIRM UPDATE" : (((root.isCertified) ? ((ownershipStatusReceived && balanceReceived && availableUpdatesReceived) ?
|
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: {
|
onClicked: {
|
||||||
if (root.isUpdating && root.itemEdition > 0) {
|
if (root.isUpdating && root.itemEdition > 0) {
|
||||||
// If we're updating an app, the existing app needs to be uninstalled.
|
// If we're updating an app, the existing app needs to be uninstalled.
|
||||||
|
@ -608,9 +603,9 @@ Rectangle {
|
||||||
} else if (root.isCertified) {
|
} else if (root.isCertified) {
|
||||||
if (!root.shouldBuyWithControlledFailure) {
|
if (!root.shouldBuyWithControlledFailure) {
|
||||||
if (root.itemType === "contentSet" && !Entities.canReplaceContent()) {
|
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 <b>" + root.itemName +
|
lightboxPopup.bodyText = "You will not be able to replace this domain's content with <b>" + root.itemName +
|
||||||
" </b>until the server owner gives you 'Replace Content' permissions.<br><br>Are you sure you want to purchase this content set?";
|
" </b>until the server owner gives you 'Replace Content' permissions.<br><br>Are you sure you want to get this content set?";
|
||||||
lightboxPopup.button1text = "CANCEL";
|
lightboxPopup.button1text = "CANCEL";
|
||||||
lightboxPopup.button1method = function() {
|
lightboxPopup.button1method = function() {
|
||||||
lightboxPopup.visible = false;
|
lightboxPopup.visible = false;
|
||||||
|
@ -694,7 +689,7 @@ Rectangle {
|
||||||
id: completeText2;
|
id: completeText2;
|
||||||
text: "The " + (root.itemTypesText)[itemTypesArray.indexOf(root.itemType)] +
|
text: "The " + (root.itemTypesText)[itemTypesArray.indexOf(root.itemType)] +
|
||||||
' <font color="' + hifi.colors.blueAccent + '"><a href="#">' + root.itemName + '</a></font>' +
|
' <font color="' + hifi.colors.blueAccent + '"><a href="#">' + root.itemName + '</a></font>' +
|
||||||
" 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
|
// Text size
|
||||||
size: 18;
|
size: 18;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -833,7 +828,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
lightboxPopup.button2text = "OPEN GOTO";
|
lightboxPopup.button2text = "OPEN GOTO";
|
||||||
lightboxPopup.button2method = function() {
|
lightboxPopup.button2method = function() {
|
||||||
sendToScript({method: 'purchases_openGoTo'});
|
sendToScript({method: 'checkout_openGoTo'});
|
||||||
lightboxPopup.visible = false;
|
lightboxPopup.visible = false;
|
||||||
};
|
};
|
||||||
lightboxPopup.visible = true;
|
lightboxPopup.visible = true;
|
||||||
|
@ -864,7 +859,7 @@ Rectangle {
|
||||||
|
|
||||||
RalewaySemiBold {
|
RalewaySemiBold {
|
||||||
id: myPurchasesLink;
|
id: myPurchasesLink;
|
||||||
text: '<font color="' + hifi.colors.primaryHighlight + '"><a href="#">View this item in My Purchases</a></font>';
|
text: '<font color="' + hifi.colors.primaryHighlight + '"><a href="#">View this item in your Inventory</a></font>';
|
||||||
// Text size
|
// Text size
|
||||||
size: 18;
|
size: 18;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -886,7 +881,8 @@ Rectangle {
|
||||||
|
|
||||||
RalewaySemiBold {
|
RalewaySemiBold {
|
||||||
id: walletLink;
|
id: walletLink;
|
||||||
text: '<font color="' + hifi.colors.primaryHighlight + '"><a href="#">View receipt in Wallet</a></font>';
|
visible: !WalletScriptingInterface.limitedCommerce;
|
||||||
|
text: '<font color="' + hifi.colors.primaryHighlight + '"><a href="#">View receipt in Recent Activity</a></font>';
|
||||||
// Text size
|
// Text size
|
||||||
size: 18;
|
size: 18;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -902,18 +898,18 @@ Rectangle {
|
||||||
horizontalAlignment: Text.AlignLeft;
|
horizontalAlignment: Text.AlignLeft;
|
||||||
verticalAlignment: Text.AlignVCenter;
|
verticalAlignment: Text.AlignVCenter;
|
||||||
onLinkActivated: {
|
onLinkActivated: {
|
||||||
sendToScript({method: 'purchases_openWallet'});
|
sendToScript({method: 'checkout_openRecentActivity'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
id: pendingText;
|
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. ' +
|
||||||
'<b><font color="' + hifi.colors.primaryHighlight + '"><a href="#">Learn More</a></font></b>';
|
'<b><font color="' + hifi.colors.primaryHighlight + '"><a href="#">Learn More</a></font></b>';
|
||||||
// Text size
|
// Text size
|
||||||
size: 18;
|
size: 18;
|
||||||
// Anchors
|
// Anchors
|
||||||
anchors.top: walletLink.bottom;
|
anchors.top: walletLink.visible ? walletLink.bottom : myPurchasesLink.bottom;
|
||||||
anchors.topMargin: 32;
|
anchors.topMargin: 32;
|
||||||
height: paintedHeight;
|
height: paintedHeight;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
|
@ -925,8 +921,8 @@ Rectangle {
|
||||||
horizontalAlignment: Text.AlignLeft;
|
horizontalAlignment: Text.AlignLeft;
|
||||||
verticalAlignment: Text.AlignVCenter;
|
verticalAlignment: Text.AlignVCenter;
|
||||||
onLinkActivated: {
|
onLinkActivated: {
|
||||||
lightboxPopup.titleText = "Purchase Confirmations";
|
lightboxPopup.titleText = "Confirmations";
|
||||||
lightboxPopup.bodyText = 'Your item is marked "pending" while your purchase is being confirmed.<br><br>' +
|
lightboxPopup.bodyText = 'Your item is marked "pending" while the transfer is being confirmed.<br><br>' +
|
||||||
'Confirmations usually take about 90 seconds.';
|
'Confirmations usually take about 90 seconds.';
|
||||||
lightboxPopup.button1text = "CLOSE";
|
lightboxPopup.button1text = "CLOSE";
|
||||||
lightboxPopup.button1method = function() {
|
lightboxPopup.button1method = function() {
|
||||||
|
@ -936,9 +932,9 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Continue Shopping" button
|
// "Continue" button
|
||||||
HifiControlsUit.Button {
|
HifiControlsUit.Button {
|
||||||
id: continueShoppingButton;
|
id: continueButton;
|
||||||
color: hifi.buttons.noneBorderlessGray;
|
color: hifi.buttons.noneBorderlessGray;
|
||||||
colorScheme: hifi.colorSchemes.light;
|
colorScheme: hifi.colorSchemes.light;
|
||||||
anchors.bottom: parent.bottom;
|
anchors.bottom: parent.bottom;
|
||||||
|
@ -946,9 +942,9 @@ Rectangle {
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
width: 193;
|
width: 193;
|
||||||
height: 44;
|
height: 44;
|
||||||
text: "Continue Shopping";
|
text: "Continue";
|
||||||
onClicked: {
|
onClicked: {
|
||||||
sendToScript({method: 'checkout_continueShopping', itemId: itemId});
|
sendToScript({method: 'checkout_continue', itemId: itemId});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -971,7 +967,7 @@ Rectangle {
|
||||||
|
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
id: failureHeaderText;
|
id: failureHeaderText;
|
||||||
text: "<b>Purchase Failed.</b><br>Your Purchases and HFC balance haven't changed.";
|
text: "<b>Purchase Failed.</b><br>Your Inventory and HFC balance haven't changed.";
|
||||||
// Text size
|
// Text size
|
||||||
size: 24;
|
size: 24;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -1037,7 +1033,7 @@ Rectangle {
|
||||||
width: parent.width/2 - anchors.leftMargin*2;
|
width: parent.width/2 - anchors.leftMargin*2;
|
||||||
text: "Back to Marketplace";
|
text: "Back to Marketplace";
|
||||||
onClicked: {
|
onClicked: {
|
||||||
sendToScript({method: 'checkout_continueShopping', itemId: itemId});
|
sendToScript({method: 'checkout_continue', itemId: itemId});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1122,10 +1118,10 @@ Rectangle {
|
||||||
if (root.balanceAfterPurchase < 0) {
|
if (root.balanceAfterPurchase < 0) {
|
||||||
// If you already own the item...
|
// If you already own the item...
|
||||||
if (!root.alreadyOwned) {
|
if (!root.alreadyOwned) {
|
||||||
buyText.text = "<b>Your Wallet does not have sufficient funds to purchase this item.</b>";
|
buyText.text = "<b>You do not have sufficient funds to purchase this item.</b>";
|
||||||
// Else if you don't already own the item...
|
// Else if you don't already own the item...
|
||||||
} else if (canBuyAgain()) {
|
} else if (canBuyAgain()) {
|
||||||
buyText.text = "<b>Your Wallet does not have sufficient funds to purchase this item again.</b>";
|
buyText.text = "<b>You do not have sufficient funds to purchase this item again.</b>";
|
||||||
} else {
|
} else {
|
||||||
buyText.text = "<b>While you do not have sufficient funds to buy this, you already have this item.</b>"
|
buyText.text = "<b>While you do not have sufficient funds to buy this, you already have this item.</b>"
|
||||||
}
|
}
|
||||||
|
@ -1171,7 +1167,7 @@ Rectangle {
|
||||||
buyText.text = "";
|
buyText.text = "";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buyText.text = '<i>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.</i>';
|
buyText.text = '<i>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.</i>';
|
||||||
buyTextContainer.color = hifi.colors.white;
|
buyTextContainer.color = hifi.colors.white;
|
||||||
buyTextContainer.border.color = hifi.colors.white;
|
buyTextContainer.border.color = hifi.colors.white;
|
||||||
buyGlyph.text = "";
|
buyGlyph.text = "";
|
||||||
|
|
|
@ -27,7 +27,6 @@ Item {
|
||||||
property string referrerURL: (Account.metaverseServerURL + "/marketplace?");
|
property string referrerURL: (Account.metaverseServerURL + "/marketplace?");
|
||||||
readonly property int additionalDropdownHeight: usernameDropdown.height - myUsernameButton.anchors.bottomMargin;
|
readonly property int additionalDropdownHeight: usernameDropdown.height - myUsernameButton.anchors.bottomMargin;
|
||||||
property alias usernameDropdownVisible: usernameDropdown.visible;
|
property alias usernameDropdownVisible: usernameDropdown.visible;
|
||||||
property bool messagesWaiting: false;
|
|
||||||
|
|
||||||
height: mainContainer.height + additionalDropdownHeight;
|
height: mainContainer.height + additionalDropdownHeight;
|
||||||
|
|
||||||
|
@ -38,7 +37,6 @@ Item {
|
||||||
if (walletStatus === 0) {
|
if (walletStatus === 0) {
|
||||||
sendToParent({method: "needsLogIn"});
|
sendToParent({method: "needsLogIn"});
|
||||||
} else if (walletStatus === 5) {
|
} else if (walletStatus === 5) {
|
||||||
Commerce.getAvailableUpdates();
|
|
||||||
Commerce.getSecurityImage();
|
Commerce.getSecurityImage();
|
||||||
} else if (walletStatus > 5) {
|
} else if (walletStatus > 5) {
|
||||||
console.log("ERROR in EmulatedMarketplaceHeader.qml: Unknown wallet status: " + walletStatus);
|
console.log("ERROR in EmulatedMarketplaceHeader.qml: Unknown wallet status: " + walletStatus);
|
||||||
|
@ -59,14 +57,6 @@ Item {
|
||||||
securityImage.source = "image://security/securityImage";
|
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: {
|
Component.onCompleted: {
|
||||||
|
@ -118,50 +108,6 @@ Item {
|
||||||
anchors.right: securityImage.left;
|
anchors.right: securityImage.left;
|
||||||
anchors.rightMargin: 6;
|
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 {
|
TextMetrics {
|
||||||
id: textMetrics;
|
id: textMetrics;
|
||||||
font.family: "Raleway"
|
font.family: "Raleway"
|
||||||
|
@ -267,7 +213,7 @@ Item {
|
||||||
anchors.topMargin: -buttonAndUsernameContainer.anchors.bottomMargin;
|
anchors.topMargin: -buttonAndUsernameContainer.anchors.bottomMargin;
|
||||||
anchors.right: buttonAndUsernameContainer.right;
|
anchors.right: buttonAndUsernameContainer.right;
|
||||||
height: childrenRect.height;
|
height: childrenRect.height;
|
||||||
width: 100;
|
width: 150;
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: myItemsButton;
|
id: myItemsButton;
|
||||||
|
@ -279,7 +225,7 @@ Item {
|
||||||
|
|
||||||
RalewaySemiBold {
|
RalewaySemiBold {
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
text: "My Items"
|
text: "My Submissions"
|
||||||
color: hifi.colors.baseGray;
|
color: hifi.colors.baseGray;
|
||||||
horizontalAlignment: Text.AlignHCenter;
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
verticalAlignment: Text.AlignVCenter;
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
|
|
@ -87,7 +87,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
id: introText2;
|
id: introText2;
|
||||||
text: "My Purchases";
|
text: "Inventory";
|
||||||
// Text size
|
// Text size
|
||||||
size: 22;
|
size: 22;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -116,7 +116,7 @@ Rectangle {
|
||||||
|
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
id: step1text;
|
id: step1text;
|
||||||
text: "The <b>'REZ IT'</b> button makes your purchase appear in front of you.";
|
text: "The <b>'REZ IT'</b> button makes your item appear in front of you.";
|
||||||
// Text size
|
// Text size
|
||||||
size: 20;
|
size: 20;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
|
|
@ -73,6 +73,10 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
onTransferAssetToNodeResult: {
|
onTransferAssetToNodeResult: {
|
||||||
|
if (!root.visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
root.isCurrentlySendingAsset = false;
|
root.isCurrentlySendingAsset = false;
|
||||||
|
|
||||||
if (result.status === 'success') {
|
if (result.status === 'success') {
|
||||||
|
@ -92,6 +96,10 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
onTransferAssetToUsernameResult: {
|
onTransferAssetToUsernameResult: {
|
||||||
|
if (!root.visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
root.isCurrentlySendingAsset = false;
|
root.isCurrentlySendingAsset = false;
|
||||||
|
|
||||||
if (result.status === 'success') {
|
if (result.status === 'success') {
|
||||||
|
@ -1309,13 +1317,13 @@ Item {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
anchors.topMargin: root.assetName === "" ? 15 : 150;
|
anchors.topMargin: root.assetName === "" ? 15 : 125;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.leftMargin: root.assetName === "" ? 15 : 50;
|
anchors.leftMargin: root.assetName === "" ? 15 : 50;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
anchors.rightMargin: root.assetName === "" ? 15 : 50;
|
anchors.rightMargin: root.assetName === "" ? 15 : 50;
|
||||||
anchors.bottom: parent.bottom;
|
anchors.bottom: parent.bottom;
|
||||||
anchors.bottomMargin: root.assetName === "" ? 15 : 240;
|
anchors.bottomMargin: root.assetName === "" ? 15 : 125;
|
||||||
color: "#FFFFFF";
|
color: "#FFFFFF";
|
||||||
|
|
||||||
RalewaySemiBold {
|
RalewaySemiBold {
|
||||||
|
|
|
@ -28,7 +28,7 @@ Rectangle {
|
||||||
property string itemName: "--";
|
property string itemName: "--";
|
||||||
property string itemOwner: "--";
|
property string itemOwner: "--";
|
||||||
property string itemEdition: "--";
|
property string itemEdition: "--";
|
||||||
property string dateOfPurchase: "--";
|
property string dateAcquired: "--";
|
||||||
property string itemCost: "--";
|
property string itemCost: "--";
|
||||||
property string certTitleTextColor: hifi.colors.darkGray;
|
property string certTitleTextColor: hifi.colors.darkGray;
|
||||||
property string certTextColor: hifi.colors.white;
|
property string certTextColor: hifi.colors.white;
|
||||||
|
@ -64,7 +64,7 @@ Rectangle {
|
||||||
root.itemName = "";
|
root.itemName = "";
|
||||||
root.itemEdition = "";
|
root.itemEdition = "";
|
||||||
root.itemOwner = "";
|
root.itemOwner = "";
|
||||||
root.dateOfPurchase = "";
|
root.dateAcquired = "";
|
||||||
root.itemCost = "";
|
root.itemCost = "";
|
||||||
errorText.text = "Information about this certificate is currently unavailable. Please try again later.";
|
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
|
// "\u2022" is the Unicode character 'BULLET' - it's what's used in password fields on the web, etc
|
||||||
root.itemOwner = root.isMyCert ? Account.username :
|
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";
|
"\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.dateAcquired = root.isMyCert ? getFormattedDate(result.data.transfer_created_at * 1000) : "Undisclosed";
|
||||||
root.itemCost = (root.isMyCert && result.data.cost !== undefined) ? result.data.cost : "Undisclosed";
|
root.itemCost = (root.isMyCert && result.data.cost !== undefined) ?
|
||||||
|
(parseInt(result.data.cost) > 0 ? result.data.cost : "Free") : "Undisclosed";
|
||||||
}
|
}
|
||||||
if (root.certInfoReplaceMode > 4) {
|
if (root.certInfoReplaceMode > 4) {
|
||||||
root.itemEdition = result.data.edition_number + "/" + (result.data.limited_run === -1 ? "\u221e" : result.data.limited_run);
|
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.certificateStatus === 4) { // CERTIFICATE_STATUS_OWNER_VERIFICATION_FAILED
|
||||||
if (root.isMyCert) {
|
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 {
|
} else {
|
||||||
errorText.text = "The person who placed this item doesn't own it.";
|
errorText.text = "The person who placed this item doesn't own it.";
|
||||||
}
|
}
|
||||||
|
@ -102,8 +103,8 @@ Rectangle {
|
||||||
showInMarketplaceButton.visible = false;
|
showInMarketplaceButton.visible = false;
|
||||||
// "Edition" text previously set above in this function
|
// "Edition" text previously set above in this function
|
||||||
// "Owner" text previously set above in this function
|
// "Owner" text previously set above in this function
|
||||||
// "Purchase Date" text previously set above in this function
|
// "Acquisition Date" text previously set above in this function
|
||||||
// "Purchase Price" text previously set above in this function
|
// "Acquisition Price" text previously set above in this function
|
||||||
if (result.data.invalid_reason) {
|
if (result.data.invalid_reason) {
|
||||||
errorText.text = result.data.invalid_reason;
|
errorText.text = result.data.invalid_reason;
|
||||||
}
|
}
|
||||||
|
@ -117,8 +118,8 @@ Rectangle {
|
||||||
showInMarketplaceButton.visible = true;
|
showInMarketplaceButton.visible = true;
|
||||||
// "Edition" text previously set above in this function
|
// "Edition" text previously set above in this function
|
||||||
// "Owner" text previously set above in this function
|
// "Owner" text previously set above in this function
|
||||||
// "Purchase Date" text previously set above in this function
|
// "Acquisition Date" text previously set above in this function
|
||||||
// "Purchase Price" 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, " +
|
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.";
|
"this entity will be cleaned up by the domain.";
|
||||||
}
|
}
|
||||||
|
@ -145,8 +146,8 @@ Rectangle {
|
||||||
// "Item Name" text will be set in "onCertificateInfoResult()"
|
// "Item Name" text will be set in "onCertificateInfoResult()"
|
||||||
// "Edition" text will be set in "onCertificateInfoResult()"
|
// "Edition" text will be set in "onCertificateInfoResult()"
|
||||||
// "Owner" text will be set in "onCertificateInfoResult()"
|
// "Owner" text will be set in "onCertificateInfoResult()"
|
||||||
// "Purchase Date" text will be set in "onCertificateInfoResult()"
|
// "Acquisition Date" text will be set in "onCertificateInfoResult()"
|
||||||
// "Purchase Price" text will be set in "onCertificateInfoResult()"
|
// "Acquisition Price" text will be set in "onCertificateInfoResult()"
|
||||||
errorText.text = "";
|
errorText.text = "";
|
||||||
} else if (root.certificateStatus === 2) { // CERTIFICATE_STATUS_VERIFICATION_TIMEOUT
|
} else if (root.certificateStatus === 2) { // CERTIFICATE_STATUS_VERIFICATION_TIMEOUT
|
||||||
root.useGoldCert = false;
|
root.useGoldCert = false;
|
||||||
|
@ -160,7 +161,7 @@ Rectangle {
|
||||||
root.itemName = "";
|
root.itemName = "";
|
||||||
root.itemEdition = "";
|
root.itemEdition = "";
|
||||||
root.itemOwner = "";
|
root.itemOwner = "";
|
||||||
root.dateOfPurchase = "";
|
root.dateAcquired = "";
|
||||||
root.itemCost = "";
|
root.itemCost = "";
|
||||||
errorText.text = "Your request to inspect this item timed out. Please try again later.";
|
errorText.text = "Your request to inspect this item timed out. Please try again later.";
|
||||||
} else if (root.certificateStatus === 3) { // CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED
|
} else if (root.certificateStatus === 3) { // CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED
|
||||||
|
@ -175,8 +176,8 @@ Rectangle {
|
||||||
// "Item Name" text will be set in "onCertificateInfoResult()"
|
// "Item Name" text will be set in "onCertificateInfoResult()"
|
||||||
// "Edition" text will be set in "onCertificateInfoResult()"
|
// "Edition" text will be set in "onCertificateInfoResult()"
|
||||||
// "Owner" text will be set in "onCertificateInfoResult()"
|
// "Owner" text will be set in "onCertificateInfoResult()"
|
||||||
// "Purchase Date" text will be set in "onCertificateInfoResult()"
|
// "Acquisition Date" text will be set in "onCertificateInfoResult()"
|
||||||
// "Purchase Price" 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.";
|
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
|
} else if (root.certificateStatus === 4) { // CERTIFICATE_STATUS_OWNER_VERIFICATION_FAILED
|
||||||
root.useGoldCert = false;
|
root.useGoldCert = false;
|
||||||
|
@ -190,8 +191,8 @@ Rectangle {
|
||||||
// "Item Name" text will be set in "onCertificateInfoResult()"
|
// "Item Name" text will be set in "onCertificateInfoResult()"
|
||||||
root.itemEdition = "Uncertified Copy"
|
root.itemEdition = "Uncertified Copy"
|
||||||
// "Owner" text will be set in "onCertificateInfoResult()"
|
// "Owner" text will be set in "onCertificateInfoResult()"
|
||||||
// "Purchase Date" text will be set in "onCertificateInfoResult()"
|
// "Acquisition Date" text will be set in "onCertificateInfoResult()"
|
||||||
// "Purchase Price" text will be set in "onCertificateInfoResult()"
|
// "Acquisition Price" text will be set in "onCertificateInfoResult()"
|
||||||
// "Error Text" text will be set in "onCertificateInfoResult()"
|
// "Error Text" text will be set in "onCertificateInfoResult()"
|
||||||
} else {
|
} else {
|
||||||
console.log("Unknown certificate status received from ledger signal!");
|
console.log("Unknown certificate status received from ledger signal!");
|
||||||
|
@ -485,8 +486,8 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
id: dateOfPurchaseHeader;
|
id: dateAcquiredHeader;
|
||||||
text: "PURCHASE DATE";
|
text: "ACQUISITION DATE";
|
||||||
// Text size
|
// Text size
|
||||||
size: 16;
|
size: 16;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -500,15 +501,15 @@ Rectangle {
|
||||||
color: hifi.colors.darkGray;
|
color: hifi.colors.darkGray;
|
||||||
}
|
}
|
||||||
AnonymousProRegular {
|
AnonymousProRegular {
|
||||||
id: dateOfPurchase;
|
id: dateAcquired;
|
||||||
text: root.dateOfPurchase;
|
text: root.dateAcquired;
|
||||||
// Text size
|
// Text size
|
||||||
size: 18;
|
size: 18;
|
||||||
// Anchors
|
// Anchors
|
||||||
anchors.top: dateOfPurchaseHeader.bottom;
|
anchors.top: dateAcquiredHeader.bottom;
|
||||||
anchors.topMargin: 8;
|
anchors.topMargin: 8;
|
||||||
anchors.left: dateOfPurchaseHeader.left;
|
anchors.left: dateAcquiredHeader.left;
|
||||||
anchors.right: dateOfPurchaseHeader.right;
|
anchors.right: dateAcquiredHeader.right;
|
||||||
height: paintedHeight;
|
height: paintedHeight;
|
||||||
// Style
|
// Style
|
||||||
color: root.infoTextColor;
|
color: root.infoTextColor;
|
||||||
|
@ -516,7 +517,7 @@ Rectangle {
|
||||||
|
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
id: priceHeader;
|
id: priceHeader;
|
||||||
text: "PURCHASE PRICE";
|
text: "ACQUISITION PRICE";
|
||||||
// Text size
|
// Text size
|
||||||
size: 16;
|
size: 16;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -530,7 +531,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
HiFiGlyphs {
|
HiFiGlyphs {
|
||||||
id: hfcGlyph;
|
id: hfcGlyph;
|
||||||
visible: priceText.text !== "Undisclosed" && priceText.text !== "";
|
visible: priceText.text !== "Undisclosed" && priceText.text !== "" && priceText.text !== "Free";
|
||||||
text: hifi.glyphs.hfc;
|
text: hifi.glyphs.hfc;
|
||||||
// Size
|
// Size
|
||||||
size: 24;
|
size: 24;
|
||||||
|
@ -618,7 +619,7 @@ Rectangle {
|
||||||
root.itemName = "--";
|
root.itemName = "--";
|
||||||
root.itemOwner = "--";
|
root.itemOwner = "--";
|
||||||
root.itemEdition = "--";
|
root.itemEdition = "--";
|
||||||
root.dateOfPurchase = "--";
|
root.dateAcquired = "--";
|
||||||
root.marketplaceUrl = "";
|
root.marketplaceUrl = "";
|
||||||
root.itemCost = "--";
|
root.itemCost = "--";
|
||||||
root.isMyCert = false;
|
root.isMyCert = false;
|
||||||
|
|
|
@ -47,8 +47,7 @@ Item {
|
||||||
property string wornEntityID;
|
property string wornEntityID;
|
||||||
property string upgradeUrl;
|
property string upgradeUrl;
|
||||||
property string upgradeTitle;
|
property string upgradeTitle;
|
||||||
property bool updateAvailable: root.upgradeUrl !== "" && !root.isShowingMyItems;
|
property bool updateAvailable: root.upgradeUrl !== "";
|
||||||
property bool isShowingMyItems;
|
|
||||||
property bool valid;
|
property bool valid;
|
||||||
|
|
||||||
property string originalStatusText;
|
property string originalStatusText;
|
||||||
|
@ -231,7 +230,7 @@ Item {
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: giftButton;
|
id: giftButton;
|
||||||
visible: !root.isShowingMyItems;
|
visible: root.itemEdition > 0;
|
||||||
sourceComponent: contextCardButton;
|
sourceComponent: contextCardButton;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
|
@ -345,6 +344,7 @@ Item {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: permissionExplanationCard;
|
id: permissionExplanationCard;
|
||||||
|
visible: false;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.leftMargin: 30;
|
anchors.leftMargin: 30;
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
|
|
|
@ -19,7 +19,6 @@ import "../../../controls" as HifiControls
|
||||||
import "qrc:////qml//hifi//models" as HifiModels // Absolute path so the same code works everywhere.
|
import "qrc:////qml//hifi//models" as HifiModels // Absolute path so the same code works everywhere.
|
||||||
import "../wallet" as HifiWallet
|
import "../wallet" as HifiWallet
|
||||||
import "../common" as HifiCommerceCommon
|
import "../common" as HifiCommerceCommon
|
||||||
import "../inspectionCertificate" as HifiInspectionCertificate
|
|
||||||
import "../common/sendAsset" as HifiSendAsset
|
import "../common/sendAsset" as HifiSendAsset
|
||||||
import "../.." as HifiCommon
|
import "../.." as HifiCommon
|
||||||
|
|
||||||
|
@ -34,7 +33,6 @@ Rectangle {
|
||||||
property bool securityImageResultReceived: false;
|
property bool securityImageResultReceived: false;
|
||||||
property bool purchasesReceived: false;
|
property bool purchasesReceived: false;
|
||||||
property bool punctuationMode: false;
|
property bool punctuationMode: false;
|
||||||
property bool isShowingMyItems: false;
|
|
||||||
property bool isDebuggingFirstUseTutorial: false;
|
property bool isDebuggingFirstUseTutorial: false;
|
||||||
property string installedApps;
|
property string installedApps;
|
||||||
property bool keyboardRaised: false;
|
property bool keyboardRaised: false;
|
||||||
|
@ -92,7 +90,6 @@ Rectangle {
|
||||||
if (result.status !== 'success') {
|
if (result.status !== 'success') {
|
||||||
console.log("Failed to get Available Updates", result.data.message);
|
console.log("Failed to get Available Updates", result.data.message);
|
||||||
} else {
|
} else {
|
||||||
sendToScript({method: 'purchases_availableUpdatesReceived', numUpdates: result.data.updates.length });
|
|
||||||
root.numUpdatesAvailable = result.total_entries;
|
root.numUpdatesAvailable = result.total_entries;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,10 +103,6 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onIsShowingMyItemsChanged: {
|
|
||||||
getPurchases();
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: notSetUpTimer;
|
id: notSetUpTimer;
|
||||||
interval: 200;
|
interval: 200;
|
||||||
|
@ -118,19 +111,6 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HifiInspectionCertificate.InspectionCertificate {
|
|
||||||
id: inspectionCertificate;
|
|
||||||
z: 998;
|
|
||||||
visible: false;
|
|
||||||
anchors.fill: parent;
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
onSendToScript: {
|
|
||||||
sendToScript(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HifiCommerceCommon.CommerceLightbox {
|
HifiCommerceCommon.CommerceLightbox {
|
||||||
id: lightboxPopup;
|
id: lightboxPopup;
|
||||||
z: 999;
|
z: 999;
|
||||||
|
@ -180,7 +160,8 @@ Rectangle {
|
||||||
HifiCommerceCommon.EmulatedMarketplaceHeader {
|
HifiCommerceCommon.EmulatedMarketplaceHeader {
|
||||||
id: titleBarContainer;
|
id: titleBarContainer;
|
||||||
z: 997;
|
z: 997;
|
||||||
visible: !needsLogIn.visible;
|
visible: false;
|
||||||
|
height: 100;
|
||||||
// Size
|
// Size
|
||||||
width: parent.width;
|
width: parent.width;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -199,11 +180,6 @@ Rectangle {
|
||||||
lightboxPopup.button1method = function() {
|
lightboxPopup.button1method = function() {
|
||||||
lightboxPopup.visible = false;
|
lightboxPopup.visible = false;
|
||||||
}
|
}
|
||||||
lightboxPopup.button2text = "GO TO WALLET";
|
|
||||||
lightboxPopup.button2method = function() {
|
|
||||||
sendToScript({method: 'purchases_openWallet'});
|
|
||||||
lightboxPopup.visible = false;
|
|
||||||
};
|
|
||||||
lightboxPopup.visible = true;
|
lightboxPopup.visible = true;
|
||||||
} else {
|
} else {
|
||||||
sendToScript(msg);
|
sendToScript(msg);
|
||||||
|
@ -475,7 +451,7 @@ Rectangle {
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.leftMargin: 16;
|
anchors.leftMargin: 16;
|
||||||
width: paintedWidth;
|
width: paintedWidth;
|
||||||
text: isShowingMyItems ? "My Items" : "My Purchases";
|
text: "Inventory";
|
||||||
color: hifi.colors.black;
|
color: hifi.colors.black;
|
||||||
size: 22;
|
size: 22;
|
||||||
}
|
}
|
||||||
|
@ -517,8 +493,13 @@ Rectangle {
|
||||||
"filterName": "wearable"
|
"filterName": "wearable"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"separator" : true,
|
||||||
"displayName": "Updatable",
|
"displayName": "Updatable",
|
||||||
"filterName": "updated"
|
"filterName": "updated"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"displayName": "My Submissions",
|
||||||
|
"filterName": "proofs"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
filterBar.primaryFilterChoices.clear();
|
filterBar.primaryFilterChoices.clear();
|
||||||
|
@ -533,6 +514,7 @@ Rectangle {
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
purchasesModel.searchFilter = filterBar.text;
|
purchasesModel.searchFilter = filterBar.text;
|
||||||
filterBar.previousText = filterBar.text;
|
filterBar.previousText = filterBar.text;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -556,10 +538,18 @@ Rectangle {
|
||||||
listModelName: 'purchases';
|
listModelName: 'purchases';
|
||||||
listView: purchasesContentsList;
|
listView: purchasesContentsList;
|
||||||
getPage: function () {
|
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(
|
Commerce.inventory(
|
||||||
root.isShowingMyItems ? "proofs" : "purchased",
|
editionFilter,
|
||||||
filterBar.primaryFilter_filterName,
|
primaryFilter,
|
||||||
filterBar.text,
|
filterBar.text,
|
||||||
purchasesModel.currentPageToRetrieve,
|
purchasesModel.currentPageToRetrieve,
|
||||||
purchasesModel.itemsPerPage
|
purchasesModel.itemsPerPage
|
||||||
|
@ -609,7 +599,6 @@ Rectangle {
|
||||||
upgradeUrl: model.upgrade_url;
|
upgradeUrl: model.upgrade_url;
|
||||||
upgradeTitle: model.upgrade_title;
|
upgradeTitle: model.upgrade_title;
|
||||||
itemType: model.item_type;
|
itemType: model.item_type;
|
||||||
isShowingMyItems: root.isShowingMyItems;
|
|
||||||
valid: model.valid;
|
valid: model.valid;
|
||||||
anchors.topMargin: 10;
|
anchors.topMargin: 10;
|
||||||
anchors.bottomMargin: 10;
|
anchors.bottomMargin: 10;
|
||||||
|
@ -626,8 +615,6 @@ Rectangle {
|
||||||
sendToScript({ method: 'purchases_updateWearables' });
|
sendToScript({ method: 'purchases_updateWearables' });
|
||||||
}
|
}
|
||||||
} else if (msg.method === 'purchases_itemCertificateClicked') {
|
} else if (msg.method === 'purchases_itemCertificateClicked') {
|
||||||
inspectionCertificate.visible = true;
|
|
||||||
inspectionCertificate.isLightbox = true;
|
|
||||||
sendToScript(msg);
|
sendToScript(msg);
|
||||||
} else if (msg.method === "showInvalidatedLightbox") {
|
} else if (msg.method === "showInvalidatedLightbox") {
|
||||||
lightboxPopup.titleText = "Item Invalidated";
|
lightboxPopup.titleText = "Item Invalidated";
|
||||||
|
@ -640,7 +627,7 @@ Rectangle {
|
||||||
lightboxPopup.visible = true;
|
lightboxPopup.visible = true;
|
||||||
} else if (msg.method === "showPendingLightbox") {
|
} else if (msg.method === "showPendingLightbox") {
|
||||||
lightboxPopup.titleText = "Item Pending";
|
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.";
|
"Usually, purchases take about 90 seconds to confirm.";
|
||||||
lightboxPopup.button1text = "CLOSE";
|
lightboxPopup.button1text = "CLOSE";
|
||||||
lightboxPopup.button1method = function() {
|
lightboxPopup.button1method = function() {
|
||||||
|
@ -822,7 +809,8 @@ Rectangle {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: updatesAvailableBanner;
|
id: updatesAvailableBanner;
|
||||||
visible: root.numUpdatesAvailable > 0 && !root.isShowingMyItems;
|
visible: root.numUpdatesAvailable > 0 &&
|
||||||
|
filterBar.primaryFilter_filterName !== "proofs";
|
||||||
anchors.bottom: parent.bottom;
|
anchors.bottom: parent.bottom;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
|
@ -883,9 +871,8 @@ Rectangle {
|
||||||
id: noItemsAlertContainer;
|
id: noItemsAlertContainer;
|
||||||
visible: !purchasesContentsList.visible &&
|
visible: !purchasesContentsList.visible &&
|
||||||
root.purchasesReceived &&
|
root.purchasesReceived &&
|
||||||
root.isShowingMyItems &&
|
|
||||||
filterBar.text === "" &&
|
filterBar.text === "" &&
|
||||||
filterBar.primaryFilter_displayName === "";
|
filterBar.primaryFilter_filterName === "proofs";
|
||||||
anchors.top: filterBarContainer.bottom;
|
anchors.top: filterBarContainer.bottom;
|
||||||
anchors.topMargin: 12;
|
anchors.topMargin: 12;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
|
@ -895,7 +882,7 @@ Rectangle {
|
||||||
// Explanitory text
|
// Explanitory text
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
id: noItemsYet;
|
id: noItemsYet;
|
||||||
text: "<b>You haven't submitted anything to the Marketplace yet!</b><br><br>Submit an item to the Marketplace to add it to My Items.";
|
text: "<b>You haven't submitted anything to the Marketplace yet!</b><br><br>Submit an item to the Marketplace to add it to My Submissions.";
|
||||||
// Text size
|
// Text size
|
||||||
size: 22;
|
size: 22;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -933,7 +920,6 @@ Rectangle {
|
||||||
id: noPurchasesAlertContainer;
|
id: noPurchasesAlertContainer;
|
||||||
visible: !purchasesContentsList.visible &&
|
visible: !purchasesContentsList.visible &&
|
||||||
root.purchasesReceived &&
|
root.purchasesReceived &&
|
||||||
!root.isShowingMyItems &&
|
|
||||||
filterBar.text === "" &&
|
filterBar.text === "" &&
|
||||||
filterBar.primaryFilter_displayName === "";
|
filterBar.primaryFilter_displayName === "";
|
||||||
anchors.top: filterBarContainer.bottom;
|
anchors.top: filterBarContainer.bottom;
|
||||||
|
@ -945,7 +931,7 @@ Rectangle {
|
||||||
// Explanitory text
|
// Explanitory text
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
id: haventPurchasedYet;
|
id: haventPurchasedYet;
|
||||||
text: "<b>You haven't purchased anything yet!</b><br><br>Get an item from <b>Marketplace</b> to add it to My Purchases.";
|
text: "<b>You haven't gotten anything yet!</b><br><br>Get an item from <b>Marketplace</b> to add it to your Inventory.";
|
||||||
// Text size
|
// Text size
|
||||||
size: 22;
|
size: 22;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -1065,11 +1051,10 @@ Rectangle {
|
||||||
titleBarContainer.referrerURL = message.referrerURL || "";
|
titleBarContainer.referrerURL = message.referrerURL || "";
|
||||||
filterBar.text = message.filterText ? message.filterText : "";
|
filterBar.text = message.filterText ? message.filterText : "";
|
||||||
break;
|
break;
|
||||||
case 'inspectionCertificate_setCertificateId':
|
|
||||||
inspectionCertificate.fromScript(message);
|
|
||||||
break;
|
|
||||||
case 'purchases_showMyItems':
|
case 'purchases_showMyItems':
|
||||||
root.isShowingMyItems = true;
|
filterBar.primaryFilter_filterName = "proofs";
|
||||||
|
filterBar.primaryFilter_displayName = "Proofs";
|
||||||
|
filterBar.primaryFilter_index = 6;
|
||||||
break;
|
break;
|
||||||
case 'updateConnections':
|
case 'updateConnections':
|
||||||
sendAsset.updateConnections(message.connections);
|
sendAsset.updateConnections(message.connections);
|
||||||
|
|
|
@ -62,7 +62,7 @@ Item {
|
||||||
isExpanded: false;
|
isExpanded: false;
|
||||||
question: "How can I get HFC?";
|
question: "How can I get HFC?";
|
||||||
answer: "High Fidelity commerce is in open beta right now. Want more HFC? \
|
answer: "High Fidelity commerce is in open beta right now. Want more HFC? \
|
||||||
Get it by going to <br><br><b><font color='#0093C5'><a href='#bank'>BankOfHighFidelity.</a></font></b> and meeting with the banker!";
|
Get it by going to <b><font color='#0093C5'><a href='#bank'>BankOfHighFidelity</a></font></b> and meeting with the banker!";
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
isExpanded: false;
|
isExpanded: false;
|
||||||
|
|
|
@ -93,7 +93,7 @@ Item {
|
||||||
// Text below helper text
|
// Text below helper text
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
id: loginDetailText;
|
id: loginDetailText;
|
||||||
text: "To buy/sell items on the <b>Marketplace</b>, or to use your <b>Wallet</b>, you must first log in to High Fidelity.";
|
text: "To get items on the <b>Marketplace</b>, or to use your <b>Assets</b>, you must first log in to High Fidelity.";
|
||||||
// Text size
|
// Text size
|
||||||
size: 18;
|
size: 18;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
|
|
@ -20,6 +20,8 @@ import "../../../controls" as HifiControls
|
||||||
import "../common" as HifiCommerceCommon
|
import "../common" as HifiCommerceCommon
|
||||||
import "../common/sendAsset"
|
import "../common/sendAsset"
|
||||||
import "../.." as HifiCommon
|
import "../.." as HifiCommon
|
||||||
|
import "../purchases" as HifiPurchases
|
||||||
|
import "../inspectionCertificate" as HifiInspectionCertificate
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
HifiConstants { id: hifi; }
|
HifiConstants { id: hifi; }
|
||||||
|
@ -27,6 +29,7 @@ Rectangle {
|
||||||
id: root;
|
id: root;
|
||||||
|
|
||||||
property string activeView: "initialize";
|
property string activeView: "initialize";
|
||||||
|
property string initialActiveViewAfterStatus5: "walletInventory";
|
||||||
property bool keyboardRaised: false;
|
property bool keyboardRaised: false;
|
||||||
property bool isPassword: false;
|
property bool isPassword: false;
|
||||||
|
|
||||||
|
@ -64,7 +67,8 @@ Rectangle {
|
||||||
}
|
}
|
||||||
} else if (walletStatus === 5) {
|
} else if (walletStatus === 5) {
|
||||||
if (root.activeView !== "walletSetup") {
|
if (root.activeView !== "walletSetup") {
|
||||||
root.activeView = "walletHome";
|
root.activeView = root.initialActiveViewAfterStatus5;
|
||||||
|
Commerce.getAvailableUpdates();
|
||||||
Commerce.getSecurityImage();
|
Commerce.getSecurityImage();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -86,6 +90,21 @@ Rectangle {
|
||||||
titleBarSecurityImage.source = "image://security/securityImage";
|
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 {
|
HifiCommerceCommon.CommerceLightbox {
|
||||||
|
@ -124,7 +143,7 @@ Rectangle {
|
||||||
// Title Bar text
|
// Title Bar text
|
||||||
RalewaySemiBold {
|
RalewaySemiBold {
|
||||||
id: titleBarText;
|
id: titleBarText;
|
||||||
text: "WALLET";
|
text: "ASSETS";
|
||||||
// Text size
|
// Text size
|
||||||
size: hifi.fontSizes.overlayTitle;
|
size: hifi.fontSizes.overlayTitle;
|
||||||
// Anchors
|
// 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 {
|
HifiCommon.RootHttpRequest {
|
||||||
id: http;
|
id: http;
|
||||||
}
|
}
|
||||||
|
@ -380,16 +432,17 @@ Rectangle {
|
||||||
// "WALLET HOME" tab button
|
// "WALLET HOME" tab button
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: walletHomeButtonContainer;
|
id: walletHomeButtonContainer;
|
||||||
|
property bool messagesWaiting: false;
|
||||||
visible: !walletSetup.visible;
|
visible: !walletSetup.visible;
|
||||||
color: root.activeView === "walletHome" ? hifi.colors.blueAccent : hifi.colors.black;
|
color: root.activeView === "walletHome" ? hifi.colors.blueAccent : hifi.colors.black;
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
anchors.left: parent.left;
|
anchors.left: exchangeMoneyButtonContainer.right;
|
||||||
anchors.bottom: parent.bottom;
|
anchors.bottom: parent.bottom;
|
||||||
width: parent.width / tabButtonsContainer.numTabs;
|
width: parent.width / tabButtonsContainer.numTabs;
|
||||||
|
|
||||||
HiFiGlyphs {
|
HiFiGlyphs {
|
||||||
id: homeTabIcon;
|
id: homeTabIcon;
|
||||||
text: hifi.glyphs.home2;
|
text: hifi.glyphs.leftRightArrows;
|
||||||
// Size
|
// Size
|
||||||
size: 50;
|
size: 50;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -397,11 +450,24 @@ Rectangle {
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
anchors.topMargin: -2;
|
anchors.topMargin: -2;
|
||||||
// Style
|
// 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 {
|
RalewaySemiBold {
|
||||||
text: "WALLET HOME";
|
text: "RECENT ACTIVITY";
|
||||||
// Text size
|
// Text size
|
||||||
size: 16;
|
size: 16;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -412,7 +478,7 @@ Rectangle {
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
anchors.rightMargin: 4;
|
anchors.rightMargin: 4;
|
||||||
// Style
|
// 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;
|
wrapMode: Text.WordWrap;
|
||||||
// Alignment
|
// Alignment
|
||||||
horizontalAlignment: Text.AlignHCenter;
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
|
@ -421,6 +487,7 @@ Rectangle {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: walletHomeTabMouseArea;
|
id: walletHomeTabMouseArea;
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
|
enabled: !WalletScriptingInterface.limitedCommerce;
|
||||||
hoverEnabled: enabled;
|
hoverEnabled: enabled;
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.activeView = "walletHome";
|
root.activeView = "walletHome";
|
||||||
|
@ -434,16 +501,18 @@ Rectangle {
|
||||||
// "EXCHANGE MONEY" tab button
|
// "EXCHANGE MONEY" tab button
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: exchangeMoneyButtonContainer;
|
id: exchangeMoneyButtonContainer;
|
||||||
|
property bool messagesWaiting: false;
|
||||||
|
|
||||||
visible: !walletSetup.visible;
|
visible: !walletSetup.visible;
|
||||||
color: hifi.colors.black;
|
color: root.activeView === "walletInventory" ? hifi.colors.blueAccent : hifi.colors.black;
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
anchors.left: walletHomeButtonContainer.right;
|
anchors.left: parent.left;
|
||||||
anchors.bottom: parent.bottom;
|
anchors.bottom: parent.bottom;
|
||||||
width: parent.width / tabButtonsContainer.numTabs;
|
width: parent.width / tabButtonsContainer.numTabs;
|
||||||
|
|
||||||
HiFiGlyphs {
|
HiFiGlyphs {
|
||||||
id: exchangeMoneyTabIcon;
|
id: exchangeMoneyTabIcon;
|
||||||
text: hifi.glyphs.leftRightArrows;
|
text: hifi.glyphs.home2;
|
||||||
// Size
|
// Size
|
||||||
size: 50;
|
size: 50;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -451,11 +520,24 @@ Rectangle {
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
anchors.topMargin: -2;
|
anchors.topMargin: -2;
|
||||||
// Style
|
// 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 {
|
RalewaySemiBold {
|
||||||
text: "EXCHANGE MONEY";
|
text: "INVENTORY";
|
||||||
// Text size
|
// Text size
|
||||||
size: 16;
|
size: 16;
|
||||||
// Anchors
|
// Anchors
|
||||||
|
@ -466,12 +548,24 @@ Rectangle {
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
anchors.rightMargin: 4;
|
anchors.rightMargin: 4;
|
||||||
// Style
|
// Style
|
||||||
color: hifi.colors.lightGray50;
|
color: root.activeView === "walletInventory" || inventoryTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
|
||||||
wrapMode: Text.WordWrap;
|
wrapMode: Text.WordWrap;
|
||||||
// Alignment
|
// Alignment
|
||||||
horizontalAlignment: Text.AlignHCenter;
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
verticalAlignment: Text.AlignTop;
|
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,7 +575,7 @@ Rectangle {
|
||||||
visible: !walletSetup.visible;
|
visible: !walletSetup.visible;
|
||||||
color: root.activeView === "sendMoney" ? hifi.colors.blueAccent : hifi.colors.black;
|
color: root.activeView === "sendMoney" ? hifi.colors.blueAccent : hifi.colors.black;
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
anchors.left: exchangeMoneyButtonContainer.right;
|
anchors.left: walletHomeButtonContainer.right;
|
||||||
anchors.bottom: parent.bottom;
|
anchors.bottom: parent.bottom;
|
||||||
width: parent.width / tabButtonsContainer.numTabs;
|
width: parent.width / tabButtonsContainer.numTabs;
|
||||||
|
|
||||||
|
@ -495,7 +589,7 @@ Rectangle {
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
anchors.topMargin: -2;
|
anchors.topMargin: -2;
|
||||||
// Style
|
// 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 {
|
RalewaySemiBold {
|
||||||
|
@ -510,7 +604,7 @@ Rectangle {
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
anchors.rightMargin: 4;
|
anchors.rightMargin: 4;
|
||||||
// Style
|
// 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;
|
wrapMode: Text.WordWrap;
|
||||||
// Alignment
|
// Alignment
|
||||||
horizontalAlignment: Text.AlignHCenter;
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
|
@ -520,6 +614,7 @@ Rectangle {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: sendMoneyTabMouseArea;
|
id: sendMoneyTabMouseArea;
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
|
enabled: !WalletScriptingInterface.limitedCommerce;
|
||||||
hoverEnabled: enabled;
|
hoverEnabled: enabled;
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.activeView = "sendMoney";
|
root.activeView = "sendMoney";
|
||||||
|
@ -588,16 +683,16 @@ Rectangle {
|
||||||
function resetTabButtonColors() {
|
function resetTabButtonColors() {
|
||||||
walletHomeButtonContainer.color = hifi.colors.black;
|
walletHomeButtonContainer.color = hifi.colors.black;
|
||||||
sendMoneyButtonContainer.color = hifi.colors.black;
|
sendMoneyButtonContainer.color = hifi.colors.black;
|
||||||
securityButtonContainer.color = hifi.colors.black;
|
|
||||||
helpButtonContainer.color = hifi.colors.black;
|
helpButtonContainer.color = hifi.colors.black;
|
||||||
|
exchangeMoneyButtonContainer.color = hifi.colors.black;
|
||||||
if (root.activeView === "walletHome") {
|
if (root.activeView === "walletHome") {
|
||||||
walletHomeButtonContainer.color = hifi.colors.blueAccent;
|
walletHomeButtonContainer.color = hifi.colors.blueAccent;
|
||||||
} else if (root.activeView === "sendMoney") {
|
} else if (root.activeView === "sendMoney") {
|
||||||
sendMoneyButtonContainer.color = hifi.colors.blueAccent;
|
sendMoneyButtonContainer.color = hifi.colors.blueAccent;
|
||||||
} else if (root.activeView === "security") {
|
|
||||||
securityButtonContainer.color = hifi.colors.blueAccent;
|
|
||||||
} else if (root.activeView === "help") {
|
} else if (root.activeView === "help") {
|
||||||
helpButtonContainer.color = hifi.colors.blueAccent;
|
helpButtonContainer.color = hifi.colors.blueAccent;
|
||||||
|
} else if (root.activeView == "walletInventory") {
|
||||||
|
exchangeMoneyButtonContainer.color = hifi.colors.blueAccent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -663,18 +758,40 @@ Rectangle {
|
||||||
break;
|
break;
|
||||||
case 'updateConnections':
|
case 'updateConnections':
|
||||||
sendMoney.updateConnections(message.connections);
|
sendMoney.updateConnections(message.connections);
|
||||||
|
walletInventory.fromScript(message);
|
||||||
break;
|
break;
|
||||||
case 'selectRecipient':
|
case 'selectRecipient':
|
||||||
case 'updateSelectedRecipientUsername':
|
case 'updateSelectedRecipientUsername':
|
||||||
sendMoney.fromScript(message);
|
sendMoney.fromScript(message);
|
||||||
|
walletInventory.fromScript(message);
|
||||||
break;
|
break;
|
||||||
case 'http.response':
|
case 'http.response':
|
||||||
http.handleHttpResponse(message);
|
http.handleHttpResponse(message);
|
||||||
|
// Duplicate handler is required because we don't track referrer for `http`
|
||||||
|
walletInventory.fromScript(message);
|
||||||
break;
|
break;
|
||||||
case 'palIsStale':
|
case 'palIsStale':
|
||||||
case 'avatarDisconnected':
|
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.
|
// 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;
|
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:
|
default:
|
||||||
console.log('Unrecognized message from wallet.js:', JSON.stringify(message));
|
console.log('Unrecognized message from wallet.js:', JSON.stringify(message));
|
||||||
}
|
}
|
||||||
|
@ -722,7 +839,8 @@ Rectangle {
|
||||||
root.activeView = "initialize";
|
root.activeView = "initialize";
|
||||||
Commerce.getWalletStatus();
|
Commerce.getWalletStatus();
|
||||||
} else if (msg.referrer === 'purchases') {
|
} else if (msg.referrer === 'purchases') {
|
||||||
sendToScript({method: 'goToPurchases'});
|
root.activeView = "walletInventory";
|
||||||
|
tabButtonsContainer.resetTabButtonColors();
|
||||||
} else if (msg.referrer === 'marketplace cta' || msg.referrer === 'mainPage') {
|
} else if (msg.referrer === 'marketplace cta' || msg.referrer === 'mainPage') {
|
||||||
sendToScript({method: 'goToMarketplaceMainPage', itemId: msg.referrer});
|
sendToScript({method: 'goToMarketplaceMainPage', itemId: msg.referrer});
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -179,28 +179,6 @@ Item {
|
||||||
color: hifi.colors.baseGrayHighlight;
|
color: hifi.colors.baseGrayHighlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
RalewaySemiBold {
|
|
||||||
id: myPurchasesLink;
|
|
||||||
text: '<font color="#0093C5"><a href="#myPurchases">My Purchases</a></font>';
|
|
||||||
// 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 {
|
HifiModels.PSFListModel {
|
||||||
id: transactionHistoryModel;
|
id: transactionHistoryModel;
|
||||||
property int lastPendingCount: 0;
|
property int lastPendingCount: 0;
|
||||||
|
|
|
@ -328,7 +328,7 @@ Rectangle {
|
||||||
|
|
||||||
HifiStylesUit.RalewayRegular {
|
HifiStylesUit.RalewayRegular {
|
||||||
text: "Your wallet is not set up.\n" +
|
text: "Your wallet is not set up.\n" +
|
||||||
"Open the WALLET app to get started.";
|
"Open the ASSETS app to get started.";
|
||||||
// Anchors
|
// Anchors
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
// Text size
|
// Text size
|
||||||
|
|
|
@ -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
|
// 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";
|
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<WalletScriptingInterface>()->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();
|
updateHeartbeat();
|
||||||
|
|
||||||
|
@ -3152,7 +3154,7 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
|
||||||
surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance());
|
surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance());
|
||||||
surfaceContext->setContextProperty("Selection", DependencyManager::get<SelectionScriptingInterface>().data());
|
surfaceContext->setContextProperty("Selection", DependencyManager::get<SelectionScriptingInterface>().data());
|
||||||
surfaceContext->setContextProperty("ContextOverlay", DependencyManager::get<ContextOverlayInterface>().data());
|
surfaceContext->setContextProperty("ContextOverlay", DependencyManager::get<ContextOverlayInterface>().data());
|
||||||
surfaceContext->setContextProperty("Wallet", DependencyManager::get<WalletScriptingInterface>().data());
|
surfaceContext->setContextProperty("WalletScriptingInterface", DependencyManager::get<WalletScriptingInterface>().data());
|
||||||
surfaceContext->setContextProperty("HiFiAbout", AboutUtil::getInstance());
|
surfaceContext->setContextProperty("HiFiAbout", AboutUtil::getInstance());
|
||||||
surfaceContext->setContextProperty("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data());
|
surfaceContext->setContextProperty("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data());
|
||||||
|
|
||||||
|
@ -6874,7 +6876,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
||||||
scriptEngine->registerGlobalObject("AvatarInputs", AvatarInputs::getInstance());
|
scriptEngine->registerGlobalObject("AvatarInputs", AvatarInputs::getInstance());
|
||||||
scriptEngine->registerGlobalObject("Selection", DependencyManager::get<SelectionScriptingInterface>().data());
|
scriptEngine->registerGlobalObject("Selection", DependencyManager::get<SelectionScriptingInterface>().data());
|
||||||
scriptEngine->registerGlobalObject("ContextOverlay", DependencyManager::get<ContextOverlayInterface>().data());
|
scriptEngine->registerGlobalObject("ContextOverlay", DependencyManager::get<ContextOverlayInterface>().data());
|
||||||
scriptEngine->registerGlobalObject("Wallet", DependencyManager::get<WalletScriptingInterface>().data());
|
scriptEngine->registerGlobalObject("WalletScriptingInterface", DependencyManager::get<WalletScriptingInterface>().data());
|
||||||
scriptEngine->registerGlobalObject("AddressManager", DependencyManager::get<AddressManager>().data());
|
scriptEngine->registerGlobalObject("AddressManager", DependencyManager::get<AddressManager>().data());
|
||||||
scriptEngine->registerGlobalObject("HifiAbout", AboutUtil::getInstance());
|
scriptEngine->registerGlobalObject("HifiAbout", AboutUtil::getInstance());
|
||||||
scriptEngine->registerGlobalObject("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data());
|
scriptEngine->registerGlobalObject("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data());
|
||||||
|
@ -7879,6 +7881,7 @@ void Application::loadAvatarBrowser() const {
|
||||||
auto tablet = dynamic_cast<TabletProxy*>(DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system"));
|
auto tablet = dynamic_cast<TabletProxy*>(DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system"));
|
||||||
// construct the url to the marketplace item
|
// construct the url to the marketplace item
|
||||||
QString url = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/marketplace?category=avatars";
|
QString url = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/marketplace?category=avatars";
|
||||||
|
|
||||||
QString MARKETPLACES_INJECT_SCRIPT_PATH = "file:///" + qApp->applicationDirPath() + "/scripts/system/html/js/marketplacesInject.js";
|
QString MARKETPLACES_INJECT_SCRIPT_PATH = "file:///" + qApp->applicationDirPath() + "/scripts/system/html/js/marketplacesInject.js";
|
||||||
tablet->gotoWebScreen(url, MARKETPLACES_INJECT_SCRIPT_PATH);
|
tablet->gotoWebScreen(url, MARKETPLACES_INJECT_SCRIPT_PATH);
|
||||||
DependencyManager::get<HMDScriptingInterface>()->openTablet();
|
DependencyManager::get<HMDScriptingInterface>()->openTablet();
|
||||||
|
|
|
@ -244,7 +244,6 @@ QString transactionString(const QJsonObject& valueObject) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const QString MARKETPLACE_ITEMS_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/marketplace/items/";
|
|
||||||
void Ledger::historySuccess(QNetworkReply* reply) {
|
void Ledger::historySuccess(QNetworkReply* reply) {
|
||||||
// here we send a historyResult with some extra stuff in it
|
// here we send a historyResult with some extra stuff in it
|
||||||
// Namely, the styled text we'd like to show. The issue is the
|
// Namely, the styled text we'd like to show. The issue is the
|
||||||
|
|
|
@ -10,13 +10,15 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "WalletScriptingInterface.h"
|
#include "WalletScriptingInterface.h"
|
||||||
|
#include <SettingHandle.h>
|
||||||
|
|
||||||
CheckoutProxy::CheckoutProxy(QObject* qmlObject, QObject* parent) : QmlWrapper(qmlObject, parent) {
|
CheckoutProxy::CheckoutProxy(QObject* qmlObject, QObject* parent) : QmlWrapper(qmlObject, parent) {
|
||||||
Q_ASSERT(QThread::currentThread() == qApp->thread());
|
Q_ASSERT(QThread::currentThread() == qApp->thread());
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletScriptingInterface::WalletScriptingInterface() {
|
WalletScriptingInterface::WalletScriptingInterface() {
|
||||||
|
connect(DependencyManager::get<AccountManager>().data(),
|
||||||
|
&AccountManager::limitedCommerceChanged, this, &WalletScriptingInterface::limitedCommerceChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WalletScriptingInterface::refreshWalletStatus() {
|
void WalletScriptingInterface::refreshWalletStatus() {
|
||||||
|
|
|
@ -15,13 +15,13 @@
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
#include "scripting/HMDScriptingInterface.h"
|
|
||||||
#include <ui/TabletScriptingInterface.h>
|
#include <ui/TabletScriptingInterface.h>
|
||||||
#include <ui/QmlWrapper.h>
|
#include <ui/QmlWrapper.h>
|
||||||
#include <OffscreenUi.h>
|
#include <OffscreenUi.h>
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "commerce/Wallet.h"
|
#include "commerce/Wallet.h"
|
||||||
#include "ui/overlays/ContextOverlayInterface.h"
|
#include "ui/overlays/ContextOverlayInterface.h"
|
||||||
|
#include <AccountManager.h>
|
||||||
|
|
||||||
class CheckoutProxy : public QmlWrapper {
|
class CheckoutProxy : public QmlWrapper {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -29,7 +29,6 @@ public:
|
||||||
CheckoutProxy(QObject* qmlObject, QObject* parent = nullptr);
|
CheckoutProxy(QObject* qmlObject, QObject* parent = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @namespace Wallet
|
* @namespace Wallet
|
||||||
*
|
*
|
||||||
|
@ -37,28 +36,31 @@ public:
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
*
|
*
|
||||||
* @property {number} walletStatus
|
* @property {number} walletStatus
|
||||||
|
* @property {bool} limitedCommerce
|
||||||
*/
|
*/
|
||||||
class WalletScriptingInterface : public QObject, public Dependency {
|
class WalletScriptingInterface : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
SINGLETON_DEPENDENCY
|
||||||
Q_PROPERTY(uint walletStatus READ getWalletStatus WRITE setWalletStatus NOTIFY walletStatusChanged)
|
Q_PROPERTY(uint walletStatus READ getWalletStatus WRITE setWalletStatus NOTIFY walletStatusChanged)
|
||||||
|
Q_PROPERTY(bool limitedCommerce READ getLimitedCommerce WRITE setLimitedCommerce NOTIFY limitedCommerceChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
WalletScriptingInterface();
|
WalletScriptingInterface();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function Wallet.refreshWalletStatus
|
* @function WalletScriptingInterface.refreshWalletStatus
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void refreshWalletStatus();
|
Q_INVOKABLE void refreshWalletStatus();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function Wallet.getWalletStatus
|
* @function WalletScriptingInterface.getWalletStatus
|
||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE uint getWalletStatus() { return _walletStatus; }
|
Q_INVOKABLE uint getWalletStatus() { return _walletStatus; }
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function Wallet.proveAvatarEntityOwnershipVerification
|
* @function WalletScriptingInterface.proveAvatarEntityOwnershipVerification
|
||||||
* @param {Uuid} entityID
|
* @param {Uuid} entityID
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void proveAvatarEntityOwnershipVerification(const QUuid& entityID);
|
Q_INVOKABLE void proveAvatarEntityOwnershipVerification(const QUuid& entityID);
|
||||||
|
@ -67,29 +69,38 @@ public:
|
||||||
// scripts could cause the Wallet to incorrectly report its status.
|
// scripts could cause the Wallet to incorrectly report its status.
|
||||||
void setWalletStatus(const uint& status);
|
void setWalletStatus(const uint& status);
|
||||||
|
|
||||||
|
bool getLimitedCommerce() { return DependencyManager::get<AccountManager>()->getLimitedCommerce(); }
|
||||||
|
void setLimitedCommerce(bool isLimited) { DependencyManager::get<AccountManager>()->setLimitedCommerce(isLimited); };
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function Wallet.walletStatusChanged
|
* @function WalletScriptingInterface.walletStatusChanged
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
void walletStatusChanged();
|
void walletStatusChanged();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function Wallet.walletNotSetup
|
* @function WalletScriptingInterface.limitedCommerceChanged
|
||||||
|
* @returns {Signal}
|
||||||
|
*/
|
||||||
|
void limitedCommerceChanged();
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* @function WalletScriptingInterface.walletNotSetup
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
void walletNotSetup();
|
void walletNotSetup();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function Wallet.ownershipVerificationSuccess
|
* @function WalletScriptingInterface.ownershipVerificationSuccess
|
||||||
* @param {Uuid} entityID
|
* @param {Uuid} entityID
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
void ownershipVerificationSuccess(const QUuid& entityID);
|
void ownershipVerificationSuccess(const QUuid& entityID);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function Wallet.ownershipVerificationFailed
|
* @function WalletScriptingInterface.ownershipVerificationFailed
|
||||||
* @param {Uuid} entityID
|
* @param {Uuid} entityID
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -223,12 +223,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID&
|
||||||
|
|
||||||
bool ContextOverlayInterface::contextOverlayFilterPassed(const EntityItemID& entityItemID) {
|
bool ContextOverlayInterface::contextOverlayFilterPassed(const EntityItemID& entityItemID) {
|
||||||
EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags);
|
EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags);
|
||||||
Setting::Handle<bool> _settingSwitch{ "commerce", true };
|
|
||||||
if (_settingSwitch.get()) {
|
|
||||||
return (entityProperties.getCertificateID().length() != 0);
|
return (entityProperties.getCertificateID().length() != 0);
|
||||||
} else {
|
|
||||||
return (entityProperties.getMarketplaceID().length() != 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event) {
|
bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event) {
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "ui/AvatarInputs.h"
|
#include "ui/AvatarInputs.h"
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
#include "scripting/AccountServicesScriptingInterface.h"
|
#include "scripting/AccountServicesScriptingInterface.h"
|
||||||
|
#include "scripting/WalletScriptingInterface.h"
|
||||||
#include <plugins/InputConfiguration.h>
|
#include <plugins/InputConfiguration.h>
|
||||||
#include "ui/Snapshot.h"
|
#include "ui/Snapshot.h"
|
||||||
#include "SoundCacheScriptingInterface.h"
|
#include "SoundCacheScriptingInterface.h"
|
||||||
|
@ -270,6 +271,7 @@ void Web3DOverlay::setupQmlSurface(bool isTablet) {
|
||||||
_webSurface->getSurfaceContext()->setContextProperty("Window", DependencyManager::get<WindowScriptingInterface>().data());
|
_webSurface->getSurfaceContext()->setContextProperty("Window", DependencyManager::get<WindowScriptingInterface>().data());
|
||||||
_webSurface->getSurfaceContext()->setContextProperty("Reticle", qApp->getApplicationCompositor().getReticleInterface());
|
_webSurface->getSurfaceContext()->setContextProperty("Reticle", qApp->getApplicationCompositor().getReticleInterface());
|
||||||
_webSurface->getSurfaceContext()->setContextProperty("HiFiAbout", AboutUtil::getInstance());
|
_webSurface->getSurfaceContext()->setContextProperty("HiFiAbout", AboutUtil::getInstance());
|
||||||
|
_webSurface->getSurfaceContext()->setContextProperty("WalletScriptingInterface", DependencyManager::get<WalletScriptingInterface>().data());
|
||||||
_webSurface->getSurfaceContext()->setContextProperty("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data());
|
_webSurface->getSurfaceContext()->setContextProperty("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data());
|
||||||
|
|
||||||
// Override min fps for tablet UI, for silky smooth scrolling
|
// Override min fps for tablet UI, for silky smooth scrolling
|
||||||
|
|
|
@ -837,3 +837,7 @@ void AccountManager::handleKeypairGenerationError() {
|
||||||
// reset our waiting state for keypair response
|
// reset our waiting state for keypair response
|
||||||
_isWaitingForKeypairResponse = false;
|
_isWaitingForKeypairResponse = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AccountManager::setLimitedCommerce(bool isLimited) {
|
||||||
|
_limitedCommerce = isLimited;
|
||||||
|
}
|
||||||
|
|
|
@ -98,6 +98,9 @@ public:
|
||||||
|
|
||||||
void removeAccountFromFile();
|
void removeAccountFromFile();
|
||||||
|
|
||||||
|
bool getLimitedCommerce() { return _limitedCommerce; }
|
||||||
|
void setLimitedCommerce(bool isLimited);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void requestAccessToken(const QString& login, const QString& password);
|
void requestAccessToken(const QString& login, const QString& password);
|
||||||
void requestAccessTokenWithSteam(QByteArray authSessionTicket);
|
void requestAccessTokenWithSteam(QByteArray authSessionTicket);
|
||||||
|
@ -121,6 +124,7 @@ signals:
|
||||||
void loginFailed();
|
void loginFailed();
|
||||||
void logoutComplete();
|
void logoutComplete();
|
||||||
void newKeypair();
|
void newKeypair();
|
||||||
|
void limitedCommerceChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleKeypairGenerationError();
|
void handleKeypairGenerationError();
|
||||||
|
@ -150,6 +154,8 @@ private:
|
||||||
QByteArray _pendingPrivateKey;
|
QByteArray _pendingPrivateKey;
|
||||||
|
|
||||||
QUuid _sessionID { QUuid::createUuid() };
|
QUuid _sessionID { QUuid::createUuid() };
|
||||||
|
|
||||||
|
bool _limitedCommerce { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AccountManager_h
|
#endif // hifi_AccountManager_h
|
||||||
|
|
|
@ -70,9 +70,9 @@ void RequestFilters::interceptHFWebEngineRequest(QWebEngineUrlRequestInfo& info,
|
||||||
|
|
||||||
// check if this is a request to a highfidelity URL
|
// check if this is a request to a highfidelity URL
|
||||||
bool isAuthable = isAuthableHighFidelityURL(info.requestUrl());
|
bool isAuthable = isAuthableHighFidelityURL(info.requestUrl());
|
||||||
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
if (isAuthable) {
|
if (isAuthable) {
|
||||||
// if we have an access token, add it to the right HTTP header for authorization
|
// if we have an access token, add it to the right HTTP header for authorization
|
||||||
auto accountManager = DependencyManager::get<AccountManager>();
|
|
||||||
|
|
||||||
if (accountManager->hasValidAccessToken()) {
|
if (accountManager->hasValidAccessToken()) {
|
||||||
static const QString OAUTH_AUTHORIZATION_HEADER = "Authorization";
|
static const QString OAUTH_AUTHORIZATION_HEADER = "Authorization";
|
||||||
|
@ -84,13 +84,9 @@ void RequestFilters::interceptHFWebEngineRequest(QWebEngineUrlRequestInfo& info,
|
||||||
static const QString USER_AGENT = "User-Agent";
|
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 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 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 tokenString = !isAuthable ? tokenStringMobile : (accountManager->getLimitedCommerce() ? tokenStringLimitedCommerce : tokenStringMetaverse);
|
||||||
const QString tokenStringCommerce{ "Chrome/48.0 (HighFidelityInterface WithHFC)" };
|
|
||||||
Setting::Handle<bool> _settingSwitch{ "commerce", true };
|
|
||||||
bool isMoney = _settingSwitch.get();
|
|
||||||
|
|
||||||
const QString tokenString = !isAuthable ? tokenStringMobile : (isMoney ? tokenStringCommerce : tokenStringMetaverse);
|
|
||||||
info.setHttpHeader(USER_AGENT.toLocal8Bit(), tokenString.toLocal8Bit());
|
info.setHttpHeader(USER_AGENT.toLocal8Bit(), tokenString.toLocal8Bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,16 +95,16 @@ function AppUi(properties) {
|
||||||
activeIcon: isWaiting ? that.activeMessagesButton : that.activeButton
|
activeIcon: isWaiting ? that.activeMessagesButton : that.activeButton
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
that.notificationPollTimeout = false;
|
that.notificationPollTimeout = [false];
|
||||||
that.notificationPollTimeoutMs = 60000;
|
that.notificationPollTimeoutMs = [60000];
|
||||||
that.notificationPollEndpoint = false;
|
that.notificationPollEndpoint = [false];
|
||||||
that.notificationPollStopPaginatingConditionMet = false;
|
that.notificationPollStopPaginatingConditionMet = [false];
|
||||||
that.notificationDataProcessPage = function (data) {
|
that.notificationDataProcessPage = function (data) {
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
that.notificationPollCallback = that.ignore;
|
that.notificationPollCallback = [that.ignore];
|
||||||
that.notificationPollCaresAboutSince = false;
|
that.notificationPollCaresAboutSince = [false];
|
||||||
that.notificationInitialCallbackMade = false;
|
that.notificationInitialCallbackMade = [false];
|
||||||
that.notificationDisplayBanner = function (message) {
|
that.notificationDisplayBanner = function (message) {
|
||||||
if (!that.isOpen) {
|
if (!that.isOpen) {
|
||||||
Window.displayAnnouncement(message);
|
Window.displayAnnouncement(message);
|
||||||
|
@ -129,7 +129,9 @@ function AppUi(properties) {
|
||||||
}
|
}
|
||||||
that.isOpen = true;
|
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);
|
that.wireEventBridge(false);
|
||||||
if (that.isOpen) {
|
if (that.isOpen) {
|
||||||
that.buttonActive(false);
|
that.buttonActive(false);
|
||||||
|
@ -139,83 +141,124 @@ function AppUi(properties) {
|
||||||
that.isOpen = false;
|
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:
|
// 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
|
// 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 METAVERSE_BASE = Account.metaverseServerURL;
|
||||||
var currentDataPageToRetrieve = 1;
|
var MS_IN_SEC = 1000;
|
||||||
var concatenatedServerResponse = new Array();
|
that.notificationPoll = function (i) {
|
||||||
that.notificationPoll = function () {
|
if (!that.notificationPollEndpoint[i]) {
|
||||||
if (!that.notificationPollEndpoint) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// User is "appearing offline" or is offline
|
// User is "appearing offline" or is not logged in
|
||||||
if (GlobalServices.findableBy === "none" || Account.username === "") {
|
if (GlobalServices.findableBy === "none" || Account.username === "Unknown user") {
|
||||||
that.notificationPollTimeout = Script.setTimeout(that.notificationPoll, that.notificationPollTimeoutMs);
|
// 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;
|
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 currentTimestamp = new Date().getTime();
|
||||||
var lastPollTimestamp = Settings.getValue(settingsKey, currentTimestamp);
|
var lastPollTimestamp = Settings.getValue(settingsKey, currentTimestamp);
|
||||||
if (that.notificationPollCaresAboutSince) {
|
if (that.notificationPollCaresAboutSince[i]) {
|
||||||
url = url + "&since=" + lastPollTimestamp/1000;
|
url = url + "&since=" + lastPollTimestamp / MS_IN_SEC;
|
||||||
}
|
}
|
||||||
Settings.setValue(settingsKey, currentTimestamp);
|
Settings.setValue(settingsKey, currentTimestamp);
|
||||||
|
|
||||||
console.debug(that.buttonName, 'polling for notifications at endpoint', url);
|
console.debug(that.buttonName, 'polling for notifications at endpoint', url);
|
||||||
|
|
||||||
function requestCallback(error, response) {
|
request({
|
||||||
if (error || (response.status !== 'success')) {
|
json: true,
|
||||||
print("Error: unable to get", url, error || response.status);
|
uri: url
|
||||||
that.notificationPollTimeout = Script.setTimeout(that.notificationPoll, that.notificationPollTimeoutMs);
|
},
|
||||||
return;
|
requestCallback,
|
||||||
}
|
{
|
||||||
|
indexOfRequest: i,
|
||||||
if (!that.notificationPollStopPaginatingConditionMet || that.notificationPollStopPaginatingConditionMet(response)) {
|
urlOfRequest: url
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This won't do anything if there isn't a notification endpoint set
|
// 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() {
|
function restartNotificationPoll() {
|
||||||
that.notificationInitialCallbackMade = false;
|
for (var j = 0; j < that.notificationPollEndpoint.length; j++) {
|
||||||
if (that.notificationPollTimeout) {
|
that.notificationInitialCallbackMade[j] = false;
|
||||||
Script.clearTimeout(that.notificationPollTimeout);
|
if (that.notificationPollTimeout[j]) {
|
||||||
that.notificationPollTimeout = false;
|
Script.clearTimeout(that.notificationPollTimeout[j]);
|
||||||
|
that.notificationPollTimeout[j] = false;
|
||||||
|
}
|
||||||
|
that.notificationPoll(j);
|
||||||
}
|
}
|
||||||
that.notificationPoll();
|
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// END Notification Handling
|
// END Notification Handling
|
||||||
|
@ -322,9 +365,11 @@ function AppUi(properties) {
|
||||||
}
|
}
|
||||||
that.tablet.removeButton(that.button);
|
that.tablet.removeButton(that.button);
|
||||||
}
|
}
|
||||||
if (that.notificationPollTimeout) {
|
for (var i = 0; i < that.notificationPollTimeout.length; i++) {
|
||||||
Script.clearInterval(that.notificationPollTimeout);
|
if (that.notificationPollTimeout[i]) {
|
||||||
that.notificationPollTimeout = false;
|
Script.clearInterval(that.notificationPollTimeout[i]);
|
||||||
|
that.notificationPollTimeout[i] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Set up the handlers.
|
// Set up the handlers.
|
||||||
|
@ -333,7 +378,7 @@ function AppUi(properties) {
|
||||||
Script.scriptEnding.connect(that.onScriptEnding);
|
Script.scriptEnding.connect(that.onScriptEnding);
|
||||||
GlobalServices.findableByChanged.connect(restartNotificationPoll);
|
GlobalServices.findableByChanged.connect(restartNotificationPoll);
|
||||||
GlobalServices.myUsernameChanged.connect(restartNotificationPoll);
|
GlobalServices.myUsernameChanged.connect(restartNotificationPoll);
|
||||||
if (that.buttonName == Settings.getValue("startUpApp")) {
|
if (that.buttonName === Settings.getValue("startUpApp")) {
|
||||||
Settings.setValue("startUpApp", "");
|
Settings.setValue("startUpApp", "");
|
||||||
Script.setTimeout(function () {
|
Script.setTimeout(function () {
|
||||||
that.open();
|
that.open();
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
module.exports = {
|
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;
|
var httpRequest = new XMLHttpRequest(), key;
|
||||||
// QT bug: apparently doesn't handle onload. Workaround using readyState.
|
// QT bug: apparently doesn't handle onload. Workaround using readyState.
|
||||||
httpRequest.onreadystatechange = function () {
|
httpRequest.onreadystatechange = function () {
|
||||||
|
@ -38,7 +39,7 @@ module.exports = {
|
||||||
if (error) {
|
if (error) {
|
||||||
response = { statusCode: httpRequest.status };
|
response = { statusCode: httpRequest.status };
|
||||||
}
|
}
|
||||||
callback(error, response);
|
callback(error, response, optionalCallbackParameter);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (typeof options === 'string') {
|
if (typeof options === 'string') {
|
||||||
|
|
|
@ -159,7 +159,7 @@ var selectedAvatarEntityGrabbable = false;
|
||||||
var selectedAvatarEntityID = null;
|
var selectedAvatarEntityID = null;
|
||||||
var grabbedAvatarEntityChangeNotifier = 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 MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace";
|
||||||
var MARKETPLACES_INJECT_SCRIPT_URL = Script.resolvePath("html/js/marketplacesInject.js");
|
var MARKETPLACES_INJECT_SCRIPT_URL = Script.resolvePath("html/js/marketplacesInject.js");
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// 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
|
(function () { // BEGIN LOCAL_SCOPE
|
||||||
Script.include("/~/system/libraries/accountUtils.js");
|
Script.include("/~/system/libraries/accountUtils.js");
|
||||||
|
@ -20,7 +20,6 @@ var AppUi = Script.require('appUi');
|
||||||
|
|
||||||
var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace";
|
var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace";
|
||||||
|
|
||||||
|
|
||||||
// BEGIN AVATAR SELECTOR LOGIC
|
// BEGIN AVATAR SELECTOR LOGIC
|
||||||
var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6 };
|
var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6 };
|
||||||
var SELECTED_COLOR = { red: 0xF3, green: 0x91, blue: 0x29 };
|
var SELECTED_COLOR = { red: 0xF3, green: 0x91, blue: 0x29 };
|
||||||
|
@ -48,7 +47,6 @@ ExtendedOverlay.prototype.editOverlay = function (properties) { // change displa
|
||||||
function color(selected, hovering) {
|
function color(selected, hovering) {
|
||||||
var base = hovering ? HOVER_COLOR : selected ? SELECTED_COLOR : UNSELECTED_COLOR;
|
var base = hovering ? HOVER_COLOR : selected ? SELECTED_COLOR : UNSELECTED_COLOR;
|
||||||
function scale(component) {
|
function scale(component) {
|
||||||
var delta = 0xFF - component;
|
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
return { red: scale(base.red), green: scale(base.green), blue: scale(base.blue) };
|
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.
|
// hit(overlay) on the one overlay intersected by pickRay, if any.
|
||||||
// noHit() if no ExtendedOverlay was intersected (helps with hover)
|
// noHit() if no ExtendedOverlay was intersected (helps with hover)
|
||||||
ExtendedOverlay.applyPickRay = function (pickRay, hit, noHit) {
|
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 (!pickedOverlay.intersects) {
|
||||||
if (noHit) {
|
if (noHit) {
|
||||||
return noHit();
|
return noHit();
|
||||||
|
@ -131,6 +130,7 @@ function addAvatarNode(id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var pingPong = true;
|
var pingPong = true;
|
||||||
|
var OVERLAY_SCALE = 0.032;
|
||||||
function updateOverlays() {
|
function updateOverlays() {
|
||||||
var eye = Camera.position;
|
var eye = Camera.position;
|
||||||
AvatarList.getAvatarIdentifiers().forEach(function (id) {
|
AvatarList.getAvatarIdentifiers().forEach(function (id) {
|
||||||
|
@ -148,7 +148,8 @@ function updateOverlays() {
|
||||||
var target = avatar.position;
|
var target = avatar.position;
|
||||||
var distance = Vec3.distance(target, eye);
|
var distance = Vec3.distance(target, eye);
|
||||||
var offset = 0.2;
|
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
|
var headIndex = avatar.getJointIndex("Head"); // base offset on 1/2 distance from hips to head if we can
|
||||||
if (headIndex > 0) {
|
if (headIndex > 0) {
|
||||||
offset = avatar.getAbsoluteJointTranslationInObjectFrame(headIndex).y / 2;
|
offset = avatar.getAbsoluteJointTranslationInObjectFrame(headIndex).y / 2;
|
||||||
|
@ -164,7 +165,7 @@ function updateOverlays() {
|
||||||
overlay.editOverlay({
|
overlay.editOverlay({
|
||||||
color: color(ExtendedOverlay.isSelected(id), overlay.hovering),
|
color: color(ExtendedOverlay.isSelected(id), overlay.hovering),
|
||||||
position: target,
|
position: target,
|
||||||
dimensions: 0.032 * distance
|
dimensions: OVERLAY_SCALE * distance
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
pingPong = !pingPong;
|
pingPong = !pingPong;
|
||||||
|
@ -382,13 +383,36 @@ function onUsernameChanged() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
// Function Name: fromQml()
|
||||||
//
|
//
|
||||||
// Description:
|
// Description:
|
||||||
// -Called when a message is received from SpectatorCamera.qml. The "message" argument is what is sent from the QML
|
// -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().
|
// 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) {
|
function fromQml(message) {
|
||||||
switch (message.method) {
|
switch (message.method) {
|
||||||
case 'passphrasePopup_cancelClicked':
|
case 'passphrasePopup_cancelClicked':
|
||||||
|
@ -413,6 +437,7 @@ function fromQml(message) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'needsLogIn_loginClicked':
|
case 'needsLogIn_loginClicked':
|
||||||
|
ui.close();
|
||||||
openLoginWindow();
|
openLoginWindow();
|
||||||
break;
|
break;
|
||||||
case 'disableHmdPreview':
|
case 'disableHmdPreview':
|
||||||
|
@ -422,10 +447,6 @@ function fromQml(message) {
|
||||||
case 'transactionHistory_linkClicked':
|
case 'transactionHistory_linkClicked':
|
||||||
ui.open(message.marketplaceLink, MARKETPLACES_INJECT_SCRIPT_URL);
|
ui.open(message.marketplaceLink, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||||
break;
|
break;
|
||||||
case 'goToPurchases_fromWalletHome':
|
|
||||||
case 'goToPurchases':
|
|
||||||
ui.open(MARKETPLACE_PURCHASES_QML_PATH);
|
|
||||||
break;
|
|
||||||
case 'goToMarketplaceMainPage':
|
case 'goToMarketplaceMainPage':
|
||||||
ui.open(MARKETPLACE_URL, MARKETPLACES_INJECT_SCRIPT_URL);
|
ui.open(MARKETPLACE_URL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||||
break;
|
break;
|
||||||
|
@ -450,10 +471,8 @@ function fromQml(message) {
|
||||||
removeOverlays();
|
removeOverlays();
|
||||||
break;
|
break;
|
||||||
case 'sendAsset_sendPublicly':
|
case 'sendAsset_sendPublicly':
|
||||||
if (message.assetName === "") {
|
|
||||||
deleteSendMoneyParticleEffect();
|
deleteSendMoneyParticleEffect();
|
||||||
sendMoneyRecipient = message.recipient;
|
sendMoneyRecipient = message.recipient;
|
||||||
var amount = message.amount;
|
|
||||||
var props = SEND_MONEY_PARTICLE_PROPERTIES;
|
var props = SEND_MONEY_PARTICLE_PROPERTIES;
|
||||||
props.parentID = MyAvatar.sessionUUID;
|
props.parentID = MyAvatar.sessionUUID;
|
||||||
props.position = MyAvatar.position;
|
props.position = MyAvatar.position;
|
||||||
|
@ -464,8 +483,8 @@ function fromQml(message) {
|
||||||
sendMoneyParticleEffect = Entities.addEntity(props, true);
|
sendMoneyParticleEffect = Entities.addEntity(props, true);
|
||||||
particleEffectTimestamp = Date.now();
|
particleEffectTimestamp = Date.now();
|
||||||
updateSendMoneyParticleEffect();
|
updateSendMoneyParticleEffect();
|
||||||
sendMoneyParticleEffectUpdateTimer = Script.setInterval(updateSendMoneyParticleEffect, SEND_MONEY_PARTICLE_TIMER_UPDATE);
|
sendMoneyParticleEffectUpdateTimer =
|
||||||
}
|
Script.setInterval(updateSendMoneyParticleEffect, SEND_MONEY_PARTICLE_TIMER_UPDATE);
|
||||||
break;
|
break;
|
||||||
case 'transactionHistory_goToBank':
|
case 'transactionHistory_goToBank':
|
||||||
if (Account.metaverseServerURL.indexOf("staging") >= 0) {
|
if (Account.metaverseServerURL.indexOf("staging") >= 0) {
|
||||||
|
@ -474,6 +493,49 @@ function fromQml(message) {
|
||||||
Window.location = "hifi://BankOfHighFidelity";
|
Window.location = "hifi://BankOfHighFidelity";
|
||||||
}
|
}
|
||||||
break;
|
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':
|
case 'http.request':
|
||||||
// Handled elsewhere, don't log.
|
// Handled elsewhere, don't log.
|
||||||
break;
|
break;
|
||||||
|
@ -482,41 +544,76 @@ function fromQml(message) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isWired = false;
|
||||||
function walletOpened() {
|
function walletOpened() {
|
||||||
Users.usernameFromIDReply.connect(usernameFromIDReply);
|
Users.usernameFromIDReply.connect(usernameFromIDReply);
|
||||||
Controller.mousePressEvent.connect(handleMouseEvent);
|
Controller.mousePressEvent.connect(handleMouseEvent);
|
||||||
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
|
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
|
||||||
triggerMapping.enable();
|
triggerMapping.enable();
|
||||||
triggerPressMapping.enable();
|
triggerPressMapping.enable();
|
||||||
shouldShowDot = false;
|
isWired = true;
|
||||||
ui.messagesWaiting(shouldShowDot);
|
|
||||||
|
if (shouldShowDotHistory) {
|
||||||
|
ui.sendMessage({
|
||||||
|
method: 'updateRecentActivityMessageLight',
|
||||||
|
messagesWaiting: shouldShowDotHistory
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function walletClosed() {
|
function walletClosed() {
|
||||||
off();
|
off();
|
||||||
}
|
}
|
||||||
|
|
||||||
function notificationDataProcessPage(data) {
|
function notificationDataProcessPageUpdates(data) {
|
||||||
|
return data.data.updates;
|
||||||
|
}
|
||||||
|
|
||||||
|
function notificationDataProcessPageHistory(data) {
|
||||||
return data.data.history;
|
return data.data.history;
|
||||||
}
|
}
|
||||||
|
|
||||||
var shouldShowDot = false;
|
var shouldShowDotUpdates = false;
|
||||||
function notificationPollCallback(historyArray) {
|
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) {
|
if (!ui.isOpen) {
|
||||||
var notificationCount = historyArray.length;
|
var notificationCount = historyArray.length;
|
||||||
shouldShowDot = shouldShowDot || notificationCount > 0;
|
shouldShowDotHistory = shouldShowDotHistory || notificationCount > 0;
|
||||||
ui.messagesWaiting(shouldShowDot);
|
ui.messagesWaiting(shouldShowDotUpdates || shouldShowDotHistory);
|
||||||
|
|
||||||
if (notificationCount > 0) {
|
if (notificationCount > 0) {
|
||||||
var message;
|
var message;
|
||||||
if (!ui.notificationInitialCallbackMade) {
|
if (!ui.notificationInitialCallbackMade[1]) {
|
||||||
message = "You have " + notificationCount + " unread wallet " +
|
message = "You have " + notificationCount + " unread recent " +
|
||||||
"transaction" + (notificationCount === 1 ? "" : "s") + ". Open WALLET to see all activity.";
|
"transaction" + (notificationCount === 1 ? "" : "s") + ". Open ASSETS to see all activity.";
|
||||||
ui.notificationDisplayBanner(message);
|
ui.notificationDisplayBanner(message);
|
||||||
} else {
|
} else {
|
||||||
for (var i = 0; i < notificationCount; i++) {
|
for (var i = 0; i < notificationCount; i++) {
|
||||||
message = '"' + (historyArray[i].message) + '" ' +
|
message = '"' + (historyArray[i].message) + '" ' +
|
||||||
"Open WALLET to see all activity.";
|
"Open ASSETS to see all activity.";
|
||||||
ui.notificationDisplayBanner(message);
|
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;
|
var historyArray = data.data.history;
|
||||||
return historyArray.length === 0;
|
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 WALLET_QML_SOURCE = "hifi/commerce/wallet/Wallet.qml";
|
||||||
|
var NOTIFICATION_POLL_TIMEOUT = 300000;
|
||||||
var ui;
|
var ui;
|
||||||
function startup() {
|
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({
|
ui = new AppUi({
|
||||||
buttonName: BUTTON_NAME,
|
buttonName: BUTTON_NAME,
|
||||||
|
buttonPrefix: "wallet-",
|
||||||
sortOrder: 10,
|
sortOrder: 10,
|
||||||
home: WALLET_QML_SOURCE,
|
home: WALLET_QML_SOURCE,
|
||||||
onOpened: walletOpened,
|
onOpened: walletOpened,
|
||||||
onClosed: walletClosed,
|
onClosed: walletClosed,
|
||||||
onMessage: fromQml,
|
onMessage: fromQml,
|
||||||
notificationPollEndpoint: "/api/v1/commerce/history?per_page=10",
|
notificationPollEndpoint: notificationPollEndpointArray,
|
||||||
notificationPollTimeoutMs: 300000,
|
notificationPollTimeoutMs: notificationPollTimeoutMsArray,
|
||||||
notificationDataProcessPage: notificationDataProcessPage,
|
notificationDataProcessPage: notificationDataProcessPageArray,
|
||||||
notificationPollCallback: notificationPollCallback,
|
notificationPollCallback: notificationPollCallbackArray,
|
||||||
notificationPollStopPaginatingConditionMet: isReturnedDataEmpty,
|
notificationPollStopPaginatingConditionMet: notificationPollStopPaginatingConditionMetArray,
|
||||||
notificationPollCaresAboutSince: true
|
notificationPollCaresAboutSince: notificationPollCaresAboutSinceArray
|
||||||
});
|
});
|
||||||
GlobalServices.myUsernameChanged.connect(onUsernameChanged);
|
GlobalServices.myUsernameChanged.connect(onUsernameChanged);
|
||||||
installMarketplaceItemTester();
|
installMarketplaceItemTester();
|
||||||
|
@ -583,11 +703,14 @@ function startup() {
|
||||||
|
|
||||||
var isUpdateOverlaysWired = false;
|
var isUpdateOverlaysWired = false;
|
||||||
function off() {
|
function off() {
|
||||||
|
if (isWired) {
|
||||||
Users.usernameFromIDReply.disconnect(usernameFromIDReply);
|
Users.usernameFromIDReply.disconnect(usernameFromIDReply);
|
||||||
Controller.mousePressEvent.disconnect(handleMouseEvent);
|
Controller.mousePressEvent.disconnect(handleMouseEvent);
|
||||||
Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent);
|
Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent);
|
||||||
triggerMapping.disable();
|
triggerMapping.disable();
|
||||||
triggerPressMapping.disable();
|
triggerPressMapping.disable();
|
||||||
|
isWired = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isUpdateOverlaysWired) {
|
if (isUpdateOverlaysWired) {
|
||||||
Script.update.disconnect(updateOverlays);
|
Script.update.disconnect(updateOverlays);
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
var xmlHttpRequest = null;
|
var xmlHttpRequest = null;
|
||||||
var isPreparing = false; // Explicitly track download request status.
|
var isPreparing = false; // Explicitly track download request status.
|
||||||
|
|
||||||
|
var limitedCommerce = false;
|
||||||
var commerceMode = false;
|
var commerceMode = false;
|
||||||
var userIsLoggedIn = false;
|
var userIsLoggedIn = false;
|
||||||
var walletNeedsSetup = false;
|
var walletNeedsSetup = false;
|
||||||
|
@ -59,7 +60,7 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
// Footer.
|
// Footer.
|
||||||
var isInitialHiFiPage = location.href === marketplaceBaseURL + "/marketplace?";
|
var isInitialHiFiPage = location.href === (marketplaceBaseURL + "/marketplace?");
|
||||||
$("body").append(
|
$("body").append(
|
||||||
'<div id="marketplace-navigation">' +
|
'<div id="marketplace-navigation">' +
|
||||||
(!isInitialHiFiPage ? '<input id="back-button" type="button" class="white" value="< Back" />' : '') +
|
(!isInitialHiFiPage ? '<input id="back-button" type="button" class="white" value="< Back" />' : '') +
|
||||||
|
@ -92,7 +93,7 @@
|
||||||
window.location = "https://clara.io/library?gameCheck=true&public=true";
|
window.location = "https://clara.io/library?gameCheck=true&public=true";
|
||||||
});
|
});
|
||||||
$('#exploreHifiMarketplace').on('click', function () {
|
$('#exploreHifiMarketplace').on('click', function () {
|
||||||
window.location = marketplaceBaseURL + "/marketplace";
|
window.location = marketplaceBaseURL + "/marketplace?";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +170,7 @@
|
||||||
|
|
||||||
var span = document.createElement('span');
|
var span = document.createElement('span');
|
||||||
span.style = "margin:10px;color:#1b6420;font-size:15px;";
|
span.style = "margin:10px;color:#1b6420;font-size:15px;";
|
||||||
span.innerHTML = "to purchase items from the Marketplace.";
|
span.innerHTML = "to get items from the Marketplace.";
|
||||||
|
|
||||||
var xButton = document.createElement('a');
|
var xButton = document.createElement('a');
|
||||||
xButton.id = "xButton";
|
xButton.id = "xButton";
|
||||||
|
@ -195,40 +196,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function maybeAddPurchasesButton() {
|
|
||||||
if (userIsLoggedIn) {
|
|
||||||
// Why isn't this an id?! This really shouldn't be a class on the website, but it is.
|
|
||||||
var navbarBrandElement = document.getElementsByClassName('navbar-brand')[0];
|
|
||||||
var purchasesElement = document.createElement('a');
|
|
||||||
var dropDownElement = document.getElementById('user-dropdown');
|
|
||||||
|
|
||||||
$('#user-dropdown').find('.username')[0].style = "max-width:80px;white-space:nowrap;overflow:hidden;" +
|
|
||||||
"text-overflow:ellipsis;display:inline-block;position:relative;top:4px;";
|
|
||||||
$('#user-dropdown').find('.caret')[0].style = "position:relative;top:-3px;";
|
|
||||||
|
|
||||||
purchasesElement.id = "purchasesButton";
|
|
||||||
purchasesElement.setAttribute('href', "#");
|
|
||||||
purchasesElement.innerHTML = "";
|
|
||||||
if (messagesWaiting) {
|
|
||||||
purchasesElement.innerHTML += "<span style='width:10px;height:10px;background-color:red;border-radius:50%;display:inline-block;'></span> ";
|
|
||||||
}
|
|
||||||
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".
|
|
||||||
$('.navbar-brand').css('margin-right', '10px');
|
|
||||||
purchasesElement.style = "height:100%;margin-top:18px;font-weight:bold;float:right;margin-right:" + (dropDownElement.offsetWidth + 30) +
|
|
||||||
"px;position:relative;z-index:999;";
|
|
||||||
navbarBrandElement.parentNode.insertAdjacentElement('beforeend', purchasesElement);
|
|
||||||
$('#purchasesButton').on('click', function () {
|
|
||||||
EventBridge.emitWebEvent(JSON.stringify({
|
|
||||||
type: "PURCHASES",
|
|
||||||
referrerURL: window.location.href,
|
|
||||||
hasUpdates: messagesWaiting
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeDropdownMenu() {
|
function changeDropdownMenu() {
|
||||||
var logInOrOutButton = document.createElement('a');
|
var logInOrOutButton = document.createElement('a');
|
||||||
logInOrOutButton.id = "logInOrOutButton";
|
logInOrOutButton.id = "logInOrOutButton";
|
||||||
|
@ -283,6 +250,7 @@
|
||||||
$(this).attr('href', '#');
|
$(this).attr('href', '#');
|
||||||
}
|
}
|
||||||
cost = $(this).closest('.col-xs-3').find('.item-cost').text();
|
cost = $(this).closest('.col-xs-3').find('.item-cost').text();
|
||||||
|
var costInt = parseInt(cost, 10);
|
||||||
|
|
||||||
$(this).closest('.col-xs-3').prev().attr("class", 'col-xs-6');
|
$(this).closest('.col-xs-3').prev().attr("class", 'col-xs-6');
|
||||||
$(this).closest('.col-xs-3').attr("class", 'col-xs-6');
|
$(this).closest('.col-xs-3').attr("class", 'col-xs-6');
|
||||||
|
@ -398,7 +366,6 @@
|
||||||
// Try this here in case it works (it will if the user just pressed the "back" button,
|
// Try this here in case it works (it will if the user just pressed the "back" button,
|
||||||
// since that doesn't trigger another AJAX request.
|
// since that doesn't trigger another AJAX request.
|
||||||
injectBuyButtonOnMainPage();
|
injectBuyButtonOnMainPage();
|
||||||
maybeAddPurchasesButton();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +386,12 @@
|
||||||
|
|
||||||
var href = purchaseButton.attr('href');
|
var href = purchaseButton.attr('href');
|
||||||
purchaseButton.attr('href', '#');
|
purchaseButton.attr('href', '#');
|
||||||
|
var cost = $('.item-cost').text();
|
||||||
|
var costInt = parseInt(cost, 10);
|
||||||
var availability = $.trim($('.item-availability').text());
|
var availability = $.trim($('.item-availability').text());
|
||||||
|
if (limitedCommerce && (costInt > 0)) {
|
||||||
|
availability = '';
|
||||||
|
}
|
||||||
if (availability === 'available') {
|
if (availability === 'available') {
|
||||||
purchaseButton.css({
|
purchaseButton.css({
|
||||||
"background": "linear-gradient(#00b4ef, #0093C5)",
|
"background": "linear-gradient(#00b4ef, #0093C5)",
|
||||||
|
@ -436,14 +408,13 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var cost = $('.item-cost').text();
|
|
||||||
var type = $('.item-type').text();
|
var type = $('.item-type').text();
|
||||||
var isUpdating = window.location.href.indexOf('edition=') > -1;
|
var isUpdating = window.location.href.indexOf('edition=') > -1;
|
||||||
var urlParams = new URLSearchParams(window.location.search);
|
var urlParams = new URLSearchParams(window.location.search);
|
||||||
if (isUpdating) {
|
if (isUpdating) {
|
||||||
purchaseButton.html('UPDATE FOR FREE');
|
purchaseButton.html('UPDATE FOR FREE');
|
||||||
} else if (availability !== 'available') {
|
} else if (availability !== 'available') {
|
||||||
purchaseButton.html('UNAVAILABLE (' + availability + ')');
|
purchaseButton.html('UNAVAILABLE ' + (availability ? ('(' + availability + ')') : ''));
|
||||||
} else if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) {
|
} else if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) {
|
||||||
purchaseButton.html('PURCHASE <span class="hifi-glyph hifi-glyph-hfc" style="filter:invert(1);background-size:20px;' +
|
purchaseButton.html('PURCHASE <span class="hifi-glyph hifi-glyph-hfc" style="filter:invert(1);background-size:20px;' +
|
||||||
'width:20px;height:20px;position:relative;top:5px;"></span> ' + cost);
|
'width:20px;height:20px;position:relative;top:5px;"></span> ' + cost);
|
||||||
|
@ -461,7 +432,6 @@
|
||||||
type);
|
type);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
maybeAddPurchasesButton();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,6 +712,7 @@
|
||||||
cancelClaraDownload();
|
cancelClaraDownload();
|
||||||
} else if (message.type === "marketplaces") {
|
} else if (message.type === "marketplaces") {
|
||||||
if (message.action === "commerceSetting") {
|
if (message.action === "commerceSetting") {
|
||||||
|
limitedCommerce = !!message.data.limitedCommerce;
|
||||||
commerceMode = !!message.data.commerceMode;
|
commerceMode = !!message.data.commerceMode;
|
||||||
userIsLoggedIn = !!message.data.userIsLoggedIn;
|
userIsLoggedIn = !!message.data.userIsLoggedIn;
|
||||||
walletNeedsSetup = !!message.data.walletNeedsSetup;
|
walletNeedsSetup = !!message.data.walletNeedsSetup;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
/* global Tablet, Script, HMD, UserActivityLogger, Entities, Account, Wallet, ContextOverlay, Settings, Camera, Vec3,
|
/* global Tablet, Script, HMD, UserActivityLogger, Entities, Account, Wallet, ContextOverlay, Settings, Camera, Vec3,
|
||||||
Quat, MyAvatar, Clipboard, Menu, Grid, Uuid, GlobalServices, openLoginWindow, getConnectionData, Overlays, SoundCache,
|
Quat, MyAvatar, Clipboard, Menu, Grid, Uuid, GlobalServices, openLoginWindow, getConnectionData, Overlays, SoundCache,
|
||||||
DesktopPreviewProvider */
|
DesktopPreviewProvider, ResourceRequestObserver */
|
||||||
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
||||||
|
|
||||||
var selectionDisplay = null; // for gridTool.js to ignore
|
var selectionDisplay = null; // for gridTool.js to ignore
|
||||||
|
@ -23,7 +23,7 @@ Script.include("/~/system/libraries/connectionUtils.js");
|
||||||
var MARKETPLACE_CHECKOUT_QML_PATH = "hifi/commerce/checkout/Checkout.qml";
|
var MARKETPLACE_CHECKOUT_QML_PATH = "hifi/commerce/checkout/Checkout.qml";
|
||||||
var MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH = "hifi/commerce/inspectionCertificate/InspectionCertificate.qml";
|
var MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH = "hifi/commerce/inspectionCertificate/InspectionCertificate.qml";
|
||||||
var MARKETPLACE_ITEM_TESTER_QML_PATH = "hifi/commerce/marketplaceItemTester/MarketplaceItemTester.qml";
|
var MARKETPLACE_ITEM_TESTER_QML_PATH = "hifi/commerce/marketplaceItemTester/MarketplaceItemTester.qml";
|
||||||
var MARKETPLACE_PURCHASES_QML_PATH = "hifi/commerce/purchases/Purchases.qml";
|
var MARKETPLACE_PURCHASES_QML_PATH = "hifi/commerce/wallet/Wallet.qml"; // HRS FIXME "hifi/commerce/purchases/Purchases.qml";
|
||||||
var MARKETPLACE_WALLET_QML_PATH = "hifi/commerce/wallet/Wallet.qml";
|
var MARKETPLACE_WALLET_QML_PATH = "hifi/commerce/wallet/Wallet.qml";
|
||||||
var MARKETPLACES_INJECT_SCRIPT_URL = Script.resolvePath("../html/js/marketplacesInject.js");
|
var MARKETPLACES_INJECT_SCRIPT_URL = Script.resolvePath("../html/js/marketplacesInject.js");
|
||||||
var MARKETPLACES_URL = Script.resolvePath("../html/marketplaces.html");
|
var MARKETPLACES_URL = Script.resolvePath("../html/marketplaces.html");
|
||||||
|
@ -137,7 +137,7 @@ function setupWallet(referrer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMarketplaceOpen(referrer) {
|
function onMarketplaceOpen(referrer) {
|
||||||
var cta = referrer, match;
|
var match;
|
||||||
if (Account.loggedIn && walletNeedsSetup()) {
|
if (Account.loggedIn && walletNeedsSetup()) {
|
||||||
if (referrer === MARKETPLACE_URL_INITIAL) {
|
if (referrer === MARKETPLACE_URL_INITIAL) {
|
||||||
setupWallet('marketplace cta');
|
setupWallet('marketplace cta');
|
||||||
|
@ -218,7 +218,7 @@ function onUsernameChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function walletNeedsSetup() {
|
function walletNeedsSetup() {
|
||||||
return Wallet.walletStatus === 1;
|
return WalletScriptingInterface.walletStatus === 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendCommerceSettings() {
|
function sendCommerceSettings() {
|
||||||
|
@ -230,289 +230,11 @@ function sendCommerceSettings() {
|
||||||
userIsLoggedIn: Account.loggedIn,
|
userIsLoggedIn: Account.loggedIn,
|
||||||
walletNeedsSetup: walletNeedsSetup(),
|
walletNeedsSetup: walletNeedsSetup(),
|
||||||
metaverseServerURL: Account.metaverseServerURL,
|
metaverseServerURL: Account.metaverseServerURL,
|
||||||
messagesWaiting: shouldShowDot
|
limitedCommerce: WalletScriptingInterface.limitedCommerce
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// BEGIN AVATAR SELECTOR LOGIC
|
|
||||||
var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6 };
|
|
||||||
var SELECTED_COLOR = { red: 0xF3, green: 0x91, blue: 0x29 };
|
|
||||||
var HOVER_COLOR = { red: 0xD0, green: 0xD0, blue: 0xD0 };
|
|
||||||
|
|
||||||
var overlays = {}; // Keeps track of all our extended overlay data objects, keyed by target identifier.
|
|
||||||
|
|
||||||
function ExtendedOverlay(key, type, properties) { // A wrapper around overlays to store the key it is associated with.
|
|
||||||
overlays[key] = this;
|
|
||||||
this.key = key;
|
|
||||||
this.selected = false;
|
|
||||||
this.hovering = false;
|
|
||||||
this.activeOverlay = Overlays.addOverlay(type, properties); // We could use different overlays for (un)selected...
|
|
||||||
}
|
|
||||||
// Instance methods:
|
|
||||||
ExtendedOverlay.prototype.deleteOverlay = function () { // remove display and data of this overlay
|
|
||||||
Overlays.deleteOverlay(this.activeOverlay);
|
|
||||||
delete overlays[this.key];
|
|
||||||
};
|
|
||||||
|
|
||||||
ExtendedOverlay.prototype.editOverlay = function (properties) { // change display of this overlay
|
|
||||||
Overlays.editOverlay(this.activeOverlay, properties);
|
|
||||||
};
|
|
||||||
|
|
||||||
function color(selected, hovering) {
|
|
||||||
var base = hovering ? HOVER_COLOR : selected ? SELECTED_COLOR : UNSELECTED_COLOR;
|
|
||||||
function scale(component) {
|
|
||||||
return component;
|
|
||||||
}
|
|
||||||
return { red: scale(base.red), green: scale(base.green), blue: scale(base.blue) };
|
|
||||||
}
|
|
||||||
// so we don't have to traverse the overlays to get the last one
|
|
||||||
var lastHoveringId = 0;
|
|
||||||
ExtendedOverlay.prototype.hover = function (hovering) {
|
|
||||||
this.hovering = hovering;
|
|
||||||
if (this.key === lastHoveringId) {
|
|
||||||
if (hovering) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lastHoveringId = 0;
|
|
||||||
}
|
|
||||||
this.editOverlay({ color: color(this.selected, hovering) });
|
|
||||||
if (hovering) {
|
|
||||||
// un-hover the last hovering overlay
|
|
||||||
if (lastHoveringId && lastHoveringId !== this.key) {
|
|
||||||
ExtendedOverlay.get(lastHoveringId).hover(false);
|
|
||||||
}
|
|
||||||
lastHoveringId = this.key;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ExtendedOverlay.prototype.select = function (selected) {
|
|
||||||
if (this.selected === selected) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.editOverlay({ color: color(selected, this.hovering) });
|
|
||||||
this.selected = selected;
|
|
||||||
};
|
|
||||||
// Class methods:
|
|
||||||
var selectedId = false;
|
|
||||||
ExtendedOverlay.isSelected = function (id) {
|
|
||||||
return selectedId === id;
|
|
||||||
};
|
|
||||||
ExtendedOverlay.get = function (key) { // answer the extended overlay data object associated with the given avatar identifier
|
|
||||||
return overlays[key];
|
|
||||||
};
|
|
||||||
ExtendedOverlay.some = function (iterator) { // Bails early as soon as iterator returns truthy.
|
|
||||||
var key;
|
|
||||||
for (key in overlays) {
|
|
||||||
if (iterator(ExtendedOverlay.get(key))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ExtendedOverlay.unHover = function () { // calls hover(false) on lastHoveringId (if any)
|
|
||||||
if (lastHoveringId) {
|
|
||||||
ExtendedOverlay.get(lastHoveringId).hover(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
if (!pickedOverlay.intersects) {
|
|
||||||
if (noHit) {
|
|
||||||
return noHit();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ExtendedOverlay.some(function (overlay) { // See if pickedOverlay is one of ours.
|
|
||||||
if ((overlay.activeOverlay) === pickedOverlay.overlayID) {
|
|
||||||
hit(overlay);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function addAvatarNode(id) {
|
|
||||||
return new ExtendedOverlay(id, "sphere", {
|
|
||||||
drawInFront: true,
|
|
||||||
solid: true,
|
|
||||||
alpha: 0.8,
|
|
||||||
color: color(false, false),
|
|
||||||
ignoreRayIntersection: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var pingPong = true;
|
|
||||||
function updateOverlays() {
|
|
||||||
var eye = Camera.position;
|
|
||||||
AvatarList.getAvatarIdentifiers().forEach(function (id) {
|
|
||||||
if (!id) {
|
|
||||||
return; // don't update ourself, or avatars we're not interested in
|
|
||||||
}
|
|
||||||
var avatar = AvatarList.getAvatar(id);
|
|
||||||
if (!avatar) {
|
|
||||||
return; // will be deleted below if there had been an overlay.
|
|
||||||
}
|
|
||||||
var overlay = ExtendedOverlay.get(id);
|
|
||||||
if (!overlay) { // For now, we're treating this as a temporary loss, as from the personal space bubble. Add it back.
|
|
||||||
overlay = addAvatarNode(id);
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// move a bit in front, towards the camera
|
|
||||||
target = Vec3.subtract(target, Vec3.multiply(Vec3.normalize(diff), offset));
|
|
||||||
|
|
||||||
// now bump it up a bit
|
|
||||||
target.y = target.y + offset;
|
|
||||||
|
|
||||||
overlay.ping = pingPong;
|
|
||||||
overlay.editOverlay({
|
|
||||||
color: color(ExtendedOverlay.isSelected(id), overlay.hovering),
|
|
||||||
position: target,
|
|
||||||
dimensions: 0.032 * distance
|
|
||||||
});
|
|
||||||
});
|
|
||||||
pingPong = !pingPong;
|
|
||||||
ExtendedOverlay.some(function (overlay) { // Remove any that weren't updated. (User is gone.)
|
|
||||||
if (overlay.ping === pingPong) {
|
|
||||||
overlay.deleteOverlay();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function removeOverlays() {
|
|
||||||
selectedId = false;
|
|
||||||
lastHoveringId = 0;
|
|
||||||
ExtendedOverlay.some(function (overlay) {
|
|
||||||
overlay.deleteOverlay();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Clicks.
|
|
||||||
//
|
|
||||||
function usernameFromIDReply(id, username, machineFingerprint, isAdmin) {
|
|
||||||
if (selectedId === id) {
|
|
||||||
var message = {
|
|
||||||
method: 'updateSelectedRecipientUsername',
|
|
||||||
userName: username === "" ? "unknown username" : username
|
|
||||||
};
|
|
||||||
ui.tablet.sendToQml(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function handleClick(pickRay) {
|
|
||||||
ExtendedOverlay.applyPickRay(pickRay, function (overlay) {
|
|
||||||
var nextSelectedStatus = !overlay.selected;
|
|
||||||
var avatarId = overlay.key;
|
|
||||||
selectedId = nextSelectedStatus ? avatarId : false;
|
|
||||||
if (nextSelectedStatus) {
|
|
||||||
Users.requestUsernameFromID(avatarId);
|
|
||||||
}
|
|
||||||
var message = {
|
|
||||||
method: 'selectRecipient',
|
|
||||||
id: avatarId,
|
|
||||||
isSelected: nextSelectedStatus,
|
|
||||||
displayName: '"' + AvatarList.getAvatar(avatarId).sessionDisplayName + '"',
|
|
||||||
userName: ''
|
|
||||||
};
|
|
||||||
ui.tablet.sendToQml(message);
|
|
||||||
|
|
||||||
ExtendedOverlay.some(function (overlay) {
|
|
||||||
var id = overlay.key;
|
|
||||||
var selected = ExtendedOverlay.isSelected(id);
|
|
||||||
overlay.select(selected);
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function handleMouseEvent(mousePressEvent) { // handleClick if we get one.
|
|
||||||
if (!mousePressEvent.isLeftButton) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handleClick(Camera.computePickRay(mousePressEvent.x, mousePressEvent.y));
|
|
||||||
}
|
|
||||||
function handleMouseMove(pickRay) { // given the pickRay, just do the hover logic
|
|
||||||
ExtendedOverlay.applyPickRay(pickRay, function (overlay) {
|
|
||||||
overlay.hover(true);
|
|
||||||
}, function () {
|
|
||||||
ExtendedOverlay.unHover();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// handy global to keep track of which hand is the mouse (if any)
|
|
||||||
var currentHandPressed = 0;
|
|
||||||
var TRIGGER_CLICK_THRESHOLD = 0.85;
|
|
||||||
var TRIGGER_PRESS_THRESHOLD = 0.05;
|
|
||||||
|
|
||||||
function handleMouseMoveEvent(event) { // find out which overlay (if any) is over the mouse position
|
|
||||||
var pickRay;
|
|
||||||
if (HMD.active) {
|
|
||||||
if (currentHandPressed !== 0) {
|
|
||||||
pickRay = controllerComputePickRay(currentHandPressed);
|
|
||||||
} else {
|
|
||||||
// nothing should hover, so
|
|
||||||
ExtendedOverlay.unHover();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pickRay = Camera.computePickRay(event.x, event.y);
|
|
||||||
}
|
|
||||||
handleMouseMove(pickRay);
|
|
||||||
}
|
|
||||||
function handleTriggerPressed(hand, value) {
|
|
||||||
// The idea is if you press one trigger, it is the one
|
|
||||||
// we will consider the mouse. Even if the other is pressed,
|
|
||||||
// we ignore it until this one is no longer pressed.
|
|
||||||
var isPressed = value > TRIGGER_PRESS_THRESHOLD;
|
|
||||||
if (currentHandPressed === 0) {
|
|
||||||
currentHandPressed = isPressed ? hand : 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (currentHandPressed === hand) {
|
|
||||||
currentHandPressed = isPressed ? hand : 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// otherwise, the other hand is still triggered
|
|
||||||
// so do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
// We get mouseMoveEvents from the handControllers, via handControllerPointer.
|
|
||||||
// But we don't get mousePressEvents.
|
|
||||||
var triggerMapping = Controller.newMapping(Script.resolvePath('') + '-click');
|
|
||||||
var triggerPressMapping = Controller.newMapping(Script.resolvePath('') + '-press');
|
|
||||||
function controllerComputePickRay(hand) {
|
|
||||||
var controllerPose = getControllerWorldLocation(hand, true);
|
|
||||||
if (controllerPose.valid) {
|
|
||||||
return { origin: controllerPose.position, direction: Quat.getUp(controllerPose.orientation) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function makeClickHandler(hand) {
|
|
||||||
return function (clicked) {
|
|
||||||
if (clicked > TRIGGER_CLICK_THRESHOLD) {
|
|
||||||
var pickRay = controllerComputePickRay(hand);
|
|
||||||
handleClick(pickRay);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function makePressHandler(hand) {
|
|
||||||
return function (value) {
|
|
||||||
handleTriggerPressed(hand, value);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
triggerMapping.from(Controller.Standard.RTClick).peek().to(makeClickHandler(Controller.Standard.RightHand));
|
|
||||||
triggerMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand));
|
|
||||||
triggerPressMapping.from(Controller.Standard.RT).peek().to(makePressHandler(Controller.Standard.RightHand));
|
|
||||||
triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand));
|
|
||||||
// END AVATAR SELECTOR LOGIC
|
|
||||||
|
|
||||||
var grid = new Grid();
|
var grid = new Grid();
|
||||||
function adjustPositionPerBoundingBox(position, direction, registration, dimensions, orientation) {
|
function adjustPositionPerBoundingBox(position, direction, registration, dimensions, orientation) {
|
||||||
// Adjust the position such that the bounding box (registration, dimenions, and orientation) lies behind the original
|
// Adjust the position such that the bounding box (registration, dimenions, and orientation) lies behind the original
|
||||||
|
@ -562,6 +284,7 @@ function defaultFor(arg, val) {
|
||||||
return typeof arg !== 'undefined' ? arg : val;
|
return typeof arg !== 'undefined' ? arg : val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var CERT_ID_URLPARAM_LENGTH = 15; // length of "certificate_id="
|
||||||
function rezEntity(itemHref, itemType, marketplaceItemTesterId) {
|
function rezEntity(itemHref, itemType, marketplaceItemTesterId) {
|
||||||
var isWearable = itemType === "wearable";
|
var isWearable = itemType === "wearable";
|
||||||
var success = Clipboard.importEntities(itemHref, true, marketplaceItemTesterId);
|
var success = Clipboard.importEntities(itemHref, true, marketplaceItemTesterId);
|
||||||
|
@ -584,7 +307,7 @@ function rezEntity(itemHref, itemType, marketplaceItemTesterId) {
|
||||||
}
|
}
|
||||||
var certPos = itemHref.search("certificate_id="); // TODO how do I parse a URL from here?
|
var certPos = itemHref.search("certificate_id="); // TODO how do I parse a URL from here?
|
||||||
if (certPos >= 0) {
|
if (certPos >= 0) {
|
||||||
certPos += 15; // length of "certificate_id="
|
certPos += CERT_ID_URLPARAM_LENGTH;
|
||||||
var certURLEncoded = itemHref.substring(certPos);
|
var certURLEncoded = itemHref.substring(certPos);
|
||||||
var certB64Encoded = decodeURIComponent(certURLEncoded);
|
var certB64Encoded = decodeURIComponent(certURLEncoded);
|
||||||
for (var key in wearableTransforms) {
|
for (var key in wearableTransforms) {
|
||||||
|
@ -593,7 +316,7 @@ function rezEntity(itemHref, itemType, marketplaceItemTesterId) {
|
||||||
if (certificateTransforms) {
|
if (certificateTransforms) {
|
||||||
for (var certID in certificateTransforms) {
|
for (var certID in certificateTransforms) {
|
||||||
if (certificateTransforms.hasOwnProperty(certID) &&
|
if (certificateTransforms.hasOwnProperty(certID) &&
|
||||||
certID == certB64Encoded) {
|
certID === certB64Encoded) {
|
||||||
var certificateTransform = certificateTransforms[certID];
|
var certificateTransform = certificateTransforms[certID];
|
||||||
wearableLocalPosition = certificateTransform.localPosition;
|
wearableLocalPosition = certificateTransform.localPosition;
|
||||||
wearableLocalRotation = certificateTransform.localRotation;
|
wearableLocalRotation = certificateTransform.localRotation;
|
||||||
|
@ -636,8 +359,10 @@ function rezEntity(itemHref, itemType, marketplaceItemTesterId) {
|
||||||
targetDirection = Vec3.multiplyQbyV(targetDirection, Vec3.UNIT_Z);
|
targetDirection = Vec3.multiplyQbyV(targetDirection, Vec3.UNIT_Z);
|
||||||
|
|
||||||
var targetPosition = getPositionToCreateEntity();
|
var targetPosition = getPositionToCreateEntity();
|
||||||
var deltaParallel = HALF_TREE_SCALE; // Distance to move entities parallel to targetDirection.
|
// Distance to move entities parallel to targetDirection.
|
||||||
var deltaPerpendicular = Vec3.ZERO; // Distance to move entities perpendicular to targetDirection.
|
var deltaParallel = HALF_TREE_SCALE;
|
||||||
|
// Distance to move entities perpendicular to targetDirection.
|
||||||
|
var deltaPerpendicular = Vec3.ZERO;
|
||||||
for (var i = 0, length = pastedEntityIDs.length; i < length; i++) {
|
for (var i = 0, length = pastedEntityIDs.length; i < length; i++) {
|
||||||
var curLoopEntityProps = Entities.getEntityProperties(pastedEntityIDs[i], ["position", "dimensions",
|
var curLoopEntityProps = Entities.getEntityProperties(pastedEntityIDs[i], ["position", "dimensions",
|
||||||
"registrationPoint", "rotation", "parentID"]);
|
"registrationPoint", "rotation", "parentID"]);
|
||||||
|
@ -665,7 +390,8 @@ function rezEntity(itemHref, itemType, marketplaceItemTesterId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Vec3.equal(deltaPosition, Vec3.ZERO)) {
|
if (!Vec3.equal(deltaPosition, Vec3.ZERO)) {
|
||||||
for (var editEntityIndex = 0, numEntities = pastedEntityIDs.length; editEntityIndex < numEntities; editEntityIndex++) {
|
for (var editEntityIndex = 0,
|
||||||
|
numEntities = pastedEntityIDs.length; editEntityIndex < numEntities; editEntityIndex++) {
|
||||||
if (Uuid.isNull(entityParentIDs[editEntityIndex])) {
|
if (Uuid.isNull(entityParentIDs[editEntityIndex])) {
|
||||||
Entities.editEntity(pastedEntityIDs[editEntityIndex], {
|
Entities.editEntity(pastedEntityIDs[editEntityIndex], {
|
||||||
position: Vec3.sum(deltaPosition, entityPositions[editEntityIndex])
|
position: Vec3.sum(deltaPosition, entityPositions[editEntityIndex])
|
||||||
|
@ -768,79 +494,6 @@ function onWebEventReceived(message) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var sendAssetRecipient;
|
|
||||||
var sendAssetParticleEffectUpdateTimer;
|
|
||||||
var particleEffectTimestamp;
|
|
||||||
var sendAssetParticleEffect;
|
|
||||||
var SEND_ASSET_PARTICLE_TIMER_UPDATE = 250;
|
|
||||||
var SEND_ASSET_PARTICLE_EMITTING_DURATION = 3000;
|
|
||||||
var SEND_ASSET_PARTICLE_LIFETIME_SECONDS = 8;
|
|
||||||
var SEND_ASSET_PARTICLE_PROPERTIES = {
|
|
||||||
accelerationSpread: { x: 0, y: 0, z: 0 },
|
|
||||||
alpha: 1,
|
|
||||||
alphaFinish: 1,
|
|
||||||
alphaSpread: 0,
|
|
||||||
alphaStart: 1,
|
|
||||||
azimuthFinish: 0,
|
|
||||||
azimuthStart: -6,
|
|
||||||
color: { red: 255, green: 222, blue: 255 },
|
|
||||||
colorFinish: { red: 255, green: 229, blue: 225 },
|
|
||||||
colorSpread: { red: 0, green: 0, blue: 0 },
|
|
||||||
colorStart: { red: 243, green: 255, blue: 255 },
|
|
||||||
emitAcceleration: { x: 0, y: 0, z: 0 }, // Immediately gets updated to be accurate
|
|
||||||
emitDimensions: { x: 0, y: 0, z: 0 },
|
|
||||||
emitOrientation: { x: 0, y: 0, z: 0 },
|
|
||||||
emitRate: 4,
|
|
||||||
emitSpeed: 2.1,
|
|
||||||
emitterShouldTrail: true,
|
|
||||||
isEmitting: 1,
|
|
||||||
lifespan: SEND_ASSET_PARTICLE_LIFETIME_SECONDS + 1, // Immediately gets updated to be accurate
|
|
||||||
lifetime: SEND_ASSET_PARTICLE_LIFETIME_SECONDS + 1,
|
|
||||||
maxParticles: 20,
|
|
||||||
name: 'asset-particles',
|
|
||||||
particleRadius: 0.2,
|
|
||||||
polarFinish: 0,
|
|
||||||
polarStart: 0,
|
|
||||||
radiusFinish: 0.05,
|
|
||||||
radiusSpread: 0,
|
|
||||||
radiusStart: 0.2,
|
|
||||||
speedSpread: 0,
|
|
||||||
textures: "http://hifi-content.s3.amazonaws.com/alan/dev/Particles/Bokeh-Particle-HFC.png",
|
|
||||||
type: 'ParticleEffect'
|
|
||||||
};
|
|
||||||
|
|
||||||
function updateSendAssetParticleEffect() {
|
|
||||||
var timestampNow = Date.now();
|
|
||||||
if ((timestampNow - particleEffectTimestamp) > (SEND_ASSET_PARTICLE_LIFETIME_SECONDS * 1000)) {
|
|
||||||
deleteSendAssetParticleEffect();
|
|
||||||
return;
|
|
||||||
} else if ((timestampNow - particleEffectTimestamp) > SEND_ASSET_PARTICLE_EMITTING_DURATION) {
|
|
||||||
Entities.editEntity(sendAssetParticleEffect, {
|
|
||||||
isEmitting: 0
|
|
||||||
});
|
|
||||||
} else if (sendAssetParticleEffect) {
|
|
||||||
var recipientPosition = AvatarList.getAvatar(sendAssetRecipient).position;
|
|
||||||
var distance = Vec3.distance(recipientPosition, MyAvatar.position);
|
|
||||||
var accel = Vec3.subtract(recipientPosition, MyAvatar.position);
|
|
||||||
accel.y -= 3.0;
|
|
||||||
var life = Math.sqrt(2 * distance / Vec3.length(accel));
|
|
||||||
Entities.editEntity(sendAssetParticleEffect, {
|
|
||||||
emitAcceleration: accel,
|
|
||||||
lifespan: life
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteSendAssetParticleEffect() {
|
|
||||||
if (sendAssetParticleEffectUpdateTimer) {
|
|
||||||
Script.clearInterval(sendAssetParticleEffectUpdateTimer);
|
|
||||||
sendAssetParticleEffectUpdateTimer = null;
|
|
||||||
}
|
|
||||||
if (sendAssetParticleEffect) {
|
|
||||||
sendAssetParticleEffect = Entities.deleteEntity(sendAssetParticleEffect);
|
|
||||||
}
|
|
||||||
sendAssetRecipient = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var savedDisablePreviewOption = Menu.isOptionChecked("Disable Preview");
|
var savedDisablePreviewOption = Menu.isOptionChecked("Disable Preview");
|
||||||
var UI_FADE_TIMEOUT_MS = 150;
|
var UI_FADE_TIMEOUT_MS = 150;
|
||||||
|
@ -874,17 +527,14 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
||||||
Window.location = "hifi://BankOfHighFidelity";
|
Window.location = "hifi://BankOfHighFidelity";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'purchases_openWallet':
|
case 'checkout_openRecentActivity':
|
||||||
case 'checkout_openWallet':
|
ui.open(MARKETPLACE_WALLET_QML_PATH);
|
||||||
case 'checkout_setUpClicked':
|
|
||||||
openWallet();
|
|
||||||
break;
|
|
||||||
case 'purchases_walletNotSetUp':
|
|
||||||
wireQmlEventBridge(true);
|
wireQmlEventBridge(true);
|
||||||
ui.tablet.sendToQml({
|
ui.tablet.sendToQml({
|
||||||
method: 'updateWalletReferrer',
|
method: 'checkout_openRecentActivity'
|
||||||
referrer: "purchases"
|
|
||||||
});
|
});
|
||||||
|
break;
|
||||||
|
case 'checkout_setUpClicked':
|
||||||
openWallet();
|
openWallet();
|
||||||
break;
|
break;
|
||||||
case 'checkout_walletNotSetUp':
|
case 'checkout_walletNotSetUp':
|
||||||
|
@ -907,15 +557,9 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
||||||
case 'checkout_itemLinkClicked':
|
case 'checkout_itemLinkClicked':
|
||||||
openMarketplace(message.itemId);
|
openMarketplace(message.itemId);
|
||||||
break;
|
break;
|
||||||
case 'checkout_continueShopping':
|
case 'checkout_continue':
|
||||||
openMarketplace();
|
openMarketplace();
|
||||||
break;
|
break;
|
||||||
case 'purchases_itemInfoClicked':
|
|
||||||
var itemId = message.itemId;
|
|
||||||
if (itemId && itemId !== "") {
|
|
||||||
openMarketplace(itemId);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'checkout_rezClicked':
|
case 'checkout_rezClicked':
|
||||||
case 'purchases_rezClicked':
|
case 'purchases_rezClicked':
|
||||||
case 'tester_rezClicked':
|
case 'tester_rezClicked':
|
||||||
|
@ -944,7 +588,6 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'header_marketplaceImageClicked':
|
case 'header_marketplaceImageClicked':
|
||||||
case 'purchases_backClicked':
|
|
||||||
openMarketplace(message.referrerURL);
|
openMarketplace(message.referrerURL);
|
||||||
break;
|
break;
|
||||||
case 'purchases_goToMarketplaceClicked':
|
case 'purchases_goToMarketplaceClicked':
|
||||||
|
@ -952,9 +595,6 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
||||||
break;
|
break;
|
||||||
case 'updateItemClicked':
|
case 'updateItemClicked':
|
||||||
openMarketplace(message.upgradeUrl + "?edition=" + message.itemEdition);
|
openMarketplace(message.upgradeUrl + "?edition=" + message.itemEdition);
|
||||||
break;
|
|
||||||
case 'giftAsset':
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'passphrasePopup_cancelClicked':
|
case 'passphrasePopup_cancelClicked':
|
||||||
case 'needsLogIn_cancelClicked':
|
case 'needsLogIn_cancelClicked':
|
||||||
|
@ -974,13 +614,9 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
||||||
case 'maybeEnableHmdPreview':
|
case 'maybeEnableHmdPreview':
|
||||||
maybeEnableHMDPreview();
|
maybeEnableHMDPreview();
|
||||||
break;
|
break;
|
||||||
case 'purchases_openGoTo':
|
case 'checkout_openGoTo':
|
||||||
ui.open("hifi/tablet/TabletAddressDialog.qml");
|
ui.open("hifi/tablet/TabletAddressDialog.qml");
|
||||||
break;
|
break;
|
||||||
case 'purchases_itemCertificateClicked':
|
|
||||||
contextOverlayEntity = "";
|
|
||||||
setCertificateInfo(contextOverlayEntity, message.itemCertificateId);
|
|
||||||
break;
|
|
||||||
case 'inspectionCertificate_closeClicked':
|
case 'inspectionCertificate_closeClicked':
|
||||||
ui.close();
|
ui.close();
|
||||||
break;
|
break;
|
||||||
|
@ -999,85 +635,25 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
||||||
method: 'purchases_showMyItems'
|
method: 'purchases_showMyItems'
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'refreshConnections':
|
|
||||||
// Guard to prevent this code from being executed while sending money --
|
|
||||||
// we only want to execute this while sending non-HFC gifts
|
|
||||||
if (!onWalletScreen) {
|
|
||||||
print('Refreshing Connections...');
|
|
||||||
getConnectionData(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'enable_ChooseRecipientNearbyMode':
|
|
||||||
// Guard to prevent this code from being executed while sending money --
|
|
||||||
// we only want to execute this while sending non-HFC gifts
|
|
||||||
if (!onWalletScreen) {
|
|
||||||
if (!isUpdateOverlaysWired) {
|
|
||||||
Script.update.connect(updateOverlays);
|
|
||||||
isUpdateOverlaysWired = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'disable_ChooseRecipientNearbyMode':
|
|
||||||
// Guard to prevent this code from being executed while sending money --
|
|
||||||
// we only want to execute this while sending non-HFC gifts
|
|
||||||
if (!onWalletScreen) {
|
|
||||||
if (isUpdateOverlaysWired) {
|
|
||||||
Script.update.disconnect(updateOverlays);
|
|
||||||
isUpdateOverlaysWired = false;
|
|
||||||
}
|
|
||||||
removeOverlays();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'purchases_availableUpdatesReceived':
|
|
||||||
shouldShowDot = message.numUpdates > 0;
|
|
||||||
ui.messagesWaiting(shouldShowDot && !ui.isOpen);
|
|
||||||
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 'sendAsset_sendPublicly':
|
|
||||||
if (message.assetName !== "") {
|
|
||||||
deleteSendAssetParticleEffect();
|
|
||||||
sendAssetRecipient = message.recipient;
|
|
||||||
var props = SEND_ASSET_PARTICLE_PROPERTIES;
|
|
||||||
props.parentID = MyAvatar.sessionUUID;
|
|
||||||
props.position = MyAvatar.position;
|
|
||||||
props.position.y += 0.2;
|
|
||||||
if (message.effectImage) {
|
|
||||||
props.textures = message.effectImage;
|
|
||||||
}
|
|
||||||
sendAssetParticleEffect = Entities.addEntity(props, true);
|
|
||||||
particleEffectTimestamp = Date.now();
|
|
||||||
updateSendAssetParticleEffect();
|
|
||||||
sendAssetParticleEffectUpdateTimer = Script.setInterval(updateSendAssetParticleEffect,
|
|
||||||
SEND_ASSET_PARTICLE_TIMER_UPDATE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'http.request':
|
case 'http.request':
|
||||||
// Handled elsewhere, don't log.
|
// Handled elsewhere, don't log.
|
||||||
break;
|
break;
|
||||||
case 'goToPurchases_fromWalletHome': // HRS FIXME What's this about?
|
// All of these are handled by wallet.js
|
||||||
|
case 'purchases_updateWearables':
|
||||||
|
case 'enable_ChooseRecipientNearbyMode':
|
||||||
|
case 'disable_ChooseRecipientNearbyMode':
|
||||||
|
case 'sendAsset_sendPublicly':
|
||||||
|
case 'refreshConnections':
|
||||||
|
case 'transactionHistory_goToBank':
|
||||||
|
case 'purchases_walletNotSetUp':
|
||||||
|
case 'purchases_openGoTo':
|
||||||
|
case 'purchases_itemInfoClicked':
|
||||||
|
case 'purchases_itemCertificateClicked':
|
||||||
|
case 'clearShouldShowDotHistory':
|
||||||
|
case 'giftAsset':
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
print('Unrecognized message from Checkout.qml or Purchases.qml: ' + JSON.stringify(message));
|
print('Unrecognized message from Checkout.qml: ' + JSON.stringify(message));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1146,6 +722,8 @@ var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
||||||
referrerURL: referrerURL,
|
referrerURL: referrerURL,
|
||||||
filterText: filterText
|
filterText: filterText
|
||||||
});
|
});
|
||||||
|
referrerURL = "";
|
||||||
|
filterText = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.isOpen = (onMarketplaceScreen || onCommerceScreen) && !onWalletScreen;
|
ui.isOpen = (onMarketplaceScreen || onCommerceScreen) && !onWalletScreen;
|
||||||
|
@ -1162,15 +740,7 @@ var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onCommerceScreen) {
|
if (onCommerceScreen) {
|
||||||
if (!isWired) {
|
WalletScriptingInterface.refreshWalletStatus();
|
||||||
Users.usernameFromIDReply.connect(usernameFromIDReply);
|
|
||||||
Controller.mousePressEvent.connect(handleMouseEvent);
|
|
||||||
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
|
|
||||||
triggerMapping.enable();
|
|
||||||
triggerPressMapping.enable();
|
|
||||||
}
|
|
||||||
isWired = true;
|
|
||||||
Wallet.refreshWalletStatus();
|
|
||||||
} else {
|
} else {
|
||||||
if (onMarketplaceScreen) {
|
if (onMarketplaceScreen) {
|
||||||
onMarketplaceOpen('marketplace cta');
|
onMarketplaceOpen('marketplace cta');
|
||||||
|
@ -1192,44 +762,11 @@ var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
||||||
"\nNew screen URL: " + url + "\nCurrent app open status: " + ui.isOpen + "\n");
|
"\nNew screen URL: " + url + "\nCurrent app open status: " + ui.isOpen + "\n");
|
||||||
};
|
};
|
||||||
|
|
||||||
function notificationDataProcessPage(data) {
|
|
||||||
return data.data.updates;
|
|
||||||
}
|
|
||||||
|
|
||||||
var shouldShowDot = false;
|
|
||||||
function notificationPollCallback(updatesArray) {
|
|
||||||
shouldShowDot = shouldShowDot || updatesArray.length > 0;
|
|
||||||
ui.messagesWaiting(shouldShowDot && !ui.isOpen);
|
|
||||||
|
|
||||||
if (updatesArray.length > 0) {
|
|
||||||
var message;
|
|
||||||
if (!ui.notificationInitialCallbackMade) {
|
|
||||||
message = updatesArray.length + " of your purchased items " +
|
|
||||||
(updatesArray.length === 1 ? "has an update " : "have updates ") +
|
|
||||||
"available. Open MARKET to update.";
|
|
||||||
ui.notificationDisplayBanner(message);
|
|
||||||
|
|
||||||
ui.notificationPollCaresAboutSince = true;
|
|
||||||
} else {
|
|
||||||
for (var i = 0; i < updatesArray.length; i++) {
|
|
||||||
message = "Update available for \"" +
|
|
||||||
updatesArray[i].base_item_title + "\"." +
|
|
||||||
"Open MARKET to update.";
|
|
||||||
ui.notificationDisplayBanner(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isReturnedDataEmpty(data) {
|
|
||||||
var historyArray = data.data.updates;
|
|
||||||
return historyArray.length === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var BUTTON_NAME = "MARKET";
|
var BUTTON_NAME = "MARKET";
|
||||||
var MARKETPLACE_URL = METAVERSE_SERVER_URL + "/marketplace";
|
var MARKETPLACE_URL = METAVERSE_SERVER_URL + "/marketplace";
|
||||||
var MARKETPLACE_URL_INITIAL = MARKETPLACE_URL + "?"; // Append "?" to signal injected script that it's the initial page.
|
// Append "?" if necessary to signal injected script that it's the initial page.
|
||||||
|
var MARKETPLACE_URL_INITIAL = MARKETPLACE_URL + (MARKETPLACE_URL.indexOf("?") > -1 ? "" : "?");
|
||||||
var ui;
|
var ui;
|
||||||
function startup() {
|
function startup() {
|
||||||
ui = new AppUi({
|
ui = new AppUi({
|
||||||
|
@ -1238,50 +775,26 @@ function startup() {
|
||||||
inject: MARKETPLACES_INJECT_SCRIPT_URL,
|
inject: MARKETPLACES_INJECT_SCRIPT_URL,
|
||||||
home: MARKETPLACE_URL_INITIAL,
|
home: MARKETPLACE_URL_INITIAL,
|
||||||
onScreenChanged: onTabletScreenChanged,
|
onScreenChanged: onTabletScreenChanged,
|
||||||
onMessage: onQmlMessageReceived,
|
onMessage: onQmlMessageReceived
|
||||||
notificationPollEndpoint: "/api/v1/commerce/available_updates?per_page=10",
|
|
||||||
notificationPollTimeoutMs: 300000,
|
|
||||||
notificationDataProcessPage: notificationDataProcessPage,
|
|
||||||
notificationPollCallback: notificationPollCallback,
|
|
||||||
notificationPollStopPaginatingConditionMet: isReturnedDataEmpty,
|
|
||||||
notificationPollCaresAboutSince: false // Changes to true after first poll
|
|
||||||
});
|
});
|
||||||
ContextOverlay.contextOverlayClicked.connect(openInspectionCertificateQML);
|
ContextOverlay.contextOverlayClicked.connect(openInspectionCertificateQML);
|
||||||
Entities.canWriteAssetsChanged.connect(onCanWriteAssetsChanged);
|
Entities.canWriteAssetsChanged.connect(onCanWriteAssetsChanged);
|
||||||
GlobalServices.myUsernameChanged.connect(onUsernameChanged);
|
GlobalServices.myUsernameChanged.connect(onUsernameChanged);
|
||||||
ui.tablet.webEventReceived.connect(onWebEventReceived);
|
ui.tablet.webEventReceived.connect(onWebEventReceived);
|
||||||
Wallet.walletStatusChanged.connect(sendCommerceSettings);
|
WalletScriptingInterface.walletStatusChanged.connect(sendCommerceSettings);
|
||||||
Window.messageBoxClosed.connect(onMessageBoxClosed);
|
Window.messageBoxClosed.connect(onMessageBoxClosed);
|
||||||
ResourceRequestObserver.resourceRequestEvent.connect(onResourceRequestEvent);
|
ResourceRequestObserver.resourceRequestEvent.connect(onResourceRequestEvent);
|
||||||
|
|
||||||
Wallet.refreshWalletStatus();
|
WalletScriptingInterface.refreshWalletStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
var isWired = false;
|
|
||||||
var isUpdateOverlaysWired = false;
|
|
||||||
function off() {
|
function off() {
|
||||||
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);
|
|
||||||
isUpdateOverlaysWired = false;
|
|
||||||
}
|
|
||||||
removeOverlays();
|
|
||||||
}
|
}
|
||||||
function shutdown() {
|
function shutdown() {
|
||||||
maybeEnableHMDPreview();
|
maybeEnableHMDPreview();
|
||||||
deleteSendAssetParticleEffect();
|
|
||||||
|
|
||||||
Window.messageBoxClosed.disconnect(onMessageBoxClosed);
|
Window.messageBoxClosed.disconnect(onMessageBoxClosed);
|
||||||
Wallet.walletStatusChanged.disconnect(sendCommerceSettings);
|
WalletScriptingInterface.walletStatusChanged.disconnect(sendCommerceSettings);
|
||||||
ui.tablet.webEventReceived.disconnect(onWebEventReceived);
|
ui.tablet.webEventReceived.disconnect(onWebEventReceived);
|
||||||
GlobalServices.myUsernameChanged.disconnect(onUsernameChanged);
|
GlobalServices.myUsernameChanged.disconnect(onUsernameChanged);
|
||||||
Entities.canWriteAssetsChanged.disconnect(onCanWriteAssetsChanged);
|
Entities.canWriteAssetsChanged.disconnect(onCanWriteAssetsChanged);
|
||||||
|
|
|
@ -634,7 +634,7 @@
|
||||||
Window.notifyEditError = onEditError;
|
Window.notifyEditError = onEditError;
|
||||||
Window.notify = onNotify;
|
Window.notify = onNotify;
|
||||||
Tablet.tabletNotification.connect(tabletNotification);
|
Tablet.tabletNotification.connect(tabletNotification);
|
||||||
Wallet.walletNotSetup.connect(walletNotSetup);
|
WalletScriptingInterface.walletNotSetup.connect(walletNotSetup);
|
||||||
|
|
||||||
Messages.subscribe(NOTIFICATIONS_MESSAGE_CHANNEL);
|
Messages.subscribe(NOTIFICATIONS_MESSAGE_CHANNEL);
|
||||||
Messages.messageReceived.connect(onMessageReceived);
|
Messages.messageReceived.connect(onMessageReceived);
|
||||||
|
|
|
@ -844,7 +844,7 @@ function notificationPollCallback(connectionsArray) {
|
||||||
newOnlineUsers++;
|
newOnlineUsers++;
|
||||||
storedOnlineUsers[user.username] = user;
|
storedOnlineUsers[user.username] = user;
|
||||||
|
|
||||||
if (!ui.isOpen && ui.notificationInitialCallbackMade) {
|
if (!ui.isOpen && ui.notificationInitialCallbackMade[0]) {
|
||||||
message = user.username + " is available in " +
|
message = user.username + " is available in " +
|
||||||
user.location.root.name + ". Open PEOPLE to join them.";
|
user.location.root.name + ". Open PEOPLE to join them.";
|
||||||
ui.notificationDisplayBanner(message);
|
ui.notificationDisplayBanner(message);
|
||||||
|
@ -868,7 +868,7 @@ function notificationPollCallback(connectionsArray) {
|
||||||
shouldShowDot: shouldShowDot
|
shouldShowDot: shouldShowDot
|
||||||
});
|
});
|
||||||
|
|
||||||
if (newOnlineUsers > 0 && !ui.notificationInitialCallbackMade) {
|
if (newOnlineUsers > 0 && !ui.notificationInitialCallbackMade[0]) {
|
||||||
message = newOnlineUsers + " of your connections " +
|
message = newOnlineUsers + " of your connections " +
|
||||||
(newOnlineUsers === 1 ? "is" : "are") + " available online. Open PEOPLE to join them.";
|
(newOnlineUsers === 1 ? "is" : "are") + " available online. Open PEOPLE to join them.";
|
||||||
ui.notificationDisplayBanner(message);
|
ui.notificationDisplayBanner(message);
|
||||||
|
@ -889,12 +889,12 @@ function startup() {
|
||||||
onOpened: palOpened,
|
onOpened: palOpened,
|
||||||
onClosed: off,
|
onClosed: off,
|
||||||
onMessage: fromQml,
|
onMessage: fromQml,
|
||||||
notificationPollEndpoint: "/api/v1/users?filter=connections&status=online&per_page=10",
|
notificationPollEndpoint: ["/api/v1/users?filter=connections&status=online&per_page=10"],
|
||||||
notificationPollTimeoutMs: 60000,
|
notificationPollTimeoutMs: [60000],
|
||||||
notificationDataProcessPage: notificationDataProcessPage,
|
notificationDataProcessPage: [notificationDataProcessPage],
|
||||||
notificationPollCallback: notificationPollCallback,
|
notificationPollCallback: [notificationPollCallback],
|
||||||
notificationPollStopPaginatingConditionMet: isReturnedDataEmpty,
|
notificationPollStopPaginatingConditionMet: [isReturnedDataEmpty],
|
||||||
notificationPollCaresAboutSince: false
|
notificationPollCaresAboutSince: [false]
|
||||||
});
|
});
|
||||||
Window.domainChanged.connect(clearLocalQMLDataAndClosePAL);
|
Window.domainChanged.connect(clearLocalQMLDataAndClosePAL);
|
||||||
Window.domainConnectionRefused.connect(clearLocalQMLDataAndClosePAL);
|
Window.domainConnectionRefused.connect(clearLocalQMLDataAndClosePAL);
|
||||||
|
|
|
@ -37,7 +37,7 @@ function notificationPollCallback(userStoriesArray) {
|
||||||
//
|
//
|
||||||
pingPong = !pingPong;
|
pingPong = !pingPong;
|
||||||
var totalNewStories = 0;
|
var totalNewStories = 0;
|
||||||
var shouldNotifyIndividually = !ui.isOpen && ui.notificationInitialCallbackMade;
|
var shouldNotifyIndividually = !ui.isOpen && ui.notificationInitialCallbackMade[0];
|
||||||
userStoriesArray.forEach(function (story) {
|
userStoriesArray.forEach(function (story) {
|
||||||
if (story.audience !== "for_connections" &&
|
if (story.audience !== "for_connections" &&
|
||||||
story.audience !== "for_feed") {
|
story.audience !== "for_feed") {
|
||||||
|
@ -91,7 +91,7 @@ function notificationPollCallback(userStoriesArray) {
|
||||||
shouldShowDot = totalNewStories > 0 || (totalStories > 0 && shouldShowDot);
|
shouldShowDot = totalNewStories > 0 || (totalStories > 0 && shouldShowDot);
|
||||||
ui.messagesWaiting(shouldShowDot && !ui.isOpen);
|
ui.messagesWaiting(shouldShowDot && !ui.isOpen);
|
||||||
|
|
||||||
if (totalStories > 0 && !ui.isOpen && !ui.notificationInitialCallbackMade) {
|
if (totalStories > 0 && !ui.isOpen && !ui.notificationInitialCallbackMade[0]) {
|
||||||
message = "There " + (totalStories === 1 ? "is " : "are ") + totalStories + " event" +
|
message = "There " + (totalStories === 1 ? "is " : "are ") + totalStories + " event" +
|
||||||
(totalStories === 1 ? "" : "s") + " to know about. " +
|
(totalStories === 1 ? "" : "s") + " to know about. " +
|
||||||
"Open GOTO to see " + (totalStories === 1 ? "it" : "them") + ".";
|
"Open GOTO to see " + (totalStories === 1 ? "it" : "them") + ".";
|
||||||
|
@ -122,12 +122,12 @@ function startup() {
|
||||||
sortOrder: 8,
|
sortOrder: 8,
|
||||||
onOpened: gotoOpened,
|
onOpened: gotoOpened,
|
||||||
home: GOTO_QML_SOURCE,
|
home: GOTO_QML_SOURCE,
|
||||||
notificationPollEndpoint: endpoint,
|
notificationPollEndpoint: [endpoint],
|
||||||
notificationPollTimeoutMs: 60000,
|
notificationPollTimeoutMs: [60000],
|
||||||
notificationDataProcessPage: notificationDataProcessPage,
|
notificationDataProcessPage: [notificationDataProcessPage],
|
||||||
notificationPollCallback: notificationPollCallback,
|
notificationPollCallback: [notificationPollCallback],
|
||||||
notificationPollStopPaginatingConditionMet: isReturnedDataEmpty,
|
notificationPollStopPaginatingConditionMet: [isReturnedDataEmpty],
|
||||||
notificationPollCaresAboutSince: false
|
notificationPollCaresAboutSince: [false]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue