mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 14:12:50 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into brown
This commit is contained in:
commit
8ec9c8502d
28 changed files with 2676 additions and 459 deletions
|
@ -662,7 +662,7 @@ Rectangle {
|
|||
anchors.right: parent.right;
|
||||
text: "Cancel"
|
||||
onClicked: {
|
||||
sendToScript({method: 'checkout_cancelClicked', params: itemId});
|
||||
sendToScript({method: 'checkout_cancelClicked', itemId: itemId});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,11 +24,8 @@ Item {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string referrerURL: (Account.metaverseServerURL + "/marketplace?");
|
||||
readonly property int additionalDropdownHeight: usernameDropdown.height - myUsernameButton.anchors.bottomMargin;
|
||||
property alias usernameDropdownVisible: usernameDropdown.visible;
|
||||
|
||||
height: mainContainer.height + additionalDropdownHeight;
|
||||
height: mainContainer.height;
|
||||
|
||||
Connections {
|
||||
target: Commerce;
|
||||
|
@ -93,77 +90,7 @@ Item {
|
|||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
sendToParent({method: "header_marketplaceImageClicked", referrerURL: root.referrerURL});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: buttonAndUsernameContainer;
|
||||
anchors.left: marketplaceHeaderImage.right;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 10;
|
||||
anchors.right: securityImage.left;
|
||||
anchors.rightMargin: 6;
|
||||
|
||||
TextMetrics {
|
||||
id: textMetrics;
|
||||
font.family: "Raleway"
|
||||
text: usernameText.text;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: myUsernameButton;
|
||||
anchors.right: parent.right;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
height: 40;
|
||||
width: usernameText.width + 25;
|
||||
color: "white";
|
||||
radius: 4;
|
||||
border.width: 1;
|
||||
border.color: hifi.colors.lightGray;
|
||||
|
||||
// Username Text
|
||||
RalewayRegular {
|
||||
id: usernameText;
|
||||
text: Account.username;
|
||||
// Text size
|
||||
size: 18;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
elide: Text.ElideRight;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
width: Math.min(textMetrics.width + 25, 110);
|
||||
// Anchors
|
||||
anchors.centerIn: parent;
|
||||
rightPadding: 10;
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
id: dropdownIcon;
|
||||
text: hifi.glyphs.caratDn;
|
||||
// Size
|
||||
size: 50;
|
||||
// Anchors
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: -14;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
usernameDropdown.visible = !usernameDropdown.visible;
|
||||
}
|
||||
onEntered: usernameText.color = hifi.colors.baseGrayShadow;
|
||||
onExited: usernameText.color = hifi.colors.baseGray;
|
||||
sendToParent({method: "header_marketplaceImageClicked"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -205,92 +132,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: usernameDropdown;
|
||||
z: 998;
|
||||
visible: false;
|
||||
anchors.top: buttonAndUsernameContainer.bottom;
|
||||
anchors.topMargin: -buttonAndUsernameContainer.anchors.bottomMargin;
|
||||
anchors.right: buttonAndUsernameContainer.right;
|
||||
height: childrenRect.height;
|
||||
width: 150;
|
||||
|
||||
Rectangle {
|
||||
id: myItemsButton;
|
||||
color: hifi.colors.white;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 50;
|
||||
|
||||
RalewaySemiBold {
|
||||
anchors.fill: parent;
|
||||
text: "My Submissions"
|
||||
color: hifi.colors.baseGray;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
size: 18;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
onEntered: {
|
||||
myItemsButton.color = hifi.colors.blueHighlight;
|
||||
}
|
||||
onExited: {
|
||||
myItemsButton.color = hifi.colors.white;
|
||||
}
|
||||
onClicked: {
|
||||
sendToParent({method: "header_myItemsClicked"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: logOutButton;
|
||||
color: hifi.colors.white;
|
||||
anchors.top: myItemsButton.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 50;
|
||||
|
||||
RalewaySemiBold {
|
||||
anchors.fill: parent;
|
||||
text: "Log Out"
|
||||
color: hifi.colors.baseGray;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
size: 18;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
onEntered: {
|
||||
logOutButton.color = hifi.colors.blueHighlight;
|
||||
}
|
||||
onExited: {
|
||||
logOutButton.color = hifi.colors.white;
|
||||
}
|
||||
onClicked: {
|
||||
Account.logOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
z: 997;
|
||||
visible: usernameDropdown.visible;
|
||||
anchors.fill: usernameDropdown;
|
||||
horizontalOffset: 3;
|
||||
verticalOffset: 3;
|
||||
radius: 8.0;
|
||||
samples: 17;
|
||||
color: "#80000000";
|
||||
source: usernameDropdown;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ Rectangle {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string marketplaceUrl: "";
|
||||
property string entityId: "";
|
||||
property string certificateId: "";
|
||||
property string itemName: "--";
|
||||
|
@ -30,6 +29,7 @@ Rectangle {
|
|||
property string itemEdition: "--";
|
||||
property string dateAcquired: "--";
|
||||
property string itemCost: "--";
|
||||
property string marketplace_item_id: "";
|
||||
property string certTitleTextColor: hifi.colors.darkGray;
|
||||
property string certTextColor: hifi.colors.white;
|
||||
property string infoTextColor: hifi.colors.blueAccent;
|
||||
|
@ -69,7 +69,7 @@ Rectangle {
|
|||
errorText.text = "Information about this certificate is currently unavailable. Please try again later.";
|
||||
}
|
||||
} else {
|
||||
root.marketplaceUrl = result.data.marketplace_item_url;
|
||||
root.marketplace_item_id = result.data.marketplace_item_id;
|
||||
root.isMyCert = result.isMyCert ? result.isMyCert : false;
|
||||
|
||||
if (root.certInfoReplaceMode > 3) {
|
||||
|
@ -352,7 +352,7 @@ Rectangle {
|
|||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', marketplaceUrl: root.marketplaceUrl});
|
||||
sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', itemId: root.marketplace_item_id});
|
||||
}
|
||||
onEntered: itemName.color = hifi.colors.blueHighlight;
|
||||
onExited: itemName.color = root.certTextColor;
|
||||
|
@ -391,7 +391,7 @@ Rectangle {
|
|||
// "Show In Marketplace" button
|
||||
HifiControlsUit.Button {
|
||||
id: showInMarketplaceButton;
|
||||
enabled: root.marketplaceUrl;
|
||||
enabled: root.marketplace_item_id && marketplace_item_id !== "";
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
@ -401,7 +401,7 @@ Rectangle {
|
|||
height: 40;
|
||||
text: "View In Market"
|
||||
onClicked: {
|
||||
sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', marketplaceUrl: root.marketplaceUrl});
|
||||
sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', itemId: root.marketplace_item_id});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -620,7 +620,7 @@ Rectangle {
|
|||
root.itemOwner = "--";
|
||||
root.itemEdition = "--";
|
||||
root.dateAcquired = "--";
|
||||
root.marketplaceUrl = "";
|
||||
root.marketplace_item_id = "";
|
||||
root.itemCost = "--";
|
||||
root.isMyCert = false;
|
||||
errorText.text = "";
|
||||
|
|
1216
interface/resources/qml/hifi/commerce/marketplace/Marketplace.qml
Normal file
1216
interface/resources/qml/hifi/commerce/marketplace/Marketplace.qml
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,648 @@
|
|||
//
|
||||
// MarketplaceListItem.qml
|
||||
// qml/hifi/commerce/marketplace
|
||||
//
|
||||
// MarketplaceListItem
|
||||
//
|
||||
// Created by Roxanne Skelly on 2019-01-22
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import Hifi 1.0 as Hifi
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtWebEngine 1.5
|
||||
import stylesUit 1.0
|
||||
import controlsUit 1.0 as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
import "../common" as HifiCommerceCommon
|
||||
import "qrc:////qml//hifi//models" as HifiModels // Absolute path so the same code works everywhere.
|
||||
import "../common/sendAsset"
|
||||
import "../.." as HifiCommon
|
||||
|
||||
Rectangle {
|
||||
id: root;
|
||||
|
||||
property string item_id: ""
|
||||
property string image_url: ""
|
||||
property string name: ""
|
||||
property int likes: 0
|
||||
property bool liked: false
|
||||
property string creator: ""
|
||||
property var categories: []
|
||||
property int price: 0
|
||||
property var attributions: []
|
||||
property string description: ""
|
||||
property string license: ""
|
||||
property string posted: ""
|
||||
property bool available: false
|
||||
property string created_at: ""
|
||||
property bool isLoggedIn: false;
|
||||
property int edition: -1;
|
||||
property bool supports3DHTML: false;
|
||||
|
||||
|
||||
onCategoriesChanged: {
|
||||
categoriesListModel.clear();
|
||||
categories.forEach(function(category) {
|
||||
categoriesListModel.append({"category":category});
|
||||
});
|
||||
}
|
||||
|
||||
onDescriptionChanged: {
|
||||
|
||||
if(root.supports3DHTML) {
|
||||
descriptionTextModel.clear();
|
||||
descriptionTextModel.append({text: description});
|
||||
} else {
|
||||
descriptionText.text = description;
|
||||
}
|
||||
}
|
||||
|
||||
onAttributionsChanged: {
|
||||
attributionsModel.clear();
|
||||
if(root.attributions) {
|
||||
root.attributions.forEach(function(attribution) {
|
||||
attributionsModel.append(attribution);
|
||||
});
|
||||
}
|
||||
footer.evalHeight();
|
||||
}
|
||||
|
||||
signal buy()
|
||||
signal categoryClicked(string category)
|
||||
signal showLicense(string url)
|
||||
|
||||
HifiConstants {
|
||||
id: hifi
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: MarketplaceScriptingInterface
|
||||
|
||||
onMarketplaceItemLikeResult: {
|
||||
if (result.status !== 'success') {
|
||||
console.log("Like/Unlike item", result.data.message);
|
||||
} else {
|
||||
root.liked = !root.liked;
|
||||
root.likes = root.liked ? root.likes + 1 : root.likes - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
function getFormattedDate(timestamp) {
|
||||
function addLeadingZero(n) {
|
||||
return n < 10 ? '0' + n : '' + n;
|
||||
}
|
||||
|
||||
var a = new Date(timestamp);
|
||||
|
||||
var year = a.getFullYear();
|
||||
var month = addLeadingZero(a.getMonth() + 1);
|
||||
var day = addLeadingZero(a.getDate());
|
||||
var hour = a.getHours();
|
||||
var drawnHour = hour;
|
||||
if (hour === 0) {
|
||||
drawnHour = 12;
|
||||
} else if (hour > 12) {
|
||||
drawnHour -= 12;
|
||||
}
|
||||
drawnHour = addLeadingZero(drawnHour);
|
||||
|
||||
var amOrPm = "AM";
|
||||
if (hour >= 12) {
|
||||
amOrPm = "PM";
|
||||
}
|
||||
|
||||
var min = addLeadingZero(a.getMinutes());
|
||||
var sec = addLeadingZero(a.getSeconds());
|
||||
return a.toDateString() + " " + drawnHour + ':' + min + amOrPm;
|
||||
}
|
||||
function evalHeight() {
|
||||
height = footer.y - header.y + footer.height;
|
||||
}
|
||||
|
||||
signal resized()
|
||||
|
||||
onHeightChanged: {
|
||||
resized();
|
||||
}
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: 15
|
||||
rightMargin: 15
|
||||
}
|
||||
height: footer.y - header.y + footer.height
|
||||
|
||||
Rectangle {
|
||||
id: header
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
height: 50
|
||||
|
||||
RalewaySemiBold {
|
||||
id: nameText
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
}
|
||||
width: paintedWidth
|
||||
|
||||
text: root.name
|
||||
size: 24
|
||||
color: hifi.colors.baseGray
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
Item {
|
||||
id: likes
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
rightMargin: 5
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: heart
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
rightMargin: 0
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
text: "\u2665"
|
||||
size: 20
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: root.liked ? hifi.colors.redAccent : hifi.colors.lightGrayText
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: likesText
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: heart.left
|
||||
rightMargin: 5
|
||||
leftMargin: 15
|
||||
bottom: parent.bottom
|
||||
}
|
||||
width: paintedWidth
|
||||
|
||||
text: root.likes
|
||||
size: hifi.fontSizes.overlayTitle
|
||||
color: hifi.colors.baseGray
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors {
|
||||
left: likesText.left
|
||||
right: heart.right
|
||||
top: likesText.top
|
||||
bottom: likesText.bottom
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if (isLoggedIn) {
|
||||
MarketplaceScriptingInterface.marketplaceItemLike(root.item_id, !root.liked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: itemImage
|
||||
|
||||
anchors {
|
||||
top: header.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
height: width*0.5625
|
||||
|
||||
source: root.image_url
|
||||
fillMode: Image.PreserveAspectCrop;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: footer
|
||||
|
||||
anchors {
|
||||
left: parent.left;
|
||||
right: parent.right;
|
||||
top: itemImage.bottom;
|
||||
}
|
||||
height: categoriesList.y - buyButton.y + categoriesList.height
|
||||
|
||||
function evalHeight() {
|
||||
height = categoriesList.y - buyButton.y + categoriesList.height;
|
||||
console.log("HEIGHT: " + height);
|
||||
}
|
||||
|
||||
HifiControlsUit.Button {
|
||||
id: buyButton
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
topMargin: 15
|
||||
}
|
||||
height: 50
|
||||
|
||||
text: root.edition >= 0 ? "UPGRADE FOR FREE" : (root.available ? (root.price ? root.price : "FREE") : "UNAVAILABLE (not for sale)")
|
||||
enabled: root.edition >= 0 || root.available
|
||||
buttonGlyph: root.available ? (root.price ? hifi.glyphs.hfc : "") : ""
|
||||
color: hifi.buttons.blue
|
||||
|
||||
onClicked: root.buy();
|
||||
}
|
||||
|
||||
Item {
|
||||
id: creatorItem
|
||||
|
||||
anchors {
|
||||
top: buyButton.bottom
|
||||
leftMargin: 15
|
||||
topMargin: 15
|
||||
}
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
RalewaySemiBold {
|
||||
id: creatorLabel
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
width: paintedWidth
|
||||
|
||||
text: "CREATOR:"
|
||||
size: 14
|
||||
color: hifi.colors.lightGrayText
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: creatorText
|
||||
|
||||
anchors {
|
||||
top: creatorLabel.bottom
|
||||
left: parent.left
|
||||
topMargin: 10
|
||||
}
|
||||
width: paintedWidth
|
||||
text: root.creator
|
||||
|
||||
size: 18
|
||||
color: hifi.colors.blueHighlight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: posted
|
||||
|
||||
anchors {
|
||||
top: creatorItem.bottom
|
||||
leftMargin: 15
|
||||
topMargin: 15
|
||||
}
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
RalewaySemiBold {
|
||||
id: postedLabel
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
width: paintedWidth
|
||||
|
||||
text: "POSTED:"
|
||||
size: 14
|
||||
color: hifi.colors.lightGrayText
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: created_at
|
||||
|
||||
anchors {
|
||||
top: postedLabel.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
topMargin: 5
|
||||
}
|
||||
|
||||
text: { getFormattedDate(root.created_at); }
|
||||
size: 14
|
||||
color: hifi.colors.lightGray
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
||||
anchors {
|
||||
top: posted.bottom
|
||||
leftMargin: 15
|
||||
topMargin: 15
|
||||
}
|
||||
width: parent.width
|
||||
height: 1
|
||||
|
||||
color: hifi.colors.lightGrayText
|
||||
}
|
||||
|
||||
Item {
|
||||
id: attributions
|
||||
|
||||
anchors {
|
||||
top: posted.bottom
|
||||
topMargin: 30
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
width: parent.width
|
||||
height: attributionsModel.count > 0 ? childrenRect.height : 0
|
||||
visible: attributionsModel.count > 0
|
||||
|
||||
RalewaySemiBold {
|
||||
id: attributionsLabel
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
width: paintedWidth
|
||||
height: paintedHeight
|
||||
|
||||
text: "ATTRIBUTIONS:"
|
||||
size: 14
|
||||
color: hifi.colors.lightGrayText
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
ListModel {
|
||||
id: attributionsModel
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: attributionsLabel.bottom
|
||||
bottomMargin: 15
|
||||
}
|
||||
|
||||
height: 24*model.count+10
|
||||
|
||||
model: attributionsModel
|
||||
delegate: Item {
|
||||
height: 24
|
||||
width: parent.width
|
||||
RalewaySemiBold {
|
||||
id: attributionName
|
||||
|
||||
anchors.leftMargin: 15
|
||||
height: 24
|
||||
width: parent.width
|
||||
|
||||
text: model.name
|
||||
elide: Text.ElideRight
|
||||
size: 14
|
||||
|
||||
color: model.link ? hifi.colors.blueHighlight : hifi.colors.baseGray
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
onClicked: {
|
||||
if (model.link) {
|
||||
sendToScript({method: 'marketplace_open_link', link: model.link});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
|
||||
anchors {
|
||||
bottom: attributions.bottom
|
||||
leftMargin: 15
|
||||
}
|
||||
width: parent.width
|
||||
height: 1
|
||||
|
||||
color: hifi.colors.lightGrayText
|
||||
}
|
||||
}
|
||||
Item {
|
||||
id: licenseItem;
|
||||
|
||||
anchors {
|
||||
top: attributions.bottom
|
||||
left: parent.left
|
||||
topMargin: 15
|
||||
}
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
RalewaySemiBold {
|
||||
id: licenseLabel
|
||||
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
width: paintedWidth;
|
||||
|
||||
text: "SHARED UNDER:";
|
||||
size: 14;
|
||||
color: hifi.colors.lightGrayText;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: licenseText
|
||||
|
||||
anchors.top: licenseLabel.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.topMargin: 5
|
||||
width: paintedWidth
|
||||
|
||||
text: root.license
|
||||
size: 14
|
||||
color: hifi.colors.lightGray
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: licenseHelp
|
||||
|
||||
anchors.top: licenseText.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.topMargin: 5
|
||||
width: paintedWidth
|
||||
|
||||
text: "More about this license"
|
||||
size: 14
|
||||
color: hifi.colors.blueHighlight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
onClicked: {
|
||||
licenseInfo.visible = true;
|
||||
var url;
|
||||
if (root.license === "No Rights Reserved (CC0)") {
|
||||
url = "https://creativecommons.org/publicdomain/zero/1.0/"
|
||||
} else if (root.license === "Attribution (CC BY)") {
|
||||
url = "https://creativecommons.org/licenses/by/4.0/legalcode.txt"
|
||||
} else if (root.license === "Attribution-ShareAlike (CC BY-SA)") {
|
||||
url = "https://creativecommons.org/licenses/by-sa/4.0/legalcode.txt"
|
||||
} else if (root.license === "Attribution-NoDerivs (CC BY-ND)") {
|
||||
url = "https://creativecommons.org/licenses/by-nd/4.0/legalcode.txt"
|
||||
} else if (root.license === "Attribution-NonCommercial (CC BY-NC)") {
|
||||
url = "https://creativecommons.org/licenses/by-nc/4.0/legalcode.txt"
|
||||
} else if (root.license === "Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)") {
|
||||
url = "https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.txt"
|
||||
} else if (root.license === "Attribution-NonCommercial-NoDerivs (CC BY-NC-ND)") {
|
||||
url = "https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode.txt"
|
||||
} else if (root.license === "Proof of Provenance License (PoP License)") {
|
||||
url = "https://digitalassetregistry.com/PoP-License/v1/"
|
||||
}
|
||||
if(url) {
|
||||
showLicense(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: descriptionItem
|
||||
property string text: ""
|
||||
|
||||
anchors {
|
||||
top: licenseItem.bottom
|
||||
topMargin: 15
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
height: childrenRect.height
|
||||
onHeightChanged: {
|
||||
footer.evalHeight();
|
||||
}
|
||||
RalewaySemiBold {
|
||||
id: descriptionLabel
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
width: paintedWidth
|
||||
height: 20
|
||||
|
||||
text: "DESCRIPTION:"
|
||||
size: 14
|
||||
color: hifi.colors.lightGrayText
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: descriptionText
|
||||
|
||||
anchors.top: descriptionLabel.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.topMargin: 5
|
||||
width: parent.width
|
||||
|
||||
text: root.description
|
||||
size: 14
|
||||
color: hifi.colors.lightGray
|
||||
linkColor: hifi.colors.blueHighlight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
textFormat: Text.RichText
|
||||
wrapMode: Text.Wrap
|
||||
onLinkActivated: {
|
||||
sendToScript({method: 'marketplace_open_link', link: link});
|
||||
}
|
||||
|
||||
onHeightChanged: { footer.evalHeight(); }
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: categoriesList
|
||||
|
||||
anchors {
|
||||
top: descriptionItem.bottom
|
||||
topMargin: 15
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
width: parent.width
|
||||
height: categoriesListModel.count*24 + categoryLabel.height + (isLoggedIn ? 50 : 150)
|
||||
|
||||
onHeightChanged: { footer.evalHeight(); }
|
||||
|
||||
RalewaySemiBold {
|
||||
id: categoryLabel
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
width: paintedWidth
|
||||
|
||||
text: "IN:"
|
||||
size: 14
|
||||
color: hifi.colors.lightGrayText
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
ListModel {
|
||||
id: categoriesListModel
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: categoryLabel.bottom
|
||||
bottomMargin: 15
|
||||
}
|
||||
|
||||
height: 24*model.count+10
|
||||
|
||||
model: categoriesListModel
|
||||
delegate: RalewaySemiBold {
|
||||
id: categoryText
|
||||
|
||||
anchors.leftMargin: 15
|
||||
width: paintedWidth
|
||||
|
||||
text: model.category
|
||||
size: 14
|
||||
height: 24
|
||||
color: hifi.colors.blueHighlight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: categoryText
|
||||
|
||||
onClicked: root.categoryClicked(model.category);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,321 @@
|
|||
//
|
||||
// MarketplaceListItem.qml
|
||||
// qml/hifi/commerce/marketplace
|
||||
//
|
||||
// MarketplaceListItem
|
||||
//
|
||||
// Created by Roxanne Skelly on 2019-01-22
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import Hifi 1.0 as Hifi
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
import stylesUit 1.0
|
||||
import controlsUit 1.0 as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
import "../common" as HifiCommerceCommon
|
||||
import "qrc:////qml//hifi//models" as HifiModels // Absolute path so the same code works everywhere.
|
||||
import "../common/sendAsset"
|
||||
import "../.." as HifiCommon
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property string item_id: ""
|
||||
property string image_url: ""
|
||||
property string name: ""
|
||||
property int likes: 0
|
||||
property bool liked: false
|
||||
property string creator: ""
|
||||
property string category: ""
|
||||
property int price: 0
|
||||
property bool available: false
|
||||
property bool isLoggedIn: false;
|
||||
|
||||
signal buy()
|
||||
signal showItem()
|
||||
signal categoryClicked(string category)
|
||||
signal requestReload()
|
||||
|
||||
HifiConstants { id: hifi }
|
||||
|
||||
width: parent.width
|
||||
height: childrenRect.height+50
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: shadowBase
|
||||
|
||||
source: shadowBase
|
||||
verticalOffset: 4
|
||||
horizontalOffset: 4
|
||||
radius: 6
|
||||
samples: 9
|
||||
color: hifi.colors.baseGrayShadow
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: shadowBase
|
||||
|
||||
anchors.fill: itemRect
|
||||
|
||||
color: "white"
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: itemRect
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
topMargin: 20
|
||||
bottomMargin: 10
|
||||
leftMargin: 15
|
||||
rightMargin: 15
|
||||
}
|
||||
height: childrenRect.height
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: root.showItem();
|
||||
onEntered: hoverRect.visible = true;
|
||||
onExited: hoverRect.visible = false;
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: header
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
height: 50
|
||||
|
||||
RalewaySemiBold {
|
||||
id: nameText
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
rightMargin: 50
|
||||
leftMargin: 15
|
||||
bottom: parent.bottom
|
||||
}
|
||||
width: paintedWidth
|
||||
|
||||
text: root.name
|
||||
size: hifi.fontSizes.overlayTitle
|
||||
elide: Text.ElideRight
|
||||
color: hifi.colors.blueHighlight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
Item {
|
||||
id: likes
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
rightMargin: 15
|
||||
bottom: parent.bottom
|
||||
}
|
||||
width: heart.width + likesText.width
|
||||
|
||||
Connections {
|
||||
target: MarketplaceScriptingInterface
|
||||
|
||||
onMarketplaceItemLikeResult: {
|
||||
if (result.status !== 'success') {
|
||||
console.log("Failed to get Marketplace Categories", result.data.message);
|
||||
root.requestReload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: heart
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
rightMargin: 0
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
text: "\u2665"
|
||||
size: 20
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
color: root.liked ? hifi.colors.redAccent : hifi.colors.lightGrayText
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: likesText
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: heart.left
|
||||
rightMargin: 5
|
||||
leftMargin: 15
|
||||
bottom: parent.bottom
|
||||
}
|
||||
width: paintedWidth
|
||||
|
||||
text: root.likes
|
||||
size: hifi.fontSizes.overlayTitle
|
||||
color: hifi.colors.baseGray
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors {
|
||||
left: likesText.left
|
||||
right: heart.right
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
onClicked: {
|
||||
if (isLoggedIn) {
|
||||
root.liked = !root.liked;
|
||||
root.likes = root.liked ? root.likes + 1 : root.likes - 1;
|
||||
MarketplaceScriptingInterface.marketplaceItemLike(root.item_id, root.liked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: itemImage
|
||||
|
||||
anchors {
|
||||
top: header.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
height: width * 0.5625
|
||||
|
||||
source: root.image_url
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
}
|
||||
|
||||
Item {
|
||||
id: footer
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: itemImage.bottom
|
||||
}
|
||||
height: 60
|
||||
|
||||
RalewaySemiBold {
|
||||
id: creatorLabel
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
leftMargin: 15
|
||||
}
|
||||
width: paintedWidth
|
||||
|
||||
text: "CREATOR:"
|
||||
size: 14
|
||||
color: hifi.colors.lightGrayText
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: creatorText
|
||||
|
||||
anchors {
|
||||
top: creatorLabel.top;
|
||||
left: creatorLabel.right;
|
||||
leftMargin: 15;
|
||||
}
|
||||
width: paintedWidth;
|
||||
|
||||
text: root.creator;
|
||||
size: 14;
|
||||
color: hifi.colors.lightGray;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: categoryLabel
|
||||
|
||||
anchors {
|
||||
top: creatorLabel.bottom
|
||||
left: parent.left
|
||||
leftMargin: 15
|
||||
}
|
||||
width: paintedWidth;
|
||||
|
||||
text: "IN:";
|
||||
size: 14;
|
||||
color: hifi.colors.lightGrayText;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: categoryText
|
||||
|
||||
anchors {
|
||||
top: categoryLabel.top
|
||||
left: categoryLabel.right
|
||||
leftMargin: 15
|
||||
}
|
||||
width: paintedWidth
|
||||
|
||||
text: root.category
|
||||
size: 14
|
||||
color: hifi.colors.blueHighlight;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
onClicked: root.categoryClicked(root.category);
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Button {
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
rightMargin: 15
|
||||
topMargin:10
|
||||
bottomMargin: 10
|
||||
}
|
||||
|
||||
text: root.price ? root.price : "FREE"
|
||||
buttonGlyph: root.price ? hifi.glyphs.hfc : ""
|
||||
color: hifi.buttons.blue;
|
||||
|
||||
onClicked: root.buy();
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: hoverRect
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
border.color: hifi.colors.blueHighlight
|
||||
border.width: 2
|
||||
color: "#00000000"
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// SortButton.qml
|
||||
// qml/hifi/commerce/marketplace
|
||||
//
|
||||
// SortButton
|
||||
//
|
||||
// Created by Roxanne Skelly on 2019-01-18
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import Hifi 1.0 as Hifi
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
import stylesUit 1.0
|
||||
import controlsUit 1.0 as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
import "../common" as HifiCommerceCommon
|
||||
import "qrc:////qml//hifi//models" as HifiModels // Absolute path so the same code works everywhere.
|
||||
import "../common/sendAsset"
|
||||
import "../.." as HifiCommon
|
||||
|
||||
Item {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
|
||||
|
||||
property string glyph: "";
|
||||
property string text: "";
|
||||
property bool checked: false;
|
||||
signal clicked();
|
||||
|
||||
width: childrenRect.width;
|
||||
height: parent.height;
|
||||
|
||||
Rectangle {
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
height: parent.height;
|
||||
width: 2;
|
||||
color: hifi.colors.faintGray;
|
||||
visible: index > 0;
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
id: buttonGlyph;
|
||||
text: root.glyph;
|
||||
// Size
|
||||
size: 14;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 0;
|
||||
anchors.top: parent.top;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
height: parent.height;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
// Style
|
||||
color: hifi.colors.lightGray;
|
||||
}
|
||||
RalewayRegular {
|
||||
id: buttonText;
|
||||
text: root.text;
|
||||
// Text size
|
||||
size: 14;
|
||||
// Style
|
||||
color: hifi.colors.lightGray;
|
||||
elide: Text.ElideRight;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
anchors.top: parent.top;
|
||||
height: parent.height;
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ Item {
|
|||
property string purchaseStatus;
|
||||
property string itemName;
|
||||
property string itemId;
|
||||
property string updateItemId;
|
||||
property string itemPreviewImageUrl;
|
||||
property string itemHref;
|
||||
property string certificateId;
|
||||
|
@ -45,9 +46,9 @@ Item {
|
|||
property bool cardBackVisible;
|
||||
property bool isInstalled;
|
||||
property string wornEntityID;
|
||||
property string upgradeUrl;
|
||||
property string updatedItemId;
|
||||
property string upgradeTitle;
|
||||
property bool updateAvailable: root.upgradeUrl !== "";
|
||||
property bool updateAvailable: root.updateItemId && root.updateItemId !== "";
|
||||
property bool valid;
|
||||
|
||||
property string originalStatusText;
|
||||
|
@ -175,7 +176,7 @@ Item {
|
|||
|
||||
Item {
|
||||
property alias buttonGlyphText: buttonGlyph.text;
|
||||
property alias buttonText: buttonText.text;
|
||||
property alias itemButtonText: buttonText.text;
|
||||
property alias glyphSize: buttonGlyph.size;
|
||||
property string buttonColor: hifi.colors.black;
|
||||
property string buttonColor_hover: hifi.colors.blueHighlight;
|
||||
|
@ -243,7 +244,7 @@ Item {
|
|||
onLoaded: {
|
||||
item.enabled = root.valid;
|
||||
item.buttonGlyphText = hifi.glyphs.gift;
|
||||
item.buttonText = "Gift";
|
||||
item.itemButtonText = "Gift";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
sendToPurchases({
|
||||
|
@ -270,7 +271,7 @@ Item {
|
|||
|
||||
onLoaded: {
|
||||
item.buttonGlyphText = hifi.glyphs.market;
|
||||
item.buttonText = "View in Marketplace";
|
||||
item.itemButtonText = "View in Marketplace";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
|
||||
|
@ -288,7 +289,7 @@ Item {
|
|||
|
||||
onLoaded: {
|
||||
item.buttonGlyphText = hifi.glyphs.certificate;
|
||||
item.buttonText = "View Certificate";
|
||||
item.itemButtonText = "View Certificate";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
sendToPurchases({method: 'purchases_itemCertificateClicked', itemCertificateId: root.certificateId});
|
||||
|
@ -307,7 +308,7 @@ Item {
|
|||
|
||||
onLoaded: {
|
||||
item.buttonGlyphText = hifi.glyphs.uninstall;
|
||||
item.buttonText = "Uninstall";
|
||||
item.itemButtonText = "Uninstall";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
Commerce.uninstallApp(root.itemHref);
|
||||
|
@ -330,15 +331,14 @@ Item {
|
|||
|
||||
onLoaded: {
|
||||
item.buttonGlyphText = hifi.glyphs.update;
|
||||
item.buttonText = "Update";
|
||||
item.itemButtonText = "Update";
|
||||
item.buttonColor = "#E2334D";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
sendToPurchases({
|
||||
method: 'updateItemClicked',
|
||||
itemId: root.itemId,
|
||||
itemId: root.updateAvailable ? root.updateItemId : root.itemId,
|
||||
itemEdition: root.itemEdition,
|
||||
upgradeUrl: root.upgradeUrl,
|
||||
itemHref: root.itemHref,
|
||||
itemType: root.itemType,
|
||||
isInstalled: root.isInstalled,
|
||||
|
@ -378,10 +378,10 @@ Item {
|
|||
|
||||
function updateProperties() {
|
||||
if (updateButton.visible && uninstallButton.visible) {
|
||||
item.buttonText = "";
|
||||
item.itemButtonText = "";
|
||||
item.glyphSize = 20;
|
||||
} else {
|
||||
item.buttonText = "Send to Trash";
|
||||
item.itemButtonText = "Send to Trash";
|
||||
item.glyphSize = 30;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ Rectangle {
|
|||
|
||||
id: root;
|
||||
property string activeView: "initialize";
|
||||
property string referrerURL: "";
|
||||
property bool securityImageResultReceived: false;
|
||||
property bool purchasesReceived: false;
|
||||
property bool punctuationMode: false;
|
||||
|
@ -154,55 +153,10 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TITLE BAR START
|
||||
//
|
||||
HifiCommerceCommon.EmulatedMarketplaceHeader {
|
||||
id: titleBarContainer;
|
||||
z: 997;
|
||||
visible: false;
|
||||
height: 100;
|
||||
// Size
|
||||
width: parent.width;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
||||
Connections {
|
||||
onSendToParent: {
|
||||
if (msg.method === 'needsLogIn' && root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
} else if (msg.method === 'showSecurityPicLightbox') {
|
||||
lightboxPopup.titleText = "Your Security Pic";
|
||||
lightboxPopup.bodyImageSource = msg.securityImageSource;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
enabled: titleBarContainer.usernameDropdownVisible;
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
titleBarContainer.usernameDropdownVisible = false;
|
||||
}
|
||||
}
|
||||
//
|
||||
// TITLE BAR END
|
||||
//
|
||||
|
||||
Rectangle {
|
||||
id: initialize;
|
||||
visible: root.activeView === "initialize";
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: -titleBarContainer.additionalDropdownHeight;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
@ -219,8 +173,7 @@ Rectangle {
|
|||
id: installedAppsContainer;
|
||||
z: 998;
|
||||
visible: false;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: -titleBarContainer.additionalDropdownHeight;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width;
|
||||
|
@ -422,8 +375,8 @@ Rectangle {
|
|||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: 8 - titleBarContainer.additionalDropdownHeight;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 8;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
//
|
||||
|
@ -585,6 +538,7 @@ Rectangle {
|
|||
delegate: PurchasedItem {
|
||||
itemName: title;
|
||||
itemId: id;
|
||||
updateItemId: model.upgrade_id ? model.upgrade_id : "";
|
||||
itemPreviewImageUrl: preview;
|
||||
itemHref: download_url;
|
||||
certificateId: certificate_id;
|
||||
|
@ -596,7 +550,6 @@ Rectangle {
|
|||
cardBackVisible: model.cardBackVisible || false;
|
||||
isInstalled: model.isInstalled || false;
|
||||
wornEntityID: model.wornEntityID;
|
||||
upgradeUrl: model.upgrade_url;
|
||||
upgradeTitle: model.upgrade_title;
|
||||
itemType: model.item_type;
|
||||
valid: model.valid;
|
||||
|
@ -1083,8 +1036,6 @@ Rectangle {
|
|||
function fromScript(message) {
|
||||
switch (message.method) {
|
||||
case 'updatePurchases':
|
||||
referrerURL = message.referrerURL || "";
|
||||
titleBarContainer.referrerURL = message.referrerURL || "";
|
||||
filterBar.text = message.filterText ? message.filterText : "";
|
||||
break;
|
||||
case 'purchases_showMyItems':
|
||||
|
|
|
@ -335,7 +335,7 @@ Item {
|
|||
if (link.indexOf("users/") !== -1) {
|
||||
sendSignalToWallet({method: 'transactionHistory_usernameLinkClicked', usernameLink: link});
|
||||
} else {
|
||||
sendSignalToWallet({method: 'transactionHistory_linkClicked', marketplaceLink: link});
|
||||
sendSignalToWallet({method: 'transactionHistory_linkClicked', itemId: model.marketplace_item});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -235,6 +235,7 @@
|
|||
#include "commerce/Ledger.h"
|
||||
#include "commerce/Wallet.h"
|
||||
#include "commerce/QmlCommerce.h"
|
||||
#include "commerce/QmlMarketplace.h"
|
||||
#include "ResourceRequestObserver.h"
|
||||
|
||||
#include "webbrowser/WebBrowserSuggestionsEngine.h"
|
||||
|
@ -3008,7 +3009,23 @@ void Application::initializeUi() {
|
|||
QUrl{ "hifi/dialogs/security/SecurityImageModel.qml" },
|
||||
QUrl{ "hifi/dialogs/security/SecurityImageSelection.qml" },
|
||||
QUrl{ "hifi/tablet/TabletMenu.qml" },
|
||||
QUrl{ "hifi/commerce/marketplace/Marketplace.qml" },
|
||||
}, commerceCallback);
|
||||
|
||||
QmlContextCallback marketplaceCallback = [](QQmlContext* context) {
|
||||
context->setContextProperty("MarketplaceScriptingInterface", new QmlMarketplace());
|
||||
};
|
||||
OffscreenQmlSurface::addWhitelistContextHandler({
|
||||
QUrl{ "hifi/commerce/marketplace/Marketplace.qml" },
|
||||
}, marketplaceCallback);
|
||||
|
||||
QmlContextCallback platformInfoCallback = [](QQmlContext* context) {
|
||||
context->setContextProperty("PlatformInfo", new PlatformInfoScriptingInterface());
|
||||
};
|
||||
OffscreenQmlSurface::addWhitelistContextHandler({
|
||||
QUrl{ "hifi/commerce/marketplace/Marketplace.qml" },
|
||||
}, platformInfoCallback);
|
||||
|
||||
QmlContextCallback ttsCallback = [](QQmlContext* context) {
|
||||
context->setContextProperty("TextToSpeech", DependencyManager::get<TTSScriptingInterface>().data());
|
||||
};
|
||||
|
|
|
@ -75,7 +75,6 @@ const float PITCH_SPEED_DEFAULT = 75.0f; // degrees/sec
|
|||
|
||||
const float MAX_BOOST_SPEED = 0.5f * DEFAULT_AVATAR_MAX_WALKING_SPEED; // action motor gets additive boost below this speed
|
||||
const float MIN_AVATAR_SPEED = 0.05f;
|
||||
const float MIN_AVATAR_SPEED_SQUARED = MIN_AVATAR_SPEED * MIN_AVATAR_SPEED; // speed is set to zero below this
|
||||
|
||||
float MIN_SCRIPTED_MOTOR_TIMESCALE = 0.005f;
|
||||
float DEFAULT_SCRIPTED_MOTOR_TIMESCALE = 1.0e6f;
|
||||
|
@ -847,6 +846,7 @@ void MyAvatar::simulate(float deltaTime, bool inView) {
|
|||
|
||||
updateOrientation(deltaTime);
|
||||
updatePosition(deltaTime);
|
||||
updateViewBoom();
|
||||
}
|
||||
|
||||
// update sensorToWorldMatrix for camera and hand controllers
|
||||
|
@ -3323,21 +3323,22 @@ void MyAvatar::updateActionMotor(float deltaTime) {
|
|||
direction = Vectors::ZERO;
|
||||
}
|
||||
|
||||
float sensorToWorldScale = getSensorToWorldScale();
|
||||
if (state == CharacterController::State::Hover) {
|
||||
// we're flying --> complex acceleration curve that builds on top of current motor speed and caps at some max speed
|
||||
|
||||
float motorSpeed = glm::length(_actionMotorVelocity);
|
||||
float finalMaxMotorSpeed = getSensorToWorldScale() * DEFAULT_AVATAR_MAX_FLYING_SPEED * _walkSpeedScalar;
|
||||
float finalMaxMotorSpeed = sensorToWorldScale * DEFAULT_AVATAR_MAX_FLYING_SPEED * _walkSpeedScalar;
|
||||
float speedGrowthTimescale = 2.0f;
|
||||
float speedIncreaseFactor = 1.8f * _walkSpeedScalar;
|
||||
motorSpeed *= 1.0f + glm::clamp(deltaTime / speedGrowthTimescale, 0.0f, 1.0f) * speedIncreaseFactor;
|
||||
const float maxBoostSpeed = getSensorToWorldScale() * MAX_BOOST_SPEED;
|
||||
const float maxBoostSpeed = sensorToWorldScale * MAX_BOOST_SPEED;
|
||||
|
||||
if (_isPushing) {
|
||||
if (motorSpeed < maxBoostSpeed) {
|
||||
// an active action motor should never be slower than this
|
||||
float boostCoefficient = (maxBoostSpeed - motorSpeed) / maxBoostSpeed;
|
||||
motorSpeed += getSensorToWorldScale() * MIN_AVATAR_SPEED * boostCoefficient;
|
||||
motorSpeed += sensorToWorldScale * MIN_AVATAR_SPEED * boostCoefficient;
|
||||
} else if (motorSpeed > finalMaxMotorSpeed) {
|
||||
motorSpeed = finalMaxMotorSpeed;
|
||||
}
|
||||
|
@ -3348,45 +3349,21 @@ void MyAvatar::updateActionMotor(float deltaTime) {
|
|||
const glm::vec2 currentVel = { direction.x, direction.z };
|
||||
float scaledSpeed = scaleSpeedByDirection(currentVel, _walkSpeed.get(), _walkBackwardSpeed.get());
|
||||
// _walkSpeedScalar is a multiplier if we are in sprint mode, otherwise 1.0
|
||||
_actionMotorVelocity = getSensorToWorldScale() * (scaledSpeed * _walkSpeedScalar) * direction;
|
||||
}
|
||||
|
||||
float previousBoomLength = _boomLength;
|
||||
float boomChange = getDriveKey(ZOOM);
|
||||
_boomLength += 2.0f * _boomLength * boomChange + boomChange * boomChange;
|
||||
_boomLength = glm::clamp<float>(_boomLength, ZOOM_MIN, ZOOM_MAX);
|
||||
|
||||
// May need to change view if boom length has changed
|
||||
if (previousBoomLength != _boomLength) {
|
||||
qApp->changeViewAsNeeded(_boomLength);
|
||||
_actionMotorVelocity = sensorToWorldScale * (scaledSpeed * _walkSpeedScalar) * direction;
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::updatePosition(float deltaTime) {
|
||||
if (_motionBehaviors & AVATAR_MOTION_ACTION_MOTOR_ENABLED) {
|
||||
updateActionMotor(deltaTime);
|
||||
}
|
||||
|
||||
vec3 velocity = getWorldVelocity();
|
||||
float sensorToWorldScale = getSensorToWorldScale();
|
||||
float sensorToWorldScale2 = sensorToWorldScale * sensorToWorldScale;
|
||||
const float MOVING_SPEED_THRESHOLD_SQUARED = 0.0001f; // 0.01 m/s
|
||||
if (!_characterController.isEnabledAndReady()) {
|
||||
// _characterController is not in physics simulation but it can still compute its target velocity
|
||||
updateMotors();
|
||||
_characterController.computeNewVelocity(deltaTime, velocity);
|
||||
|
||||
float speed2 = glm::length(velocity);
|
||||
if (speed2 > sensorToWorldScale2 * MIN_AVATAR_SPEED_SQUARED) {
|
||||
// update position ourselves
|
||||
applyPositionDelta(deltaTime * velocity);
|
||||
if (_characterController.isEnabledAndReady()) {
|
||||
if (_motionBehaviors & AVATAR_MOTION_ACTION_MOTOR_ENABLED) {
|
||||
updateActionMotor(deltaTime);
|
||||
}
|
||||
measureMotionDerivatives(deltaTime);
|
||||
_moving = speed2 > sensorToWorldScale2 * MOVING_SPEED_THRESHOLD_SQUARED;
|
||||
} else {
|
||||
float sensorToWorldScale = getSensorToWorldScale();
|
||||
float sensorToWorldScale2 = sensorToWorldScale * sensorToWorldScale;
|
||||
vec3 velocity = getWorldVelocity();
|
||||
float speed2 = glm::length2(velocity);
|
||||
const float MOVING_SPEED_THRESHOLD_SQUARED = 0.0001f; // 0.01 m/s
|
||||
_moving = speed2 > sensorToWorldScale2 * MOVING_SPEED_THRESHOLD_SQUARED;
|
||||
|
||||
if (_moving) {
|
||||
// scan for walkability
|
||||
glm::vec3 position = getWorldPosition();
|
||||
|
@ -3398,6 +3375,18 @@ void MyAvatar::updatePosition(float deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
void MyAvatar::updateViewBoom() {
|
||||
float previousBoomLength = _boomLength;
|
||||
float boomChange = getDriveKey(ZOOM);
|
||||
_boomLength += 2.0f * _boomLength * boomChange + boomChange * boomChange;
|
||||
_boomLength = glm::clamp<float>(_boomLength, ZOOM_MIN, ZOOM_MAX);
|
||||
|
||||
// May need to change view if boom length has changed
|
||||
if (previousBoomLength != _boomLength) {
|
||||
qApp->changeViewAsNeeded(_boomLength);
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::updateCollisionSound(const glm::vec3 &penetration, float deltaTime, float frequency) {
|
||||
// COLLISION SOUND API in Audio has been removed
|
||||
}
|
||||
|
|
|
@ -1732,6 +1732,7 @@ private:
|
|||
void updateOrientation(float deltaTime);
|
||||
void updateActionMotor(float deltaTime);
|
||||
void updatePosition(float deltaTime);
|
||||
void updateViewBoom();
|
||||
void updateCollisionSound(const glm::vec3& penetration, float deltaTime, float frequency);
|
||||
void initHeadBones();
|
||||
void initAnimGraph();
|
||||
|
|
|
@ -54,11 +54,10 @@ void QmlCommerce::openSystemApp(const QString& appName) {
|
|||
{"GOTO", "hifi/tablet/TabletAddressDialog.qml"},
|
||||
{"PEOPLE", "hifi/Pal.qml"},
|
||||
{"WALLET", "hifi/commerce/wallet/Wallet.qml"},
|
||||
{"MARKET", "/marketplace.html"}
|
||||
{"MARKET", "hifi/commerce/marketplace/Marketplace.qml"}
|
||||
};
|
||||
|
||||
static const QMap<QString, QString> systemInject{
|
||||
{"MARKET", "/scripts/system/html/js/marketplacesInject.js"}
|
||||
};
|
||||
|
||||
|
||||
|
|
135
interface/src/commerce/QmlMarketplace.cpp
Normal file
135
interface/src/commerce/QmlMarketplace.cpp
Normal file
|
@ -0,0 +1,135 @@
|
|||
//
|
||||
// QmlMarketplace.cpp
|
||||
// interface/src/commerce
|
||||
//
|
||||
// Guard for safe use of Marketplace by authorized QML.
|
||||
//
|
||||
// Created by Roxanne Skelly on 1/18/19.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
#include "QmlMarketplace.h"
|
||||
#include "CommerceLogging.h"
|
||||
#include "Application.h"
|
||||
#include "DependencyManager.h"
|
||||
#include <Application.h>
|
||||
#include <UserActivityLogger.h>
|
||||
#include <ScriptEngines.h>
|
||||
#include <ui/TabletScriptingInterface.h>
|
||||
#include "scripting/HMDScriptingInterface.h"
|
||||
|
||||
#define ApiHandler(NAME) void QmlMarketplace::NAME##Success(QNetworkReply* reply) { emit NAME##Result(apiResponse(#NAME, reply)); }
|
||||
#define FailHandler(NAME) void QmlMarketplace::NAME##Failure(QNetworkReply* reply) { emit NAME##Result(failResponse(#NAME, reply)); }
|
||||
#define Handler(NAME) ApiHandler(NAME) FailHandler(NAME)
|
||||
Handler(getMarketplaceItems)
|
||||
Handler(getMarketplaceItem)
|
||||
Handler(marketplaceItemLike)
|
||||
Handler(getMarketplaceCategories)
|
||||
|
||||
QmlMarketplace::QmlMarketplace() {
|
||||
}
|
||||
|
||||
void QmlMarketplace::openMarketplace(const QString& marketplaceItemId) {
|
||||
auto tablet = dynamic_cast<TabletProxy*>(
|
||||
DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system"));
|
||||
tablet->loadQMLSource("hifi/commerce/marketplace/Marketplace.qml");
|
||||
DependencyManager::get<HMDScriptingInterface>()->openTablet();
|
||||
if (!marketplaceItemId.isEmpty()) {
|
||||
tablet->sendToQml(QVariantMap({ { "method", "marketplace_openItem" }, { "itemId", marketplaceItemId } }));
|
||||
}
|
||||
}
|
||||
|
||||
void QmlMarketplace::getMarketplaceItems(
|
||||
const QString& q,
|
||||
const QString& view,
|
||||
const QString& category,
|
||||
const QString& adminFilter,
|
||||
const QString& adminFilterCost,
|
||||
const QString& sort,
|
||||
const bool isFree,
|
||||
const int& page,
|
||||
const int& perPage) {
|
||||
|
||||
QString endpoint = "items";
|
||||
QUrlQuery request;
|
||||
request.addQueryItem("q", q);
|
||||
request.addQueryItem("view", view);
|
||||
request.addQueryItem("category", category);
|
||||
request.addQueryItem("adminFilter", adminFilter);
|
||||
request.addQueryItem("adminFilterCost", adminFilterCost);
|
||||
request.addQueryItem("sort", sort);
|
||||
if (isFree) {
|
||||
request.addQueryItem("isFree", "true");
|
||||
}
|
||||
request.addQueryItem("page", QString::number(page));
|
||||
request.addQueryItem("perPage", QString::number(perPage));
|
||||
send(endpoint, "getMarketplaceItemsSuccess", "getMarketplaceItemsFailure", QNetworkAccessManager::GetOperation, AccountManagerAuth::Optional, request);
|
||||
}
|
||||
|
||||
void QmlMarketplace::getMarketplaceItem(const QString& marketplaceItemId) {
|
||||
QString endpoint = QString("items/") + marketplaceItemId;
|
||||
QUrlQuery request;
|
||||
send(endpoint, "getMarketplaceItemSuccess", "getMarketplaceItemFailure", QNetworkAccessManager::GetOperation, AccountManagerAuth::Optional, request);
|
||||
}
|
||||
|
||||
void QmlMarketplace::marketplaceItemLike(const QString& marketplaceItemId, const bool like) {
|
||||
QString endpoint = QString("items/") + marketplaceItemId + "/like";
|
||||
QUrlQuery request;
|
||||
send(endpoint, "marketplaceItemLikeSuccess", "marketplaceItemLikeFailure", like ? QNetworkAccessManager::PostOperation : QNetworkAccessManager::DeleteOperation, AccountManagerAuth::Required, request);
|
||||
}
|
||||
|
||||
void QmlMarketplace::getMarketplaceCategories() {
|
||||
QString endpoint = "categories";
|
||||
QUrlQuery request;
|
||||
send(endpoint, "getMarketplaceCategoriesSuccess", "getMarketplaceCategoriesFailure", QNetworkAccessManager::GetOperation, AccountManagerAuth::None, request);
|
||||
}
|
||||
|
||||
|
||||
void QmlMarketplace::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, const QUrlQuery & request) {
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
const QString URL = "/api/v1/marketplace/";
|
||||
JSONCallbackParameters callbackParams(this, success, fail);
|
||||
|
||||
accountManager->sendRequest(URL + endpoint,
|
||||
authType,
|
||||
method,
|
||||
callbackParams,
|
||||
QByteArray(),
|
||||
NULL,
|
||||
QVariantMap(),
|
||||
request);
|
||||
|
||||
}
|
||||
|
||||
QJsonObject QmlMarketplace::apiResponse(const QString& label, QNetworkReply* reply) {
|
||||
QByteArray response = reply->readAll();
|
||||
QJsonObject data = QJsonDocument::fromJson(response).object();
|
||||
#if defined(DEV_BUILD) // Don't expose user's personal data in the wild. But during development this can be handy.
|
||||
qInfo(commerce) << label << "response" << QJsonDocument(data).toJson(QJsonDocument::Compact);
|
||||
#endif
|
||||
return data;
|
||||
}
|
||||
|
||||
// Non-200 responses are not json:
|
||||
QJsonObject QmlMarketplace::failResponse(const QString& label, QNetworkReply* reply) {
|
||||
QString response = reply->readAll();
|
||||
qWarning(commerce) << "FAILED" << label << response;
|
||||
|
||||
// tempResult will be NULL if the response isn't valid JSON.
|
||||
QJsonDocument tempResult = QJsonDocument::fromJson(response.toLocal8Bit());
|
||||
if (tempResult.isNull()) {
|
||||
QJsonObject result
|
||||
{
|
||||
{ "status", "fail" },
|
||||
{ "message", response }
|
||||
};
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return tempResult.object();
|
||||
}
|
||||
}
|
68
interface/src/commerce/QmlMarketplace.h
Normal file
68
interface/src/commerce/QmlMarketplace.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
//
|
||||
// QmlMarketplace.h
|
||||
// interface/src/commerce
|
||||
//
|
||||
// Guard for safe use of Marketplace by authorized QML.
|
||||
//
|
||||
// Created by Roxanne Skelly on 1/18/19.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef hifi_QmlMarketplace_h
|
||||
#define hifi_QmlMarketplace_h
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include "AccountManager.h"
|
||||
|
||||
class QmlMarketplace : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QmlMarketplace();
|
||||
|
||||
public slots:
|
||||
void getMarketplaceItemsSuccess(QNetworkReply* reply);
|
||||
void getMarketplaceItemsFailure(QNetworkReply* reply);
|
||||
void getMarketplaceItemSuccess(QNetworkReply* reply);
|
||||
void getMarketplaceItemFailure(QNetworkReply* reply);
|
||||
void getMarketplaceCategoriesSuccess(QNetworkReply* reply);
|
||||
void getMarketplaceCategoriesFailure(QNetworkReply* reply);
|
||||
void marketplaceItemLikeSuccess(QNetworkReply* reply);
|
||||
void marketplaceItemLikeFailure(QNetworkReply* reply);
|
||||
|
||||
protected:
|
||||
Q_INVOKABLE void openMarketplace(const QString& marketplaceItemId = QString());
|
||||
Q_INVOKABLE void getMarketplaceItems(
|
||||
const QString& q = QString(),
|
||||
const QString& view = QString(),
|
||||
const QString& category = QString(),
|
||||
const QString& adminFilter = QString("published"),
|
||||
const QString& adminFilterCost = QString(),
|
||||
const QString& sort = QString(),
|
||||
const bool isFree = false,
|
||||
const int& page = 1,
|
||||
const int& perPage = 20);
|
||||
Q_INVOKABLE void getMarketplaceItem(const QString& marketplaceItemId);
|
||||
Q_INVOKABLE void marketplaceItemLike(const QString& marketplaceItemId, const bool like = true);
|
||||
Q_INVOKABLE void getMarketplaceCategories();
|
||||
|
||||
signals:
|
||||
void getMarketplaceItemsResult(QJsonObject result);
|
||||
void getMarketplaceItemResult(QJsonObject result);
|
||||
void getMarketplaceCategoriesResult(QJsonObject result);
|
||||
void marketplaceItemLikeResult(QJsonObject result);
|
||||
|
||||
private:
|
||||
void send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, const QUrlQuery & request);
|
||||
QJsonObject apiResponse(const QString& label, QNetworkReply* reply);
|
||||
QJsonObject failResponse(const QString& label, QNetworkReply* reply);
|
||||
};
|
||||
|
||||
#endif // hifi_QmlMarketplace_h
|
|
@ -133,3 +133,11 @@ bool PlatformInfoScriptingInterface::hasRiftControllers() {
|
|||
bool PlatformInfoScriptingInterface::hasViveControllers() {
|
||||
return qApp->hasViveControllers();
|
||||
}
|
||||
|
||||
bool PlatformInfoScriptingInterface::has3DHTML() {
|
||||
#if defined(Q_OS_ANDROID)
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -65,6 +65,12 @@ public slots:
|
|||
* @function Window.hasRift
|
||||
* @returns {boolean} <code>true</code> if running on Windows, otherwise <code>false</code>.*/
|
||||
bool hasViveControllers();
|
||||
|
||||
/**jsdoc
|
||||
* Returns true if device supports 3d HTML
|
||||
* @function Window.hasRift
|
||||
* @returns {boolean} <code>true</code> if device supports 3d HTML, otherwise <code>false</code>.*/
|
||||
bool has3DHTML();
|
||||
};
|
||||
|
||||
#endif // hifi_PlatformInfoScriptingInterface_h
|
||||
|
|
|
@ -208,7 +208,7 @@ void AccountManager::setSessionID(const QUuid& sessionID) {
|
|||
}
|
||||
}
|
||||
|
||||
QNetworkRequest AccountManager::createRequest(QString path, AccountManagerAuth::Type authType) {
|
||||
QNetworkRequest AccountManager::createRequest(QString path, AccountManagerAuth::Type authType, const QUrlQuery & query) {
|
||||
QNetworkRequest networkRequest;
|
||||
networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter());
|
||||
|
@ -227,6 +227,7 @@ QNetworkRequest AccountManager::createRequest(QString path, AccountManagerAuth::
|
|||
} else {
|
||||
requestURL.setPath("/" + path);
|
||||
}
|
||||
requestURL.setQuery(query);
|
||||
|
||||
if (authType != AccountManagerAuth::None ) {
|
||||
if (hasValidAccessToken()) {
|
||||
|
@ -263,13 +264,14 @@ void AccountManager::sendRequest(const QString& path,
|
|||
Q_ARG(const JSONCallbackParameters&, callbackParams),
|
||||
Q_ARG(const QByteArray&, dataByteArray),
|
||||
Q_ARG(QHttpMultiPart*, dataMultiPart),
|
||||
Q_ARG(QVariantMap, propertyMap));
|
||||
Q_ARG(QVariantMap, propertyMap),
|
||||
Q_ARG(QUrlQuery, query));
|
||||
return;
|
||||
}
|
||||
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
|
||||
QNetworkRequest networkRequest = createRequest(path, authType);
|
||||
QNetworkRequest networkRequest = createRequest(path, authType, query);
|
||||
|
||||
if (VERBOSE_HTTP_REQUEST_DEBUGGING) {
|
||||
qCDebug(networking) << "Making a request to" << qPrintable(networkRequest.url().toString());
|
||||
|
|
|
@ -61,7 +61,7 @@ class AccountManager : public QObject, public Dependency {
|
|||
public:
|
||||
AccountManager(UserAgentGetter userAgentGetter = DEFAULT_USER_AGENT_GETTER);
|
||||
|
||||
QNetworkRequest createRequest(QString path, AccountManagerAuth::Type authType);
|
||||
QNetworkRequest createRequest(QString path, AccountManagerAuth::Type authType, const QUrlQuery & query = QUrlQuery());
|
||||
Q_INVOKABLE void sendRequest(const QString& path,
|
||||
AccountManagerAuth::Type authType,
|
||||
QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation,
|
||||
|
|
|
@ -729,12 +729,6 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVecto
|
|||
uint16_t length;
|
||||
memcpy(&length, dataBytes, sizeof(uint16_t));
|
||||
dataBytes += sizeof(length);
|
||||
|
||||
// FIXME - this size check is wrong if we allow larger packets
|
||||
if (length * sizeof(glm::vec3) > MAX_OCTREE_UNCOMRESSED_PACKET_SIZE) {
|
||||
result.resize(0);
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
result.resize(length);
|
||||
memcpy(result.data(), dataBytes, length * sizeof(glm::vec3));
|
||||
return sizeof(uint16_t) + length * sizeof(glm::vec3);
|
||||
|
@ -744,14 +738,7 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVecto
|
|||
uint16_t length;
|
||||
memcpy(&length, dataBytes, sizeof(uint16_t));
|
||||
dataBytes += sizeof(length);
|
||||
|
||||
// FIXME - this size check is wrong if we allow larger packets
|
||||
if (length * sizeof(glm::quat) > MAX_OCTREE_UNCOMRESSED_PACKET_SIZE) {
|
||||
result.resize(0);
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
result.resize(length);
|
||||
|
||||
const unsigned char *start = dataBytes;
|
||||
for (int i = 0; i < length; i++) {
|
||||
dataBytes += unpackOrientationQuatFromBytes(dataBytes, result[i]);
|
||||
|
@ -764,12 +751,6 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVecto
|
|||
uint16_t length;
|
||||
memcpy(&length, dataBytes, sizeof(uint16_t));
|
||||
dataBytes += sizeof(length);
|
||||
|
||||
// FIXME - this size check is wrong if we allow larger packets
|
||||
if (length * sizeof(float) > MAX_OCTREE_UNCOMRESSED_PACKET_SIZE) {
|
||||
result.resize(0);
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
result.resize(length);
|
||||
memcpy(result.data(), dataBytes, length * sizeof(float));
|
||||
return sizeof(uint16_t) + length * sizeof(float);
|
||||
|
@ -779,14 +760,7 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVecto
|
|||
uint16_t length;
|
||||
memcpy(&length, dataBytes, sizeof(uint16_t));
|
||||
dataBytes += sizeof(length);
|
||||
|
||||
// FIXME - this size check is wrong if we allow larger packets
|
||||
if (length / 8 > MAX_OCTREE_UNCOMRESSED_PACKET_SIZE) {
|
||||
result.resize(0);
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
result.resize(length);
|
||||
|
||||
int bit = 0;
|
||||
unsigned char current = 0;
|
||||
const unsigned char *start = dataBytes;
|
||||
|
@ -797,7 +771,6 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVecto
|
|||
result[i] = (bool)(current & (1 << bit));
|
||||
bit = (bit + 1) % BITS_IN_BYTE;
|
||||
}
|
||||
|
||||
return (dataBytes - start) + (int)sizeof(uint16_t);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,16 @@
|
|||
|
||||
#include "CrashHelpers.h"
|
||||
|
||||
#ifdef NDEBUG
|
||||
// undefine NDEBUG so doAssert() works for all builds
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
#define NDEBUG
|
||||
#else
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace crash {
|
||||
|
||||
class B;
|
||||
|
@ -34,6 +44,11 @@ A::~A() {
|
|||
_b->virtualFunction();
|
||||
}
|
||||
|
||||
// only use doAssert() for debug purposes
|
||||
void doAssert(bool value) {
|
||||
assert(value);
|
||||
}
|
||||
|
||||
void pureVirtualCall() {
|
||||
qCDebug(shared) << "About to make a pure virtual call";
|
||||
B b;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
namespace crash {
|
||||
|
||||
void doAssert(bool value); // works for Release
|
||||
void pureVirtualCall();
|
||||
void doubleFree();
|
||||
void nullDeref();
|
||||
|
|
|
@ -38,7 +38,6 @@ LogHandler::LogHandler() {
|
|||
}
|
||||
|
||||
LogHandler::~LogHandler() {
|
||||
flushRepeatedMessages();
|
||||
}
|
||||
|
||||
const char* stringForLogType(LogMsgType msgType) {
|
||||
|
|
|
@ -379,21 +379,16 @@ function deleteSendMoneyParticleEffect() {
|
|||
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;
|
||||
var MARKETPLACE_QML_PATH = "hifi/commerce/marketplace/Marketplace.qml";
|
||||
function openMarketplace(optionalItem) {
|
||||
ui.open(MARKETPLACE_QML_PATH);
|
||||
|
||||
if (optionalItem) {
|
||||
ui.tablet.sendToQml({
|
||||
method: 'updateMarketplaceQMLItem',
|
||||
params: { itemId: optionalItem }
|
||||
});
|
||||
}
|
||||
ui.open(url, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
}
|
||||
|
||||
function setCertificateInfo(itemCertificateId) {
|
||||
|
@ -425,10 +420,10 @@ function fromQml(message) {
|
|||
case 'purchases':
|
||||
case 'marketplace cta':
|
||||
case 'mainPage':
|
||||
ui.open(MARKETPLACE_URL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
openMarketplace();
|
||||
break;
|
||||
default: // User needs to return to an individual marketplace item URL
|
||||
ui.open(MARKETPLACE_URL + '/items/' + message.referrer, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
default:
|
||||
openMarketplace();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -440,13 +435,13 @@ function fromQml(message) {
|
|||
case 'maybeEnableHmdPreview':
|
||||
break; // do nothing here, handled in marketplaces.js
|
||||
case 'transactionHistory_linkClicked':
|
||||
ui.open(message.marketplaceLink, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
openMarketplace(message.itemId);
|
||||
break;
|
||||
case 'goToMarketplaceMainPage':
|
||||
ui.open(MARKETPLACE_URL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
openMarketplace();
|
||||
break;
|
||||
case 'goToMarketplaceItemPage':
|
||||
ui.open(MARKETPLACE_URL + '/items/' + message.itemId, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
openMarketplace(message.itemId);
|
||||
break;
|
||||
case 'refreshConnections':
|
||||
print('Refreshing Connections...');
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
var CLARA_IO_CANCEL_DOWNLOAD = "CLARA.IO CANCEL DOWNLOAD";
|
||||
var CLARA_IO_CANCELLED_DOWNLOAD = "CLARA.IO CANCELLED DOWNLOAD";
|
||||
var GOTO_DIRECTORY = "GOTO_DIRECTORY";
|
||||
var GOTO_MARKETPLACE = "GOTO_MARKETPLACE";
|
||||
var QUERY_CAN_WRITE_ASSETS = "QUERY_CAN_WRITE_ASSETS";
|
||||
var CAN_WRITE_ASSETS = "CAN_WRITE_ASSETS";
|
||||
var WARN_USER_NO_PERMISSIONS = "WARN_USER_NO_PERMISSIONS";
|
||||
|
@ -72,7 +73,16 @@
|
|||
|
||||
// Footer actions.
|
||||
$("#back-button").on("click", function () {
|
||||
(document.referrer !== "") ? window.history.back() : window.location = (marketplaceBaseURL + "/marketplace?");
|
||||
if (document.referrer !== "") {
|
||||
window.history.back();
|
||||
} else {
|
||||
var params = { type: GOTO_MARKETPLACE };
|
||||
var itemIdMatch = location.search.match(/itemId=([^&]*)/);
|
||||
if (itemIdMatch && itemIdMatch.length === 2) {
|
||||
params.itemId = itemIdMatch[1];
|
||||
}
|
||||
EventBridge.emitWebEvent(JSON.stringify(params));
|
||||
}
|
||||
});
|
||||
$("#all-markets").on("click", function () {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
|
@ -93,7 +103,9 @@
|
|||
window.location = "https://clara.io/library?gameCheck=true&public=true";
|
||||
});
|
||||
$('#exploreHifiMarketplace').on('click', function () {
|
||||
window.location = marketplaceBaseURL + "/marketplace?";
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: GOTO_MARKETPLACE
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//
|
||||
// marketplace.js
|
||||
//
|
||||
// Created by Eric Levin on 8 Jan 2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
// Created by Roxanne Skelly on 1/18/2019
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -10,108 +10,27 @@
|
|||
|
||||
(function() { // BEGIN LOCAL_SCOPE
|
||||
|
||||
/* global WebTablet */
|
||||
Script.include("../libraries/WebTablet.js");
|
||||
var AppUi = Script.require('appUi');
|
||||
|
||||
var toolIconUrl = Script.resolvePath("../assets/images/tools/");
|
||||
var BUTTON_NAME = "MARKET";
|
||||
var MARKETPLACE_QML_SOURCE = "hifi/commerce/marketplace/Marketplace.qml";
|
||||
var ui;
|
||||
function startup() {
|
||||
|
||||
var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace";
|
||||
var marketplaceWindow = new OverlayWebWindow({
|
||||
title: "Marketplace",
|
||||
source: "about:blank",
|
||||
width: 900,
|
||||
height: 700,
|
||||
visible: false
|
||||
});
|
||||
|
||||
var toolHeight = 50;
|
||||
var toolWidth = 50;
|
||||
var TOOLBAR_MARGIN_Y = 0;
|
||||
var marketplaceVisible = false;
|
||||
var marketplaceWebTablet;
|
||||
|
||||
// We persist avatarEntity data in the .ini file, and reconsistitute it on restart.
|
||||
// To keep things consistent, we pickle the tablet data in Settings, and kill any existing such on restart and domain change.
|
||||
var persistenceKey = "io.highfidelity.lastDomainTablet";
|
||||
|
||||
function shouldShowWebTablet() {
|
||||
var rightPose = Controller.getPoseValue(Controller.Standard.RightHand);
|
||||
var leftPose = Controller.getPoseValue(Controller.Standard.LeftHand);
|
||||
var hasHydra = !!Controller.Hardware.Hydra;
|
||||
return HMD.active && (leftPose.valid || rightPose.valid || hasHydra);
|
||||
ui = new AppUi({
|
||||
buttonName: BUTTON_NAME,
|
||||
sortOrder: 10,
|
||||
home: MARKETPLACE_QML_SOURCE
|
||||
});
|
||||
}
|
||||
|
||||
function showMarketplace(marketplaceID) {
|
||||
var url = MARKETPLACE_URL;
|
||||
if (marketplaceID) {
|
||||
url = url + "/items/" + marketplaceID;
|
||||
}
|
||||
tablet.gotoWebScreen(url);
|
||||
marketplaceVisible = true;
|
||||
UserActivityLogger.openedMarketplace();
|
||||
function shutdown() {
|
||||
}
|
||||
|
||||
function hideTablet(tablet) {
|
||||
if (!tablet) {
|
||||
return;
|
||||
}
|
||||
updateButtonState(false);
|
||||
tablet.unregister();
|
||||
tablet.destroy();
|
||||
marketplaceWebTablet = null;
|
||||
Settings.setValue(persistenceKey, "");
|
||||
}
|
||||
function clearOldTablet() { // If there was a tablet from previous domain or session, kill it and let it be recreated
|
||||
|
||||
}
|
||||
function hideMarketplace() {
|
||||
if (marketplaceWindow.visible) {
|
||||
marketplaceWindow.setVisible(false);
|
||||
marketplaceWindow.setURL("about:blank");
|
||||
} else if (marketplaceWebTablet) {
|
||||
|
||||
}
|
||||
marketplaceVisible = false;
|
||||
}
|
||||
|
||||
function toggleMarketplace() {
|
||||
if (marketplaceVisible) {
|
||||
hideMarketplace();
|
||||
} else {
|
||||
showMarketplace();
|
||||
}
|
||||
}
|
||||
|
||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
|
||||
var browseExamplesButton = tablet.addButton({
|
||||
icon: "icons/tablet-icons/market-i.svg",
|
||||
text: "MARKET"
|
||||
});
|
||||
|
||||
function updateButtonState(visible) {
|
||||
|
||||
}
|
||||
function onMarketplaceWindowVisibilityChanged() {
|
||||
updateButtonState(marketplaceWindow.visible);
|
||||
marketplaceVisible = marketplaceWindow.visible;
|
||||
}
|
||||
|
||||
function onClick() {
|
||||
toggleMarketplace();
|
||||
}
|
||||
|
||||
browseExamplesButton.clicked.connect(onClick);
|
||||
marketplaceWindow.visibleChanged.connect(onMarketplaceWindowVisibilityChanged);
|
||||
|
||||
clearOldTablet(); // Run once at startup, in case there's anything laying around from a crash.
|
||||
// We could also optionally do something like Window.domainChanged.connect(function () {Script.setTimeout(clearOldTablet, 2000)}),
|
||||
// but the HUD version stays around, so lets do the same.
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
browseExamplesButton.clicked.disconnect(onClick);
|
||||
tablet.removeButton(browseExamplesButton);
|
||||
marketplaceWindow.visibleChanged.disconnect(onMarketplaceWindowVisibilityChanged);
|
||||
});
|
||||
//
|
||||
// Run the functions.
|
||||
//
|
||||
startup();
|
||||
Script.scriptEnding.connect(shutdown);
|
||||
|
||||
}()); // END LOCAL_SCOPE
|
||||
|
|
|
@ -19,12 +19,14 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
var AppUi = Script.require('appUi');
|
||||
Script.include("/~/system/libraries/gridTool.js");
|
||||
Script.include("/~/system/libraries/connectionUtils.js");
|
||||
Script.include("/~/system/libraries/accountUtils.js");
|
||||
|
||||
var MARKETPLACE_CHECKOUT_QML_PATH = "hifi/commerce/checkout/Checkout.qml";
|
||||
var MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH = "hifi/commerce/inspectionCertificate/InspectionCertificate.qml";
|
||||
var MARKETPLACE_ITEM_TESTER_QML_PATH = "hifi/commerce/marketplaceItemTester/MarketplaceItemTester.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_QML_PATH = "hifi/commerce/marketplace/Marketplace.qml";
|
||||
var MARKETPLACES_INJECT_SCRIPT_URL = Script.resolvePath("../html/js/marketplacesInject.js");
|
||||
var MARKETPLACES_URL = Script.resolvePath("../html/marketplaces.html");
|
||||
var METAVERSE_SERVER_URL = Account.metaverseServerURL;
|
||||
|
@ -36,6 +38,7 @@ var CLARA_IO_STATUS = "CLARA.IO STATUS";
|
|||
var CLARA_IO_CANCEL_DOWNLOAD = "CLARA.IO CANCEL DOWNLOAD";
|
||||
var CLARA_IO_CANCELLED_DOWNLOAD = "CLARA.IO CANCELLED DOWNLOAD";
|
||||
var GOTO_DIRECTORY = "GOTO_DIRECTORY";
|
||||
var GOTO_MARKETPLACE = "GOTO_MARKETPLACE";
|
||||
var QUERY_CAN_WRITE_ASSETS = "QUERY_CAN_WRITE_ASSETS";
|
||||
var CAN_WRITE_ASSETS = "CAN_WRITE_ASSETS";
|
||||
var WARN_USER_NO_PERMISSIONS = "WARN_USER_NO_PERMISSIONS";
|
||||
|
@ -154,18 +157,14 @@ function onMarketplaceOpen(referrer) {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
function openMarketplace(optionalItem, edition) {
|
||||
ui.open(MARKETPLACE_QML_PATH);
|
||||
if (optionalItem) {
|
||||
ui.tablet.sendToQml({
|
||||
method: 'updateMarketplaceQMLItem',
|
||||
params: { itemId: optionalItem, edition: edition }
|
||||
});
|
||||
}
|
||||
ui.open(url, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
}
|
||||
|
||||
// Function Name: wireQmlEventBridge()
|
||||
|
@ -439,7 +438,9 @@ var referrerURL; // Used for updating Purchases QML
|
|||
var filterText; // Used for updating Purchases QML
|
||||
function onWebEventReceived(message) {
|
||||
message = JSON.parse(message);
|
||||
if (message.type === GOTO_DIRECTORY) {
|
||||
if (message.type === GOTO_MARKETPLACE) {
|
||||
openMarketplace(message.itemId);
|
||||
} else if (message.type === GOTO_DIRECTORY) {
|
||||
// This is the chooser between marketplaces. Only OUR markteplace
|
||||
// requires/makes-use-of wallet, so doesn't go through openMarketplace bottleneck.
|
||||
ui.open(MARKETPLACES_URL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
|
@ -485,7 +486,6 @@ function onWebEventReceived(message) {
|
|||
} else if (message.type === "WALLET_SETUP") {
|
||||
setupWallet('marketplace cta');
|
||||
} else if (message.type === "MY_ITEMS") {
|
||||
referrerURL = MARKETPLACE_URL_INITIAL;
|
||||
filterText = "";
|
||||
ui.open(MARKETPLACE_PURCHASES_QML_PATH);
|
||||
wireQmlEventBridge(true);
|
||||
|
@ -546,11 +546,10 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
|||
openWallet();
|
||||
break;
|
||||
case 'checkout_cancelClicked':
|
||||
openMarketplace(message.params);
|
||||
openMarketplace(message.itemId);
|
||||
break;
|
||||
case 'header_goToPurchases':
|
||||
case 'checkout_goToPurchases':
|
||||
referrerURL = MARKETPLACE_URL_INITIAL;
|
||||
filterText = message.filterText;
|
||||
ui.open(MARKETPLACE_PURCHASES_QML_PATH);
|
||||
break;
|
||||
|
@ -560,6 +559,25 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
|||
case 'checkout_continue':
|
||||
openMarketplace();
|
||||
break;
|
||||
case 'marketplace_checkout':
|
||||
ui.open(MARKETPLACE_CHECKOUT_QML_PATH);
|
||||
ui.tablet.sendToQml({
|
||||
method: 'updateCheckoutQMLItemID',
|
||||
params: message
|
||||
});
|
||||
break;
|
||||
case 'marketplace_marketplaces':
|
||||
// This is the chooser between marketplaces. Only OUR markteplace
|
||||
// requires/makes-use-of wallet, so doesn't go through openMarketplace bottleneck.
|
||||
var url = MARKETPLACES_URL;
|
||||
if(message.itemId) {
|
||||
url = url + "?itemId=" + message.itemId
|
||||
}
|
||||
ui.open(url, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
break;
|
||||
case 'marketplace_open_link':
|
||||
ui.open(message.link);
|
||||
break;
|
||||
case 'checkout_rezClicked':
|
||||
case 'purchases_rezClicked':
|
||||
case 'tester_rezClicked':
|
||||
|
@ -588,18 +606,18 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
|||
}
|
||||
break;
|
||||
case 'header_marketplaceImageClicked':
|
||||
openMarketplace(message.referrerURL);
|
||||
openMarketplace();
|
||||
break;
|
||||
case 'purchases_goToMarketplaceClicked':
|
||||
openMarketplace();
|
||||
break;
|
||||
case 'updateItemClicked':
|
||||
openMarketplace(message.upgradeUrl + "?edition=" + message.itemEdition);
|
||||
openMarketplace(message.itemId, message.itemEdition);
|
||||
break;
|
||||
case 'passphrasePopup_cancelClicked':
|
||||
case 'needsLogIn_cancelClicked':
|
||||
// Should/must NOT check for wallet setup.
|
||||
ui.open(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
openMarketplace();
|
||||
break;
|
||||
case 'needsLogIn_loginClicked':
|
||||
openLoginWindow();
|
||||
|
@ -624,10 +642,10 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
|||
ContextOverlay.requestOwnershipVerification(message.entity);
|
||||
break;
|
||||
case 'inspectionCertificate_showInMarketplaceClicked':
|
||||
openMarketplace(message.marketplaceUrl);
|
||||
console.log("INSPECTION CERTIFICATE SHOW IN MARKETPLACE CLICKED: " + message.itemId);
|
||||
openMarketplace(message.itemId);
|
||||
break;
|
||||
case 'header_myItemsClicked':
|
||||
referrerURL = MARKETPLACE_URL_INITIAL;
|
||||
filterText = "";
|
||||
ui.open(MARKETPLACE_PURCHASES_QML_PATH);
|
||||
wireQmlEventBridge(true);
|
||||
|
@ -689,7 +707,7 @@ var onMarketplaceScreen = false;
|
|||
var onWalletScreen = false;
|
||||
var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
||||
ui.setCurrentVisibleScreenMetadata(type, url);
|
||||
onMarketplaceScreen = type === "Web" && url.indexOf(MARKETPLACE_URL) !== -1;
|
||||
onMarketplaceScreen = type === "QML" && url.indexOf(MARKETPLACE_QML_PATH) !== -1;
|
||||
onInspectionCertificateScreen = type === "QML" && url.indexOf(MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH) !== -1;
|
||||
var onWalletScreenNow = url.indexOf(MARKETPLACE_WALLET_QML_PATH) !== -1;
|
||||
var onCommerceScreenNow = type === "QML" && (
|
||||
|
@ -699,7 +717,9 @@ var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
|||
var onMarketplaceItemTesterScreenNow = (
|
||||
url.indexOf(MARKETPLACE_ITEM_TESTER_QML_PATH) !== -1 ||
|
||||
url === MARKETPLACE_ITEM_TESTER_QML_PATH);
|
||||
|
||||
var onMarketplaceScreenNow = (
|
||||
url.indexOf(MARKETPLACE_QML_PATH) !== -1 ||
|
||||
url === MARKETPLACE_QML_PATH);
|
||||
if ((!onWalletScreenNow && onWalletScreen) ||
|
||||
(!onCommerceScreenNow && onCommerceScreen) ||
|
||||
(!onMarketplaceItemTesterScreenNow && onMarketplaceScreen)
|
||||
|
@ -711,7 +731,7 @@ var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
|||
onCommerceScreen = onCommerceScreenNow;
|
||||
onWalletScreen = onWalletScreenNow;
|
||||
onMarketplaceItemTesterScreen = onMarketplaceItemTesterScreenNow;
|
||||
wireQmlEventBridge(onCommerceScreen || onWalletScreen || onMarketplaceItemTesterScreen);
|
||||
wireQmlEventBridge(onCommerceScreen || onWalletScreen || onMarketplaceItemTesterScreen || onMarketplaceScreenNow);
|
||||
|
||||
if (url === MARKETPLACE_PURCHASES_QML_PATH) {
|
||||
// FIXME? Is there a race condition here in which the event
|
||||
|
@ -734,11 +754,8 @@ var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
|||
Keyboard.raised = false;
|
||||
}
|
||||
|
||||
if (type === "Web" && url.indexOf(MARKETPLACE_URL) !== -1) {
|
||||
ContextOverlay.isInMarketplaceInspectionMode = true;
|
||||
} else {
|
||||
ContextOverlay.isInMarketplaceInspectionMode = false;
|
||||
}
|
||||
ContextOverlay.isInMarketplaceInspectionMode = false;
|
||||
|
||||
|
||||
if (onInspectionCertificateScreen) {
|
||||
setCertificateInfo(contextOverlayEntity);
|
||||
|
@ -769,16 +786,13 @@ var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
|||
|
||||
|
||||
var BUTTON_NAME = "MARKET";
|
||||
var MARKETPLACE_URL = METAVERSE_SERVER_URL + "/marketplace";
|
||||
// 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;
|
||||
function startup() {
|
||||
ui = new AppUi({
|
||||
buttonName: BUTTON_NAME,
|
||||
sortOrder: 9,
|
||||
inject: MARKETPLACES_INJECT_SCRIPT_URL,
|
||||
home: MARKETPLACE_URL_INITIAL,
|
||||
home: MARKETPLACE_QML_PATH,
|
||||
onScreenChanged: onTabletScreenChanged,
|
||||
onMessage: onQmlMessageReceived
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue