mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +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,24 +30,72 @@ Rectangle {
|
|||
|
||||
property string activeView: "initialize";
|
||||
property bool keyboardRaised: false;
|
||||
property int category_index: -1;
|
||||
property alias categoryChoices: categoriesModel;
|
||||
property int currentSortIndex: 0;
|
||||
property string sortString: "";
|
||||
property string categoryString: "";
|
||||
property string searchString: "";
|
||||
|
||||
anchors.fill: (typeof parent === undefined) ? undefined : parent;
|
||||
|
||||
function getMarketplaceItems() {
|
||||
marketplaceItemView.visible = false;
|
||||
itemsList.visible = true;
|
||||
marketBrowseModel.getFirstPage();
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
KeyboardScriptingInterface.raised = false;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Marketplace;
|
||||
target: MarketplaceScriptingInterface;
|
||||
|
||||
onGetMarketplaceCategoriesResult: {
|
||||
if (result.status !== 'success') {
|
||||
console.log("Failed to get Marketplace Categories", result.data.message);
|
||||
} 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
|
||||
//
|
||||
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;
|
||||
visible: true;
|
||||
width: parent.width;
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
|
||||
Item {
|
||||
anchors.topMargin: -1;
|
||||
anchors.leftMargin: -1;
|
||||
anchors.rightMargin: -1;
|
||||
height: childrenRect.height+5;
|
||||
z: 5;
|
||||
|
||||
Rectangle {
|
||||
id: titleBarContainer;
|
||||
visible: true;
|
||||
// Size
|
||||
|
@ -77,13 +146,14 @@ Rectangle {
|
|||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
||||
// Wallet icon
|
||||
|
||||
|
||||
// Marketplace icon
|
||||
Image {
|
||||
id: walletIcon;
|
||||
id: marketplaceIcon;
|
||||
source: "../../../../images/hifi-logo-blackish.svg";
|
||||
height: 20
|
||||
width: walletIcon.height;
|
||||
width: marketplaceIcon.height;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
|
@ -98,7 +168,7 @@ Rectangle {
|
|||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: walletIcon.right;
|
||||
anchors.left: marketplaceIcon.right;
|
||||
anchors.leftMargin: 6;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
|
@ -109,9 +179,10 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Rectangle {
|
||||
id: searchBarContainer;
|
||||
visible: true;
|
||||
clip: false;
|
||||
// Size
|
||||
width: parent.width;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
|
@ -125,10 +196,10 @@ Rectangle {
|
|||
anchors.verticalCenter: parent.verticalCenter;
|
||||
height: 34;
|
||||
width: categoriesText.width + 25;
|
||||
color: "white";
|
||||
color: hifi.colors.white;
|
||||
radius: 4;
|
||||
border.width: 1;
|
||||
border.color: hifi.colors.lightGray;
|
||||
border.color: hifi.colors.lightGrayText;
|
||||
|
||||
|
||||
// Categories Text
|
||||
|
@ -136,9 +207,9 @@ Rectangle {
|
|||
id: categoriesText;
|
||||
text: "Categories";
|
||||
// Text size
|
||||
size: 18;
|
||||
size: 14;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
color: hifi.colors.lightGrayText;
|
||||
elide: Text.ElideRight;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
@ -166,6 +237,8 @@ Rectangle {
|
|||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
categoriesDropdown.visible = !categoriesDropdown.visible;
|
||||
categoriesButton.color = categoriesDropdown.visible ? hifi.colors.lightGray : hifi.colors.white;
|
||||
categoriesDropdown.forceActiveFocus();
|
||||
}
|
||||
onEntered: categoriesText.color = hifi.colors.baseGrayShadow;
|
||||
onExited: categoriesText.color = hifi.colors.baseGray;
|
||||
|
@ -173,77 +246,10 @@ Rectangle {
|
|||
|
||||
Component.onCompleted: {
|
||||
console.log("Getting Marketplace Categories");
|
||||
console.log(JSON.stringify(Marketplace));
|
||||
Marketplace.getMarketplaceItems();
|
||||
MarketplaceScriptingInterface.getMarketplaceCategories();
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// or
|
||||
RalewayRegular {
|
||||
id: orText;
|
||||
|
@ -283,7 +289,6 @@ Rectangle {
|
|||
font.family: "FiraSans Regular";
|
||||
font.pixelSize: hifi.fontSizes.textFieldInput;
|
||||
font.capitalization: Font.AllUppercase;
|
||||
text: root.primaryFilter_displayName;
|
||||
}
|
||||
|
||||
// workaround for https://bugreports.qt.io/browse/QTBUG-49297
|
||||
|
@ -295,20 +300,22 @@ Rectangle {
|
|||
|
||||
// emit accepted signal manually
|
||||
if (acceptableInput) {
|
||||
root.accepted();
|
||||
root.forceActiveFocus();
|
||||
searchField.accepted();
|
||||
searchField.forceActiveFocus();
|
||||
}
|
||||
break;
|
||||
case Qt.Key_Backspace:
|
||||
if (textField.text === "") {
|
||||
if (searchField.text === "") {
|
||||
primaryFilter_index = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onTextChanged: root.searchString = text;
|
||||
onAccepted: {
|
||||
root.forceActiveFocus();
|
||||
root.searchString = searchField.text;
|
||||
getMarketplaceItems();
|
||||
searchField.forceActiveFocus();
|
||||
}
|
||||
|
||||
onActiveFocusChanged: {
|
||||
|
@ -320,17 +327,579 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// HEADER BAR END
|
||||
//
|
||||
DropShadow {
|
||||
anchors.fill: header;
|
||||
horizontalOffset: 0;
|
||||
verticalOffset: 4;
|
||||
radius: 4.0;
|
||||
samples: 9
|
||||
color: Qt.rgba(0, 0, 0, 0.25);
|
||||
source: header;
|
||||
visible: header.visible;
|
||||
|
||||
//
|
||||
// CATEGORIES LIST START
|
||||
//
|
||||
Item {
|
||||
id: categoriesDropdown;
|
||||
anchors.fill: parent;
|
||||
visible: false;
|
||||
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);
|
||||
|
||||
QmlContextCallback marketplaceCallback = [](QQmlContext* context) {
|
||||
context->setContextProperty("Marketplace", new QmlMarketplace());
|
||||
context->setContextProperty("MarketplaceScriptingInterface", new QmlMarketplace());
|
||||
};
|
||||
OffscreenQmlSurface::addWhitelistContextHandler({
|
||||
QUrl{ "hifi/commerce/marketplace/Marketplace.qml" },
|
||||
|
|
|
@ -55,50 +55,54 @@ void QmlMarketplace::getMarketplaceItems(
|
|||
const int& perPage) {
|
||||
|
||||
QString endpoint = "items";
|
||||
QJsonObject request;
|
||||
request["q"] = q;
|
||||
request["view"] = view;
|
||||
request["category"] = category;
|
||||
request["adminFilter"] = adminFilter;
|
||||
request["adminFilterCost"] = adminFilterCost;
|
||||
request["sort"] = sort;
|
||||
request["isFree"] = isFree;
|
||||
request["page"] = page;
|
||||
request["perPage"] = perPage;
|
||||
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;
|
||||
QJsonObject request;
|
||||
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";
|
||||
QJsonObject request;
|
||||
send(endpoint, "marketplaceItemLikeSuccess", "marketplaceItemLikeFailure", like ? QNetworkAccessManager::PutOperation : QNetworkAccessManager::DeleteOperation, AccountManagerAuth::Required, request);
|
||||
QUrlQuery request;
|
||||
send(endpoint, "marketplaceItemLikeSuccess", "marketplaceItemLikeFailure", like ? QNetworkAccessManager::PostOperation : QNetworkAccessManager::DeleteOperation, AccountManagerAuth::Required, request);
|
||||
}
|
||||
|
||||
void QmlMarketplace::getMarketplaceCategories() {
|
||||
QString endpoint = "categories";
|
||||
QJsonObject request;
|
||||
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, 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>();
|
||||
const QString URL = "/api/v1/marketplace/";
|
||||
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,
|
||||
authType,
|
||||
method,
|
||||
callbackParams,
|
||||
QJsonDocument(request).toJson());
|
||||
QByteArray(),
|
||||
NULL,
|
||||
QVariantMap(),
|
||||
request);
|
||||
|
||||
}
|
||||
|
||||
QJsonObject QmlMarketplace::apiResponse(const QString& label, QNetworkReply* reply) {
|
||||
|
|
|
@ -60,7 +60,7 @@ signals:
|
|||
void marketplaceItemLikeResult(QJsonObject result);
|
||||
|
||||
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 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;
|
||||
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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,13 @@
|
|||
|
||||
// Footer actions.
|
||||
$("#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 () {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
|
@ -93,7 +100,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
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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_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 +37,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 +156,15 @@ 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) {
|
||||
ui.open(MARKETPLACE_QML_PATH);
|
||||
|
||||
if (optionalItem) {
|
||||
ui.tablet.sendToQml({
|
||||
method: 'updateMarketplaceQMLItem',
|
||||
params: { itemId: optionalItem }
|
||||
});
|
||||
}
|
||||
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();
|
||||
} 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);
|
||||
|
@ -518,6 +519,7 @@ var onQmlMessageReceived = function onQmlMessageReceived(message) {
|
|||
if (message.messageSrc === "HTML") {
|
||||
return;
|
||||
}
|
||||
console.log(JSON.stringify(message));
|
||||
switch (message.method) {
|
||||
case 'gotoBank':
|
||||
ui.close();
|
||||
|
@ -560,6 +562,18 @@ 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.
|
||||
ui.open(MARKETPLACES_URL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
break;
|
||||
case 'checkout_rezClicked':
|
||||
case 'purchases_rezClicked':
|
||||
case 'tester_rezClicked':
|
||||
|
@ -699,7 +713,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 +727,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
|
||||
|
@ -769,14 +785,13 @@ var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
|||
|
||||
|
||||
var BUTTON_NAME = "MARKET";
|
||||
var MARKETPLACE_QML_SOURCE = "hifi/commerce/marketplace/Marketplace.qml";
|
||||
|
||||
var ui;
|
||||
function startup() {
|
||||
ui = new AppUi({
|
||||
buttonName: BUTTON_NAME,
|
||||
sortOrder: 9,
|
||||
home: MARKETPLACE_QML_SOURCE,
|
||||
home: MARKETPLACE_QML_PATH,
|
||||
onScreenChanged: onTabletScreenChanged,
|
||||
onMessage: onQmlMessageReceived
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue