diff --git a/interface/resources/icons/standalone-optimized.svg b/interface/resources/icons/standalone-optimized.svg new file mode 100644 index 0000000000..f721be9ebb --- /dev/null +++ b/interface/resources/icons/standalone-optimized.svg @@ -0,0 +1,27 @@ + + + + + + diff --git a/interface/resources/qml/hifi/Card.qml b/interface/resources/qml/hifi/Card.qml index 238c26236f..fc49bcf048 100644 --- a/interface/resources/qml/hifi/Card.qml +++ b/interface/resources/qml/hifi/Card.qml @@ -30,6 +30,7 @@ Item { property string imageUrl: ""; property var goFunction: null; property string storyId: ""; + property bool standaloneOptimized: false; property bool drillDownToPlace: false; property bool showPlace: isConcurrency; @@ -40,6 +41,7 @@ Item { property bool isAnnouncement: action === 'announcement'; property bool isStacked: !isConcurrency && drillDownToPlace; + property int textPadding: 10; property int smallMargin: 4; property int messageHeight: 40; @@ -267,9 +269,33 @@ Item { hoverEnabled: false onClicked: { Tablet.playSound(TabletEnums.ButtonClick); - goFunction("hifi://" + hifiUrl); + goFunction("hifi://" + hifiUrl, standaloneOptimized); } } + + Image { + id: standaloneOptomizedBadge + + anchors { + right: actionIcon.left + top: actionIcon.top + topMargin: 2 + rightMargin: 3 + } + height: root.standaloneOptimized ? 25 : 0 + width: 25 + + visible: root.standaloneOptimized && isConcurrency + fillMode: Image.PreserveAspectFit + source: "../../icons/standalone-optimized.svg" + } + ColorOverlay { + anchors.fill: standaloneOptomizedBadge + source: standaloneOptomizedBadge + color: hifi.colors.blueHighlight + visible: root.standaloneOptimized && isConcurrency + } + StateImage { id: actionIcon; visible: !isAnnouncement; @@ -281,7 +307,8 @@ Item { right: parent.right; margins: smallMargin; } - } + } + function go() { Tablet.playSound(TabletEnums.ButtonClick); goFunction(drillDownToPlace ? ("/places/" + placeName) : ("/user_stories/" + storyId)); diff --git a/interface/resources/qml/hifi/Feed.qml b/interface/resources/qml/hifi/Feed.qml index 1e89971938..68aab2fdd2 100644 --- a/interface/resources/qml/hifi/Feed.qml +++ b/interface/resources/qml/hifi/Feed.qml @@ -82,6 +82,7 @@ Column { action: data.action || "", thumbnail_url: resolveUrl(thumbnail_url), image_url: resolveUrl(data.details && data.details.image_url), + standalone_optimized: data.standalone_optimized, metaverseId: (data.id || "").toString(), // Some are strings from server while others are numbers. Model objects require uniformity. @@ -127,6 +128,7 @@ Column { hifiUrl: model.place_name + model.path; thumbnail: model.thumbnail_url; imageUrl: model.image_url; + standaloneOptimized: model.standalone_optimized; action: model.action; timestamp: model.created_at; onlineUsers: model.online_users; diff --git a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml index 8ca34af28a..16faf2feb7 100644 --- a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml +++ b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml @@ -30,6 +30,8 @@ Rectangle { property string dateAcquired: "--"; property string itemCost: "--"; property string marketplace_item_id: ""; + property bool standaloneOptimized: false; + property bool standaloneIncompatible: false; property string certTitleTextColor: hifi.colors.darkGray; property string certTextColor: hifi.colors.white; property string infoTextColor: hifi.colors.blueAccent; @@ -71,6 +73,8 @@ Rectangle { } else { root.marketplace_item_id = result.data.marketplace_item_id; root.isMyCert = result.isMyCert ? result.isMyCert : false; + root.standaloneOptimized = result.data.standalone_optimized; + root.standaloneIncompatible = result.data.standalone_incompatible; if (root.certInfoReplaceMode > 3) { root.itemName = result.data.marketplace_item_name; @@ -421,6 +425,24 @@ Rectangle { anchors.rightMargin: 24; height: root.useGoldCert ? 220 : 372; + HiFiGlyphs { + id: standaloneOptomizedBadge + + anchors { + right: parent.right + top: ownedByHeader.top + rightMargin: 15 + topMargin: 28 + } + + visible: root.standaloneOptimized + + text: hifi.glyphs.hmd + size: 34 + horizontalAlignment: Text.AlignHCenter + color: hifi.colors.blueHighlight + } + RalewayRegular { id: errorText; visible: !root.useGoldCert; @@ -467,6 +489,7 @@ Rectangle { color: root.infoTextColor; elide: Text.ElideRight; } + AnonymousProRegular { id: isMyCertText; visible: root.isMyCert && ownedBy.text !== "--" && ownedBy.text !== ""; @@ -485,14 +508,46 @@ Rectangle { verticalAlignment: Text.AlignVCenter; } + RalewayRegular { + id: standaloneHeader; + text: root.standaloneOptimized ? "STAND-ALONE OPTIMIZED" : "STAND-ALONE INCOMPATIBLE"; + // Text size + size: 16; + // Anchors + anchors.top: ownedBy.bottom; + anchors.topMargin: 15; + anchors.left: parent.left; + anchors.right: parent.right; + visible: root.standaloneOptimized || root.standaloneIncompatible; + height: visible ? paintedHeight : 0; + // Style + color: hifi.colors.darkGray; + } + + RalewayRegular { + id: standaloneText; + text: root.standaloneOptimized ? "This item is stand-alone optimized" : "This item is incompatible with stand-alone devices"; + // Text size + size: 18; + // Anchors + anchors.top: standaloneHeader.bottom; + anchors.topMargin: 8; + anchors.left: standaloneHeader.left; + visible: root.standaloneOptimized || root.standaloneIncompatible; + height: visible ? paintedHeight : 0; + // Style + color: root.infoTextColor; + elide: Text.ElideRight; + } + RalewayRegular { id: dateAcquiredHeader; text: "ACQUISITION DATE"; // Text size size: 16; // Anchors - anchors.top: ownedBy.bottom; - anchors.topMargin: 28; + anchors.top: standaloneText.bottom; + anchors.topMargin: 20; anchors.left: parent.left; anchors.right: parent.horizontalCenter; anchors.rightMargin: 8; @@ -521,8 +576,8 @@ Rectangle { // Text size size: 16; // Anchors - anchors.top: ownedBy.bottom; - anchors.topMargin: 28; + anchors.top: standaloneText.bottom; + anchors.topMargin: 20; anchors.left: parent.horizontalCenter; anchors.right: parent.right; height: paintedHeight; diff --git a/interface/resources/qml/hifi/commerce/marketplace/Marketplace.qml b/interface/resources/qml/hifi/commerce/marketplace/Marketplace.qml index 4ff935921f..07ded49956 100644 --- a/interface/resources/qml/hifi/commerce/marketplace/Marketplace.qml +++ b/interface/resources/qml/hifi/commerce/marketplace/Marketplace.qml @@ -91,6 +91,14 @@ Rectangle { id: -1, name: "Everything" }); + categoriesModel.append({ + id: -1, + name: "Stand-alone Optimized" + }); + categoriesModel.append({ + id: -1, + name: "Stand-alone Compatible" + }); result.data.items.forEach(function(category) { categoriesModel.append({ id: category.id, @@ -127,6 +135,8 @@ Rectangle { marketplaceItem.availability = result.data.availability; marketplaceItem.updated_item_id = result.data.updated_item_id || ""; marketplaceItem.created_at = result.data.created_at; + marketplaceItem.standaloneOptimized = result.data.standalone_optimized; + marketplaceItem.standaloneVisible = result.data.standalone_optimized || result.data.standalone_incompatible; marketplaceItemScrollView.contentHeight = marketplaceItemContent.height; itemsList.visible = false; marketplaceItemView.visible = true; @@ -191,16 +201,16 @@ Rectangle { visible: true Image { - id: marketplaceHeaderImage; - source: "../common/images/marketplaceHeaderImage.png"; - anchors.top: parent.top; - anchors.topMargin: 2; - anchors.bottom: parent.bottom; - anchors.bottomMargin: 0; - anchors.left: parent.left; - anchors.leftMargin: 8; - width: 140; - fillMode: Image.PreserveAspectFit; + id: marketplaceHeaderImage + source: "../common/images/marketplaceHeaderImage.png" + anchors.top: parent.top + anchors.topMargin: 2 + anchors.bottom: parent.bottom + anchors.bottomMargin: 0 + anchors.left: parent.left + anchors.leftMargin: 8 + width: 140 + fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent; @@ -546,7 +556,8 @@ Rectangle { price: model.cost availability: model.availability isLoggedIn: root.isLoggedIn; - + standaloneOptimized: model.standalone_optimized + onShowItem: { MarketplaceScriptingInterface.getMarketplaceItem(item_id); } diff --git a/interface/resources/qml/hifi/commerce/marketplace/MarketplaceItem.qml b/interface/resources/qml/hifi/commerce/marketplace/MarketplaceItem.qml index fa7e311026..605a68fe73 100644 --- a/interface/resources/qml/hifi/commerce/marketplace/MarketplaceItem.qml +++ b/interface/resources/qml/hifi/commerce/marketplace/MarketplaceItem.qml @@ -15,6 +15,7 @@ import Hifi 1.0 as Hifi import QtQuick 2.9 import QtQuick.Controls 2.2 import stylesUit 1.0 +import QtGraphicalEffects 1.0 import controlsUit 1.0 as HifiControlsUit import "../../../controls" as HifiControls import "../common" as HifiCommerceCommon @@ -40,9 +41,11 @@ Rectangle { property string license: "" property string posted: "" property string created_at: "" - property bool isLoggedIn: false; - property int edition: -1; - property bool supports3DHTML: false; + property bool isLoggedIn: false + property int edition: -1 + property bool supports3DHTML: false + property bool standaloneVisible: false + property bool standaloneOptimized: false onCategoriesChanged: { categoriesListModel.clear(); @@ -240,10 +243,43 @@ Rectangle { right: parent.right; top: itemImage.bottom; } - height: categoriesList.y - buyButton.y + categoriesList.height + height: categoriesList.y - badges.y + categoriesList.height function evalHeight() { - height = categoriesList.y - buyButton.y + categoriesList.height; + height = categoriesList.y - badges.y + categoriesList.height; + } + + Item { + id: badges + + anchors { + right: buyButton.left + top: parent.top + rightMargin: 10 + } + height: childrenRect.height + + Image { + id: standaloneOptomizedBadge + + anchors { + topMargin: 15 + right: parent.right + top: parent.top + } + height: root.standaloneOptimized ? 50 : 0 + width: 50 + + visible: root.standaloneOptimized + fillMode: Image.PreserveAspectFit + source: "../../../../icons/standalone-optimized.svg" + } + ColorOverlay { + anchors.fill: standaloneOptomizedBadge + source: standaloneOptomizedBadge + color: hifi.colors.blueHighlight + visible: root.standaloneOptimized + } } HifiControlsUit.Button { @@ -252,10 +288,10 @@ Rectangle { anchors { right: parent.right top: parent.top - left: parent.left topMargin: 15 } - height: 50 + height: 50 + width: 180 property bool isUpdate: root.edition >= 0 // Special case of updating from a specific older item property bool isStocking: (creator === Account.username) && (availability === "not for sale") && !updated_item_id // Note: server will say "sold out" or "invalidated" before it says NFS @@ -275,11 +311,11 @@ Rectangle { id: creatorItem anchors { - top: buyButton.bottom + top: parent.top leftMargin: 15 topMargin: 15 } - width: parent.width + width: paintedWidth height: childrenRect.height RalewaySemiBold { @@ -528,13 +564,55 @@ Rectangle { } } } + + Item { + id: standaloneItem + + anchors { + top: licenseItem.bottom + topMargin: 15 + left: parent.left + right: parent.right + } + height: root.standaloneVisible ? childrenRect.height : 0 + + visible: root.standaloneVisible + + RalewaySemiBold { + id: standaloneLabel + + anchors.top: parent.top + anchors.left: parent.left + width: paintedWidth + height: 20 + + text: root.standaloneOptimized ? "STAND-ALONE OPTIMIZED:" : "STAND-ALONE INCOMPATIBLE:" + size: 14 + color: hifi.colors.lightGrayText + verticalAlignment: Text.AlignVCenter + } + + RalewaySemiBold { + id: standaloneOptimizedText + + anchors.top: standaloneLabel.bottom + anchors.left: parent.left + anchors.topMargin: 5 + width: paintedWidth + + text: root.standaloneOptimized ? "This item is stand-alone optimized" : "This item is incompatible with stand-alone devices" + size: 14 + color: hifi.colors.lightGray + verticalAlignment: Text.AlignVCenter + } + } Item { id: descriptionItem property string text: "" anchors { - top: licenseItem.bottom + top: standaloneItem.bottom topMargin: 15 left: parent.left right: parent.right diff --git a/interface/resources/qml/hifi/commerce/marketplace/MarketplaceListItem.qml b/interface/resources/qml/hifi/commerce/marketplace/MarketplaceListItem.qml index 439247e410..8ad6191f04 100644 --- a/interface/resources/qml/hifi/commerce/marketplace/MarketplaceListItem.qml +++ b/interface/resources/qml/hifi/commerce/marketplace/MarketplaceListItem.qml @@ -35,8 +35,9 @@ Rectangle { property string category: "" property int price: 0 property string availability: "unknown" - property bool isLoggedIn: false; - + property bool isLoggedIn: false + property bool standaloneOptimized: false + signal buy() signal showItem() signal categoryClicked(string category) @@ -240,16 +241,18 @@ Rectangle { id: creatorText anchors { - top: creatorLabel.top; - left: creatorLabel.right; - leftMargin: 10; + top: creatorLabel.top + left: creatorLabel.right + leftMargin: 15 + right: badges.left } - width: paintedWidth; + width: paintedWidth - text: root.creator; - size: 14; - color: hifi.colors.lightGray; - verticalAlignment: Text.AlignVCenter; + text: root.creator + size: 14 + elide: Text.ElideRight + color: hifi.colors.lightGray + verticalAlignment: Text.AlignVCenter } RalewaySemiBold { @@ -260,12 +263,12 @@ Rectangle { left: parent.left leftMargin: 15 } - width: paintedWidth; + width: paintedWidth - text: "IN:"; - size: 14; - color: hifi.colors.lightGrayText; - verticalAlignment: Text.AlignVCenter; + text: "IN:" + size: 14 + color: hifi.colors.lightGrayText + verticalAlignment: Text.AlignVCenter } RalewaySemiBold { @@ -274,23 +277,57 @@ Rectangle { anchors { top: categoryLabel.top left: categoryLabel.right - leftMargin: 10 + leftMargin: 15 + right: badges.left } width: paintedWidth text: root.category size: 14 - color: hifi.colors.blueHighlight; - verticalAlignment: Text.AlignVCenter; - + color: hifi.colors.blueHighlight + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight MouseArea { anchors.fill: parent onClicked: root.categoryClicked(root.category); } } + Item { + id: badges + + anchors { + right: buyButton.left + top: parent.top + topMargin: 10 + rightMargin: 10 + } + height: 50 + + Image { + id: standaloneOptomizedBadge + + anchors { + right: parent.right + top: parent.top + } + height: root.standaloneOptimized ? 40 : 0 + width: 40 + + visible: root.standaloneOptimized + fillMode: Image.PreserveAspectFit + source: "../../../../icons/standalone-optimized.svg" + } + ColorOverlay { + anchors.fill: standaloneOptomizedBadge + source: standaloneOptomizedBadge + color: hifi.colors.blueHighlight + visible: root.standaloneOptimized + } + } HifiControlsUit.Button { + id: buyButton anchors { right: parent.right top: parent.top diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml index 2c2fed1d8f..a7b36eae36 100644 --- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml +++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml @@ -13,6 +13,7 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 +import QtGraphicalEffects 1.0 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import stylesUit 1.0 @@ -50,6 +51,8 @@ Item { property string upgradeTitle; property bool updateAvailable: root.updateItemId && root.updateItemId !== ""; property bool valid; + property bool standaloneOptimized; + property bool standaloneIncompatible; property string originalStatusText; property string originalStatusColor; @@ -403,7 +406,9 @@ Item { id: permissionExplanationText; anchors.fill: parent; text: { - if (root.itemType === "contentSet") { + if (root.standaloneIncompatible) { + "This item is incompatible with stand-alone devices. Learn more"; + } else if (root.itemType === "contentSet") { "You do not have 'Replace Content' permissions in this domain. Learn more"; } else if (root.itemType === "entity") { "You do not have 'Rez Certified' permissions in this domain. Learn more"; @@ -417,7 +422,11 @@ Item { verticalAlignment: Text.AlignVCenter; onLinkActivated: { - sendToPurchases({method: 'showPermissionsExplanation', itemType: root.itemType}); + if (link === "#standaloneIncompatible") { + sendToPurchases({method: 'showStandaloneIncompatibleExplanation'}); + } else { + sendToPurchases({method: 'showPermissionsExplanation', itemType: root.itemType}); + } } } } @@ -699,7 +708,8 @@ Item { anchors.bottomMargin: 8; width: 160; height: 40; - enabled: root.hasPermissionToRezThis && + enabled: !root.standaloneIncompatible && + root.hasPermissionToRezThis && MyAvatar.skeletonModelURL !== root.itemHref && !root.wornEntityID && root.valid; @@ -838,6 +848,28 @@ Item { root.sendToPurchases({ method: 'flipCard' }); } } + } + Image { + id: standaloneOptomizedBadge + + anchors { + right: parent.right + bottom: parent.bottom + rightMargin: 15 + bottomMargin:12 + } + height: root.standaloneOptimized ? 36 : 0 + width: 36 + + visible: root.standaloneOptimized + fillMode: Image.PreserveAspectFit + source: "../../../../icons/standalone-optimized.svg" + } + ColorOverlay { + anchors.fill: standaloneOptomizedBadge + source: standaloneOptomizedBadge + color: hifi.colors.blueHighlight + visible: root.standaloneOptimized } } diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index dc892e6640..311c20d120 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -12,7 +12,7 @@ // import Hifi 1.0 as Hifi -import QtQuick 2.5 +import QtQuick 2.9 import stylesUit 1.0 import controlsUit 1.0 as HifiControlsUit import "../../../controls" as HifiControls @@ -33,6 +33,7 @@ Rectangle { property bool purchasesReceived: false; property bool punctuationMode: false; property bool isDebuggingFirstUseTutorial: false; + property bool isStandalone: false; property string installedApps; property bool keyboardRaised: false; property int numUpdatesAvailable: 0; @@ -44,6 +45,7 @@ Rectangle { purchasesModel.getFirstPage(); Commerce.getAvailableUpdates(); } + Connections { target: Commerce; @@ -110,6 +112,10 @@ Rectangle { } } + Component.onCompleted: { + isStandalone = PlatformInfo.isStandalone(); + } + HifiCommerceCommon.CommerceLightbox { id: lightboxPopup; z: 999; @@ -553,6 +559,8 @@ Rectangle { upgradeTitle: model.upgrade_title; itemType: model.item_type; valid: model.valid; + standaloneOptimized: model.standalone_optimized + standaloneIncompatible: root.isStandalone && model.standalone_incompatible anchors.topMargin: 10; anchors.bottomMargin: 10; @@ -673,6 +681,14 @@ Rectangle { lightboxPopup.visible = false; } lightboxPopup.visible = true; + } else if (msg.method === "showStandaloneIncompatibleExplanation") { + lightboxPopup.titleText = "Stand-alone Incompatible"; + lightboxPopup.bodyText = "The item is incompatible with stand-alone devices."; + lightboxPopup.button1text = "CLOSE"; + lightboxPopup.button1method = function() { + lightboxPopup.visible = false; + } + lightboxPopup.visible = true; } else if (msg.method === "setFilterText") { filterBar.text = msg.filterText; } else if (msg.method === "flipCard") { diff --git a/interface/resources/qml/hifi/tablet/TADLightbox.qml b/interface/resources/qml/hifi/tablet/TADLightbox.qml new file mode 100644 index 0000000000..35a01aeec3 --- /dev/null +++ b/interface/resources/qml/hifi/tablet/TADLightbox.qml @@ -0,0 +1,144 @@ +// +// TADLightbox.qml +// qml/hifi/tablet +// +// TADLightbox +// +// Created by Roxanne Skelly on 2019-03-07 +// 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.5 +import QtGraphicalEffects 1.0 +import stylesUit 1.0 +import controlsUit 1.0 as HifiControlsUit +import "qrc:////qml//controls" as HifiControls + +// references XXX from root context + +Rectangle { + property string titleText; + property string bodyImageSource; + property string bodyText; + property string button1color: hifi.buttons.noneBorderlessGray; + property string button1text; + property var button1method; + property string button2color: hifi.buttons.blue; + property string button2text; + property var button2method; + property string buttonLayout: "leftright"; + + id: root; + visible: false; + anchors.fill: parent; + color: Qt.rgba(0, 0, 0, 0.5); + z: 999; + + HifiConstants { id: hifi; } + + // This object is always used in a popup. + // This MouseArea is used to prevent a user from being + // able to click on a button/mouseArea underneath the popup. + MouseArea { + anchors.fill: parent; + propagateComposedEvents: false; + hoverEnabled: true; + } + + Rectangle { + anchors.centerIn: parent; + width: 376; + height: childrenRect.height + 30; + color: "white"; + + RalewaySemiBold { + id: titleText; + text: root.titleText; + anchors.top: parent.top; + anchors.topMargin: 30; + anchors.left: parent.left; + anchors.leftMargin: 30; + anchors.right: parent.right; + anchors.rightMargin: 30; + height: paintedHeight; + color: hifi.colors.black; + size: 24; + verticalAlignment: Text.AlignTop; + wrapMode: Text.WordWrap; + } + + RalewayRegular { + id: bodyText; + text: root.bodyText; + anchors.top: root.bodyImageSource ? bodyImage.bottom : (root.titleText ? titleText.bottom : parent.top); + anchors.topMargin: root.bodyImageSource ? 20 : (root.titleText ? 20 : 30); + anchors.left: parent.left; + anchors.leftMargin: 30; + anchors.right: parent.right; + anchors.rightMargin: 30; + height: paintedHeight; + color: hifi.colors.black; + size: 20; + verticalAlignment: Text.AlignTop; + wrapMode: Text.WordWrap; + + } + + Item { + id: buttons; + anchors.top: bodyText.bottom; + anchors.topMargin: 30; + anchors.left: parent.left; + anchors.right: parent.right; + height: root.buttonLayout === "leftright" ? 70 : 150; + + // Button 1 + HifiControlsUit.Button { + id: button1; + color: root.button1color; + colorScheme: hifi.colorSchemes.light; + anchors.top: root.buttonLayout === "leftright" ? parent.top : parent.top; + anchors.left: parent.left; + anchors.leftMargin: root.buttonLayout === "leftright" ? 30 : 10; + anchors.right: root.buttonLayout === "leftright" ? undefined : parent.right; + anchors.rightMargin: root.buttonLayout === "leftright" ? undefined : 10; + width: root.buttonLayout === "leftright" ? (root.button2text ? parent.width/2 - anchors.leftMargin*2 : parent.width - anchors.leftMargin * 2) : + (undefined); + height: 40; + text: root.button1text; + onClicked: { + button1method(); + } + visible: (root.button1text !== ""); + } + + // Button 2 + HifiControlsUit.Button { + id: button2; + visible: root.button2text; + color: root.button2color; + colorScheme: hifi.colorSchemes.light; + anchors.top: root.buttonLayout === "leftright" ? parent.top : button1.bottom; + anchors.topMargin: root.buttonLayout === "leftright" ? undefined : 20; + anchors.left: root.buttonLayout === "leftright" ? undefined : parent.left; + anchors.leftMargin: root.buttonLayout === "leftright" ? undefined : 10; + anchors.right: parent.right; + anchors.rightMargin: root.buttonLayout === "leftright" ? 30 : 10; + width: root.buttonLayout === "leftright" ? parent.width/2 - anchors.rightMargin*2 : undefined; + height: 40; + text: root.button2text; + onClicked: { + button2method(); + } + } + } + } + + // + // FUNCTION DEFINITIONS END + // +} diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index ab0a98a8c5..311d20955b 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -73,7 +73,7 @@ StackView { function resetAfterTeleport() { //storyCardFrame.shown = root.shown = false; } - function goCard(targetString) { + function goCard(targetString, standaloneOptimized) { if (0 !== targetString.indexOf('hifi://')) { var card = tabletWebView.createObject(); card.url = addressBarDialog.metaverseServerUrl + targetString; @@ -82,7 +82,7 @@ StackView { return; } location.text = targetString; - toggleOrGo(targetString, true); + toggleOrGo(targetString, true, standaloneOptimized); clearAddressLineTimer.start(); } @@ -392,7 +392,18 @@ StackView { right: parent.right } } + } + TADLightbox { + id: unoptimizedDomain + titleText: "Unoptimized Domain" + bodyText: "You're trying to access a place that hasn't been optimized for your device. Are you sure you want to continue." + button1text: "CANCEL" + button2text: "YES CONTINUE" + visible: false + button1method: function() { + visible = false; + } } function updateLocationText(enteringAddress) { @@ -407,14 +418,30 @@ StackView { } } - function toggleOrGo(address, fromSuggestions) { - if (address !== undefined && address !== "") { - addressBarDialog.loadAddress(address, fromSuggestions); - clearAddressLineTimer.start(); - } else if (addressLine.text !== "") { - addressBarDialog.loadAddress(addressLine.text, fromSuggestions); - clearAddressLineTimer.start(); + function toggleOrGo(address, fromSuggestions, standaloneOptimized) { + + var goTarget = function () { + if (address !== undefined && address !== "") { + addressBarDialog.loadAddress(address, fromSuggestions); + clearAddressLineTimer.start(); + } else if (addressLine.text !== "") { + addressBarDialog.loadAddress(addressLine.text, fromSuggestions); + clearAddressLineTimer.start(); + } + DialogsManager.hideAddressBar(); + } + + unoptimizedDomain.button2method = function() { + Settings.setValue("ShowUnoptimizedDomainWarning", false); + goTarget(); + } + + var showPopup = PlatformInfo.isStandalone() && !standaloneOptimized && Settings.getValue("ShowUnoptimizedDomainWarning", true); + + if(!showPopup) { + goTarget(); + } else { + unoptimizedDomain.visible = true; } - DialogsManager.hideAddressBar(); } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ca8883f660..0ba8ac0b28 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -755,6 +755,11 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { bool isStore = cmdOptionExists(argc, const_cast(argv), OCULUS_STORE_ARG); qApp->setProperty(hifi::properties::OCULUS_STORE, isStore); + // emulate standalone device + static const auto STANDALONE_ARG = "--standalone"; + bool isStandalone = cmdOptionExists(argc, const_cast(argv), STANDALONE_ARG); + qApp->setProperty(hifi::properties::STANDALONE, isStandalone); + // Ignore any previous crashes if running from command line with a test script. bool inTestMode { false }; for (int i = 0; i < argc; ++i) { @@ -3030,6 +3035,10 @@ void Application::initializeUi() { }; OffscreenQmlSurface::addWhitelistContextHandler({ QUrl{ "hifi/commerce/marketplace/Marketplace.qml" }, + QUrl{ "hifi/commerce/purchases/Purchases.qml" }, + QUrl{ "hifi/commerce/wallet/Wallet.qml" }, + QUrl{ "hifi/commerce/wallet/WalletHome.qml" }, + QUrl{ "hifi/tablet/TabletAddressDialog.qml" }, }, platformInfoCallback); QmlContextCallback ttsCallback = [](QQmlContext* context) { diff --git a/interface/src/scripting/PlatformInfoScriptingInterface.cpp b/interface/src/scripting/PlatformInfoScriptingInterface.cpp index b390ab7119..89d609810c 100644 --- a/interface/src/scripting/PlatformInfoScriptingInterface.cpp +++ b/interface/src/scripting/PlatformInfoScriptingInterface.cpp @@ -7,7 +7,7 @@ // #include "PlatformInfoScriptingInterface.h" #include "Application.h" - +#include #include #ifdef Q_OS_WIN @@ -138,6 +138,14 @@ bool PlatformInfoScriptingInterface::has3DHTML() { #if defined(Q_OS_ANDROID) return false; #else - return true; + return !qApp->property(hifi::properties::STANDALONE).toBool(); +#endif +} + +bool PlatformInfoScriptingInterface::isStandalone() { +#if defined(Q_OS_ANDROID) + return false; +#else + return qApp->property(hifi::properties::STANDALONE).toBool(); #endif } diff --git a/interface/src/scripting/PlatformInfoScriptingInterface.h b/interface/src/scripting/PlatformInfoScriptingInterface.h index aece09b008..31f0058585 100644 --- a/interface/src/scripting/PlatformInfoScriptingInterface.h +++ b/interface/src/scripting/PlatformInfoScriptingInterface.h @@ -68,9 +68,15 @@ public slots: /**jsdoc * Returns true if device supports 3d HTML - * @function Window.hasRift + * @function Window.has3DHTML * @returns {boolean} true if device supports 3d HTML, otherwise false.*/ bool has3DHTML(); + + /**jsdoc + * Returns true if device is standalone + * @function Window.hasRift + * @returns {boolean} true if device is a standalone device, otherwise false.*/ + bool isStandalone(); }; #endif // hifi_PlatformInfoScriptingInterface_h diff --git a/libraries/shared/src/shared/GlobalAppProperties.cpp b/libraries/shared/src/shared/GlobalAppProperties.cpp index 54e50da3ea..1fd6c191b2 100644 --- a/libraries/shared/src/shared/GlobalAppProperties.cpp +++ b/libraries/shared/src/shared/GlobalAppProperties.cpp @@ -14,6 +14,7 @@ namespace hifi { namespace properties { const char* STEAM = "com.highfidelity.launchedFromSteam"; const char* LOGGER = "com.highfidelity.logger"; const char* OCULUS_STORE = "com.highfidelity.oculusStore"; + const char* STANDALONE = "com.highfidelity.standalone"; const char* TEST = "com.highfidelity.test"; const char* TRACING = "com.highfidelity.tracing"; const char* HMD = "com.highfidelity.hmd"; diff --git a/libraries/shared/src/shared/GlobalAppProperties.h b/libraries/shared/src/shared/GlobalAppProperties.h index 174be61939..6809d5530a 100644 --- a/libraries/shared/src/shared/GlobalAppProperties.h +++ b/libraries/shared/src/shared/GlobalAppProperties.h @@ -16,6 +16,7 @@ namespace hifi { namespace properties { extern const char* STEAM; extern const char* LOGGER; extern const char* OCULUS_STORE; + extern const char* STANDALONE; extern const char* TEST; extern const char* TRACING; extern const char* HMD;