mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-14 11:46:34 +02:00
QML Marketplace support
Support QML UI for the Marketplace as some devices do not handle web on 3d surfaces. Checkpoint code
This commit is contained in:
parent
0ab13f1e48
commit
8010d86210
6 changed files with 565 additions and 104 deletions
|
@ -0,0 +1,336 @@
|
|||
//
|
||||
// Marketplace.qml
|
||||
// qml/hifi/commerce/marketplace
|
||||
//
|
||||
// Marketplace
|
||||
//
|
||||
// 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
|
||||
|
||||
Rectangle {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
|
||||
property string activeView: "initialize";
|
||||
property bool keyboardRaised: false;
|
||||
property int category_index: -1;
|
||||
property alias categoryChoices: categoriesModel;
|
||||
|
||||
anchors.fill: (typeof parent === undefined) ? undefined : parent;
|
||||
|
||||
Component.onDestruction: {
|
||||
KeyboardScriptingInterface.raised = false;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Marketplace;
|
||||
|
||||
onGetMarketplaceCategoriesResult: {
|
||||
if (result.status !== 'success') {
|
||||
console.log("Failed to get Marketplace Categories", result.data.message);
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HifiCommerceCommon.CommerceLightbox {
|
||||
id: lightboxPopup;
|
||||
visible: false;
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
//
|
||||
// HEADER BAR START
|
||||
//
|
||||
Item {
|
||||
id: header;
|
||||
visible: true;
|
||||
width: parent.width;
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
|
||||
Item {
|
||||
id: titleBarContainer;
|
||||
visible: true;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
||||
// Wallet icon
|
||||
Image {
|
||||
id: walletIcon;
|
||||
source: "../../../../images/hifi-logo-blackish.svg";
|
||||
height: 20
|
||||
width: walletIcon.height;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
visible: true;
|
||||
}
|
||||
|
||||
// Title Bar text
|
||||
RalewaySemiBold {
|
||||
id: titleBarText;
|
||||
text: "Marketplace";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: walletIcon.right;
|
||||
anchors.leftMargin: 6;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.black;
|
||||
// Alignment
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: searchBarContainer;
|
||||
visible: true;
|
||||
// Size
|
||||
width: parent.width;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
height: 50;
|
||||
|
||||
|
||||
Rectangle {
|
||||
id: categoriesButton;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 10;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
height: 34;
|
||||
width: categoriesText.width + 25;
|
||||
color: "white";
|
||||
radius: 4;
|
||||
border.width: 1;
|
||||
border.color: hifi.colors.lightGray;
|
||||
|
||||
|
||||
// Categories Text
|
||||
RalewayRegular {
|
||||
id: categoriesText;
|
||||
text: "Categories";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
elide: Text.ElideRight;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
width: Math.min(textMetrics.width + 25, 110);
|
||||
// Anchors
|
||||
anchors.centerIn: parent;
|
||||
rightPadding: 10;
|
||||
}
|
||||
HiFiGlyphs {
|
||||
id: categoriesDropdownIcon;
|
||||
text: hifi.glyphs.caratDn;
|
||||
// Size
|
||||
size: 34;
|
||||
// Anchors
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: -8;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
categoriesDropdown.visible = !categoriesDropdown.visible;
|
||||
}
|
||||
onEntered: categoriesText.color = hifi.colors.baseGrayShadow;
|
||||
onExited: categoriesText.color = hifi.colors.baseGray;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
console.log("Getting Marketplace Categories");
|
||||
console.log(JSON.stringify(Marketplace));
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// or
|
||||
RalewayRegular {
|
||||
id: orText;
|
||||
text: "or";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
elide: Text.ElideRight;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
width: Math.min(textMetrics.width + 25, 110);
|
||||
// Anchors
|
||||
anchors.left: categoriesButton.right;
|
||||
rightPadding: 10;
|
||||
leftPadding: 10;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
}
|
||||
HifiControlsUit.TextField {
|
||||
id: searchField;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.right: parent.right;
|
||||
anchors.left: orText.right;
|
||||
anchors.rightMargin: 10;
|
||||
height: 34;
|
||||
isSearchField: true;
|
||||
colorScheme: hifi.colorSchemes.faintGray;
|
||||
|
||||
|
||||
font.family: "Fira Sans"
|
||||
font.pixelSize: hifi.fontSizes.textFieldInput;
|
||||
|
||||
placeholderText: "Search Marketplace";
|
||||
|
||||
TextMetrics {
|
||||
id: primaryFilterTextMetrics;
|
||||
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
|
||||
Keys.onPressed: {
|
||||
switch (event.key) {
|
||||
case Qt.Key_Return:
|
||||
case Qt.Key_Enter:
|
||||
event.accepted = true;
|
||||
|
||||
// emit accepted signal manually
|
||||
if (acceptableInput) {
|
||||
root.accepted();
|
||||
root.forceActiveFocus();
|
||||
}
|
||||
break;
|
||||
case Qt.Key_Backspace:
|
||||
if (textField.text === "") {
|
||||
primaryFilter_index = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
root.forceActiveFocus();
|
||||
}
|
||||
|
||||
onActiveFocusChanged: {
|
||||
if (!activeFocus) {
|
||||
dropdownContainer.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
}
|
|
@ -232,6 +232,7 @@
|
|||
#include "commerce/Ledger.h"
|
||||
#include "commerce/Wallet.h"
|
||||
#include "commerce/QmlCommerce.h"
|
||||
#include "commerce/QmlMarketplace.h"
|
||||
#include "ResourceRequestObserver.h"
|
||||
|
||||
#include "webbrowser/WebBrowserSuggestionsEngine.h"
|
||||
|
@ -2913,6 +2914,14 @@ void Application::initializeUi() {
|
|||
QUrl{ "hifi/dialogs/security/SecurityImageModel.qml" },
|
||||
QUrl{ "hifi/dialogs/security/SecurityImageSelection.qml" },
|
||||
}, commerceCallback);
|
||||
|
||||
QmlContextCallback marketplaceCallback = [](QQmlContext* context) {
|
||||
context->setContextProperty("Marketplace", new QmlMarketplace());
|
||||
};
|
||||
OffscreenQmlSurface::addWhitelistContextHandler({
|
||||
QUrl{ "hifi/commerce/marketplace/Marketplace.qml" },
|
||||
}, marketplaceCallback);
|
||||
|
||||
QmlContextCallback ttsCallback = [](QQmlContext* context) {
|
||||
context->setContextProperty("TextToSpeech", DependencyManager::get<TTSScriptingInterface>().data());
|
||||
};
|
||||
|
|
131
interface/src/commerce/QmlMarketplace.cpp
Normal file
131
interface/src/commerce/QmlMarketplace.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
//
|
||||
// QmlMarketplace.cpp
|
||||
// interface/src/commerce
|
||||
//
|
||||
// Guard for safe use of Marketplace by authorized QML.
|
||||
//
|
||||
// Created by Roxanne Skelly on 1/18/19.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
#include "QmlMarketplace.h"
|
||||
#include "CommerceLogging.h"
|
||||
#include "Application.h"
|
||||
#include "DependencyManager.h"
|
||||
#include <Application.h>
|
||||
#include <UserActivityLogger.h>
|
||||
#include <ScriptEngines.h>
|
||||
#include <ui/TabletScriptingInterface.h>
|
||||
#include "scripting/HMDScriptingInterface.h"
|
||||
|
||||
#define ApiHandler(NAME) void QmlMarketplace::NAME##Success(QNetworkReply* reply) { emit NAME##Result(apiResponse(#NAME, reply)); }
|
||||
#define FailHandler(NAME) void QmlMarketplace::NAME##Failure(QNetworkReply* reply) { emit NAME##Result(failResponse(#NAME, reply)); }
|
||||
#define Handler(NAME) ApiHandler(NAME) FailHandler(NAME)
|
||||
Handler(getMarketplaceItems)
|
||||
Handler(getMarketplaceItem)
|
||||
Handler(marketplaceItemLike)
|
||||
Handler(getMarketplaceCategories)
|
||||
|
||||
QmlMarketplace::QmlMarketplace() {
|
||||
}
|
||||
|
||||
void QmlMarketplace::openMarketplace(const QString& marketplaceItemId) {
|
||||
auto tablet = dynamic_cast<TabletProxy*>(
|
||||
DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system"));
|
||||
tablet->loadQMLSource("hifi/commerce/marketplace/Marketplace.qml");
|
||||
DependencyManager::get<HMDScriptingInterface>()->openTablet();
|
||||
if (!marketplaceItemId.isEmpty()) {
|
||||
tablet->sendToQml(QVariantMap({ { "method", "marketplace_openItem" }, { "itemId", marketplaceItemId } }));
|
||||
}
|
||||
}
|
||||
|
||||
void QmlMarketplace::getMarketplaceItems(
|
||||
const QString& q,
|
||||
const QString& view,
|
||||
const QString& category,
|
||||
const QString& adminFilter,
|
||||
const QString& adminFilterCost,
|
||||
const QString& sort,
|
||||
const bool isFree,
|
||||
const int& page,
|
||||
const int& perPage) {
|
||||
|
||||
QString endpoint = "items";
|
||||
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;
|
||||
send(endpoint, "getMarketplaceItemsSuccess", "getMarketplaceItemsFailure", QNetworkAccessManager::GetOperation, AccountManagerAuth::Optional, request);
|
||||
}
|
||||
|
||||
void QmlMarketplace::getMarketplaceItem(const QString& marketplaceItemId) {
|
||||
QString endpoint = QString("items/") + marketplaceItemId;
|
||||
QJsonObject 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);
|
||||
}
|
||||
|
||||
void QmlMarketplace::getMarketplaceCategories() {
|
||||
QString endpoint = "categories";
|
||||
QJsonObject 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) {
|
||||
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());
|
||||
}
|
||||
|
||||
QJsonObject QmlMarketplace::apiResponse(const QString& label, QNetworkReply* reply) {
|
||||
QByteArray response = reply->readAll();
|
||||
QJsonObject data = QJsonDocument::fromJson(response).object();
|
||||
#if defined(DEV_BUILD) // Don't expose user's personal data in the wild. But during development this can be handy.
|
||||
qInfo(commerce) << label << "response" << QJsonDocument(data).toJson(QJsonDocument::Compact);
|
||||
#endif
|
||||
return data;
|
||||
}
|
||||
|
||||
// Non-200 responses are not json:
|
||||
QJsonObject QmlMarketplace::failResponse(const QString& label, QNetworkReply* reply) {
|
||||
QString response = reply->readAll();
|
||||
qWarning(commerce) << "FAILED" << label << response;
|
||||
|
||||
// tempResult will be NULL if the response isn't valid JSON.
|
||||
QJsonDocument tempResult = QJsonDocument::fromJson(response.toLocal8Bit());
|
||||
if (tempResult.isNull()) {
|
||||
QJsonObject result
|
||||
{
|
||||
{ "status", "fail" },
|
||||
{ "message", response }
|
||||
};
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return tempResult.object();
|
||||
}
|
||||
}
|
68
interface/src/commerce/QmlMarketplace.h
Normal file
68
interface/src/commerce/QmlMarketplace.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
//
|
||||
// QmlMarketplace.h
|
||||
// interface/src/commerce
|
||||
//
|
||||
// Guard for safe use of Marketplace by authorized QML.
|
||||
//
|
||||
// Created by Roxanne Skelly on 1/18/19.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef hifi_QmlMarketplace_h
|
||||
#define hifi_QmlMarketplace_h
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include "AccountManager.h"
|
||||
|
||||
class QmlMarketplace : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QmlMarketplace();
|
||||
|
||||
public slots:
|
||||
void getMarketplaceItemsSuccess(QNetworkReply* reply);
|
||||
void getMarketplaceItemsFailure(QNetworkReply* reply);
|
||||
void getMarketplaceItemSuccess(QNetworkReply* reply);
|
||||
void getMarketplaceItemFailure(QNetworkReply* reply);
|
||||
void getMarketplaceCategoriesSuccess(QNetworkReply* reply);
|
||||
void getMarketplaceCategoriesFailure(QNetworkReply* reply);
|
||||
void marketplaceItemLikeSuccess(QNetworkReply* reply);
|
||||
void marketplaceItemLikeFailure(QNetworkReply* reply);
|
||||
|
||||
protected:
|
||||
Q_INVOKABLE void openMarketplace(const QString& marketplaceItemId = QString());
|
||||
Q_INVOKABLE void getMarketplaceItems(
|
||||
const QString& q = QString(),
|
||||
const QString& view = QString(),
|
||||
const QString& category = QString(),
|
||||
const QString& adminFilter = QString("published"),
|
||||
const QString& adminFilterCost = QString(),
|
||||
const QString& sort = QString(),
|
||||
const bool isFree = false,
|
||||
const int& page = 1,
|
||||
const int& perPage = 20);
|
||||
Q_INVOKABLE void getMarketplaceItem(const QString& marketplaceItemId);
|
||||
Q_INVOKABLE void marketplaceItemLike(const QString& marketplaceItemId, const bool like = true);
|
||||
Q_INVOKABLE void getMarketplaceCategories();
|
||||
|
||||
signals:
|
||||
void getMarketplaceItemsResult(QJsonObject result);
|
||||
void getMarketplaceItemResult(QJsonObject result);
|
||||
void getMarketplaceCategoriesResult(QJsonObject result);
|
||||
void marketplaceItemLikeResult(QJsonObject result);
|
||||
|
||||
private:
|
||||
void send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request);
|
||||
QJsonObject apiResponse(const QString& label, QNetworkReply* reply);
|
||||
QJsonObject failResponse(const QString& label, QNetworkReply* reply);
|
||||
};
|
||||
|
||||
#endif // hifi_QmlMarketplace_h
|
|
@ -1,8 +1,8 @@
|
|||
//
|
||||
// marketplace.js
|
||||
//
|
||||
// Created by Eric Levin on 8 Jan 2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
// Created by Roxanne Skelly on 1/18/2019
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -10,108 +10,27 @@
|
|||
|
||||
(function() { // BEGIN LOCAL_SCOPE
|
||||
|
||||
/* global WebTablet */
|
||||
Script.include("../libraries/WebTablet.js");
|
||||
var AppUi = Script.require('appUi');
|
||||
|
||||
var toolIconUrl = Script.resolvePath("../assets/images/tools/");
|
||||
var BUTTON_NAME = "MARKET";
|
||||
var MARKETPLACE_QML_SOURCE = "hifi/commerce/marketplace/Marketplace.qml";
|
||||
var ui;
|
||||
function startup() {
|
||||
|
||||
var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace";
|
||||
var marketplaceWindow = new OverlayWebWindow({
|
||||
title: "Marketplace",
|
||||
source: "about:blank",
|
||||
width: 900,
|
||||
height: 700,
|
||||
visible: false
|
||||
});
|
||||
|
||||
var toolHeight = 50;
|
||||
var toolWidth = 50;
|
||||
var TOOLBAR_MARGIN_Y = 0;
|
||||
var marketplaceVisible = false;
|
||||
var marketplaceWebTablet;
|
||||
|
||||
// We persist avatarEntity data in the .ini file, and reconsistitute it on restart.
|
||||
// To keep things consistent, we pickle the tablet data in Settings, and kill any existing such on restart and domain change.
|
||||
var persistenceKey = "io.highfidelity.lastDomainTablet";
|
||||
|
||||
function shouldShowWebTablet() {
|
||||
var rightPose = Controller.getPoseValue(Controller.Standard.RightHand);
|
||||
var leftPose = Controller.getPoseValue(Controller.Standard.LeftHand);
|
||||
var hasHydra = !!Controller.Hardware.Hydra;
|
||||
return HMD.active && (leftPose.valid || rightPose.valid || hasHydra);
|
||||
ui = new AppUi({
|
||||
buttonName: BUTTON_NAME,
|
||||
sortOrder: 10,
|
||||
home: MARKETPLACE_QML_SOURCE
|
||||
});
|
||||
}
|
||||
|
||||
function showMarketplace(marketplaceID) {
|
||||
var url = MARKETPLACE_URL;
|
||||
if (marketplaceID) {
|
||||
url = url + "/items/" + marketplaceID;
|
||||
}
|
||||
tablet.gotoWebScreen(url);
|
||||
marketplaceVisible = true;
|
||||
UserActivityLogger.openedMarketplace();
|
||||
function shutdown() {
|
||||
}
|
||||
|
||||
function hideTablet(tablet) {
|
||||
if (!tablet) {
|
||||
return;
|
||||
}
|
||||
updateButtonState(false);
|
||||
tablet.unregister();
|
||||
tablet.destroy();
|
||||
marketplaceWebTablet = null;
|
||||
Settings.setValue(persistenceKey, "");
|
||||
}
|
||||
function clearOldTablet() { // If there was a tablet from previous domain or session, kill it and let it be recreated
|
||||
|
||||
}
|
||||
function hideMarketplace() {
|
||||
if (marketplaceWindow.visible) {
|
||||
marketplaceWindow.setVisible(false);
|
||||
marketplaceWindow.setURL("about:blank");
|
||||
} else if (marketplaceWebTablet) {
|
||||
|
||||
}
|
||||
marketplaceVisible = false;
|
||||
}
|
||||
|
||||
function toggleMarketplace() {
|
||||
if (marketplaceVisible) {
|
||||
hideMarketplace();
|
||||
} else {
|
||||
showMarketplace();
|
||||
}
|
||||
}
|
||||
|
||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
|
||||
var browseExamplesButton = tablet.addButton({
|
||||
icon: "icons/tablet-icons/market-i.svg",
|
||||
text: "MARKET"
|
||||
});
|
||||
|
||||
function updateButtonState(visible) {
|
||||
|
||||
}
|
||||
function onMarketplaceWindowVisibilityChanged() {
|
||||
updateButtonState(marketplaceWindow.visible);
|
||||
marketplaceVisible = marketplaceWindow.visible;
|
||||
}
|
||||
|
||||
function onClick() {
|
||||
toggleMarketplace();
|
||||
}
|
||||
|
||||
browseExamplesButton.clicked.connect(onClick);
|
||||
marketplaceWindow.visibleChanged.connect(onMarketplaceWindowVisibilityChanged);
|
||||
|
||||
clearOldTablet(); // Run once at startup, in case there's anything laying around from a crash.
|
||||
// We could also optionally do something like Window.domainChanged.connect(function () {Script.setTimeout(clearOldTablet, 2000)}),
|
||||
// but the HUD version stays around, so lets do the same.
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
browseExamplesButton.clicked.disconnect(onClick);
|
||||
tablet.removeButton(browseExamplesButton);
|
||||
marketplaceWindow.visibleChanged.disconnect(onMarketplaceWindowVisibilityChanged);
|
||||
});
|
||||
//
|
||||
// Run the functions.
|
||||
//
|
||||
startup();
|
||||
Script.scriptEnding.connect(shutdown);
|
||||
|
||||
}()); // END LOCAL_SCOPE
|
||||
|
|
|
@ -769,16 +769,14 @@ var onTabletScreenChanged = function onTabletScreenChanged(type, url) {
|
|||
|
||||
|
||||
var BUTTON_NAME = "MARKET";
|
||||
var MARKETPLACE_URL = METAVERSE_SERVER_URL + "/marketplace";
|
||||
// Append "?" if necessary to signal injected script that it's the initial page.
|
||||
var MARKETPLACE_URL_INITIAL = MARKETPLACE_URL + (MARKETPLACE_URL.indexOf("?") > -1 ? "" : "?");
|
||||
var MARKETPLACE_QML_SOURCE = "hifi/commerce/marketplace/Marketplace.qml";
|
||||
|
||||
var ui;
|
||||
function startup() {
|
||||
ui = new AppUi({
|
||||
buttonName: BUTTON_NAME,
|
||||
sortOrder: 9,
|
||||
inject: MARKETPLACES_INJECT_SCRIPT_URL,
|
||||
home: MARKETPLACE_URL_INITIAL,
|
||||
home: MARKETPLACE_QML_SOURCE,
|
||||
onScreenChanged: onTabletScreenChanged,
|
||||
onMessage: onQmlMessageReceived
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue