mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-11 00:18:40 +02:00
QML Marketplace
Checkpoint full functionality
This commit is contained in:
parent
8010d86210
commit
c1ff51a02d
12 changed files with 1592 additions and 160 deletions
|
@ -30,23 +30,71 @@ Rectangle {
|
||||||
|
|
||||||
property string activeView: "initialize";
|
property string activeView: "initialize";
|
||||||
property bool keyboardRaised: false;
|
property bool keyboardRaised: false;
|
||||||
property int category_index: -1;
|
property int currentSortIndex: 0;
|
||||||
property alias categoryChoices: categoriesModel;
|
property string sortString: "";
|
||||||
|
property string categoryString: "";
|
||||||
|
property string searchString: "";
|
||||||
|
|
||||||
anchors.fill: (typeof parent === undefined) ? undefined : parent;
|
anchors.fill: (typeof parent === undefined) ? undefined : parent;
|
||||||
|
|
||||||
|
function getMarketplaceItems() {
|
||||||
|
marketplaceItemView.visible = false;
|
||||||
|
itemsList.visible = true;
|
||||||
|
marketBrowseModel.getFirstPage();
|
||||||
|
}
|
||||||
|
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
KeyboardScriptingInterface.raised = false;
|
KeyboardScriptingInterface.raised = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: Marketplace;
|
target: MarketplaceScriptingInterface;
|
||||||
|
|
||||||
onGetMarketplaceCategoriesResult: {
|
onGetMarketplaceCategoriesResult: {
|
||||||
if (result.status !== 'success') {
|
if (result.status !== 'success') {
|
||||||
console.log("Failed to get Marketplace Categories", result.data.message);
|
console.log("Failed to get Marketplace Categories", result.data.message);
|
||||||
} else {
|
} else {
|
||||||
|
categoriesModel.clear();
|
||||||
|
categoriesModel.append({
|
||||||
|
id: -1,
|
||||||
|
name: "Everything"
|
||||||
|
});
|
||||||
|
result.data.items.forEach(function(category) {
|
||||||
|
categoriesModel.append({
|
||||||
|
id: category.id,
|
||||||
|
name: category.name
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getMarketplaceItems();
|
||||||
|
}
|
||||||
|
onGetMarketplaceItemsResult: {
|
||||||
|
marketBrowseModel.handlePage(result.status !== "success" && result.message, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
onGetMarketplaceItemResult: {
|
||||||
|
if (result.status !== 'success') {
|
||||||
|
console.log("Failed to get Marketplace Item", result.data.message);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
console.log(JSON.stringify(result.data));
|
||||||
|
marketplaceItem.item_id = result.data.id;
|
||||||
|
marketplaceItem.image_url = result.data.thumbnail_url;
|
||||||
|
marketplaceItem.name = result.data.title;
|
||||||
|
marketplaceItem.likes = result.data.likes;
|
||||||
|
marketplaceItem.liked = result.data.has_liked;
|
||||||
|
marketplaceItem.creator = result.data.creator;
|
||||||
|
marketplaceItem.categories = result.data.categories;
|
||||||
|
marketplaceItem.price = result.data.cost;
|
||||||
|
marketplaceItem.description = result.data.description;
|
||||||
|
marketplaceItem.attributions = result.data.attributions;
|
||||||
|
marketplaceItem.license = result.data.license;
|
||||||
|
marketplaceItem.available = result.data.availability == "available";
|
||||||
|
marketplaceItem.created_at = result.data.created_at;
|
||||||
|
console.log("HEIGHT: " + marketplaceItemContent.height);
|
||||||
|
marketplaceItemScrollView.contentHeight = marketplaceItemContent.height;
|
||||||
|
itemsList.visible = false;
|
||||||
|
marketplaceItemView.visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,15 +108,36 @@ Rectangle {
|
||||||
//
|
//
|
||||||
// HEADER BAR START
|
// HEADER BAR START
|
||||||
//
|
//
|
||||||
Item {
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: headerShadowBase;
|
||||||
|
anchors.fill: header;
|
||||||
|
color: "white";
|
||||||
|
}
|
||||||
|
DropShadow {
|
||||||
|
anchors.fill: headerShadowBase;
|
||||||
|
source: headerShadowBase;
|
||||||
|
verticalOffset: 4;
|
||||||
|
horizontalOffset: 4;
|
||||||
|
radius: 6;
|
||||||
|
samples: 9;
|
||||||
|
color: hifi.colors.baseGrayShadow;
|
||||||
|
z:5;
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
id: header;
|
id: header;
|
||||||
visible: true;
|
visible: true;
|
||||||
width: parent.width;
|
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
|
anchors.topMargin: -1;
|
||||||
|
anchors.leftMargin: -1;
|
||||||
|
anchors.rightMargin: -1;
|
||||||
|
height: childrenRect.height+5;
|
||||||
|
z: 5;
|
||||||
|
|
||||||
Item {
|
Rectangle {
|
||||||
id: titleBarContainer;
|
id: titleBarContainer;
|
||||||
visible: true;
|
visible: true;
|
||||||
// Size
|
// Size
|
||||||
|
@ -78,12 +147,13 @@ Rectangle {
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
|
|
||||||
// Wallet icon
|
|
||||||
|
// Marketplace icon
|
||||||
Image {
|
Image {
|
||||||
id: walletIcon;
|
id: marketplaceIcon;
|
||||||
source: "../../../../images/hifi-logo-blackish.svg";
|
source: "../../../../images/hifi-logo-blackish.svg";
|
||||||
height: 20
|
height: 20
|
||||||
width: walletIcon.height;
|
width: marketplaceIcon.height;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.leftMargin: 8;
|
anchors.leftMargin: 8;
|
||||||
anchors.verticalCenter: parent.verticalCenter;
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
@ -98,7 +168,7 @@ Rectangle {
|
||||||
size: hifi.fontSizes.overlayTitle;
|
size: hifi.fontSizes.overlayTitle;
|
||||||
// Anchors
|
// Anchors
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
anchors.left: walletIcon.right;
|
anchors.left: marketplaceIcon.right;
|
||||||
anchors.leftMargin: 6;
|
anchors.leftMargin: 6;
|
||||||
anchors.bottom: parent.bottom;
|
anchors.bottom: parent.bottom;
|
||||||
width: paintedWidth;
|
width: paintedWidth;
|
||||||
|
@ -109,9 +179,10 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Rectangle {
|
||||||
id: searchBarContainer;
|
id: searchBarContainer;
|
||||||
visible: true;
|
visible: true;
|
||||||
|
clip: false;
|
||||||
// Size
|
// Size
|
||||||
width: parent.width;
|
width: parent.width;
|
||||||
anchors.top: titleBarContainer.bottom;
|
anchors.top: titleBarContainer.bottom;
|
||||||
|
@ -125,10 +196,10 @@ Rectangle {
|
||||||
anchors.verticalCenter: parent.verticalCenter;
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
height: 34;
|
height: 34;
|
||||||
width: categoriesText.width + 25;
|
width: categoriesText.width + 25;
|
||||||
color: "white";
|
color: hifi.colors.white;
|
||||||
radius: 4;
|
radius: 4;
|
||||||
border.width: 1;
|
border.width: 1;
|
||||||
border.color: hifi.colors.lightGray;
|
border.color: hifi.colors.lightGrayText;
|
||||||
|
|
||||||
|
|
||||||
// Categories Text
|
// Categories Text
|
||||||
|
@ -136,9 +207,9 @@ Rectangle {
|
||||||
id: categoriesText;
|
id: categoriesText;
|
||||||
text: "Categories";
|
text: "Categories";
|
||||||
// Text size
|
// Text size
|
||||||
size: 18;
|
size: 14;
|
||||||
// Style
|
// Style
|
||||||
color: hifi.colors.baseGray;
|
color: hifi.colors.lightGrayText;
|
||||||
elide: Text.ElideRight;
|
elide: Text.ElideRight;
|
||||||
horizontalAlignment: Text.AlignHCenter;
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
verticalAlignment: Text.AlignVCenter;
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
@ -166,6 +237,8 @@ Rectangle {
|
||||||
hoverEnabled: enabled;
|
hoverEnabled: enabled;
|
||||||
onClicked: {
|
onClicked: {
|
||||||
categoriesDropdown.visible = !categoriesDropdown.visible;
|
categoriesDropdown.visible = !categoriesDropdown.visible;
|
||||||
|
categoriesButton.color = categoriesDropdown.visible ? hifi.colors.lightGray : hifi.colors.white;
|
||||||
|
categoriesDropdown.forceActiveFocus();
|
||||||
}
|
}
|
||||||
onEntered: categoriesText.color = hifi.colors.baseGrayShadow;
|
onEntered: categoriesText.color = hifi.colors.baseGrayShadow;
|
||||||
onExited: categoriesText.color = hifi.colors.baseGray;
|
onExited: categoriesText.color = hifi.colors.baseGray;
|
||||||
|
@ -173,74 +246,7 @@ Rectangle {
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
console.log("Getting Marketplace Categories");
|
console.log("Getting Marketplace Categories");
|
||||||
console.log(JSON.stringify(Marketplace));
|
MarketplaceScriptingInterface.getMarketplaceCategories();
|
||||||
Marketplace.getMarketplaceItems();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: categoriesContainer;
|
|
||||||
visible: true;
|
|
||||||
height: 50 * categoriesModel.count;
|
|
||||||
width: parent.width;
|
|
||||||
anchors.top: categoriesButton.bottom;
|
|
||||||
anchors.left: categoriesButton.left;
|
|
||||||
color: hifi.colors.white;
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: categoriesModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: dropdownListView;
|
|
||||||
interactive: false;
|
|
||||||
anchors.fill: parent;
|
|
||||||
model: categoriesModel;
|
|
||||||
delegate: Item {
|
|
||||||
width: parent.width;
|
|
||||||
height: 50;
|
|
||||||
Rectangle {
|
|
||||||
id: dropDownButton;
|
|
||||||
color: hifi.colors.white;
|
|
||||||
width: parent.width;
|
|
||||||
height: 50;
|
|
||||||
visible: true;
|
|
||||||
|
|
||||||
RalewaySemiBold {
|
|
||||||
id: dropDownButtonText;
|
|
||||||
text: model.displayName;
|
|
||||||
anchors.fill: parent;
|
|
||||||
anchors.topMargin: 2;
|
|
||||||
anchors.leftMargin: 12;
|
|
||||||
color: hifi.colors.baseGray;
|
|
||||||
horizontalAlignment: Text.AlignLeft;
|
|
||||||
verticalAlignment: Text.AlignVCenter;
|
|
||||||
size: 18;
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent;
|
|
||||||
hoverEnabled: true;
|
|
||||||
propagateComposedEvents: false;
|
|
||||||
onEntered: {
|
|
||||||
dropDownButton.color = hifi.colors.blueHighlight;
|
|
||||||
}
|
|
||||||
onExited: {
|
|
||||||
dropDownButton.color = hifi.colors.white;
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
root.category_index = index;
|
|
||||||
dropdownContainer.visible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
height: 2;
|
|
||||||
width: parent.width;
|
|
||||||
color: hifi.colors.lightGray;
|
|
||||||
visible: model.separator
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +289,6 @@ Rectangle {
|
||||||
font.family: "FiraSans Regular";
|
font.family: "FiraSans Regular";
|
||||||
font.pixelSize: hifi.fontSizes.textFieldInput;
|
font.pixelSize: hifi.fontSizes.textFieldInput;
|
||||||
font.capitalization: Font.AllUppercase;
|
font.capitalization: Font.AllUppercase;
|
||||||
text: root.primaryFilter_displayName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// workaround for https://bugreports.qt.io/browse/QTBUG-49297
|
// workaround for https://bugreports.qt.io/browse/QTBUG-49297
|
||||||
|
@ -295,20 +300,22 @@ Rectangle {
|
||||||
|
|
||||||
// emit accepted signal manually
|
// emit accepted signal manually
|
||||||
if (acceptableInput) {
|
if (acceptableInput) {
|
||||||
root.accepted();
|
searchField.accepted();
|
||||||
root.forceActiveFocus();
|
searchField.forceActiveFocus();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt.Key_Backspace:
|
case Qt.Key_Backspace:
|
||||||
if (textField.text === "") {
|
if (searchField.text === "") {
|
||||||
primaryFilter_index = -1;
|
primaryFilter_index = -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
onTextChanged: root.searchString = text;
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
root.forceActiveFocus();
|
root.searchString = searchField.text;
|
||||||
|
getMarketplaceItems();
|
||||||
|
searchField.forceActiveFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
onActiveFocusChanged: {
|
onActiveFocusChanged: {
|
||||||
|
@ -320,17 +327,579 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// HEADER BAR END
|
// HEADER BAR END
|
||||||
//
|
//
|
||||||
DropShadow {
|
|
||||||
anchors.fill: header;
|
//
|
||||||
horizontalOffset: 0;
|
// CATEGORIES LIST START
|
||||||
verticalOffset: 4;
|
//
|
||||||
radius: 4.0;
|
Item {
|
||||||
samples: 9
|
id: categoriesDropdown;
|
||||||
color: Qt.rgba(0, 0, 0, 0.25);
|
anchors.fill: parent;
|
||||||
source: header;
|
visible: false;
|
||||||
visible: header.visible;
|
z: 10;
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
propagateComposedEvents: true;
|
||||||
|
onClicked: {
|
||||||
|
categoriesDropdown.visible = false;
|
||||||
|
categoriesButton.color = hifi.colors.white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.topMargin: 100;
|
||||||
|
width: parent.width/3;
|
||||||
|
color: hifi.colors.white;
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: categoriesModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: categoriesListView;
|
||||||
|
anchors.fill: parent;
|
||||||
|
anchors.rightMargin: 10;
|
||||||
|
width: parent.width;
|
||||||
|
clip: true;
|
||||||
|
|
||||||
|
model: categoriesModel;
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
height: 34;
|
||||||
|
width: parent.width;
|
||||||
|
clip: true;
|
||||||
|
contentItem: Rectangle {
|
||||||
|
id: categoriesItem;
|
||||||
|
anchors.fill: parent;
|
||||||
|
color: hifi.colors.white;
|
||||||
|
visible: true;
|
||||||
|
|
||||||
|
RalewayRegular {
|
||||||
|
id: categoriesItemText;
|
||||||
|
text: model.name;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.fill:parent;
|
||||||
|
color: ListView.isCurrentItem ? hifi.colors.lightBlueHighlight : hifi.colors.baseGray;
|
||||||
|
horizontalAlignment: Text.AlignLeft;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
size: 14;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
hoverEnabled: true;
|
||||||
|
propagateComposedEvents: false;
|
||||||
|
z: 10;
|
||||||
|
onEntered: {
|
||||||
|
categoriesItem.color = ListView.isCurrentItem ? hifi.colors.white : hifi.colors.lightBlueHighlight;
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
categoriesItem.color = ListView.isCurrentItem ? hifi.colors.lightBlueHighlight : hifi.colors.white;
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
categoriesListView.currentIndex = index;
|
||||||
|
categoriesText.text = categoriesItemText.text;
|
||||||
|
categoriesDropdown.visible = false;
|
||||||
|
categoriesButton.color = hifi.colors.white;
|
||||||
|
root.categoryString = categoriesItemText.text;
|
||||||
|
getMarketplaceItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ScrollBar.vertical: ScrollBar {
|
||||||
|
parent: categoriesListView.parent;
|
||||||
|
anchors.top: categoriesListView.top;
|
||||||
|
anchors.bottom: categoriesListView.bottom;
|
||||||
|
anchors.left: categoriesListView.right;
|
||||||
|
contentItem.opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// CATEGORIES LIST END
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// ITEMS LIST START
|
||||||
|
//
|
||||||
|
Item {
|
||||||
|
id: itemsList;
|
||||||
|
anchors.fill: parent;
|
||||||
|
anchors.topMargin: 100;
|
||||||
|
anchors.bottomMargin: 50;
|
||||||
|
visible: true;
|
||||||
|
|
||||||
|
HifiModels.PSFListModel {
|
||||||
|
id: marketBrowseModel;
|
||||||
|
itemsPerPage: 7;
|
||||||
|
listModelName: 'marketBrowse';
|
||||||
|
listView: marketBrowseList;
|
||||||
|
getPage: function () {
|
||||||
|
|
||||||
|
MarketplaceScriptingInterface.getMarketplaceItems(
|
||||||
|
root.searchString == "" ? undefined : root.searchString,
|
||||||
|
"",
|
||||||
|
root.categoryString.toLowerCase(),
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
root.sortString,
|
||||||
|
false,
|
||||||
|
marketBrowseModel.currentPageToRetrieve,
|
||||||
|
marketBrowseModel.itemsPerPage
|
||||||
|
);
|
||||||
|
}
|
||||||
|
processPage: function(data) {
|
||||||
|
console.log(JSON.stringify(data));
|
||||||
|
data.items.forEach(function (item) {
|
||||||
|
console.log(JSON.stringify(item));
|
||||||
|
});
|
||||||
|
return data.items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ListView {
|
||||||
|
id: marketBrowseList;
|
||||||
|
model: marketBrowseModel;
|
||||||
|
// Anchors
|
||||||
|
anchors.fill: parent;
|
||||||
|
anchors.rightMargin: 10;
|
||||||
|
orientation: ListView.Vertical;
|
||||||
|
focus: true;
|
||||||
|
clip: true;
|
||||||
|
|
||||||
|
delegate: MarketplaceListItem {
|
||||||
|
item_id: model.id;
|
||||||
|
image_url:model.thumbnail_url;
|
||||||
|
name: model.title;
|
||||||
|
likes: model.likes;
|
||||||
|
liked: model.has_liked;
|
||||||
|
creator: model.creator;
|
||||||
|
category: model.primary_category;
|
||||||
|
price: model.cost;
|
||||||
|
available: model.availability == "available";
|
||||||
|
anchors.topMargin: 10;
|
||||||
|
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
console.log("Rendering marketplace list item " + model.id);
|
||||||
|
console.log(marketBrowseModel.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
onShowItem: {
|
||||||
|
MarketplaceScriptingInterface.getMarketplaceItem(item_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
onBuy: {
|
||||||
|
sendToScript({method: 'marketplace_checkout', itemId: item_id});
|
||||||
|
}
|
||||||
|
|
||||||
|
onCategoryClicked: {
|
||||||
|
root.categoryString = category;
|
||||||
|
categoriesText.text = category;
|
||||||
|
getMarketplaceItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
onRequestReload: getMarketplaceItems();
|
||||||
|
}
|
||||||
|
ScrollBar.vertical: ScrollBar {
|
||||||
|
parent: marketBrowseList.parent;
|
||||||
|
anchors.top: marketBrowseList.top;
|
||||||
|
anchors.bottom: marketBrowseList.bottom;
|
||||||
|
anchors.left: marketBrowseList.right;
|
||||||
|
contentItem.opacity: 1;
|
||||||
|
}
|
||||||
|
headerPositioning: ListView.InlineHeader;
|
||||||
|
header: Item {
|
||||||
|
id: itemsHeading;
|
||||||
|
|
||||||
|
height: childrenRect.height;
|
||||||
|
width: parent.width;
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: breadcrumbs;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
height: 34;
|
||||||
|
visible: categoriesListView.currentIndex >= 0;
|
||||||
|
RalewayRegular {
|
||||||
|
id: categoriesItemText;
|
||||||
|
text: "Home /";
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.fill:parent;
|
||||||
|
color: hifi.colors.blueHighlight;
|
||||||
|
horizontalAlignment: Text.AlignLeft;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
size: 18;
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
onClicked: {
|
||||||
|
categoriesListView.currentIndex = -1;
|
||||||
|
categoriesText.text = "Categories";
|
||||||
|
root.categoryString = "";
|
||||||
|
getMarketplaceItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: searchScope;
|
||||||
|
anchors.top: breadcrumbs.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
height: 50;
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: searchScopeText;
|
||||||
|
text: "Featured";
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.fill:parent;
|
||||||
|
anchors.topMargin: 10;
|
||||||
|
color: hifi.colors.baseGray;
|
||||||
|
horizontalAlignment: Text.AlignLeft;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
size: 22;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
id: sort;
|
||||||
|
anchors.top: searchScope.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.topMargin: 10;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
height: childrenRect.height;
|
||||||
|
RalewayRegular {
|
||||||
|
id: sortText;
|
||||||
|
text: "Sort:";
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.rightMargin: 20;
|
||||||
|
height: 34;
|
||||||
|
color: hifi.colors.lightGrayText;
|
||||||
|
horizontalAlignment: Text.AlignLeft;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
size: 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
radius: 4;
|
||||||
|
border.width: 1;
|
||||||
|
border.color: hifi.colors.faintGray;
|
||||||
|
anchors.left: sortText.right;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
width: 322;
|
||||||
|
height: 36;
|
||||||
|
anchors.leftMargin: 20;
|
||||||
|
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: sortModel;
|
||||||
|
ListElement {
|
||||||
|
name: "Name";
|
||||||
|
glyph: ";";
|
||||||
|
sortString: "alpha";
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Date";
|
||||||
|
glyph: ";";
|
||||||
|
sortString: "recent";
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Popular";
|
||||||
|
glyph: ";";
|
||||||
|
sortString: "likes";
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "My Likes";
|
||||||
|
glyph: ";";
|
||||||
|
sortString: "my_likes";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: sortListView;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.topMargin:1;
|
||||||
|
anchors.bottomMargin:1;
|
||||||
|
anchors.leftMargin:1;
|
||||||
|
anchors.rightMargin:1;
|
||||||
|
width: childrenRect.width;
|
||||||
|
height: 34;
|
||||||
|
orientation: ListView.Horizontal;
|
||||||
|
focus: true;
|
||||||
|
clip: true;
|
||||||
|
highlightFollowsCurrentItem: false;
|
||||||
|
|
||||||
|
delegate: SortButton {
|
||||||
|
width: 80;
|
||||||
|
height: parent.height;
|
||||||
|
glyph: model.glyph;
|
||||||
|
text: model.name;
|
||||||
|
|
||||||
|
checked: {
|
||||||
|
ListView.isCurrentItem;
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
root.currentSortIndex = index;
|
||||||
|
sortListView.positionViewAtIndex(index, ListView.Beginning);
|
||||||
|
sortListView.currentIndex = index;
|
||||||
|
root.sortString = model.sortString;
|
||||||
|
getMarketplaceItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
highlight: Rectangle {
|
||||||
|
width: 80;
|
||||||
|
height: parent.height;
|
||||||
|
color: hifi.colors.faintGray;
|
||||||
|
x: sortListView.currentItem.x;
|
||||||
|
}
|
||||||
|
model: sortModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ITEMS LIST END
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// ITEM START
|
||||||
|
//
|
||||||
|
Item {
|
||||||
|
id: marketplaceItemView;
|
||||||
|
anchors.fill: parent;
|
||||||
|
width: parent.width;
|
||||||
|
anchors.topMargin: 120;
|
||||||
|
visible: false;
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
id: marketplaceItemScrollView;
|
||||||
|
anchors.fill: parent;
|
||||||
|
|
||||||
|
clip: true;
|
||||||
|
ScrollBar.vertical.policy: ScrollBar.AlwaysOn;
|
||||||
|
contentWidth: parent.width;
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: marketplaceItemContent;
|
||||||
|
width: parent.width;
|
||||||
|
height: childrenRect.height + 100;
|
||||||
|
|
||||||
|
// Title Bar text
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: backText;
|
||||||
|
text: "Back";
|
||||||
|
// Text size
|
||||||
|
size: hifi.fontSizes.overlayTitle;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.bottomMargin: 10;
|
||||||
|
width: paintedWidth;
|
||||||
|
height: paintedHeight;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.blueHighlight;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: backText;
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
getMarketplaceItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MarketplaceItem {
|
||||||
|
id: marketplaceItem;
|
||||||
|
anchors.top: backText.bottom;
|
||||||
|
width: parent.width;
|
||||||
|
height: childrenRect.height;
|
||||||
|
anchors.topMargin: 15;
|
||||||
|
|
||||||
|
onBuy: {
|
||||||
|
sendToScript({method: 'marketplace_checkout', itemId: item_id});
|
||||||
|
}
|
||||||
|
|
||||||
|
onShowLicense: {
|
||||||
|
licenseInfoWebView.url = url;
|
||||||
|
licenseInfo.visible = true;
|
||||||
|
}
|
||||||
|
onCategoryClicked: {
|
||||||
|
root.categoryString = category;
|
||||||
|
categoriesText.text = category;
|
||||||
|
getMarketplaceItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// ITEM END
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// FOOTER START
|
||||||
|
//
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: footer;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
height: 50;
|
||||||
|
|
||||||
|
color: hifi.colors.blueHighlight;
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.fill: parent;
|
||||||
|
anchors.rightMargin: 15;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
|
||||||
|
HiFiGlyphs {
|
||||||
|
id: footerGlyph;
|
||||||
|
text: hifi.glyphs.info;
|
||||||
|
// Size
|
||||||
|
size: 34;
|
||||||
|
// Anchors
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
|
||||||
|
anchors.rightMargin: 10;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.white;
|
||||||
|
// Alignment
|
||||||
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: footerInfo;
|
||||||
|
text: "Get items from Clara.io!";
|
||||||
|
anchors.left: footerGlyph.right;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
color: hifi.colors.white;
|
||||||
|
horizontalAlignment: Text.AlignLeft;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
size: 18;
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiControlsUit.Button {
|
||||||
|
text: "SEE ALL MARKETS";
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
anchors.topMargin: 10;
|
||||||
|
anchors.bottomMargin: 10;
|
||||||
|
anchors.leftMargin: 10;
|
||||||
|
anchors.rightMargin: 10;
|
||||||
|
width: 180;
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
sendToScript({method: 'marketplace_marketplaces'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// FOOTER END
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// LICENSE START
|
||||||
|
//
|
||||||
|
Rectangle {
|
||||||
|
id: licenseInfo;
|
||||||
|
anchors.fill: root;
|
||||||
|
anchors.topMargin: 100;
|
||||||
|
anchors.bottomMargin: 0;
|
||||||
|
visible: false;
|
||||||
|
|
||||||
|
|
||||||
|
HifiControlsUit.WebView {
|
||||||
|
id: licenseInfoWebView;
|
||||||
|
anchors.bottomMargin: 1;
|
||||||
|
anchors.topMargin: 50;
|
||||||
|
anchors.leftMargin: 1;
|
||||||
|
anchors.rightMargin: 1;
|
||||||
|
anchors.fill: parent;
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
id: licenseClose;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.topMargin: 10;
|
||||||
|
anchors.rightMargin: 10;
|
||||||
|
|
||||||
|
width: 30;
|
||||||
|
height: 30;
|
||||||
|
HiFiGlyphs {
|
||||||
|
anchors.fill: parent;
|
||||||
|
height: 30;
|
||||||
|
text: hifi.glyphs.close;
|
||||||
|
// Size
|
||||||
|
size: 34;
|
||||||
|
// Anchors
|
||||||
|
anchors.rightMargin: 0;
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.baseGray;
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: licenseClose;
|
||||||
|
onClicked: licenseInfo.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// LICENSE END
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Function Name: fromScript()
|
||||||
|
//
|
||||||
|
// Relevant Variables:
|
||||||
|
// None
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
// message: The message sent from the JavaScript, in this case the Marketplaces JavaScript.
|
||||||
|
// Messages are in format "{method, params}", like json-rpc.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// Called when a message is received from a script.
|
||||||
|
//
|
||||||
|
|
||||||
|
function fromScript(message) {
|
||||||
|
console.log("FROM SCRIPT " + JSON.stringify(message));
|
||||||
|
switch (message.method) {
|
||||||
|
case 'updateMarketplaceQMLItem':
|
||||||
|
if (!message.params.itemId) {
|
||||||
|
console.log("A message with method 'updateMarketplaceQMLItem' was sent without an itemId!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MarketplaceScriptingInterface.getMarketplaceItem(message.params.itemId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,473 @@
|
||||||
|
//
|
||||||
|
// 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 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: "";
|
||||||
|
|
||||||
|
onCategoriesChanged: {
|
||||||
|
categoriesListModel.clear();
|
||||||
|
categories.forEach(function(category) {
|
||||||
|
console.log("category is " + category);
|
||||||
|
categoriesListModel.append({"category":category});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
signal buy();
|
||||||
|
signal categoryClicked(string category);
|
||||||
|
signal showLicense(string url);
|
||||||
|
|
||||||
|
HifiConstants { id: hifi; }
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: MarketplaceScriptingInterface;
|
||||||
|
|
||||||
|
onMarketplaceItemLikeResult: {
|
||||||
|
if (result.status !== 'success') {
|
||||||
|
console.log("Failed to get Marketplace Categories", 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.rightMargin: 15;
|
||||||
|
height: childrenRect.height;
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: header;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
|
||||||
|
height: 50;
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: nameText;
|
||||||
|
text: root.name;
|
||||||
|
// Text size
|
||||||
|
size: 24;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.baseGray;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
id: likes;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
anchors.rightMargin: 5;
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: heart;
|
||||||
|
text: "\u2665";
|
||||||
|
// Size
|
||||||
|
size: 20;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.rightMargin: 0;
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
|
// Style
|
||||||
|
color: root.liked ? hifi.colors.redAccent : hifi.colors.lightGrayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: likesText;
|
||||||
|
text: root.likes;
|
||||||
|
// Text size
|
||||||
|
size: hifi.fontSizes.overlayTitle;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.right: heart.left;
|
||||||
|
anchors.rightMargin: 5;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.baseGray;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.left: likesText.left;
|
||||||
|
anchors.right: heart.right;
|
||||||
|
anchors.top: likesText.top;
|
||||||
|
anchors.bottom: likesText.bottom;
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
MarketplaceScriptingInterface.marketplaceItemLike(root.item_id, !root.liked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
id: itemImage;
|
||||||
|
source: root.image_url;
|
||||||
|
anchors.top: header.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
height: width*0.5625
|
||||||
|
fillMode: Image.PreserveAspectCrop;
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
id: footer;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.top: itemImage.bottom;
|
||||||
|
height: childrenRect.height;
|
||||||
|
|
||||||
|
HifiControlsUit.Button {
|
||||||
|
id: buyButton;
|
||||||
|
text: root.available ? (root.price ? root.price : "FREE") : "UNAVAILABLE (not for sale)";
|
||||||
|
enabled: root.available;
|
||||||
|
buttonGlyph: root.available ? (root.price ? hifi.glyphs.hfc : "") : "";
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.topMargin: 15;
|
||||||
|
height: 50;
|
||||||
|
color: hifi.buttons.blue;
|
||||||
|
|
||||||
|
onClicked: root.buy();
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: creatorItem;
|
||||||
|
anchors.top: buyButton.bottom;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.topMargin: 15;
|
||||||
|
width: parent.width;
|
||||||
|
height: childrenRect.height;
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: creatorLabel;
|
||||||
|
text: "CREATOR:";
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.lightGrayText;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: creatorText;
|
||||||
|
text: root.creator;
|
||||||
|
// Text size
|
||||||
|
size: 18;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: creatorLabel.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.topMargin: 10;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.blueHighlight;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: posted;
|
||||||
|
anchors.top: creatorItem.bottom;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.topMargin: 15;
|
||||||
|
width: parent.width;
|
||||||
|
height: childrenRect.height;
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: postedLabel;
|
||||||
|
text: "POSTED:";
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.lightGrayText;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: created_at;
|
||||||
|
text: { getFormattedDate(root.created_at); }
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: postedLabel.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.topMargin: 10;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.lightGray;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.top: posted.bottom;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.topMargin: 15;
|
||||||
|
width: parent.width;
|
||||||
|
height: 1;
|
||||||
|
color: hifi.colors.lightGray;
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: licenseItem;
|
||||||
|
anchors.top: posted.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.topMargin: 30;
|
||||||
|
width: parent.width;
|
||||||
|
height: childrenRect.height;
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: licenseLabel;
|
||||||
|
text: "SHARED UNDER:";
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.lightGrayText;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: licenseText;
|
||||||
|
text: root.license;
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: licenseLabel.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.lightGray;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: licenseHelp;
|
||||||
|
text: "More about this license";
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: licenseText.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.blueHighlight;
|
||||||
|
// Alignment
|
||||||
|
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/"
|
||||||
|
} else if (root.license == "Attribution-ShareAlike (CC BY-SA)") {
|
||||||
|
url = "https://creativecommons.org/licenses/by-sa/4.0/"
|
||||||
|
} else if (root.license == "Attribution-NoDerivs (CC BY-ND)") {
|
||||||
|
url = "https://creativecommons.org/licenses/by-nd/4.0/"
|
||||||
|
} else if (root.license == "Attribution-NonCommercial (CC BY-NC)") {
|
||||||
|
url = "https://creativecommons.org/licenses/by-nc/4.0/"
|
||||||
|
} else if (root.license == "Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)") {
|
||||||
|
url = "https://creativecommons.org/licenses/by-nc-sa/4.0/"
|
||||||
|
} else if (root.license == "Attribution-NonCommercial-NoDerivs (CC BY-NC-ND)") {
|
||||||
|
url = "https://creativecommons.org/licenses/by-nc-nd/4.0/"
|
||||||
|
} else if (root.license == "Proof of Provenance License (PoP License)") {
|
||||||
|
url = "https://digitalassetregistry.com/PoP-License/v1/"
|
||||||
|
}
|
||||||
|
if(url) {
|
||||||
|
licenseInfoWebView.url = url;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: descriptionItem;
|
||||||
|
anchors.top: licenseItem.bottom;
|
||||||
|
anchors.topMargin: 15;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
height: childrenRect.height;
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: descriptionLabel;
|
||||||
|
text: "DESCRIPTION:";
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.lightGrayText;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: descriptionText;
|
||||||
|
text: root.description;
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: descriptionLabel.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
width: parent.width;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.lightGray;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
wrapMode: Text.Wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: categoriesList;
|
||||||
|
anchors.top: descriptionItem.bottom;
|
||||||
|
anchors.topMargin: 15;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
width: parent.width;
|
||||||
|
height: childrenRect.height;
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: categoryLabel;
|
||||||
|
text: "IN:";
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.lightGrayText;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
ListModel {
|
||||||
|
id: categoriesListModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.top: categoryLabel.bottom;
|
||||||
|
model: categoriesListModel;
|
||||||
|
height: 20*model.count;
|
||||||
|
delegate: RalewaySemiBold {
|
||||||
|
id: categoryText;
|
||||||
|
text: model.category;
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
width: paintedWidth;
|
||||||
|
height: 20;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.blueHighlight;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: categoryText;
|
||||||
|
onClicked: root.categoryClicked(model.category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,278 @@
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
height: childrenRect.height;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.topMargin: 20;
|
||||||
|
anchors.bottomMargin: 10;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.rightMargin: 15;
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
onClicked: root.showItem();
|
||||||
|
onEntered: { hoverRect.visible = true; console.log("entered"); }
|
||||||
|
onExited: { hoverRect.visible = false; console.log("exited"); }
|
||||||
|
hoverEnabled: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: header;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
|
||||||
|
height: 50;
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: nameText;
|
||||||
|
text: root.name;
|
||||||
|
// Text size
|
||||||
|
size: hifi.fontSizes.overlayTitle;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.rightMargin: 50;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
elide: Text.ElideRight;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.blueHighlight;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
id: likes;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.rightMargin: 15;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
width: childrenRect.width;
|
||||||
|
Connections {
|
||||||
|
target: MarketplaceScriptingInterface;
|
||||||
|
|
||||||
|
onMarketplaceItemLikeResult: {
|
||||||
|
if (result.status !== 'success') {
|
||||||
|
console.log("Failed to get Marketplace Categories", result.data.message);
|
||||||
|
root.requestReload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: heart;
|
||||||
|
text: "\u2665";
|
||||||
|
// Size
|
||||||
|
size: 20;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.rightMargin: 0;
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
|
// Style
|
||||||
|
color: root.liked ? hifi.colors.redAccent : hifi.colors.lightGrayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: likesText;
|
||||||
|
text: root.likes;
|
||||||
|
// Text size
|
||||||
|
size: hifi.fontSizes.overlayTitle;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.right: heart.left;
|
||||||
|
anchors.rightMargin: 5;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.baseGray;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
onClicked: {
|
||||||
|
console.log("like " + root.item_id);
|
||||||
|
root.liked = !root.liked;
|
||||||
|
root.likes = root.liked ? root.likes + 1 : root.likes - 1;
|
||||||
|
MarketplaceScriptingInterface.marketplaceItemLike(root.item_id, root.liked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
id: itemImage;
|
||||||
|
source: root.image_url;
|
||||||
|
anchors.top: header.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
height: width*0.5625
|
||||||
|
fillMode: Image.PreserveAspectCrop;
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
id: footer;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.top: itemImage.bottom;
|
||||||
|
height: 60;
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: creatorLabel;
|
||||||
|
text: "CREATOR:";
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.lightGrayText;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: creatorText;
|
||||||
|
text: root.creator;
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: creatorLabel.top;
|
||||||
|
anchors.left: creatorLabel.right;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.lightGray;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: categoryLabel;
|
||||||
|
text: "IN:";
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: creatorLabel.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.lightGrayText;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: categoryText;
|
||||||
|
text: root.category;
|
||||||
|
// Text size
|
||||||
|
size: 14;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: categoryLabel.top;
|
||||||
|
anchors.left: categoryLabel.right;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.blueHighlight;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
onClicked: root.categoryClicked(root.category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiControlsUit.Button {
|
||||||
|
text: root.price ? root.price : "FREE";
|
||||||
|
buttonGlyph: root.price ? hifi.glyphs.hfc : "";
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
anchors.rightMargin: 15;
|
||||||
|
anchors.topMargin:10;
|
||||||
|
anchors.bottomMargin: 10;
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2916,7 +2916,7 @@ void Application::initializeUi() {
|
||||||
}, commerceCallback);
|
}, commerceCallback);
|
||||||
|
|
||||||
QmlContextCallback marketplaceCallback = [](QQmlContext* context) {
|
QmlContextCallback marketplaceCallback = [](QQmlContext* context) {
|
||||||
context->setContextProperty("Marketplace", new QmlMarketplace());
|
context->setContextProperty("MarketplaceScriptingInterface", new QmlMarketplace());
|
||||||
};
|
};
|
||||||
OffscreenQmlSurface::addWhitelistContextHandler({
|
OffscreenQmlSurface::addWhitelistContextHandler({
|
||||||
QUrl{ "hifi/commerce/marketplace/Marketplace.qml" },
|
QUrl{ "hifi/commerce/marketplace/Marketplace.qml" },
|
||||||
|
|
|
@ -55,50 +55,54 @@ void QmlMarketplace::getMarketplaceItems(
|
||||||
const int& perPage) {
|
const int& perPage) {
|
||||||
|
|
||||||
QString endpoint = "items";
|
QString endpoint = "items";
|
||||||
QJsonObject request;
|
QUrlQuery request;
|
||||||
request["q"] = q;
|
request.addQueryItem("q", q);
|
||||||
request["view"] = view;
|
request.addQueryItem("view", view);
|
||||||
request["category"] = category;
|
request.addQueryItem("category", category);
|
||||||
request["adminFilter"] = adminFilter;
|
request.addQueryItem("adminFilter", adminFilter);
|
||||||
request["adminFilterCost"] = adminFilterCost;
|
request.addQueryItem("adminFilterCost", adminFilterCost);
|
||||||
request["sort"] = sort;
|
request.addQueryItem("sort", sort);
|
||||||
request["isFree"] = isFree;
|
if (isFree) {
|
||||||
request["page"] = page;
|
request.addQueryItem("isFree", "true");
|
||||||
request["perPage"] = perPage;
|
}
|
||||||
|
request.addQueryItem("page", QString::number(page));
|
||||||
|
request.addQueryItem("perPage", QString::number(perPage));
|
||||||
send(endpoint, "getMarketplaceItemsSuccess", "getMarketplaceItemsFailure", QNetworkAccessManager::GetOperation, AccountManagerAuth::Optional, request);
|
send(endpoint, "getMarketplaceItemsSuccess", "getMarketplaceItemsFailure", QNetworkAccessManager::GetOperation, AccountManagerAuth::Optional, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlMarketplace::getMarketplaceItem(const QString& marketplaceItemId) {
|
void QmlMarketplace::getMarketplaceItem(const QString& marketplaceItemId) {
|
||||||
QString endpoint = QString("items/") + marketplaceItemId;
|
QString endpoint = QString("items/") + marketplaceItemId;
|
||||||
QJsonObject request;
|
QUrlQuery request;
|
||||||
send(endpoint, "getMarketplaceItemSuccess", "getMarketplaceItemFailure", QNetworkAccessManager::GetOperation, AccountManagerAuth::Optional, request);
|
send(endpoint, "getMarketplaceItemSuccess", "getMarketplaceItemFailure", QNetworkAccessManager::GetOperation, AccountManagerAuth::Optional, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlMarketplace::marketplaceItemLike(const QString& marketplaceItemId, const bool like) {
|
void QmlMarketplace::marketplaceItemLike(const QString& marketplaceItemId, const bool like) {
|
||||||
QString endpoint = QString("items/") + marketplaceItemId + "/like";
|
QString endpoint = QString("items/") + marketplaceItemId + "/like";
|
||||||
QJsonObject request;
|
QUrlQuery request;
|
||||||
send(endpoint, "marketplaceItemLikeSuccess", "marketplaceItemLikeFailure", like ? QNetworkAccessManager::PutOperation : QNetworkAccessManager::DeleteOperation, AccountManagerAuth::Required, request);
|
send(endpoint, "marketplaceItemLikeSuccess", "marketplaceItemLikeFailure", like ? QNetworkAccessManager::PostOperation : QNetworkAccessManager::DeleteOperation, AccountManagerAuth::Required, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlMarketplace::getMarketplaceCategories() {
|
void QmlMarketplace::getMarketplaceCategories() {
|
||||||
QString endpoint = "categories";
|
QString endpoint = "categories";
|
||||||
QJsonObject request;
|
QUrlQuery request;
|
||||||
send(endpoint, "getMarketplaceCategoriesSuccess", "getMarketplaceCategoriesFailure", QNetworkAccessManager::GetOperation, AccountManagerAuth::None, 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, QJsonObject 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>();
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
const QString URL = "/api/v1/marketplace/";
|
const QString URL = "/api/v1/marketplace/";
|
||||||
JSONCallbackParameters callbackParams(this, success, fail);
|
JSONCallbackParameters callbackParams(this, success, fail);
|
||||||
#if defined(DEV_BUILD) // Don't expose user's personal data in the wild. But during development this can be handy.
|
|
||||||
qCInfo(commerce) << "Sending" << QJsonDocument(request).toJson(QJsonDocument::Compact);
|
|
||||||
#endif
|
|
||||||
accountManager->sendRequest(URL + endpoint,
|
accountManager->sendRequest(URL + endpoint,
|
||||||
authType,
|
authType,
|
||||||
method,
|
method,
|
||||||
callbackParams,
|
callbackParams,
|
||||||
QJsonDocument(request).toJson());
|
QByteArray(),
|
||||||
|
NULL,
|
||||||
|
QVariantMap(),
|
||||||
|
request);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject QmlMarketplace::apiResponse(const QString& label, QNetworkReply* reply) {
|
QJsonObject QmlMarketplace::apiResponse(const QString& label, QNetworkReply* reply) {
|
||||||
|
|
|
@ -60,7 +60,7 @@ signals:
|
||||||
void marketplaceItemLikeResult(QJsonObject result);
|
void marketplaceItemLikeResult(QJsonObject result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request);
|
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 apiResponse(const QString& label, QNetworkReply* reply);
|
||||||
QJsonObject failResponse(const QString& label, QNetworkReply* reply);
|
QJsonObject failResponse(const QString& label, QNetworkReply* reply);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
QNetworkRequest networkRequest;
|
||||||
networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||||
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter());
|
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter());
|
||||||
|
@ -227,6 +227,7 @@ QNetworkRequest AccountManager::createRequest(QString path, AccountManagerAuth::
|
||||||
} else {
|
} else {
|
||||||
requestURL.setPath("/" + path);
|
requestURL.setPath("/" + path);
|
||||||
}
|
}
|
||||||
|
requestURL.setQuery(query);
|
||||||
|
|
||||||
if (authType != AccountManagerAuth::None ) {
|
if (authType != AccountManagerAuth::None ) {
|
||||||
if (hasValidAccessToken()) {
|
if (hasValidAccessToken()) {
|
||||||
|
@ -263,13 +264,14 @@ void AccountManager::sendRequest(const QString& path,
|
||||||
Q_ARG(const JSONCallbackParameters&, callbackParams),
|
Q_ARG(const JSONCallbackParameters&, callbackParams),
|
||||||
Q_ARG(const QByteArray&, dataByteArray),
|
Q_ARG(const QByteArray&, dataByteArray),
|
||||||
Q_ARG(QHttpMultiPart*, dataMultiPart),
|
Q_ARG(QHttpMultiPart*, dataMultiPart),
|
||||||
Q_ARG(QVariantMap, propertyMap));
|
Q_ARG(QVariantMap, propertyMap),
|
||||||
|
Q_ARG(QUrlQuery, query));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
|
|
||||||
QNetworkRequest networkRequest = createRequest(path, authType);
|
QNetworkRequest networkRequest = createRequest(path, authType, query);
|
||||||
|
|
||||||
if (VERBOSE_HTTP_REQUEST_DEBUGGING) {
|
if (VERBOSE_HTTP_REQUEST_DEBUGGING) {
|
||||||
qCDebug(networking) << "Making a request to" << qPrintable(networkRequest.url().toString());
|
qCDebug(networking) << "Making a request to" << qPrintable(networkRequest.url().toString());
|
||||||
|
|
|
@ -61,7 +61,7 @@ class AccountManager : public QObject, public Dependency {
|
||||||
public:
|
public:
|
||||||
AccountManager(UserAgentGetter userAgentGetter = DEFAULT_USER_AGENT_GETTER);
|
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,
|
Q_INVOKABLE void sendRequest(const QString& path,
|
||||||
AccountManagerAuth::Type authType,
|
AccountManagerAuth::Type authType,
|
||||||
QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation,
|
QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation,
|
||||||
|
|
|
@ -379,21 +379,16 @@ function deleteSendMoneyParticleEffect() {
|
||||||
function onUsernameChanged() {
|
function onUsernameChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var MARKETPLACES_INJECT_SCRIPT_URL = Script.resolvePath("../html/js/marketplacesInject.js");
|
var MARKETPLACE_QML_PATH = "hifi/commerce/marketplace/Marketplace.qml";
|
||||||
var METAVERSE_SERVER_URL = Account.metaverseServerURL;
|
function openMarketplace(optionalItem) {
|
||||||
var MARKETPLACE_URL_INITIAL = MARKETPLACE_URL + "?"; // Append "?" to signal injected script that it's the initial page.
|
ui.open(MARKETPLACE_QML_PATH);
|
||||||
function openMarketplace(optionalItemOrUrl) {
|
|
||||||
// This is a bit of a kluge, but so is the whole file.
|
if (optionalItem) {
|
||||||
// If given a whole path, use it with no cta.
|
ui.tablet.sendToQml({
|
||||||
// If given an id, build the appropriate url and use the id as the cta.
|
method: 'updateMarketplaceQMLItem',
|
||||||
// Otherwise, use home and 'marketplace cta'.
|
params: { itemId: optionalItem }
|
||||||
// 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) {
|
function setCertificateInfo(itemCertificateId) {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
var CLARA_IO_CANCEL_DOWNLOAD = "CLARA.IO CANCEL DOWNLOAD";
|
var CLARA_IO_CANCEL_DOWNLOAD = "CLARA.IO CANCEL DOWNLOAD";
|
||||||
var CLARA_IO_CANCELLED_DOWNLOAD = "CLARA.IO CANCELLED DOWNLOAD";
|
var CLARA_IO_CANCELLED_DOWNLOAD = "CLARA.IO CANCELLED DOWNLOAD";
|
||||||
var GOTO_DIRECTORY = "GOTO_DIRECTORY";
|
var GOTO_DIRECTORY = "GOTO_DIRECTORY";
|
||||||
|
var GOTO_MARKETPLACE = "GOTO_MARKETPLACE";
|
||||||
var QUERY_CAN_WRITE_ASSETS = "QUERY_CAN_WRITE_ASSETS";
|
var QUERY_CAN_WRITE_ASSETS = "QUERY_CAN_WRITE_ASSETS";
|
||||||
var CAN_WRITE_ASSETS = "CAN_WRITE_ASSETS";
|
var CAN_WRITE_ASSETS = "CAN_WRITE_ASSETS";
|
||||||
var WARN_USER_NO_PERMISSIONS = "WARN_USER_NO_PERMISSIONS";
|
var WARN_USER_NO_PERMISSIONS = "WARN_USER_NO_PERMISSIONS";
|
||||||
|
@ -72,7 +73,13 @@
|
||||||
|
|
||||||
// Footer actions.
|
// Footer actions.
|
||||||
$("#back-button").on("click", function () {
|
$("#back-button").on("click", function () {
|
||||||
(document.referrer !== "") ? window.history.back() : window.location = (marketplaceBaseURL + "/marketplace?");
|
if (document.referrer !== "") {
|
||||||
|
window.history.back();
|
||||||
|
} else {
|
||||||
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
|
type: GOTO_MARKETPLACE
|
||||||
|
}));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
$("#all-markets").on("click", function () {
|
$("#all-markets").on("click", function () {
|
||||||
EventBridge.emitWebEvent(JSON.stringify({
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
|
@ -93,7 +100,9 @@
|
||||||
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?";
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
|
type: GOTO_MARKETPLACE
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ var MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH = "hifi/commerce/inspectionCertif
|
||||||
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/wallet/Wallet.qml"; // HRS FIXME "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 MARKETPLACE_QML_PATH = "hifi/commerce/marketplace/Marketplace.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");
|
||||||
var METAVERSE_SERVER_URL = Account.metaverseServerURL;
|
var METAVERSE_SERVER_URL = Account.metaverseServerURL;
|
||||||
|
@ -36,6 +37,7 @@ var CLARA_IO_STATUS = "CLARA.IO STATUS";
|
||||||
var CLARA_IO_CANCEL_DOWNLOAD = "CLARA.IO CANCEL DOWNLOAD";
|
var CLARA_IO_CANCEL_DOWNLOAD = "CLARA.IO CANCEL DOWNLOAD";
|
||||||
var CLARA_IO_CANCELLED_DOWNLOAD = "CLARA.IO CANCELLED DOWNLOAD";
|
var CLARA_IO_CANCELLED_DOWNLOAD = "CLARA.IO CANCELLED DOWNLOAD";
|
||||||
var GOTO_DIRECTORY = "GOTO_DIRECTORY";
|
var GOTO_DIRECTORY = "GOTO_DIRECTORY";
|
||||||
|
var GOTO_MARKETPLACE = "GOTO_MARKETPLACE";
|
||||||
var QUERY_CAN_WRITE_ASSETS = "QUERY_CAN_WRITE_ASSETS";
|
var QUERY_CAN_WRITE_ASSETS = "QUERY_CAN_WRITE_ASSETS";
|
||||||
var CAN_WRITE_ASSETS = "CAN_WRITE_ASSETS";
|
var CAN_WRITE_ASSETS = "CAN_WRITE_ASSETS";
|
||||||
var WARN_USER_NO_PERMISSIONS = "WARN_USER_NO_PERMISSIONS";
|
var WARN_USER_NO_PERMISSIONS = "WARN_USER_NO_PERMISSIONS";
|
||||||
|
@ -154,18 +156,15 @@ function onMarketplaceOpen(referrer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function openMarketplace(optionalItemOrUrl) {
|
function openMarketplace(optionalItem) {
|
||||||
// This is a bit of a kluge, but so is the whole file.
|
ui.open(MARKETPLACE_QML_PATH);
|
||||||
// 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.
|
if (optionalItem) {
|
||||||
// Otherwise, use home and 'marketplace cta'.
|
ui.tablet.sendToQml({
|
||||||
// AND... if call onMarketplaceOpen to setupWallet if we need to.
|
method: 'updateMarketplaceQMLItem',
|
||||||
var url = optionalItemOrUrl || MARKETPLACE_URL_INITIAL;
|
params: { itemId: optionalItem }
|
||||||
// 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 Name: wireQmlEventBridge()
|
// Function Name: wireQmlEventBridge()
|
||||||
|
@ -439,7 +438,9 @@ var referrerURL; // Used for updating Purchases QML
|
||||||
var filterText; // Used for updating Purchases QML
|
var filterText; // Used for updating Purchases QML
|
||||||
function onWebEventReceived(message) {
|
function onWebEventReceived(message) {
|
||||||
message = JSON.parse(message);
|
message = JSON.parse(message);
|
||||||
if (message.type === GOTO_DIRECTORY) {
|
if (message.type === GOTO_MARKETPLACE) {
|
||||||
|
openMarketplace();
|
||||||
|
} else if (message.type === GOTO_DIRECTORY) {
|
||||||
// This is the chooser between marketplaces. Only OUR markteplace
|
// This is the chooser between marketplaces. Only OUR markteplace
|
||||||
// requires/makes-use-of wallet, so doesn't go through openMarketplace bottleneck.
|
// requires/makes-use-of wallet, so doesn't go through openMarketplace bottleneck.
|
||||||
ui.open(MARKETPLACES_URL, MARKETPLACES_INJECT_SCRIPT_URL);
|
ui.open(MARKETPLACES_URL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||||
|
@ -518,6 +519,7 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
||||||
if (message.messageSrc === "HTML") {
|
if (message.messageSrc === "HTML") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log(JSON.stringify(message));
|
||||||
switch (message.method) {
|
switch (message.method) {
|
||||||
case 'gotoBank':
|
case 'gotoBank':
|
||||||
ui.close();
|
ui.close();
|
||||||
|
@ -560,6 +562,18 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
||||||
case 'checkout_continue':
|
case 'checkout_continue':
|
||||||
openMarketplace();
|
openMarketplace();
|
||||||
break;
|
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.
|
||||||
|
ui.open(MARKETPLACES_URL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||||
|
break;
|
||||||
case 'checkout_rezClicked':
|
case 'checkout_rezClicked':
|
||||||
case 'purchases_rezClicked':
|
case 'purchases_rezClicked':
|
||||||
case 'tester_rezClicked':
|
case 'tester_rezClicked':
|
||||||
|
@ -699,7 +713,9 @@ var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
||||||
var onMarketplaceItemTesterScreenNow = (
|
var onMarketplaceItemTesterScreenNow = (
|
||||||
url.indexOf(MARKETPLACE_ITEM_TESTER_QML_PATH) !== -1 ||
|
url.indexOf(MARKETPLACE_ITEM_TESTER_QML_PATH) !== -1 ||
|
||||||
url === MARKETPLACE_ITEM_TESTER_QML_PATH);
|
url === MARKETPLACE_ITEM_TESTER_QML_PATH);
|
||||||
|
var onMarketplaceScreenNow = (
|
||||||
|
url.indexOf(MARKETPLACE_QML_PATH) !== -1 ||
|
||||||
|
url === MARKETPLACE_QML_PATH);
|
||||||
if ((!onWalletScreenNow && onWalletScreen) ||
|
if ((!onWalletScreenNow && onWalletScreen) ||
|
||||||
(!onCommerceScreenNow && onCommerceScreen) ||
|
(!onCommerceScreenNow && onCommerceScreen) ||
|
||||||
(!onMarketplaceItemTesterScreenNow && onMarketplaceScreen)
|
(!onMarketplaceItemTesterScreenNow && onMarketplaceScreen)
|
||||||
|
@ -711,7 +727,7 @@ var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
||||||
onCommerceScreen = onCommerceScreenNow;
|
onCommerceScreen = onCommerceScreenNow;
|
||||||
onWalletScreen = onWalletScreenNow;
|
onWalletScreen = onWalletScreenNow;
|
||||||
onMarketplaceItemTesterScreen = onMarketplaceItemTesterScreenNow;
|
onMarketplaceItemTesterScreen = onMarketplaceItemTesterScreenNow;
|
||||||
wireQmlEventBridge(onCommerceScreen || onWalletScreen || onMarketplaceItemTesterScreen);
|
wireQmlEventBridge(onCommerceScreen || onWalletScreen || onMarketplaceItemTesterScreen || onMarketplaceScreenNow);
|
||||||
|
|
||||||
if (url === MARKETPLACE_PURCHASES_QML_PATH) {
|
if (url === MARKETPLACE_PURCHASES_QML_PATH) {
|
||||||
// FIXME? Is there a race condition here in which the event
|
// FIXME? Is there a race condition here in which the event
|
||||||
|
@ -769,14 +785,13 @@ var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
||||||
|
|
||||||
|
|
||||||
var BUTTON_NAME = "MARKET";
|
var BUTTON_NAME = "MARKET";
|
||||||
var MARKETPLACE_QML_SOURCE = "hifi/commerce/marketplace/Marketplace.qml";
|
|
||||||
|
|
||||||
var ui;
|
var ui;
|
||||||
function startup() {
|
function startup() {
|
||||||
ui = new AppUi({
|
ui = new AppUi({
|
||||||
buttonName: BUTTON_NAME,
|
buttonName: BUTTON_NAME,
|
||||||
sortOrder: 9,
|
sortOrder: 9,
|
||||||
home: MARKETPLACE_QML_SOURCE,
|
home: MARKETPLACE_QML_PATH,
|
||||||
onScreenChanged: onTabletScreenChanged,
|
onScreenChanged: onTabletScreenChanged,
|
||||||
onMessage: onQmlMessageReceived
|
onMessage: onQmlMessageReceived
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue