Merge pull request #11147 from elisa-lj11/blocks

Adding Blocks Tablet App to Marketplace
This commit is contained in:
Elisa Lupin-Jimenez 2017-08-18 15:06:18 -07:00 committed by GitHub
commit 44f1f340e1
14 changed files with 146 additions and 33 deletions

View file

@ -24,6 +24,7 @@ Item {
property alias webView: webview
property alias profile: webview.profile
property bool remove: false
property bool closeButtonVisible: true
// Manage own browse history because WebEngineView history is wiped when a new URL is loaded via
// onNewViewRequested, e.g., as happens when a social media share button is clicked.
@ -64,6 +65,7 @@ Item {
disabledColor: hifi.colors.lightGrayText
enabled: true
text: "CLOSE"
visible: closeButtonVisible
MouseArea {
anchors.fill: parent

View file

@ -93,6 +93,11 @@ Item {
loader.source = "";
loader.source = "TabletWebView.qml";
}
function loadTabletWebBase() {
loader.source = "";
loader.source = "../../controls/TabletWebView.qml";
}
function returnToPreviousApp() {
tabletApps.remove(currentApp);
@ -121,6 +126,9 @@ Item {
loader.item.url = url;
loader.item.scriptURL = injectedJavaScriptUrl;
tabletApps.append({"appUrl": "TabletWebView.qml", "isWebUrl": true, "scriptUrl": injectedJavaScriptUrl, "appWebUrl": url});
if (loader.item.hasOwnProperty("closeButtonVisible")) {
loader.item.closeButtonVisible = false;
}
}
// used to send a message from qml to interface script.

View file

@ -42,9 +42,17 @@ Windows.ScrollingWindow {
loader.source = "WindowWebView.qml";
}
function loadTabletWebBase() {
loader.source = "";
loader.source = "../../controls/TabletWebView.qml";
}
function loadWebUrl(url, injectedJavaScriptUrl) {
loader.item.url = url;
loader.item.scriptURL = injectedJavaScriptUrl;
if (loader.item.hasOwnProperty("closeButtonVisible")) {
loader.item.closeButtonVisible = false;
}
}
// used to send a message from qml to interface script.

View file

@ -2851,6 +2851,18 @@ bool Application::importSVOFromURL(const QString& urlString) {
return true;
}
bool Application::importFromZIP(const QString& filePath) {
qDebug() << "A zip file has been dropped in: " << filePath;
QUrl empty;
// handle Blocks download from Marketplace
if (filePath.contains("vr.google.com/downloads")) {
addAssetToWorldFromURL(filePath);
} else {
qApp->getFileDownloadInterface()->runUnzip(filePath, empty, true, true, false);
}
return true;
}
void Application::onPresent(quint32 frameCount) {
if (shouldPaint()) {
postEvent(this, new QEvent(static_cast<QEvent::Type>(Idle)), Qt::HighEventPriority);
@ -2858,13 +2870,6 @@ void Application::onPresent(quint32 frameCount) {
}
}
bool Application::importFromZIP(const QString& filePath) {
qDebug() << "A zip file has been dropped in: " << filePath;
QUrl empty;
qApp->getFileDownloadInterface()->runUnzip(filePath, empty, true, true);
return true;
}
bool _renderRequested { false };
bool Application::event(QEvent* event) {
@ -6354,8 +6359,15 @@ void Application::showAssetServerWidget(QString filePath) {
void Application::addAssetToWorldFromURL(QString url) {
qInfo(interfaceapp) << "Download model and add to world from" << url;
QString filename = url.section("filename=", 1, 1); // Filename is in "?filename=" parameter at end of URL.
QString filename;
if (url.contains("filename")) {
filename = url.section("filename=", 1, 1); // Filename is in "?filename=" parameter at end of URL.
}
if (url.contains("vr.google.com/downloads")) {
filename = url.section('/', -1);
filename.remove(".zip?noDownload=false");
}
if (!DependencyManager::get<NodeList>()->getThisNodeCanWriteAssets()) {
QString errorInfo = "You do not have permissions to write to the Asset Server.";
@ -6376,7 +6388,17 @@ void Application::addAssetToWorldFromURLRequestFinished() {
auto url = request->getUrl().toString();
auto result = request->getResult();
QString filename = url.section("filename=", 1, 1); // Filename from trailing "?filename=" URL parameter.
QString filename;
bool isBlocks = false;
if (url.contains("filename")) {
filename = url.section("filename=", 1, 1); // Filename is in "?filename=" parameter at end of URL.
}
if (url.contains("vr.google.com/downloads")) {
filename = url.section('/', -1);
filename.remove(".zip?noDownload=false");
isBlocks = true;
}
if (result == ResourceRequest::Success) {
qInfo(interfaceapp) << "Downloaded model from" << url;
@ -6391,7 +6413,7 @@ void Application::addAssetToWorldFromURLRequestFinished() {
if (tempFile.open(QIODevice::WriteOnly)) {
tempFile.write(request->getData());
addAssetToWorldInfoClear(filename); // Remove message from list; next one added will have a different key.
qApp->getFileDownloadInterface()->runUnzip(downloadPath, url, true, false);
qApp->getFileDownloadInterface()->runUnzip(downloadPath, url, true, false, isBlocks);
} else {
QString errorInfo = "Couldn't open temporary file for download";
qWarning(interfaceapp) << errorInfo;
@ -6421,7 +6443,7 @@ void Application::addAssetToWorldUnzipFailure(QString filePath) {
addAssetToWorldError(filename, "Couldn't unzip file " + filename + ".");
}
void Application::addAssetToWorld(QString filePath, QString zipFile, bool isZip) {
void Application::addAssetToWorld(QString filePath, QString zipFile, bool isZip, bool isBlocks) {
// Automatically upload and add asset to world as an alternative manual process initiated by showAssetServerWidget().
QString mapping;
QString path = filePath;
@ -6430,6 +6452,11 @@ void Application::addAssetToWorld(QString filePath, QString zipFile, bool isZip)
QString assetFolder = zipFile.section("/", -1);
assetFolder.remove(".zip");
mapping = "/" + assetFolder + "/" + filename;
} else if (isBlocks) {
qCDebug(interfaceapp) << "Path to asset folder: " << zipFile;
QString assetFolder = zipFile.section('/', -1);
assetFolder.remove(".zip?noDownload=false");
mapping = "/" + assetFolder + "/" + filename;
} else {
mapping = "/" + filename;
}
@ -6809,12 +6836,12 @@ void Application::onAssetToWorldMessageBoxClosed() {
}
void Application::handleUnzip(QString zipFile, QStringList unzipFile, bool autoAdd, bool isZip) {
void Application::handleUnzip(QString zipFile, QStringList unzipFile, bool autoAdd, bool isZip, bool isBlocks) {
if (autoAdd) {
if (!unzipFile.isEmpty()) {
for (int i = 0; i < unzipFile.length(); i++) {
qCDebug(interfaceapp) << "Preparing file for asset server: " << unzipFile.at(i);
addAssetToWorld(unzipFile.at(i), zipFile, isZip);
addAssetToWorld(unzipFile.at(i), zipFile, isZip, isBlocks);
}
} else {
addAssetToWorldUnzipFailure(zipFile);

View file

@ -339,14 +339,14 @@ public slots:
// FIXME: Move addAssetToWorld* methods to own class?
void addAssetToWorldFromURL(QString url);
void addAssetToWorldFromURLRequestFinished();
void addAssetToWorld(QString filePath, QString zipFile, bool isZip);
void addAssetToWorld(QString filePath, QString zipFile, bool isZip, bool isBlocks);
void addAssetToWorldUnzipFailure(QString filePath);
void addAssetToWorldWithNewMapping(QString filePath, QString mapping, int copy);
void addAssetToWorldUpload(QString filePath, QString mapping);
void addAssetToWorldSetMapping(QString filePath, QString mapping, QString hash);
void addAssetToWorldAddEntity(QString filePath, QString mapping);
void handleUnzip(QString sourceFile, QStringList destinationFile, bool autoAdd, bool isZip);
void handleUnzip(QString sourceFile, QStringList destinationFile, bool autoAdd, bool isZip, bool isBlocks);
FileScriptingInterface* getFileDownloadInterface() { return _fileDownload; }

View file

@ -216,7 +216,17 @@ int main(int argc, const char* argv[]) {
SandboxUtils::runLocalSandbox(serverContentPath, true, noUpdater);
}
Application app(argc, const_cast<char**>(argv), startupTime, runningMarkerExisted);
// to enable WebGL rendering
char* additionalCommandLineArg = (char*)"--ignore-gpu-blacklist";
int newArgc = argc + 1;
char** newArgv = new char*[newArgc];
for (int i = 0; i < argc; ++i) {
newArgv[i] = (char*)argv[i];
}
newArgv[argc] = additionalCommandLineArg;
Application app(newArgc, const_cast<char**>(newArgv), startupTime, runningMarkerExisted);
delete[] newArgv;
// If we failed the OpenGLVersion check, log it.
if (override) {

View file

@ -264,6 +264,10 @@ void WindowScriptingInterface::showAssetServer(const QString& upload) {
QMetaObject::invokeMethod(qApp, "showAssetServerWidget", Qt::QueuedConnection, Q_ARG(QString, upload));
}
QString WindowScriptingInterface::checkVersion() {
return QCoreApplication::applicationVersion();
}
int WindowScriptingInterface::getInnerWidth() {
return qApp->getWindow()->geometry().width();
}

View file

@ -58,6 +58,7 @@ public slots:
QScriptValue save(const QString& title = "", const QString& directory = "", const QString& nameFilter = "");
QScriptValue browseAssets(const QString& title = "", const QString& directory = "", const QString& nameFilter = "");
void showAssetServer(const QString& upload = "");
QString checkVersion();
void copyToClipboard(const QString& text);
void takeSnapshot(bool notify = true, bool includeAnimated = false, float aspectRatio = 0.0f);
void takeSecondaryCameraSnapshot();

View file

@ -32,10 +32,11 @@ FileScriptingInterface::FileScriptingInterface(QObject* parent) : QObject(parent
// nothing for now
}
void FileScriptingInterface::runUnzip(QString path, QUrl url, bool autoAdd, bool isZip) {
void FileScriptingInterface::runUnzip(QString path, QUrl url, bool autoAdd, bool isZip, bool isBlocks) {
qCDebug(scriptengine) << "Url that was downloaded: " + url.toString();
qCDebug(scriptengine) << "Path where download is saved: " + path;
QString fileName = "/" + path.section("/", -1);
qCDebug(scriptengine) << "Filename: " << fileName;
QString tempDir = path;
if (!isZip) {
tempDir.remove(fileName);
@ -52,14 +53,17 @@ void FileScriptingInterface::runUnzip(QString path, QUrl url, bool autoAdd, bool
}
QStringList fileList = unzipFile(path, tempDir);
QString filename = QUrl::fromLocalFile(fileList.first()).toString();
if (filename != "") {
qCDebug(scriptengine) << "File to upload: " + filename;
if (!fileList.isEmpty()) {
qCDebug(scriptengine) << "File to upload: " + fileList.first();
} else {
qCDebug(scriptengine) << "Unzip failed";
}
emit unzipResult(path, fileList, autoAdd, isZip);
if (path.contains("vr.google.com/downloads")) {
isZip = true;
}
emit unzipResult(path, fileList, autoAdd, isZip, isBlocks);
}

View file

@ -24,11 +24,11 @@ public:
public slots:
QString convertUrlToPath(QUrl url);
void runUnzip(QString path, QUrl url, bool autoAdd, bool isZip);
void runUnzip(QString path, QUrl url, bool autoAdd, bool isZip, bool isBlocks);
QString getTempDir();
signals:
void unzipResult(QString zipFile, QStringList unzipFile, bool autoAdd, bool isZip);
void unzipResult(QString zipFile, QStringList unzipFile, bool autoAdd, bool isZip, bool isBlocks);
private:
bool isTempDir(QString tempDir);

View file

@ -604,9 +604,9 @@ void TabletProxy::loadWebScreenOnTop(const QVariant& url, const QString& injectJ
_state = State::Web;
}
void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaScriptUrl) {
void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaScriptUrl, bool loadOtherBase) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "gotoWebScreen", Q_ARG(QString, url), Q_ARG(QString, injectedJavaScriptUrl));
QMetaObject::invokeMethod(this, "gotoWebScreen", Q_ARG(QString, url), Q_ARG(QString, injectedJavaScriptUrl), Q_ARG(bool, loadOtherBase));
return;
}
@ -619,7 +619,11 @@ void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaS
if (root) {
removeButtonsFromHomeScreen();
QMetaObject::invokeMethod(root, "loadWebBase");
if (loadOtherBase) {
QMetaObject::invokeMethod(root, "loadTabletWebBase");
} else {
QMetaObject::invokeMethod(root, "loadWebBase");
}
QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true)));
QMetaObject::invokeMethod(root, "loadWebUrl", Q_ARG(const QVariant&, QVariant(url)), Q_ARG(const QVariant&, QVariant(injectedJavaScriptUrl)));
}

View file

@ -122,7 +122,7 @@ public:
* @param [injectedJavaScriptUrl] {string} optional url to an additional JS script to inject into the web page.
*/
Q_INVOKABLE void gotoWebScreen(const QString& url);
Q_INVOKABLE void gotoWebScreen(const QString& url, const QString& injectedJavaScriptUrl);
Q_INVOKABLE void gotoWebScreen(const QString& url, const QString& injectedJavaScriptUrl, bool loadOtherBase = false);
Q_INVOKABLE void loadQMLSource(const QVariant& path);
// FIXME: This currently relies on a script initializing the tablet (hence the bool denoting success);

View file

@ -81,6 +81,7 @@
letUsKnow.replaceWith(letUsKnow.html());
// Add button links.
$('#exploreClaraMarketplace').on('click', function () {
window.location = "https://clara.io/library?gameCheck=true&public=true";
});
@ -221,7 +222,7 @@
// One file request at a time.
if (isPreparing) {
console.log("WARNIKNG: Clara.io FBX: Prepare only one download at a time");
console.log("WARNING: Clara.io FBX: Prepare only one download at a time");
return;
}
@ -397,8 +398,8 @@
var pageType = DIRECTORY;
if (location.href.indexOf("highfidelity.com/") !== -1) { pageType = HIFI; }
if (location.href.indexOf("highfidelity.com/marketplace/items/") !== -1) { pageType = HIFI_ITEM_PAGE; }
if (location.href.indexOf("clara.io/") !== -1) { pageType = CLARA; }
if (location.href.indexOf("highfidelity.com/marketplace/items/") !== -1) { pageType = HIFI_ITEM_PAGE; }
injectCommonCode(pageType === DIRECTORY);
switch (pageType) {
@ -408,12 +409,13 @@
case HIFI:
injectHiFiCode();
break;
case HIFI_ITEM_PAGE:
injectHiFiItemPageCode();
break;
case CLARA:
injectClaraCode();
break;
case HIFI_ITEM_PAGE:
injectHiFiItemPageCode();
break;
}
}

View file

@ -0,0 +1,43 @@
///
/// blocksApp.js
/// A tablet app for downloading 3D assets from Google Blocks
///
/// Author: Elisa Lupin-Jimenez
/// Copyright High Fidelity 2017
///
/// Licensed under the Apache 2.0 License
/// See accompanying license file or http://apache.org/
///
/// All assets are under CC Attribution Non-Commerical
/// http://creativecommons.org/licenses/
///
(function () {
var APP_NAME = "BLOCKS";
var APP_URL = "https://vr.google.com/objects/";
var APP_ICON = "https://hifi-content.s3.amazonaws.com/elisalj/blocks/blocks-i.svg";
try {
print("Current Interface version: " + Window.checkVersion());
} catch(err) {
print("Outdated Interface version does not support Blocks");
APP_URL = "https://hifi-content.s3.amazonaws.com/elisalj/blocks/updateToBlocks.html";
}
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
var button = tablet.addButton({
icon: APP_ICON,
text: APP_NAME
});
function onClicked() {
tablet.gotoWebScreen(APP_URL, "", true);
}
button.clicked.connect(onClicked);
function cleanup() {
tablet.removeButton(button);
}
Script.scriptEnding.connect(cleanup);
}());