Commerce: Tons of Interface changes (#11463)
* canRez(Tmp)Certified() * CertifiedItem beginnings * Skeleton of verifyOwnerChallenge() * Controlled failure; updateLocation() skeletion * Controlled failure on checkout page with ctrl+f * Skeleton Purchases first-use tutorial * Initial progress on new setup * Security pic tip * Skeleton Certificate page * Updates to Certificate * General progress; setup is nearly complete * Better buttons; last step almost done * Initial progress on wallet home * Completed recent transactions * Security page * Scrollbar * Fix auth error text * PassphraseSelection * Change security pic * Minor layout changes; beginnings of emulated header * Various layout changes; wallet nav bar * Help screen * Quick onaccepted change * First pass at new purchases * Small style updates * Some error progress * Lightbox in purchases * Collapse other help answers when clicking on another * REZZED notif * Commerce Lightbox * Lots of new interactions in Purchases * Hook up 'view certificate' * Fix errors, fix close button on cert * Purchases timer; much faster filter * Add debugCheckout * Purchase updates * GlyphButton; separator; Checkout Success; Ledger fix; debug modes * Lock glyph below security pic should be white * Various fixes, round 1 * Circular mask * Passphrase change button fix; TextField error edge highlighting * Recent Activity fixes * Various changes * Standard Security Pic location * Color changes * Filter bar changes * Styling for multiple owned items * Minor language change * Header dropdown (harder than expected) * Small fixes * View backup instructions * marketplaces.js onCommerceScreen * Beginnign of new injection * Marketplace injection changes * Purchase button style changes * More button styling * MY PURCHASES button * marketplace onUsernameChanged * New help QA * Help text changes etc * Downscale security image, reducing filesize * Lots of bugfixes * Cleanup before PR * Only open cert during inspection if commerce switch is on * Help text changes * Purchase status incl. change to confirmed; Help text; Open Explorer to hifikey * Quick glyph change * New 'wallet not set up' flow for when entering Purchases or Checkout without set-up wallet
|
@ -102,7 +102,7 @@ static const QString ENTITY_SCRIPT_SERVER_LOGGING_NAME = "entity-script-server";
|
|||
void EntityScriptServer::handleReloadEntityServerScriptPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
// These are temporary checks until we can ensure that nodes eventually disconnect if the Domain Server stops telling them
|
||||
// about each other.
|
||||
if (senderNode->getCanRez() || senderNode->getCanRezTmp()) {
|
||||
if (senderNode->getCanRez() || senderNode->getCanRezTmp() || senderNode->getCanRezCertified() || senderNode->getCanRezTmpCertified()) {
|
||||
auto entityID = QUuid::fromRfc4122(message->read(NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
if (_entityViewer.getTree() && !_shuttingDown) {
|
||||
|
@ -116,7 +116,7 @@ void EntityScriptServer::handleReloadEntityServerScriptPacket(QSharedPointer<Rec
|
|||
void EntityScriptServer::handleEntityScriptGetStatusPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
// These are temporary checks until we can ensure that nodes eventually disconnect if the Domain Server stops telling them
|
||||
// about each other.
|
||||
if (senderNode->getCanRez() || senderNode->getCanRezTmp()) {
|
||||
if (senderNode->getCanRez() || senderNode->getCanRezTmp() || senderNode->getCanRezCertified() || senderNode->getCanRezTmpCertified()) {
|
||||
MessageID messageID;
|
||||
message->readPrimitive(&messageID);
|
||||
auto entityID = QUuid::fromRfc4122(message->read(NUM_BYTES_RFC4122_UUID));
|
||||
|
|
|
@ -269,6 +269,8 @@ void DomainGatekeeper::updateNodePermissions() {
|
|||
userPerms.permissions |= NodePermissions::Permission::canAdjustLocks;
|
||||
userPerms.permissions |= NodePermissions::Permission::canRezPermanentEntities;
|
||||
userPerms.permissions |= NodePermissions::Permission::canRezTemporaryEntities;
|
||||
userPerms.permissions |= NodePermissions::Permission::canRezPermanentCertifiedEntities;
|
||||
userPerms.permissions |= NodePermissions::Permission::canRezTemporaryCertifiedEntities;
|
||||
userPerms.permissions |= NodePermissions::Permission::canWriteToAssetServer;
|
||||
userPerms.permissions |= NodePermissions::Permission::canReplaceDomainContent;
|
||||
} else {
|
||||
|
@ -358,6 +360,8 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo
|
|||
userPerms.permissions |= NodePermissions::Permission::canAdjustLocks;
|
||||
userPerms.permissions |= NodePermissions::Permission::canRezPermanentEntities;
|
||||
userPerms.permissions |= NodePermissions::Permission::canRezTemporaryEntities;
|
||||
userPerms.permissions |= NodePermissions::Permission::canRezPermanentCertifiedEntities;
|
||||
userPerms.permissions |= NodePermissions::Permission::canRezTemporaryCertifiedEntities;
|
||||
userPerms.permissions |= NodePermissions::Permission::canWriteToAssetServer;
|
||||
userPerms.permissions |= NodePermissions::Permission::canReplaceDomainContent;
|
||||
newNode->setPermissions(userPerms);
|
||||
|
|
|
@ -959,7 +959,8 @@ bool DomainServer::isInInterestSet(const SharedNodePointer& nodeA, const SharedN
|
|||
|
||||
bool isAgentWithoutRights = nodeA->getType() == NodeType::Agent
|
||||
&& nodeB->getType() == NodeType::EntityScriptServer
|
||||
&& !nodeA->getCanRez() && !nodeA->getCanRezTmp();
|
||||
&& !nodeA->getCanRez() && !nodeA->getCanRezTmp()
|
||||
&& !nodeA->getCanRezCertified() && !nodeA->getCanRezTmpCertified();
|
||||
|
||||
if (isAgentWithoutRights) {
|
||||
return false;
|
||||
|
@ -968,7 +969,7 @@ bool DomainServer::isInInterestSet(const SharedNodePointer& nodeA, const SharedN
|
|||
bool isScriptServerForIneffectiveAgent =
|
||||
(nodeA->getType() == NodeType::EntityScriptServer && nodeB->getType() == NodeType::Agent)
|
||||
&& ((nodeBData && !nodeBData->getNodeInterestSet().contains(NodeType::EntityScriptServer))
|
||||
|| (!nodeB->getCanRez() && !nodeB->getCanRezTmp()));
|
||||
|| (!nodeB->getCanRez() && !nodeB->getCanRezTmp() && !nodeB->getCanRezCertified() && !nodeB->getCanRezTmpCertified()));
|
||||
|
||||
return !isScriptServerForIneffectiveAgent;
|
||||
} else {
|
||||
|
|
|
@ -302,6 +302,14 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList
|
|||
_standardAgentPermissions[NodePermissions::standardNameLocalhost]->set(NodePermissions::Permission::canReplaceDomainContent);
|
||||
packPermissions();
|
||||
}
|
||||
|
||||
if (oldVersion < 1.9) {
|
||||
unpackPermissions();
|
||||
// This was prior to addition of canRez(Tmp)Certified; add those to localhost permissions by default
|
||||
_standardAgentPermissions[NodePermissions::standardNameLocalhost]->set(NodePermissions::Permission::canRezPermanentCertifiedEntities);
|
||||
_standardAgentPermissions[NodePermissions::standardNameLocalhost]->set(NodePermissions::Permission::canRezTemporaryCertifiedEntities);
|
||||
packPermissions();
|
||||
}
|
||||
}
|
||||
|
||||
unpackPermissions();
|
||||
|
|
|
@ -15,8 +15,11 @@ import QtQuick.Controls.Styles 1.4
|
|||
import "../styles-uit"
|
||||
|
||||
Original.Button {
|
||||
id: root;
|
||||
|
||||
property int color: 0
|
||||
property int colorScheme: hifi.colorSchemes.light
|
||||
property string buttonGlyph: "";
|
||||
|
||||
width: 120
|
||||
height: hifi.dimensions.controlLineHeight
|
||||
|
@ -28,6 +31,13 @@ Original.Button {
|
|||
background: Rectangle {
|
||||
radius: hifi.buttons.radius
|
||||
|
||||
border.width: (control.color === hifi.buttons.none ||
|
||||
(control.color === hifi.buttons.noneBorderless && control.hovered) ||
|
||||
(control.color === hifi.buttons.noneBorderlessWhite && control.hovered) ||
|
||||
(control.color === hifi.buttons.noneBorderlessGray && control.hovered)) ? 1 : 0;
|
||||
border.color: control.color === hifi.buttons.noneBorderless ? hifi.colors.blueHighlight :
|
||||
(control.color === hifi.buttons.noneBorderlessGray ? hifi.colors.baseGray : hifi.colors.white);
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.2
|
||||
|
@ -60,14 +70,35 @@ Original.Button {
|
|||
}
|
||||
}
|
||||
|
||||
label: RalewayBold {
|
||||
font.capitalization: Font.AllUppercase
|
||||
color: enabled ? hifi.buttons.textColor[control.color]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme]
|
||||
size: hifi.fontSizes.buttonLabel
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: control.text
|
||||
label: Item {
|
||||
HiFiGlyphs {
|
||||
id: buttonGlyph;
|
||||
visible: root.buttonGlyph !== "";
|
||||
text: root.buttonGlyph === "" ? hifi.glyphs.question : root.buttonGlyph;
|
||||
// Size
|
||||
size: 34;
|
||||
// Anchors
|
||||
anchors.right: buttonText.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
// Style
|
||||
color: enabled ? hifi.buttons.textColor[control.color]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme];
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
RalewayBold {
|
||||
id: buttonText;
|
||||
anchors.centerIn: parent;
|
||||
font.capitalization: Font.AllUppercase
|
||||
color: enabled ? hifi.buttons.textColor[control.color]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme]
|
||||
size: hifi.fontSizes.buttonLabel
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: control.text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,19 @@ RalewaySemiBold {
|
|||
property int colorScheme: hifi.colorSchemes.light
|
||||
|
||||
size: hifi.fontSizes.inputLabel
|
||||
color: enabled ? (colorScheme == hifi.colorSchemes.light ? hifi.colors.lightGray : hifi.colors.lightGrayText)
|
||||
: (colorScheme == hifi.colorSchemes.light ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight);
|
||||
color: {
|
||||
if (colorScheme === hifi.colorSchemes.dark) {
|
||||
if (enabled) {
|
||||
hifi.colors.lightGrayText
|
||||
} else {
|
||||
hifi.colors.baseGrayHighlight
|
||||
}
|
||||
} else {
|
||||
if (enabled) {
|
||||
hifi.colors.lightGray
|
||||
} else {
|
||||
hifi.colors.lightGrayText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,13 @@ import QtQuick 2.5
|
|||
import "../styles-uit"
|
||||
|
||||
Item {
|
||||
property int colorScheme: 0;
|
||||
|
||||
readonly property var topColor: [ hifi.colors.baseGrayShadow, hifi.colors.faintGray ];
|
||||
readonly property var bottomColor: [ hifi.colors.baseGrayHighlight, hifi.colors.faintGray ];
|
||||
|
||||
// Size
|
||||
height: 2;
|
||||
height: colorScheme === 0 ? 2 : 1;
|
||||
Rectangle {
|
||||
// Size
|
||||
width: parent.width;
|
||||
|
@ -21,18 +26,19 @@ Item {
|
|||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: height;
|
||||
// Style
|
||||
color: hifi.colors.baseGrayShadow;
|
||||
color: topColor[colorScheme];
|
||||
}
|
||||
Rectangle {
|
||||
visible: colorScheme === 0;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 1;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: -height;
|
||||
// Style
|
||||
color: hifi.colors.baseGrayHighlight;
|
||||
color: bottomColor[colorScheme];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,9 +20,13 @@ TextField {
|
|||
|
||||
property int colorScheme: hifi.colorSchemes.light
|
||||
readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light
|
||||
readonly property bool isFaintGrayColorScheme: colorScheme == hifi.colorSchemes.faintGray
|
||||
property bool isSearchField: false
|
||||
property string label: ""
|
||||
property real controlHeight: height + (textFieldLabel.visible ? textFieldLabel.height + 1 : 0)
|
||||
property bool hasRoundedBorder: false
|
||||
property bool error: false;
|
||||
property bool hasClearButton: false;
|
||||
|
||||
placeholderText: textField.placeholderText
|
||||
|
||||
|
@ -35,16 +39,53 @@ TextField {
|
|||
y: textFieldLabel.visible ? textFieldLabel.height + textFieldLabel.anchors.bottomMargin : 0
|
||||
|
||||
style: TextFieldStyle {
|
||||
textColor: isLightColorScheme
|
||||
? (textField.activeFocus ? hifi.colors.black : hifi.colors.lightGray)
|
||||
: (textField.activeFocus ? hifi.colors.white : hifi.colors.lightGrayText)
|
||||
textColor: {
|
||||
if (isLightColorScheme) {
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.black
|
||||
} else {
|
||||
hifi.colors.lightGray
|
||||
}
|
||||
} else if (isFaintGrayColorScheme) {
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.black
|
||||
} else {
|
||||
hifi.colors.lightGray
|
||||
}
|
||||
} else {
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.white
|
||||
} else {
|
||||
hifi.colors.lightGrayText
|
||||
}
|
||||
}
|
||||
}
|
||||
background: Rectangle {
|
||||
color: isLightColorScheme
|
||||
? (textField.activeFocus ? hifi.colors.white : hifi.colors.textFieldLightBackground)
|
||||
: (textField.activeFocus ? hifi.colors.black : hifi.colors.baseGrayShadow)
|
||||
border.color: hifi.colors.primaryHighlight
|
||||
border.width: textField.activeFocus ? 1 : 0
|
||||
radius: isSearchField ? textField.height / 2 : 0
|
||||
color: {
|
||||
if (isLightColorScheme) {
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.white
|
||||
} else {
|
||||
hifi.colors.textFieldLightBackground
|
||||
}
|
||||
} else if (isFaintGrayColorScheme) {
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.white
|
||||
} else {
|
||||
hifi.colors.faintGray50
|
||||
}
|
||||
} else {
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.black
|
||||
} else {
|
||||
hifi.colors.baseGrayShadow
|
||||
}
|
||||
}
|
||||
}
|
||||
border.color: textField.error ? hifi.colors.redHighlight :
|
||||
(textField.activeFocus ? hifi.colors.primaryHighlight : (isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray))
|
||||
border.width: textField.activeFocus || hasRoundedBorder || textField.error ? 1 : 0
|
||||
radius: isSearchField ? textField.height / 2 : (hasRoundedBorder ? 4 : 0)
|
||||
|
||||
HiFiGlyphs {
|
||||
text: hifi.glyphs.search
|
||||
|
@ -55,12 +96,29 @@ TextField {
|
|||
anchors.leftMargin: hifi.dimensions.textPadding - 2
|
||||
visible: isSearchField
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
text: hifi.glyphs.error
|
||||
color: textColor
|
||||
size: 40
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: hifi.dimensions.textPadding - 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: hasClearButton && textField.text !== "";
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
textField.text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
placeholderTextColor: hifi.colors.lightGray
|
||||
placeholderTextColor: isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray
|
||||
selectedTextColor: hifi.colors.black
|
||||
selectionColor: hifi.colors.primaryHighlight
|
||||
padding.left: (isSearchField ? textField.height - 2 : 0) + hifi.dimensions.textPadding
|
||||
padding.right: hifi.dimensions.textPadding
|
||||
padding.right: (hasClearButton ? textField.height - 2 : 0) + hifi.dimensions.textPadding
|
||||
}
|
||||
|
||||
HifiControls.Label {
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
//
|
||||
// CommerceLightbox.qml
|
||||
// qml/hifi/commerce/common
|
||||
//
|
||||
// CommerceLightbox
|
||||
//
|
||||
// Created by Zach Fox on 2017-09-19
|
||||
// Copyright 2017 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 QtQuick.Controls 1.4
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
Rectangle {
|
||||
property string titleText;
|
||||
property string bodyImageSource;
|
||||
property string bodyText;
|
||||
property string button1text;
|
||||
property string button1method;
|
||||
property string button2text;
|
||||
property string button2method;
|
||||
|
||||
readonly property string securityPicBodyText: "When you see your Security Pic, your actions and data are securely making use of your " +
|
||||
"Wallet's private keys.<br><br>You can change your Security Pic in your Wallet.";
|
||||
|
||||
id: root;
|
||||
visible: false;
|
||||
anchors.fill: parent;
|
||||
color: Qt.rgba(0, 0, 0, 0.5);
|
||||
z: 999;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent;
|
||||
width: parent.width - 100;
|
||||
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.baseGray;
|
||||
size: 24;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
wrapMode: Text.WordWrap;
|
||||
}
|
||||
|
||||
Image {
|
||||
id: bodyImage;
|
||||
visible: root.bodyImageSource;
|
||||
source: root.bodyImageSource ? root.bodyImageSource : "";
|
||||
anchors.top: root.titleText ? titleText.bottom : parent.top;
|
||||
anchors.topMargin: root.titleText ? 20 : 30;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: 140;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
}
|
||||
|
||||
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.baseGray;
|
||||
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: 70;
|
||||
|
||||
// Button 1
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.noneBorderlessGray;
|
||||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 20;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 10;
|
||||
width: root.button2text ? parent.width/2 - anchors.leftMargin*2 : parent.width - anchors.leftMargin * 2;
|
||||
text: root.button1text;
|
||||
onClicked: {
|
||||
eval(button1method);
|
||||
}
|
||||
}
|
||||
|
||||
// Button 2
|
||||
HifiControlsUit.Button {
|
||||
visible: root.button2text;
|
||||
color: hifi.buttons.noneBorderless;
|
||||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 20;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 10;
|
||||
width: parent.width/2 - anchors.rightMargin*2;
|
||||
text: root.button2text;
|
||||
onClicked: {
|
||||
eval(button2method);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
signal sendToParent(var msg);
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
||||
}
|
|
@ -0,0 +1,333 @@
|
|||
//
|
||||
// EmulatedMarketplaceHeader.qml
|
||||
// qml/hifi/commerce/common
|
||||
//
|
||||
// EmulatedMarketplaceHeader
|
||||
//
|
||||
// Created by Zach Fox on 2017-09-18
|
||||
// Copyright 2017 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.7
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 1.4
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
Item {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string referrerURL: "https://metaverse.highfidelity.com/marketplace?";
|
||||
readonly property int additionalDropdownHeight: usernameDropdown.height - myUsernameButton.anchors.bottomMargin;
|
||||
|
||||
height: mainContainer.height + additionalDropdownHeight;
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onLoginStatusResult: {
|
||||
if (!isLoggedIn) {
|
||||
sendToParent({method: "needsLogIn"});
|
||||
}
|
||||
}
|
||||
|
||||
onAccountResult: {
|
||||
if (result.status === "success") {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
} else {
|
||||
// unsure how to handle a failure here. We definitely cannot proceed.
|
||||
}
|
||||
}
|
||||
|
||||
onSecurityImageResult: {
|
||||
if (exists) {
|
||||
securityImage.source = "";
|
||||
securityImage.source = "image://security/securityImage";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
commerce.getLoginStatus();
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: GlobalServices
|
||||
onMyUsernameChanged: {
|
||||
commerce.getLoginStatus();
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: mainContainer;
|
||||
color: hifi.colors.white;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: parent.top;
|
||||
height: 70;
|
||||
|
||||
Image {
|
||||
id: marketplaceHeaderImage;
|
||||
source: "images/marketplaceHeaderImage.png";
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 2;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 10;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
width: 140;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
sendToParent({method: "header_marketplaceImageClicked", referrerURL: root.referrerURL});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: buttonAndUsernameContainer;
|
||||
anchors.left: marketplaceHeaderImage.right;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 10;
|
||||
anchors.right: securityImage.left;
|
||||
anchors.rightMargin: 6;
|
||||
|
||||
Rectangle {
|
||||
id: myPurchasesLink;
|
||||
anchors.right: myUsernameButton.left;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
height: 40;
|
||||
width: myPurchasesText.paintedWidth + 10;
|
||||
|
||||
RalewaySemiBold {
|
||||
id: myPurchasesText;
|
||||
text: "My Purchases";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Style
|
||||
color: hifi.colors.blueAccent;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
// Anchors
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
sendToParent({method: 'header_goToPurchases'});
|
||||
}
|
||||
onEntered: myPurchasesText.color = hifi.colors.blueHighlight;
|
||||
onExited: myPurchasesText.color = hifi.colors.blueAccent;
|
||||
}
|
||||
}
|
||||
|
||||
FontLoader { id: ralewayRegular; source: "../../../../fonts/Raleway-Regular.ttf"; }
|
||||
TextMetrics {
|
||||
id: textMetrics;
|
||||
font.family: ralewayRegular.name
|
||||
text: usernameText.text;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: myUsernameButton;
|
||||
anchors.right: parent.right;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
height: 40;
|
||||
width: usernameText.width + 25;
|
||||
color: "white";
|
||||
radius: 4;
|
||||
border.width: 1;
|
||||
border.color: hifi.colors.lightGray;
|
||||
|
||||
// Username Text
|
||||
RalewayRegular {
|
||||
id: usernameText;
|
||||
text: Account.username;
|
||||
// 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: dropdownIcon;
|
||||
text: hifi.glyphs.caratDn;
|
||||
// Size
|
||||
size: 50;
|
||||
// Anchors
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: -14;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
usernameDropdown.visible = !usernameDropdown.visible;
|
||||
}
|
||||
onEntered: usernameText.color = hifi.colors.baseGrayShadow;
|
||||
onExited: usernameText.color = hifi.colors.baseGray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: securityImage;
|
||||
source: "";
|
||||
visible: securityImage.source !== "";
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 6;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 6;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 16;
|
||||
width: height;
|
||||
mipmap: true;
|
||||
|
||||
MouseArea {
|
||||
enabled: securityImage.visible;
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
sendToParent({method: "showSecurityPicLightbox", securityImageSource: securityImage.source});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LinearGradient {
|
||||
z: 996;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 10;
|
||||
start: Qt.point(0, 0);
|
||||
end: Qt.point(0, height);
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: hifi.colors.lightGrayText }
|
||||
GradientStop { position: 1.0; color: hifi.colors.white }
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: usernameDropdown;
|
||||
z: 998;
|
||||
visible: false;
|
||||
anchors.top: buttonAndUsernameContainer.bottom;
|
||||
anchors.topMargin: -buttonAndUsernameContainer.anchors.bottomMargin;
|
||||
anchors.right: buttonAndUsernameContainer.right;
|
||||
height: childrenRect.height;
|
||||
width: 100;
|
||||
|
||||
Rectangle {
|
||||
id: myItemsButton;
|
||||
color: hifi.colors.white;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 50;
|
||||
|
||||
RalewaySemiBold {
|
||||
anchors.fill: parent;
|
||||
text: "My Items"
|
||||
color: hifi.colors.baseGray;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
size: 18;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
onEntered: {
|
||||
myItemsButton.color = hifi.colors.blueHighlight;
|
||||
}
|
||||
onExited: {
|
||||
myItemsButton.color = hifi.colors.white;
|
||||
}
|
||||
onClicked: {
|
||||
sendToParent({method: "header_myItemsClicked"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: logOutButton;
|
||||
color: hifi.colors.white;
|
||||
anchors.top: myItemsButton.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 50;
|
||||
|
||||
RalewaySemiBold {
|
||||
anchors.fill: parent;
|
||||
text: "Log Out"
|
||||
color: hifi.colors.baseGray;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
size: 18;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
onEntered: {
|
||||
logOutButton.color = hifi.colors.blueHighlight;
|
||||
}
|
||||
onExited: {
|
||||
logOutButton.color = hifi.colors.white;
|
||||
}
|
||||
onClicked: {
|
||||
Account.logOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
z: 997;
|
||||
visible: usernameDropdown.visible;
|
||||
anchors.fill: usernameDropdown;
|
||||
horizontalOffset: 3;
|
||||
verticalOffset: 3;
|
||||
radius: 8.0;
|
||||
samples: 17;
|
||||
color: "#80000000";
|
||||
source: usernameDropdown;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
signal sendToParent(var msg);
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
||||
}
|
After Width: | Height: | Size: 5.7 KiB |
|
@ -0,0 +1,321 @@
|
|||
//
|
||||
// InspectionCertificate.qml
|
||||
// qml/hifi/commerce/inspectionCertificate
|
||||
//
|
||||
// InspectionCertificate
|
||||
//
|
||||
// Created by Zach Fox on 2017-09-14
|
||||
// Copyright 2017 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 QtQuick.Controls 1.4
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
import "../wallet" as HifiWallet
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
Rectangle {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string marketplaceId: "";
|
||||
property string itemName: "--";
|
||||
property string itemOwner: "--";
|
||||
property string itemEdition: "--";
|
||||
property string dateOfPurchase: "";
|
||||
property bool closeGoesToPurchases: false;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.fill: parent;
|
||||
source: "images/cert-bg.jpg";
|
||||
}
|
||||
|
||||
// Title text
|
||||
RalewayLight {
|
||||
id: titleBarText;
|
||||
text: "Certificate";
|
||||
// Text size
|
||||
size: 40;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 40;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 45;
|
||||
anchors.right: parent.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.darkGray;
|
||||
}
|
||||
// Title text
|
||||
RalewayRegular {
|
||||
id: popText;
|
||||
text: "PROOF OF PURCHASE";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: titleBarText.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: titleBarText.left;
|
||||
anchors.right: titleBarText.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
}
|
||||
|
||||
//
|
||||
// "CERTIFICATE" START
|
||||
//
|
||||
Item {
|
||||
id: certificateContainer;
|
||||
anchors.top: popText.bottom;
|
||||
anchors.topMargin: 30;
|
||||
anchors.bottom: buttonsContainer.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
RalewayRegular {
|
||||
id: itemNameHeader;
|
||||
text: "ITEM NAME";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 45;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
}
|
||||
RalewaySemiBold {
|
||||
id: itemName;
|
||||
text: root.itemName;
|
||||
// Text size
|
||||
size: 28;
|
||||
// Anchors
|
||||
anchors.top: itemNameHeader.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: itemNameHeader.left;
|
||||
anchors.right: itemNameHeader.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.blueAccent;
|
||||
elide: Text.ElideRight;
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', itemId: root.marketplaceId});
|
||||
}
|
||||
onEntered: itemName.color = hifi.colors.blueHighlight;
|
||||
onExited: itemName.color = hifi.colors.blueAccent;
|
||||
}
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: ownedByHeader;
|
||||
text: "OWNER";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: itemName.bottom;
|
||||
anchors.topMargin: 20;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 45;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
}
|
||||
RalewayRegular {
|
||||
id: ownedBy;
|
||||
text: root.itemOwner;
|
||||
// Text size
|
||||
size: 22;
|
||||
// Anchors
|
||||
anchors.top: ownedByHeader.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: ownedByHeader.left;
|
||||
anchors.right: ownedByHeader.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.darkGray;
|
||||
elide: Text.ElideRight;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: editionHeader;
|
||||
text: "EDITION";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: ownedBy.bottom;
|
||||
anchors.topMargin: 20;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 45;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
}
|
||||
AnonymousProRegular {
|
||||
id: edition;
|
||||
text: root.itemEdition;
|
||||
// Text size
|
||||
size: 22;
|
||||
// Anchors
|
||||
anchors.top: editionHeader.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: editionHeader.left;
|
||||
anchors.right: editionHeader.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.darkGray;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: dateOfPurchaseHeader;
|
||||
text: "DATE OF PURCHASE";
|
||||
visible: root.dateOfPurchase !== "";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: ownedBy.bottom;
|
||||
anchors.topMargin: 20;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 45;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
}
|
||||
AnonymousProRegular {
|
||||
id: dateOfPurchase;
|
||||
text: root.dateOfPurchase;
|
||||
visible: root.dateOfPurchase !== "";
|
||||
// Text size
|
||||
size: 22;
|
||||
// Anchors
|
||||
anchors.top: editionHeader.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: editionHeader.left;
|
||||
anchors.right: editionHeader.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.darkGray;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: errorText;
|
||||
text: "Here we will display some text if there's an <b>error</b> with the certificate " +
|
||||
"(DMCA takedown, invalid cert, location of item updated)";
|
||||
// Text size
|
||||
size: 20;
|
||||
// Anchors
|
||||
anchors.top: root.dateOfPurchase !== "" ? dateOfPurchase.bottom : edition.bottom;
|
||||
anchors.topMargin: 40;
|
||||
anchors.left: root.dateOfPurchase !== "" ? dateOfPurchase.left : edition.left;
|
||||
anchors.right: root.dateOfPurchase !== "" ? dateOfPurchase.right : edition.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
// Style
|
||||
wrapMode: Text.WordWrap;
|
||||
color: hifi.colors.redHighlight;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
}
|
||||
//
|
||||
// "CERTIFICATE" END
|
||||
//
|
||||
|
||||
Item {
|
||||
id: buttonsContainer;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 50;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 50;
|
||||
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.noneBorderless;
|
||||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
width: parent.width/2 - 50;
|
||||
height: 50;
|
||||
text: "close";
|
||||
onClicked: {
|
||||
sendToScript({method: 'inspectionCertificate_closeClicked', closeGoesToPurchases: root.closeGoesToPurchases});
|
||||
}
|
||||
}
|
||||
|
||||
// "Show In Marketplace" button
|
||||
HifiControlsUit.Button {
|
||||
id: showInMarketplaceButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
width: parent.width/2 - 50;
|
||||
height: 50;
|
||||
text: "View In Market"
|
||||
onClicked: {
|
||||
sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', itemId: root.marketplaceId});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
//
|
||||
// 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) {
|
||||
switch (message.method) {
|
||||
case 'inspectionCertificate_setMarketplaceId':
|
||||
root.marketplaceId = message.marketplaceId;
|
||||
root.closeGoesToPurchases = message.closeGoesToPurchases;
|
||||
break;
|
||||
case 'inspectionCertificate_setItemInfo':
|
||||
root.itemName = message.itemName;
|
||||
root.itemOwner = message.itemOwner;
|
||||
root.itemEdition = message.itemEdition;
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
signal sendToScript(var message);
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
||||
}
|
After Width: | Height: | Size: 63 KiB |
|
@ -0,0 +1,196 @@
|
|||
//
|
||||
// FirstUseTutorial.qml
|
||||
// qml/hifi/commerce/purchases
|
||||
//
|
||||
// FirstUseTutorial
|
||||
//
|
||||
// Created by Zach Fox on 2017-09-13
|
||||
// Copyright 2017 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 QtQuick.Controls 1.4
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
Rectangle {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string activeView: "step_1";
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
|
||||
//
|
||||
// "STEP 1" START
|
||||
//
|
||||
Item {
|
||||
id: step_1;
|
||||
visible: root.activeView === "step_1";
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: tutorialActionButtonsContainer.top;
|
||||
|
||||
RalewayRegular {
|
||||
id: step1text;
|
||||
text: "<b>This is the first-time Purchases tutorial.</b><br><br>Here is some <b>bold text</b> " +
|
||||
"inside Step 1.";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
//
|
||||
// "STEP 1" END
|
||||
//
|
||||
|
||||
//
|
||||
// "STEP 2" START
|
||||
//
|
||||
Item {
|
||||
id: step_2;
|
||||
visible: root.activeView === "step_2";
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: tutorialActionButtonsContainer.top;
|
||||
|
||||
RalewayRegular {
|
||||
id: step2text;
|
||||
text: "<b>STEP TWOOO!!!</b>";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
//
|
||||
// "STEP 2" END
|
||||
//
|
||||
|
||||
Item {
|
||||
id: tutorialActionButtonsContainer;
|
||||
// Size
|
||||
width: root.width;
|
||||
height: 70;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 24;
|
||||
|
||||
// "Skip" or "Back" button
|
||||
HifiControlsUit.Button {
|
||||
id: skipOrBackButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: parent.width/2 - anchors.leftMargin*2;
|
||||
text: root.activeView === "step_1" ? "Skip" : "Back";
|
||||
onClicked: {
|
||||
if (root.activeView === "step_1") {
|
||||
sendSignalToParent({method: 'tutorial_skipClicked'});
|
||||
} else {
|
||||
root.activeView = "step_" + (parseInt(root.activeView.split("_")[1]) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "Next" or "Finish" button
|
||||
HifiControlsUit.Button {
|
||||
id: nextButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: parent.width/2 - anchors.rightMargin*2;
|
||||
text: root.activeView === "step_2" ? "Finish" : "Next";
|
||||
onClicked: {
|
||||
// If this is the final step...
|
||||
if (root.activeView === "step_2") {
|
||||
sendSignalToParent({method: 'tutorial_finished'});
|
||||
} else {
|
||||
root.activeView = "step_" + (parseInt(root.activeView.split("_")[1]) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
//
|
||||
// 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) {
|
||||
switch (message.method) {
|
||||
case 'updatePurchases':
|
||||
referrerURL = message.referrerURL;
|
||||
break;
|
||||
case 'purchases_getIsFirstUseResult':
|
||||
if (message.isFirstUseOfPurchases && root.activeView !== "firstUseTutorial") {
|
||||
root.activeView = "firstUseTutorial";
|
||||
} else if (!message.isFirstUseOfPurchases && root.activeView === "initialize") {
|
||||
root.activeView = "purchasesMain";
|
||||
commerce.inventory();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
signal sendSignalToParent(var message);
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
||||
}
|
|
@ -13,7 +13,9 @@
|
|||
|
||||
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 "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
|
@ -21,116 +23,395 @@ import "../wallet" as HifiWallet
|
|||
|
||||
// references XXX from root context
|
||||
|
||||
Rectangle {
|
||||
Item {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string itemName: "";
|
||||
property string itemId: "";
|
||||
property string itemPreviewImageUrl: "";
|
||||
property string itemHref: "";
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 120;
|
||||
property string purchaseStatus;
|
||||
property bool purchaseStatusChanged;
|
||||
property bool canRezCertifiedItems: false;
|
||||
property string itemName;
|
||||
property string itemId;
|
||||
property string itemPreviewImageUrl;
|
||||
property string itemHref;
|
||||
property int ownedItemCount;
|
||||
property int itemEdition;
|
||||
|
||||
Image {
|
||||
id: itemPreviewImage;
|
||||
source: root.itemPreviewImageUrl;
|
||||
height: 110;
|
||||
width: parent.width;
|
||||
|
||||
onPurchaseStatusChangedChanged: {
|
||||
if (root.purchaseStatusChanged === true && root.purchaseStatus === "confirmed") {
|
||||
statusText.text = "CONFIRMED!";
|
||||
statusText.color = hifi.colors.blueAccent;
|
||||
confirmedTimer.start();
|
||||
root.purchaseStatusChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: confirmedTimer;
|
||||
interval: 3000;
|
||||
onTriggered: {
|
||||
root.purchaseStatus = "";
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: mainContainer;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
// Size
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 8;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 8;
|
||||
width: 180;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
height: root.height - 10;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RalewayRegular {
|
||||
id: itemName;
|
||||
anchors.top: itemPreviewImage.top;
|
||||
anchors.left: itemPreviewImage.right;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
height: 30;
|
||||
// Text size
|
||||
size: 20;
|
||||
// Style
|
||||
color: hifi.colors.blueAccent;
|
||||
text: root.itemName;
|
||||
elide: Text.ElideRight;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
|
||||
}
|
||||
onEntered: {
|
||||
itemName.color = hifi.colors.blueHighlight;
|
||||
}
|
||||
onExited: {
|
||||
itemName.color = hifi.colors.blueAccent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: buttonContainer;
|
||||
anchors.top: itemName.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 8;
|
||||
anchors.left: itemPreviewImage.right;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
|
||||
// "Rez" button
|
||||
HifiControlsUit.Button {
|
||||
id: rezButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
Image {
|
||||
id: itemPreviewImage;
|
||||
source: root.itemPreviewImageUrl;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: parent.height/2 - 4;
|
||||
text: "Rez Item"
|
||||
onClicked: {
|
||||
if (urlHandler.canHandleUrl(root.itemHref)) {
|
||||
urlHandler.handleUrl(root.itemHref);
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: height;
|
||||
fillMode: Image.PreserveAspectCrop;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "More Info" button
|
||||
HifiControlsUit.Button {
|
||||
id: moreInfoButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: parent.height/2 - 4;
|
||||
text: "More Info"
|
||||
onClicked: {
|
||||
sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
|
||||
|
||||
RalewaySemiBold {
|
||||
id: itemName;
|
||||
anchors.top: itemPreviewImage.top;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: itemPreviewImage.right;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: buttonContainer.left;
|
||||
anchors.rightMargin: 8;
|
||||
height: paintedHeight;
|
||||
// Text size
|
||||
size: 24;
|
||||
// Style
|
||||
color: hifi.colors.blueAccent;
|
||||
text: root.itemName;
|
||||
elide: Text.ElideRight;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
|
||||
}
|
||||
onEntered: {
|
||||
itemName.color = hifi.colors.blueHighlight;
|
||||
}
|
||||
onExited: {
|
||||
itemName.color = hifi.colors.blueAccent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: certificateContainer;
|
||||
anchors.top: itemName.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: itemName.left;
|
||||
anchors.right: buttonContainer.left;
|
||||
anchors.rightMargin: 2;
|
||||
height: 24;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: certificateIcon;
|
||||
text: hifi.glyphs.scriptNew;
|
||||
// Size
|
||||
size: 30;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 32;
|
||||
// Style
|
||||
color: hifi.colors.lightGray;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: viewCertificateText;
|
||||
text: "VIEW CERTIFICATE";
|
||||
size: 14;
|
||||
anchors.left: certificateIcon.right;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
color: hifi.colors.lightGray;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
sendToPurchases({method: 'purchases_itemCertificateClicked', itemMarketplaceId: root.itemId});
|
||||
}
|
||||
onEntered: {
|
||||
certificateIcon.color = hifi.colors.black;
|
||||
viewCertificateText.color = hifi.colors.black;
|
||||
}
|
||||
onExited: {
|
||||
certificateIcon.color = hifi.colors.lightGray;
|
||||
viewCertificateText.color = hifi.colors.lightGray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusContainer;
|
||||
|
||||
visible: root.purchaseStatus || root.ownedItemCount > 1;
|
||||
anchors.left: itemName.left;
|
||||
anchors.top: certificateContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: buttonContainer.left;
|
||||
anchors.rightMargin: 2;
|
||||
|
||||
RalewaySemiBold {
|
||||
id: statusText;
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
text: {
|
||||
if (root.purchaseStatus === "pending") {
|
||||
"PENDING..."
|
||||
} else if (root.purchaseStatus === "invalidated") {
|
||||
"INVALIDATED"
|
||||
} else if (root.ownedItemCount > 1) {
|
||||
"<font color='#6a6a6a'>(#" + root.itemEdition + ")</font> <u>You own " + root.ownedItemCount + " others</u>"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
size: 18;
|
||||
color: {
|
||||
if (root.purchaseStatus === "pending") {
|
||||
hifi.colors.blueAccent
|
||||
} else if (root.purchaseStatus === "invalidated") {
|
||||
hifi.colors.redAccent
|
||||
} else if (root.ownedItemCount > 1) {
|
||||
hifi.colors.blueAccent
|
||||
} else {
|
||||
hifi.colors.baseGray
|
||||
}
|
||||
}
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
id: statusIcon;
|
||||
text: {
|
||||
if (root.purchaseStatus === "pending") {
|
||||
hifi.glyphs.question
|
||||
} else if (root.purchaseStatus === "invalidated") {
|
||||
hifi.glyphs.question
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
// Size
|
||||
size: 36;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: -8;
|
||||
anchors.left: statusText.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
// Style
|
||||
color: {
|
||||
if (root.purchaseStatus === "pending") {
|
||||
hifi.colors.blueAccent
|
||||
} else if (root.purchaseStatus === "invalidated") {
|
||||
hifi.colors.redAccent
|
||||
} else if (root.ownedItemCount > 1) {
|
||||
hifi.colors.blueAccent
|
||||
} else {
|
||||
hifi.colors.baseGray
|
||||
}
|
||||
}
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
if (root.purchaseStatus === "pending") {
|
||||
sendToPurchases({method: 'showPendingLightbox'});
|
||||
} else if (root.purchaseStatus === "invalidated") {
|
||||
sendToPurchases({method: 'showInvalidatedLightbox'});
|
||||
} else if (root.ownedItemCount > 1) {
|
||||
sendToPurchases({method: 'setFilterText', filterText: root.itemName});
|
||||
}
|
||||
}
|
||||
onEntered: {
|
||||
if (root.purchaseStatus === "pending") {
|
||||
statusText.color = hifi.colors.blueHighlight;
|
||||
statusIcon.color = hifi.colors.blueHighlight;
|
||||
} else if (root.purchaseStatus === "invalidated") {
|
||||
statusText.color = hifi.colors.redAccent;
|
||||
statusIcon.color = hifi.colors.redAccent;
|
||||
} else if (root.ownedItemCount > 1) {
|
||||
statusText.color = hifi.colors.blueHighlight;
|
||||
statusIcon.color = hifi.colors.blueHighlight;
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
if (root.purchaseStatus === "pending") {
|
||||
statusText.color = hifi.colors.blueAccent;
|
||||
statusIcon.color = hifi.colors.blueAccent;
|
||||
} else if (root.purchaseStatus === "invalidated") {
|
||||
statusText.color = hifi.colors.redHighlight;
|
||||
statusIcon.color = hifi.colors.redHighlight;
|
||||
} else if (root.ownedItemCount > 1) {
|
||||
statusText.color = hifi.colors.blueAccent;
|
||||
statusIcon.color = hifi.colors.blueAccent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rezzedNotifContainer;
|
||||
z: 998;
|
||||
visible: false;
|
||||
color: hifi.colors.blueHighlight;
|
||||
anchors.fill: buttonContainer;
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
propagateComposedEvents: false;
|
||||
}
|
||||
|
||||
RalewayBold {
|
||||
anchors.fill: parent;
|
||||
text: "REZZED";
|
||||
size: 18;
|
||||
color: hifi.colors.white;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: rezzedNotifContainerTimer;
|
||||
interval: 2000;
|
||||
onTriggered: rezzedNotifContainer.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: buttonContainer;
|
||||
property int color: hifi.buttons.red;
|
||||
property int colorScheme: hifi.colorSchemes.light;
|
||||
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
width: height;
|
||||
enabled: root.canRezCertifiedItems && root.purchaseStatus !== "invalidated";
|
||||
|
||||
onClicked: {
|
||||
if (urlHandler.canHandleUrl(root.itemHref)) {
|
||||
urlHandler.handleUrl(root.itemHref);
|
||||
}
|
||||
rezzedNotifContainer.visible = true;
|
||||
rezzedNotifContainerTimer.start();
|
||||
}
|
||||
|
||||
style: ButtonStyle {
|
||||
|
||||
background: Rectangle {
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.2
|
||||
color: {
|
||||
if (!control.enabled) {
|
||||
hifi.buttons.disabledColorStart[control.colorScheme]
|
||||
} else if (control.pressed) {
|
||||
hifi.buttons.pressedColor[control.color]
|
||||
} else if (control.hovered) {
|
||||
hifi.buttons.hoveredColor[control.color]
|
||||
} else {
|
||||
hifi.buttons.colorStart[control.color]
|
||||
}
|
||||
}
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: {
|
||||
if (!control.enabled) {
|
||||
hifi.buttons.disabledColorFinish[control.colorScheme]
|
||||
} else if (control.pressed) {
|
||||
hifi.buttons.pressedColor[control.color]
|
||||
} else if (control.hovered) {
|
||||
hifi.buttons.hoveredColor[control.color]
|
||||
} else {
|
||||
hifi.buttons.colorFinish[control.color]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
label: Item {
|
||||
HiFiGlyphs {
|
||||
id: lightningIcon;
|
||||
text: hifi.glyphs.lightning;
|
||||
// Size
|
||||
size: 32;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 12;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
// Style
|
||||
color: enabled ? hifi.buttons.textColor[control.color]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme]
|
||||
}
|
||||
RalewayBold {
|
||||
anchors.top: lightningIcon.bottom;
|
||||
anchors.topMargin: -20;
|
||||
anchors.right: parent.right;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
font.capitalization: Font.AllUppercase
|
||||
color: enabled ? hifi.buttons.textColor[control.color]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme]
|
||||
size: 16;
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: "Rez It"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: mainContainer;
|
||||
horizontalOffset: 3;
|
||||
verticalOffset: 3;
|
||||
radius: 8.0;
|
||||
samples: 17;
|
||||
color: "#80000000";
|
||||
source: mainContainer;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -18,6 +18,7 @@ import "../../../styles-uit"
|
|||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
import "../wallet" as HifiWallet
|
||||
import "../common" as HifiCommerceCommon
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
|
@ -30,19 +31,13 @@ Rectangle {
|
|||
property bool securityImageResultReceived: false;
|
||||
property bool purchasesReceived: false;
|
||||
property bool punctuationMode: false;
|
||||
property bool canRezCertifiedItems: false;
|
||||
property bool pendingInventoryReply: true;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
color: hifi.colors.white;
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onAccountResult: {
|
||||
if (result.status === "success") {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
} else {
|
||||
// unsure how to handle a failure here. We definitely cannot proceed.
|
||||
}
|
||||
}
|
||||
|
||||
onLoginStatusResult: {
|
||||
if (!isLoggedIn && root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
|
@ -52,9 +47,18 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
onAccountResult: {
|
||||
if (result.status === "success") {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
} else {
|
||||
// unsure how to handle a failure here. We definitely cannot proceed.
|
||||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
if (path === "" && root.activeView !== "notSetUp") {
|
||||
root.activeView = "notSetUp";
|
||||
notSetUpTimer.start();
|
||||
} else if (path !== "" && root.activeView === "initialize") {
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
|
@ -64,103 +68,101 @@ Rectangle {
|
|||
securityImageResultReceived = true;
|
||||
if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up"
|
||||
root.activeView = "notSetUp";
|
||||
notSetUpTimer.start();
|
||||
} else if (exists && root.activeView === "initialize") {
|
||||
commerce.getWalletAuthenticatedStatus();
|
||||
} else if (exists) {
|
||||
// just set the source again (to be sure the change was noticed)
|
||||
securityImage.source = "";
|
||||
securityImage.source = "image://security/securityImage";
|
||||
}
|
||||
}
|
||||
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
if (!isAuthenticated && !passphraseModal.visible) {
|
||||
passphraseModal.visible = true;
|
||||
if (!isAuthenticated && root.activeView !== "passphraseModal") {
|
||||
root.activeView = "passphraseModal";
|
||||
} else if (isAuthenticated) {
|
||||
root.activeView = "purchasesMain";
|
||||
commerce.inventory();
|
||||
sendToScript({method: 'purchases_getIsFirstUse'});
|
||||
}
|
||||
}
|
||||
|
||||
onInventoryResult: {
|
||||
purchasesReceived = true;
|
||||
|
||||
if (result.status !== 'success') {
|
||||
console.log("Failed to get purchases", result.message);
|
||||
} else {
|
||||
purchasesModel.clear();
|
||||
purchasesModel.append(result.data.assets);
|
||||
filteredPurchasesModel.clear();
|
||||
filteredPurchasesModel.append(result.data.assets);
|
||||
|
||||
if (previousPurchasesModel.count !== 0) {
|
||||
checkIfAnyItemStatusChanged();
|
||||
} else {
|
||||
// Fill statusChanged default value
|
||||
// Not doing this results in the default being true...
|
||||
for (var i = 0; i < purchasesModel.count; i++) {
|
||||
purchasesModel.setProperty(i, "statusChanged", false);
|
||||
}
|
||||
}
|
||||
previousPurchasesModel.append(result.data.assets);
|
||||
|
||||
buildFilteredPurchasesModel();
|
||||
|
||||
if (root.pendingInventoryReply) {
|
||||
inventoryTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
root.pendingInventoryReply = false;
|
||||
}
|
||||
}
|
||||
|
||||
HifiWallet.SecurityImageModel {
|
||||
id: securityImageModel;
|
||||
Timer {
|
||||
id: notSetUpTimer;
|
||||
interval: 200;
|
||||
onTriggered: {
|
||||
sendToScript({method: 'checkout_walletNotSetUp'});
|
||||
}
|
||||
}
|
||||
|
||||
HifiCommerceCommon.CommerceLightbox {
|
||||
id: lightboxPopup;
|
||||
visible: false;
|
||||
anchors.fill: parent;
|
||||
|
||||
Connections {
|
||||
onSendToParent: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TITLE BAR START
|
||||
//
|
||||
Item {
|
||||
HifiCommerceCommon.EmulatedMarketplaceHeader {
|
||||
id: titleBarContainer;
|
||||
z: 998;
|
||||
visible: !needsLogIn.visible;
|
||||
// Size
|
||||
height: 50;
|
||||
width: parent.width;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: parent.top;
|
||||
|
||||
// Title Bar text
|
||||
RalewaySemiBold {
|
||||
id: titleBarText;
|
||||
text: "PURCHASES";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// Security Image (TEMPORARY!)
|
||||
Image {
|
||||
id: securityImage;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
height: parent.height - 10;
|
||||
width: height;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
cache: false;
|
||||
source: "image://security/securityImage";
|
||||
}
|
||||
Image {
|
||||
id: securityImageOverlay;
|
||||
source: "../wallet/images/lockOverlay.png";
|
||||
width: securityImage.width * 0.45;
|
||||
height: securityImage.height * 0.45;
|
||||
anchors.bottom: securityImage.bottom;
|
||||
anchors.right: securityImage.right;
|
||||
mipmap: true;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
// Separator
|
||||
HifiControlsUit.Separator {
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
Connections {
|
||||
onSendToParent: {
|
||||
if (msg.method === 'needsLogIn' && root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
} else if (msg.method === 'showSecurityPicLightbox') {
|
||||
lightboxPopup.titleText = "Your Security Pic";
|
||||
lightboxPopup.bodyImageSource = msg.securityImageSource;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button2text = "GO TO WALLET";
|
||||
lightboxPopup.button2method = "sendToParent({method: 'purchases_openWallet'});";
|
||||
lightboxPopup.visible = true;
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
@ -171,10 +173,11 @@ Rectangle {
|
|||
id: initialize;
|
||||
visible: root.activeView === "initialize";
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: -titleBarContainer.additionalDropdownHeight;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
color: hifi.colors.baseGray;
|
||||
color: hifi.colors.white;
|
||||
|
||||
Component.onCompleted: {
|
||||
securityImageResultReceived = false;
|
||||
|
@ -206,101 +209,45 @@ Rectangle {
|
|||
|
||||
HifiWallet.PassphraseModal {
|
||||
id: passphraseModal;
|
||||
visible: false;
|
||||
visible: root.activeView === "passphraseModal";
|
||||
anchors.fill: parent;
|
||||
titleBarText: "Purchases";
|
||||
titleBarIcon: hifi.glyphs.wallet;
|
||||
|
||||
Connections {
|
||||
onSendSignalToParent: {
|
||||
if (msg.method === "authSuccess") {
|
||||
root.activeView = "initialize";
|
||||
sendToScript({method: 'purchases_getIsFirstUse'});
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FirstUseTutorial {
|
||||
id: firstUseTutorial;
|
||||
visible: root.activeView === "firstUseTutorial";
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: -titleBarContainer.additionalDropdownHeight;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
Connections {
|
||||
onSendSignalToParent: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// "WALLET NOT SET UP" START
|
||||
//
|
||||
Item {
|
||||
id: notSetUp;
|
||||
visible: root.activeView === "notSetUp";
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
RalewayRegular {
|
||||
id: notSetUpText;
|
||||
text: "<b>Your wallet isn't set up.</b><br><br>Set up your Wallet (no credit card necessary) to claim your <b>free HFC</b> " +
|
||||
"and get items from the Marketplace.";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: notSetUpActionButtonsContainer.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: notSetUpActionButtonsContainer;
|
||||
// Size
|
||||
width: root.width;
|
||||
height: 70;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 24;
|
||||
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
id: cancelButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: parent.width/2 - anchors.leftMargin*2;
|
||||
text: "Cancel"
|
||||
onClicked: {
|
||||
sendToScript({method: 'purchases_backClicked', referrerURL: referrerURL});
|
||||
}
|
||||
}
|
||||
|
||||
// "Set Up" button
|
||||
HifiControlsUit.Button {
|
||||
id: setUpButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: parent.width/2 - anchors.rightMargin*2;
|
||||
text: "Set Up Wallet"
|
||||
onClicked: {
|
||||
sendToScript({method: 'checkout_setUpClicked'});
|
||||
switch (message.method) {
|
||||
case 'tutorial_skipClicked':
|
||||
case 'tutorial_finished':
|
||||
sendToScript({method: 'purchases_setIsFirstUse'});
|
||||
root.activeView = "purchasesMain";
|
||||
commerce.inventory();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// "WALLET NOT SET UP" END
|
||||
//
|
||||
|
||||
//
|
||||
// PURCHASES CONTENTS START
|
||||
|
@ -310,13 +257,10 @@ Rectangle {
|
|||
visible: root.activeView === "purchasesMain";
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 4;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.bottom: actionButtonsContainer.top;
|
||||
anchors.bottomMargin: 8;
|
||||
anchors.topMargin: 8 - titleBarContainer.additionalDropdownHeight;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
//
|
||||
// FILTER BAR START
|
||||
|
@ -329,32 +273,38 @@ Rectangle {
|
|||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.rightMargin: 12;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 4;
|
||||
|
||||
RalewayRegular {
|
||||
id: myPurchasesText;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 10;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 10;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 4;
|
||||
width: paintedWidth;
|
||||
text: "My Purchases";
|
||||
color: hifi.colors.baseGray;
|
||||
size: 28;
|
||||
}
|
||||
|
||||
HifiControlsUit.TextField {
|
||||
id: filterBar;
|
||||
property int previousLength: 0;
|
||||
anchors.fill: parent;
|
||||
placeholderText: "Filter";
|
||||
colorScheme: hifi.colorSchemes.faintGray;
|
||||
hasClearButton: true;
|
||||
hasRoundedBorder: true;
|
||||
anchors.left: myPurchasesText.right;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
placeholderText: "filter items";
|
||||
|
||||
onTextChanged: {
|
||||
if (filterBar.text.length < previousLength) {
|
||||
filteredPurchasesModel.clear();
|
||||
|
||||
for (var i = 0; i < purchasesModel.count; i++) {
|
||||
filteredPurchasesModel.append(purchasesModel.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < filteredPurchasesModel.count; i++) {
|
||||
if (filteredPurchasesModel.get(i).title.toLowerCase().indexOf(filterBar.text.toLowerCase()) === -1) {
|
||||
filteredPurchasesModel.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
previousLength = filterBar.text.length;
|
||||
buildFilteredPurchasesModel();
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
|
@ -366,29 +316,107 @@ Rectangle {
|
|||
// FILTER BAR END
|
||||
//
|
||||
|
||||
HifiControlsUit.Separator {
|
||||
id: separator;
|
||||
colorScheme: 1;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: filterBarContainer.bottom;
|
||||
anchors.topMargin: 16;
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: purchasesModel;
|
||||
}
|
||||
ListModel {
|
||||
id: previousPurchasesModel;
|
||||
}
|
||||
ListModel {
|
||||
id: filteredPurchasesModel;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: cantRezCertified;
|
||||
visible: !root.canRezCertifiedItems;
|
||||
color: "#FFC3CD";
|
||||
radius: 4;
|
||||
border.color: hifi.colors.redAccent;
|
||||
border.width: 1;
|
||||
anchors.top: separator.bottom;
|
||||
anchors.topMargin: 12;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 80;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: lightningIcon;
|
||||
text: hifi.glyphs.lightning;
|
||||
// Size
|
||||
size: 36;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 18;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 12;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
// Style
|
||||
color: hifi.colors.lightGray;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
text: "You don't have permission to rez certified items in this domain. " +
|
||||
'<b><font color="' + hifi.colors.blueAccent + '"><a href="#">Learn More</a></font></b>';
|
||||
// Text size
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: lightningIcon.right;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 4;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
onLinkActivated: {
|
||||
lightboxPopup.titleText = "Rez Permission Required";
|
||||
lightboxPopup.bodyText = "You don't have permission to rez certified items in this domain.<br><br>" +
|
||||
"Use the <b>GOTO app</b> to visit another domain or <b>go to your own sandbox.</b>";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button2text = "OPEN GOTO";
|
||||
lightboxPopup.button2method = "sendToParent({method: 'purchases_openGoTo'});";
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: purchasesContentsList;
|
||||
visible: purchasesModel.count !== 0;
|
||||
clip: true;
|
||||
model: filteredPurchasesModel;
|
||||
// Anchors
|
||||
anchors.top: filterBarContainer.bottom;
|
||||
anchors.top: root.canRezCertifiedItems ? separator.bottom : cantRezCertified.bottom;
|
||||
anchors.topMargin: 12;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width;
|
||||
delegate: PurchasedItem {
|
||||
canRezCertifiedItems: root.canRezCertifiedItems;
|
||||
itemName: title;
|
||||
itemId: id;
|
||||
itemPreviewImageUrl: preview;
|
||||
itemHref: root_file_url;
|
||||
purchaseStatus: status;
|
||||
purchaseStatusChanged: statusChanged;
|
||||
anchors.topMargin: 12;
|
||||
anchors.bottomMargin: 12;
|
||||
|
||||
|
@ -396,6 +424,24 @@ Rectangle {
|
|||
onSendToPurchases: {
|
||||
if (msg.method === 'purchases_itemInfoClicked') {
|
||||
sendToScript({method: 'purchases_itemInfoClicked', itemId: itemId});
|
||||
} else if (msg.method === 'purchases_itemCertificateClicked') {
|
||||
sendToScript(msg);
|
||||
} else if (msg.method === "showInvalidatedLightbox") {
|
||||
lightboxPopup.titleText = "Item Invalidated";
|
||||
lightboxPopup.bodyText = 'Your item is marked "invalidated" because this item has been suspended ' +
|
||||
"from the Marketplace due to a claim against its author.";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.method === "showPendingLightbox") {
|
||||
lightboxPopup.titleText = "Item Pending";
|
||||
lightboxPopup.bodyText = 'Your item is marked "pending" while your purchase is being confirmed. ' +
|
||||
"Usually, purchases take about 90 seconds to confirm.";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.method === "setFilterText") {
|
||||
filterBar.text = msg.filterText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -414,7 +460,7 @@ Rectangle {
|
|||
// Explanitory text
|
||||
RalewayRegular {
|
||||
id: haventPurchasedYet;
|
||||
text: "<b>You haven't purchased anything yet!</b><br><br>Get an item from <b>Marketplace</b> to add it to your <b>Purchases</b>.";
|
||||
text: "<b>You haven't purchased anything yet!</b><br><br>Get an item from <b>Marketplace</b> to add it to My Purchases.";
|
||||
// Text size
|
||||
size: 22;
|
||||
// Anchors
|
||||
|
@ -426,7 +472,7 @@ Rectangle {
|
|||
anchors.rightMargin: 24;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
color: hifi.colors.baseGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
|
@ -452,42 +498,6 @@ Rectangle {
|
|||
// PURCHASES CONTENTS END
|
||||
//
|
||||
|
||||
//
|
||||
// ACTION BUTTONS START
|
||||
//
|
||||
Item {
|
||||
id: actionButtonsContainer;
|
||||
visible: purchasesContentsContainer.visible;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 40;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: keyboard.top;
|
||||
anchors.bottomMargin: 8;
|
||||
|
||||
// "Back" button
|
||||
HifiControlsUit.Button {
|
||||
id: backButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: parent.width/2 - anchors.leftMargin*2;
|
||||
text: "Back"
|
||||
onClicked: {
|
||||
sendToScript({method: 'purchases_backClicked', referrerURL: referrerURL});
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// ACTION BUTTONS END
|
||||
//
|
||||
|
||||
HifiControlsUit.Keyboard {
|
||||
id: keyboard;
|
||||
raised: HMD.mounted && filterBar.focus;
|
||||
|
@ -499,9 +509,60 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
inventoryTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: inventoryTimer;
|
||||
interval: 90000;
|
||||
onTriggered: {
|
||||
if (root.activeView === "purchasesMain" && !root.pendingInventoryReply) {
|
||||
root.pendingInventoryReply = true;
|
||||
commerce.inventory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
|
||||
function buildFilteredPurchasesModel() {
|
||||
filteredPurchasesModel.clear();
|
||||
for (var i = 0; i < purchasesModel.count; i++) {
|
||||
if (purchasesModel.get(i).title.toLowerCase().indexOf(filterBar.text.toLowerCase()) !== -1) {
|
||||
if (purchasesModel.get(i).status !== "confirmed") {
|
||||
filteredPurchasesModel.insert(0, purchasesModel.get(i));
|
||||
} else {
|
||||
filteredPurchasesModel.append(purchasesModel.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkIfAnyItemStatusChanged() {
|
||||
var currentPurchasesModelId, currentPurchasesModelEdition, currentPurchasesModelStatus;
|
||||
var previousPurchasesModelStatus;
|
||||
for (var i = 0; i < purchasesModel.count; i++) {
|
||||
currentPurchasesModelId = purchasesModel.get(i).id;
|
||||
currentPurchasesModelEdition = purchasesModel.get(i).edition_number;
|
||||
currentPurchasesModelStatus = purchasesModel.get(i).status;
|
||||
|
||||
for (var j = 0; j < previousPurchasesModel.count; j++) {
|
||||
previousPurchasesModelStatus = previousPurchasesModel.get(j).status;
|
||||
if (currentPurchasesModelId === previousPurchasesModel.get(j).id &&
|
||||
currentPurchasesModelEdition === previousPurchasesModel.get(j).edition_number &&
|
||||
currentPurchasesModelStatus !== previousPurchasesModelStatus) {
|
||||
|
||||
purchasesModel.setProperty(i, "statusChanged", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Function Name: fromScript()
|
||||
//
|
||||
|
@ -519,6 +580,17 @@ Rectangle {
|
|||
switch (message.method) {
|
||||
case 'updatePurchases':
|
||||
referrerURL = message.referrerURL;
|
||||
titleBarContainer.referrerURL = message.referrerURL;
|
||||
root.canRezCertifiedItems = message.canRezCertifiedItems;
|
||||
filterBar.text = message.filterText ? message.filterText : "";
|
||||
break;
|
||||
case 'purchases_getIsFirstUseResult':
|
||||
if (message.isFirstUseOfPurchases && root.activeView !== "firstUseTutorial") {
|
||||
root.activeView = "firstUseTutorial";
|
||||
} else if (!message.isFirstUseOfPurchases && root.activeView === "initialize") {
|
||||
root.activeView = "purchasesMain";
|
||||
commerce.inventory();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//
|
||||
// SendMoney.qml
|
||||
// Help.qml
|
||||
// qml/hifi/commerce/wallet
|
||||
//
|
||||
// SendMoney
|
||||
// Help
|
||||
//
|
||||
// Created by Zach Fox on 2017-08-18
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
|
@ -12,8 +12,8 @@
|
|||
//
|
||||
|
||||
import Hifi 1.0 as Hifi
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.2
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
|
@ -24,35 +24,44 @@ Item {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string keyFilePath;
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
keyFilePath = path;
|
||||
}
|
||||
}
|
||||
|
||||
// "Unavailable"
|
||||
RalewayRegular {
|
||||
id: helpText;
|
||||
text: "Help me!";
|
||||
Component.onCompleted: {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: helpTitleText;
|
||||
text: "Help Topics";
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: paintedWidth;
|
||||
height: 30;
|
||||
// Text size
|
||||
size: 24;
|
||||
size: 18;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
color: hifi.colors.blueHighlight;
|
||||
}
|
||||
HifiControlsUit.Button {
|
||||
id: clearCachedPassphraseButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: resetButton.top;
|
||||
anchors.bottomMargin: 15;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
height: 50;
|
||||
width: 250;
|
||||
text: "DEBUG: Clear Cached Passphrase";
|
||||
anchors.top: parent.top;
|
||||
anchors.left: helpTitleText.right;
|
||||
anchors.leftMargin: 20;
|
||||
height: 40;
|
||||
width: 150;
|
||||
text: "DBG: Clear Pass";
|
||||
onClicked: {
|
||||
commerce.setPassphrase("");
|
||||
sendSignalToWallet({method: 'passphraseReset'});
|
||||
|
@ -62,18 +71,184 @@ Item {
|
|||
id: resetButton;
|
||||
color: hifi.buttons.red;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: helpText.bottom;
|
||||
anchors.bottomMargin: 15;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
height: 50;
|
||||
width: 250;
|
||||
text: "DEBUG: Reset Wallet!";
|
||||
anchors.top: clearCachedPassphraseButton.top;
|
||||
anchors.left: clearCachedPassphraseButton.right;
|
||||
height: 40;
|
||||
width: 150;
|
||||
text: "DBG: RST Wallet";
|
||||
onClicked: {
|
||||
commerce.reset();
|
||||
sendSignalToWallet({method: 'walletReset'});
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: helpModel;
|
||||
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "What are private keys?"
|
||||
answer: qsTr("A private key is a secret piece of text that is used to decrypt code.<br><br>In High Fidelity, <b>your private keys are used to decrypt the contents of your Wallet and Purchases.</b>");
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "Where are my private keys stored?"
|
||||
answer: qsTr('Your private keys are <b>only stored on your hard drive</b> in High Fidelity Interface\'s AppData directory.<br><br><b><font color="#0093C5"><a href="#privateKeyPath">Tap here to open the file path of your hifikey in your file explorer.</a></font></b><br><br> You may backup this file by copying it to a USB flash drive, or to a service like Dropbox or Google Drive. Restore your backup by replacing the file in Interface\'s AppData directory with your backed-up copy.');
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "What happens if I lose my passphrase?"
|
||||
answer: qsTr("If you lose your passphrase, you will no longer have access to the contents of your Wallet or My Purchases.<br><br><b>Nobody can help you recover your passphrase, including High Fidelity.</b> Please write it down and store it securely.");
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "What is a 'Security Pic'?"
|
||||
answer: qsTr("Your Security Pic is an encrypted image that you selected during Wallet Setup. <b>It acts as an extra layer of Wallet security.</b><br><br>When you see your Security Pic, you know that your actions and data are securely making use of your private keys.<br><br><b>If you don't see your Security Pic on a page that is asking you for your Wallet passphrase, someone untrustworthy may be trying to gain access to your Wallet.</b><br><br>The Pic is stored on your hard drive inside the same file as your private keys.");
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "My HFC balance isn't what I expect it to be. Why?"
|
||||
answer: qsTr('High Fidelity Coin (HFC) transactions are backed by a <b>blockchain</b>, which takes time to update. The status of a transaction usually updates within 90 seconds.<br><br><b><font color="#0093C5"><a href="#blockchain">Tap here to learn more about the blockchain.</a></font></b>');
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "My friend purchased my item from the Marketplace, but I still haven't received the money from the sale. Why not?"
|
||||
answer: qsTr('High Fidelity Coin (HFC) transactions are backed by a <b>blockchain</b>, which takes time to update. The status of a transaction usually updates within 90 seconds, at which point you will receive your money.<br><br><b><font color="#0093C5"><a href="#blockchain">Tap here to learn more about the blockchain.</a></font></b>');
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "Do I get charged money if a transaction fails?"
|
||||
answer: qsTr("<b>No.</b> Your HFC balance only changes after a transaction is confirmed.");
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "How do I convert HFC to other currencies?"
|
||||
answer: qsTr("We are still building the tools needed to support a vibrant economy in High Fidelity. <b>There is currently no way to convert HFC to other currencies.</b>");
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: helpListView;
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
policy: helpListView.contentHeight > helpListView.height ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded;
|
||||
parent: helpListView.parent;
|
||||
anchors.top: helpListView.top;
|
||||
anchors.right: helpListView.right;
|
||||
anchors.bottom: helpListView.bottom;
|
||||
width: 20;
|
||||
}
|
||||
anchors.top: helpTitleText.bottom;
|
||||
anchors.topMargin: 30;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right
|
||||
clip: true;
|
||||
model: helpModel;
|
||||
delegate: Item {
|
||||
width: parent.width;
|
||||
height: model.isExpanded ? questionContainer.height + answerContainer.height : questionContainer.height;
|
||||
|
||||
HifiControlsUit.Separator {
|
||||
colorScheme: 1;
|
||||
visible: index === 0;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: parent.top;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: questionContainer;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
width: parent.width;
|
||||
height: questionText.paintedHeight + 50;
|
||||
|
||||
RalewaySemiBold {
|
||||
id: plusMinusButton;
|
||||
text: model.isExpanded ? "-" : "+";
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: model.isExpanded ? -9 : 0;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
width: 60;
|
||||
// Text size
|
||||
size: 60;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: questionText;
|
||||
text: model.question;
|
||||
size: 18;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.left: plusMinusButton.right;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 10;
|
||||
wrapMode: Text.WordWrap;
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.white;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: securityTabMouseArea;
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
model.isExpanded = !model.isExpanded;
|
||||
if (model.isExpanded) {
|
||||
collapseAllOtherHelpItems(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: answerContainer;
|
||||
visible: model.isExpanded;
|
||||
color: Qt.rgba(0, 0, 0, 0.5);
|
||||
anchors.top: questionContainer.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: answerText.paintedHeight + 50;
|
||||
|
||||
RalewayRegular {
|
||||
id: answerText;
|
||||
text: model.answer;
|
||||
size: 18;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 32;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 32;
|
||||
wrapMode: Text.WordWrap;
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.white;
|
||||
|
||||
onLinkActivated: {
|
||||
if (link === "#privateKeyPath") {
|
||||
Qt.openUrlExternally("file:///" + root.keyFilePath.substring(0, root.keyFilePath.lastIndexOf('/')));
|
||||
} else if (link === "#blockchain") {
|
||||
Qt.openUrlExternally("https://www.highfidelity.com/");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Separator {
|
||||
colorScheme: 1;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
|
@ -97,6 +272,14 @@ Item {
|
|||
}
|
||||
}
|
||||
signal sendSignalToWallet(var msg);
|
||||
|
||||
function collapseAllOtherHelpItems(thisIndex) {
|
||||
for (var i = 0; i < helpModel.count; i++) {
|
||||
if (i !== thisIndex) {
|
||||
helpModel.setProperty(i, "isExpanded", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
||||
|
|
|
@ -24,6 +24,12 @@ Item {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
|
||||
Image {
|
||||
anchors.fill: parent;
|
||||
source: "images/wallet-bg.jpg";
|
||||
}
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
}
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
//
|
||||
// NotSetUp.qml
|
||||
// qml/hifi/commerce/wallet
|
||||
//
|
||||
// NotSetUp
|
||||
//
|
||||
// Created by Zach Fox on 2017-08-18
|
||||
// Copyright 2017 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 QtQuick.Controls 1.4
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
Item {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
}
|
||||
|
||||
//
|
||||
// TAB CONTENTS START
|
||||
//
|
||||
|
||||
// Text below title bar
|
||||
RalewaySemiBold {
|
||||
id: notSetUpText;
|
||||
text: "Your Wallet Account Has Not Been Set Up";
|
||||
// Text size
|
||||
size: 22;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 100;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 50;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// Explanitory text
|
||||
RalewayRegular {
|
||||
text: "To buy and sell items in High Fidelity Coin (HFC), you first need " +
|
||||
"to set up your wallet.<br><b>You do not need to submit a credit card or personal information to set up your wallet.</b>";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: notSetUpText.bottom;
|
||||
anchors.topMargin: 16;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: 100;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// "Set Up" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 150;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
width: parent.width/2;
|
||||
height: 50;
|
||||
text: "Set Up My Wallet";
|
||||
onClicked: {
|
||||
sendSignalToWallet({method: 'setUpClicked'});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// TAB CONTENTS END
|
||||
//
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
//
|
||||
// Function Name: fromScript()
|
||||
//
|
||||
// Relevant Variables:
|
||||
// None
|
||||
//
|
||||
// Arguments:
|
||||
// message: The message sent from the JavaScript.
|
||||
// Messages are in format "{method, params}", like json-rpc.
|
||||
//
|
||||
// Description:
|
||||
// Called when a message is received from a script.
|
||||
//
|
||||
function fromScript(message) {
|
||||
switch (message.method) {
|
||||
default:
|
||||
console.log('Unrecognized message from wallet.js:', JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
signal sendSignalToWallet(var msg);
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
//
|
||||
// PassphraseSelectionLightbox.qml
|
||||
// PassphraseChange.qml
|
||||
// qml/hifi/commerce/wallet
|
||||
//
|
||||
// PassphraseSelectionLightbox
|
||||
// PassphraseChange
|
||||
//
|
||||
// Created by Zach Fox on 2017-08-18
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
|
@ -20,12 +20,31 @@ import "../../../controls" as HifiControls
|
|||
|
||||
// references XXX from root context
|
||||
|
||||
Rectangle {
|
||||
Item {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
|
||||
SecurityImageModel {
|
||||
id: securityImageModel;
|
||||
}
|
||||
|
||||
// Username Text
|
||||
RalewayRegular {
|
||||
id: usernameText;
|
||||
text: Account.username;
|
||||
// Text size
|
||||
size: 24;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
elide: Text.ElideRight;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: parent.width/2;
|
||||
height: 80;
|
||||
}
|
||||
|
||||
//
|
||||
// SECURE PASSPHRASE SELECTION START
|
||||
|
@ -33,60 +52,31 @@ Rectangle {
|
|||
Item {
|
||||
id: choosePassphraseContainer;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
anchors.top: usernameText.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
Item {
|
||||
id: passphraseTitle;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
||||
// Title Bar text
|
||||
RalewaySemiBold {
|
||||
text: "CHANGE PASSPHRASE";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
// Text below title bar
|
||||
// "Change Passphrase" text
|
||||
RalewaySemiBold {
|
||||
id: passphraseTitleHelper;
|
||||
text: "Choose a Secure Passphrase";
|
||||
id: passphraseTitle;
|
||||
text: "Change Passphrase:";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: passphraseTitle.bottom;
|
||||
size: 18;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.leftMargin: 20;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 50;
|
||||
height: 30;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
color: hifi.colors.blueHighlight;
|
||||
}
|
||||
|
||||
PassphraseSelection {
|
||||
id: passphraseSelection;
|
||||
anchors.top: passphraseTitleHelper.bottom;
|
||||
anchors.topMargin: 30;
|
||||
isChangingPassphrase: true;
|
||||
anchors.top: passphraseTitle.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: passphraseNavBar.top;
|
||||
|
@ -96,11 +86,10 @@ Rectangle {
|
|||
if (msg.method === 'statusResult') {
|
||||
if (msg.status) {
|
||||
// Success submitting new passphrase
|
||||
root.resetSubmitButton();
|
||||
root.visible = false;
|
||||
sendSignalToWallet({method: "walletSecurity_changePassphraseSuccess"});
|
||||
} else {
|
||||
// Error submitting new passphrase
|
||||
root.resetSubmitButton();
|
||||
resetSubmitButton();
|
||||
passphraseSelection.setErrorText("Backend error");
|
||||
}
|
||||
} else {
|
||||
|
@ -115,40 +104,37 @@ Rectangle {
|
|||
id: passphraseNavBar;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 100;
|
||||
height: 40;
|
||||
// Anchors:
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 30;
|
||||
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.black;
|
||||
color: hifi.buttons.noneBorderlessWhite;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: 100;
|
||||
width: 150;
|
||||
text: "Cancel"
|
||||
onClicked: {
|
||||
root.visible = false;
|
||||
sendSignalToWallet({method: "walletSecurity_changePassphraseCancelled"});
|
||||
}
|
||||
}
|
||||
|
||||
// "Submit" button
|
||||
HifiControlsUit.Button {
|
||||
id: passphraseSubmitButton;
|
||||
color: hifi.buttons.black;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: 100;
|
||||
width: 150;
|
||||
text: "Submit";
|
||||
onClicked: {
|
||||
if (passphraseSelection.validateAndSubmitPassphrase()) {
|
|
@ -17,6 +17,7 @@ import QtQuick.Controls 1.4
|
|||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
import "../common" as HifiCommerceCommon
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
|
@ -26,11 +27,20 @@ Item {
|
|||
id: root;
|
||||
z: 998;
|
||||
property bool keyboardRaised: false;
|
||||
property string titleBarIcon: "";
|
||||
property string titleBarText: "";
|
||||
|
||||
Image {
|
||||
anchors.fill: parent;
|
||||
source: "images/wallet-bg.jpg";
|
||||
}
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onSecurityImageResult: {
|
||||
titleBarSecurityImage.source = "";
|
||||
titleBarSecurityImage.source = "image://security/securityImage";
|
||||
passphraseModalSecurityImage.source = "";
|
||||
passphraseModalSecurityImage.source = "image://security/securityImage";
|
||||
}
|
||||
|
@ -40,7 +50,7 @@ Item {
|
|||
if (!isAuthenticated) {
|
||||
errorText.text = "Authentication failed - please try again.";
|
||||
} else {
|
||||
root.visible = false;
|
||||
sendSignalToParent({method: 'authSuccess'});;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,24 +76,88 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
// Background rectangle
|
||||
Rectangle {
|
||||
HifiCommerceCommon.CommerceLightbox {
|
||||
id: lightboxPopup;
|
||||
visible: false;
|
||||
anchors.fill: parent;
|
||||
color: "black";
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Item {
|
||||
id: titleBar;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 50;
|
||||
|
||||
// Wallet icon
|
||||
HiFiGlyphs {
|
||||
id: titleBarIcon;
|
||||
text: root.titleBarIcon;
|
||||
// Size
|
||||
size: parent.height * 0.8;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
// Style
|
||||
color: hifi.colors.blueHighlight;
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: titleBarText;
|
||||
text: root.titleBarText;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: titleBarIcon.right;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
size: 20;
|
||||
color: hifi.colors.white;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
Image {
|
||||
id: titleBarSecurityImage;
|
||||
source: "";
|
||||
visible: titleBarSecurityImage.source !== "";
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 6;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 6;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 6;
|
||||
width: height;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
|
||||
MouseArea {
|
||||
enabled: titleBarSecurityImage.visible;
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
lightboxPopup.titleText = "Your Security Pic";
|
||||
lightboxPopup.bodyImageSource = titleBarSecurityImage.source;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: passphraseContainer;
|
||||
anchors.top: titleBar.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
height: 250;
|
||||
color: hifi.colors.baseGray;
|
||||
|
||||
RalewaySemiBold {
|
||||
id: instructionsText;
|
||||
text: "Enter Wallet Passphrase";
|
||||
size: 16;
|
||||
text: "Please Enter Your Passphrase";
|
||||
size: 24;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 30;
|
||||
anchors.left: parent.left;
|
||||
|
@ -91,17 +165,34 @@ Item {
|
|||
width: passphraseField.width;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
color: hifi.colors.white;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
}
|
||||
|
||||
// Error text above buttons
|
||||
RalewaySemiBold {
|
||||
id: errorText;
|
||||
text: "";
|
||||
// Text size
|
||||
size: 15;
|
||||
// Anchors
|
||||
anchors.bottom: passphraseField.top;
|
||||
anchors.bottomMargin: 4;
|
||||
anchors.left: passphraseField.left;
|
||||
anchors.right: parent.right;
|
||||
height: 20;
|
||||
// Style
|
||||
color: hifi.colors.redHighlight;
|
||||
}
|
||||
|
||||
HifiControlsUit.TextField {
|
||||
id: passphraseField;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: instructionsText.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.topMargin: 40;
|
||||
anchors.left: instructionsText.left;
|
||||
width: 280;
|
||||
width: 260;
|
||||
height: 50;
|
||||
echoMode: TextInput.Password;
|
||||
placeholderText: "passphrase";
|
||||
|
@ -133,7 +224,7 @@ Item {
|
|||
anchors.top: passphraseField.bottom;
|
||||
anchors.topMargin: 8;
|
||||
height: 30;
|
||||
text: "Show passphrase as plain text";
|
||||
text: "Show passphrase";
|
||||
boxSize: 24;
|
||||
onClicked: {
|
||||
passphraseField.echoMode = checked ? TextInput.Normal : TextInput.Password;
|
||||
|
@ -144,16 +235,18 @@ Item {
|
|||
Item {
|
||||
id: securityImageContainer;
|
||||
// Anchors
|
||||
anchors.top: instructionsText.top;
|
||||
anchors.top: passphraseField.top;
|
||||
anchors.left: passphraseField.right;
|
||||
anchors.leftMargin: 12;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
height: 145;
|
||||
Image {
|
||||
id: passphraseModalSecurityImage;
|
||||
anchors.top: parent.top;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
height: 75;
|
||||
width: height;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: iconAndTextContainer.top;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
source: "image://security/securityImage";
|
||||
|
@ -162,54 +255,43 @@ Item {
|
|||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: passphraseModalSecurityImageOverlay;
|
||||
source: "images/lockOverlay.png";
|
||||
width: passphraseModalSecurityImage.width * 0.45;
|
||||
height: passphraseModalSecurityImage.height * 0.45;
|
||||
anchors.bottom: passphraseModalSecurityImage.bottom;
|
||||
Item {
|
||||
id: iconAndTextContainer;
|
||||
anchors.left: passphraseModalSecurityImage.left;
|
||||
anchors.right: passphraseModalSecurityImage.right;
|
||||
mipmap: true;
|
||||
opacity: 0.9;
|
||||
anchors.bottom: parent.bottom;
|
||||
height: 24;
|
||||
// Lock icon
|
||||
HiFiGlyphs {
|
||||
id: lockIcon;
|
||||
text: hifi.glyphs.lock;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
size: 20;
|
||||
width: height;
|
||||
verticalAlignment: Text.AlignBottom;
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
// "Security image" text below pic
|
||||
RalewayRegular {
|
||||
id: securityImageText;
|
||||
text: "SECURITY PIC";
|
||||
// Text size
|
||||
size: 12;
|
||||
// Anchors
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: lockIcon.anchors.leftMargin;
|
||||
width: paintedWidth;
|
||||
height: 22;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignRight;
|
||||
verticalAlignment: Text.AlignBottom;
|
||||
}
|
||||
}
|
||||
// "Security image" text below pic
|
||||
RalewayRegular {
|
||||
text: "security image";
|
||||
// Text size
|
||||
size: 12;
|
||||
// Anchors
|
||||
anchors.top: passphraseModalSecurityImage.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: securityImageContainer.left;
|
||||
anchors.right: securityImageContainer.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
// Error text above buttons
|
||||
RalewaySemiBold {
|
||||
id: errorText;
|
||||
text: "";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.bottom: passphrasePopupActionButtonsContainer.top;
|
||||
anchors.bottomMargin: 4;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 30;
|
||||
// Style
|
||||
color: hifi.colors.redHighlight;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -217,29 +299,10 @@ Item {
|
|||
//
|
||||
Item {
|
||||
id: passphrasePopupActionButtonsContainer;
|
||||
// Size
|
||||
width: root.width;
|
||||
height: 50;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 10;
|
||||
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
id: cancelPassphraseInputButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
height: 40;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: parent.width/2 - anchors.leftMargin*2;
|
||||
text: "Cancel"
|
||||
onClicked: {
|
||||
sendSignalToParent({method: 'passphrasePopup_cancelClicked'});
|
||||
}
|
||||
}
|
||||
|
||||
// "Submit" button
|
||||
HifiControlsUit.Button {
|
||||
|
@ -247,16 +310,38 @@ Item {
|
|||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 20;
|
||||
height: 40;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: parent.width/2 - anchors.rightMargin*2;
|
||||
anchors.rightMargin: 16;
|
||||
width: parent.width/2 -4;
|
||||
text: "Submit"
|
||||
onClicked: {
|
||||
submitPassphraseInputButton.enabled = false;
|
||||
commerce.setPassphrase(passphraseField.text);
|
||||
}
|
||||
}
|
||||
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
id: cancelPassphraseInputButton;
|
||||
color: hifi.buttons.noneBorderlessWhite;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: submitPassphraseInputButton.bottom;
|
||||
anchors.topMargin: 20;
|
||||
height: 40;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
width: parent.width/2 - 4;
|
||||
text: "Cancel"
|
||||
onClicked: {
|
||||
sendSignalToParent({method: 'passphrasePopup_cancelClicked'});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@ Item {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property bool isChangingPassphrase: false;
|
||||
property bool isShowingTip: false;
|
||||
|
||||
// This object is always used in a popup.
|
||||
// This MouseArea is used to prevent a user from being
|
||||
|
@ -51,23 +53,62 @@ Item {
|
|||
// TODO: Fix this unlikely bug
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
passphraseField.focus = true;
|
||||
if (root.isChangingPassphrase) {
|
||||
currentPassphraseField.focus = true;
|
||||
} else {
|
||||
passphraseField.focus = true;
|
||||
}
|
||||
sendMessageToLightbox({method: 'disableHmdPreview'});
|
||||
} else {
|
||||
sendMessageToLightbox({method: 'maybeEnableHmdPreview'});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HifiControlsUit.TextField {
|
||||
id: currentPassphraseField;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
visible: root.isChangingPassphrase;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
anchors.right: passphraseField.right;
|
||||
height: 50;
|
||||
echoMode: TextInput.Password;
|
||||
placeholderText: "enter current passphrase";
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
sendSignalToWallet({method: 'walletSetup_raiseKeyboard'});
|
||||
} else if (!passphraseFieldAgain.focus) {
|
||||
sendSignalToWallet({method: 'walletSetup_lowerKeyboard'});
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
parent.focus = true;
|
||||
sendSignalToWallet({method: 'walletSetup_raiseKeyboard'});
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
passphraseField.focus = true;
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.TextField {
|
||||
id: passphraseField;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 30;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: root.isChangingPassphrase ? currentPassphraseField.bottom : parent.top;
|
||||
anchors.topMargin: root.isChangingPassphrase ? 40 : 0;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
width: 280;
|
||||
anchors.leftMargin: 20;
|
||||
width: 285;
|
||||
height: 50;
|
||||
echoMode: TextInput.Password;
|
||||
placeholderText: "passphrase";
|
||||
placeholderText: root.isShowingTip ? "" : "enter new passphrase";
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
|
@ -91,13 +132,14 @@ Item {
|
|||
}
|
||||
HifiControlsUit.TextField {
|
||||
id: passphraseFieldAgain;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: passphraseField.bottom;
|
||||
anchors.topMargin: 10;
|
||||
anchors.topMargin: root.isChangingPassphrase ? 20 : 40;
|
||||
anchors.left: passphraseField.left;
|
||||
anchors.right: passphraseField.right;
|
||||
height: 50;
|
||||
echoMode: TextInput.Password;
|
||||
placeholderText: "re-enter passphrase";
|
||||
placeholderText: root.isShowingTip ? "" : "re-enter new passphrase";
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
|
@ -124,16 +166,16 @@ Item {
|
|||
Item {
|
||||
id: securityImageContainer;
|
||||
// Anchors
|
||||
anchors.top: passphraseField.top;
|
||||
anchors.top: root.isChangingPassphrase ? currentPassphraseField.top : passphraseField.top;
|
||||
anchors.left: passphraseField.right;
|
||||
anchors.leftMargin: 12;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: root.isChangingPassphrase ? passphraseField.bottom : passphraseFieldAgain.bottom;
|
||||
Image {
|
||||
id: passphrasePageSecurityImage;
|
||||
anchors.top: parent.top;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
height: 75;
|
||||
width: height;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: iconAndTextContainer.top;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
source: "image://security/securityImage";
|
||||
|
@ -142,123 +184,125 @@ Item {
|
|||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: topSecurityImageOverlay;
|
||||
source: "images/lockOverlay.png";
|
||||
width: passphrasePageSecurityImage.width * 0.45;
|
||||
height: passphrasePageSecurityImage.height * 0.45;
|
||||
anchors.bottom: passphrasePageSecurityImage.bottom;
|
||||
Item {
|
||||
id: iconAndTextContainer;
|
||||
anchors.left: passphrasePageSecurityImage.left;
|
||||
anchors.right: passphrasePageSecurityImage.right;
|
||||
mipmap: true;
|
||||
opacity: 0.9;
|
||||
}
|
||||
// "Security image" text below pic
|
||||
RalewayRegular {
|
||||
text: "security image";
|
||||
// Text size
|
||||
size: 12;
|
||||
// Anchors
|
||||
anchors.top: passphrasePageSecurityImage.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: securityImageContainer.left;
|
||||
anchors.right: securityImageContainer.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
anchors.bottom: parent.bottom;
|
||||
height: 22;
|
||||
// Lock icon
|
||||
HiFiGlyphs {
|
||||
id: lockIcon;
|
||||
text: hifi.glyphs.lock;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 35;
|
||||
size: 20;
|
||||
width: height;
|
||||
verticalAlignment: Text.AlignBottom;
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
// "Security image" text below pic
|
||||
RalewayRegular {
|
||||
id: securityImageText;
|
||||
text: "SECURITY PIC";
|
||||
// Text size
|
||||
size: 12;
|
||||
// Anchors
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: lockIcon.anchors.leftMargin;
|
||||
width: paintedWidth;
|
||||
height: 22;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignRight;
|
||||
verticalAlignment: Text.AlignBottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Error text below TextFields
|
||||
// Error text above TextFields
|
||||
RalewaySemiBold {
|
||||
id: errorText;
|
||||
text: "";
|
||||
// Text size
|
||||
size: 16;
|
||||
size: 15;
|
||||
// Anchors
|
||||
anchors.top: passphraseFieldAgain.bottom;
|
||||
anchors.topMargin: 0;
|
||||
anchors.bottom: passphraseField.top;
|
||||
anchors.bottomMargin: 4;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
anchors.leftMargin: 20;
|
||||
anchors.right: securityImageContainer.left;
|
||||
anchors.rightMargin: 4;
|
||||
height: 30;
|
||||
// Style
|
||||
color: hifi.colors.redHighlight;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// Text below TextFields
|
||||
RalewaySemiBold {
|
||||
id: passwordReqs;
|
||||
text: "Passphrase must be at least 3 characters";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: passphraseFieldAgain.bottom;
|
||||
anchors.topMargin: 16;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 30;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// Show passphrase text
|
||||
HifiControlsUit.CheckBox {
|
||||
id: showPassphrase;
|
||||
visible: !root.isShowingTip;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.top: passwordReqs.bottom;
|
||||
anchors.leftMargin: 20;
|
||||
anchors.top: passphraseFieldAgain.bottom;
|
||||
anchors.topMargin: 16;
|
||||
height: 30;
|
||||
text: "Show passphrase as plain text";
|
||||
text: "Show passphrase";
|
||||
boxSize: 24;
|
||||
onClicked: {
|
||||
passphraseField.echoMode = checked ? TextInput.Normal : TextInput.Password;
|
||||
passphraseFieldAgain.echoMode = checked ? TextInput.Normal : TextInput.Password;
|
||||
if (root.isChangingPassphrase) {
|
||||
currentPassphraseField.echoMode = checked ? TextInput.Normal : TextInput.Password;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Text below checkbox
|
||||
RalewayRegular {
|
||||
text: "Your passphrase is used to encrypt your private keys. <b>Please write it down.</b> If it is lost, you will not be able to recover it.";
|
||||
visible: !root.isShowingTip;
|
||||
text: "Your passphrase is used to encrypt your private keys. Only you have it.<br><br>Please write it down.<br><br><b>If it is lost, you will not be able to recover it.</b>";
|
||||
// Text size
|
||||
size: 16;
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: showPassphrase.bottom;
|
||||
anchors.topMargin: 16;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.leftMargin: 24;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
anchors.rightMargin: 24;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
color: hifi.colors.white;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
function validateAndSubmitPassphrase() {
|
||||
if (passphraseField.text.length < 3) {
|
||||
setErrorText("Passphrase too short.");
|
||||
setErrorText("Passphrase must be at least 3 characters.");
|
||||
passphraseField.error = true;
|
||||
passphraseFieldAgain.error = true;
|
||||
currentPassphraseField.error = true;
|
||||
return false;
|
||||
} else if (passphraseField.text !== passphraseFieldAgain.text) {
|
||||
setErrorText("Passphrases don't match.");
|
||||
passphraseField.error = true;
|
||||
passphraseFieldAgain.error = true;
|
||||
currentPassphraseField.error = true;
|
||||
return false;
|
||||
} else {
|
||||
passphraseField.error = false;
|
||||
passphraseFieldAgain.error = false;
|
||||
currentPassphraseField.error = false;
|
||||
setErrorText("");
|
||||
commerce.setPassphrase(passphraseField.text);
|
||||
return true;
|
||||
|
@ -270,6 +314,7 @@ Item {
|
|||
}
|
||||
|
||||
function clearPassphraseFields() {
|
||||
currentPassphraseField.text = "";
|
||||
passphraseField.text = "";
|
||||
passphraseFieldAgain.text = "";
|
||||
setErrorText("");
|
||||
|
|
|
@ -25,29 +25,16 @@ Item {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string keyFilePath: "";
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onSecurityImageResult: {
|
||||
if (exists) { // "If security image is set up"
|
||||
var path = "image://security/securityImage";
|
||||
topSecurityImage.source = "";
|
||||
topSecurityImage.source = path;
|
||||
changeSecurityImageImage.source = "";
|
||||
changeSecurityImageImage.source = path;
|
||||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
keyFilePath.text = path;
|
||||
keyFilePath = path;
|
||||
}
|
||||
}
|
||||
|
||||
SecurityImageModel {
|
||||
id: securityImageModel;
|
||||
}
|
||||
|
||||
// Username Text
|
||||
RalewayRegular {
|
||||
id: usernameText;
|
||||
|
@ -55,253 +42,258 @@ Item {
|
|||
// Text size
|
||||
size: 24;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
color: hifi.colors.white;
|
||||
elide: Text.ElideRight;
|
||||
// Anchors
|
||||
anchors.top: securityImageContainer.top;
|
||||
anchors.bottom: securityImageContainer.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: securityImageContainer.left;
|
||||
}
|
||||
|
||||
// Security Image
|
||||
Item {
|
||||
id: securityImageContainer;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
width: 75;
|
||||
height: childrenRect.height;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: topSecurityImage;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
height: parent.width - 10;
|
||||
width: height;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
source: "image://security/securityImage";
|
||||
cache: false;
|
||||
}
|
||||
Image {
|
||||
id: topSecurityImageMask;
|
||||
source: "images/lockOverlay.png";
|
||||
width: topSecurityImage.width * 0.45;
|
||||
height: topSecurityImage.height * 0.45;
|
||||
anchors.bottom: topSecurityImage.bottom;
|
||||
anchors.right: topSecurityImage.right;
|
||||
mipmap: true;
|
||||
opacity: 0.9;
|
||||
}
|
||||
// "Security image" text below pic
|
||||
RalewayRegular {
|
||||
text: "security image";
|
||||
// Text size
|
||||
size: 12;
|
||||
// Anchors
|
||||
anchors.top: topSecurityImage.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: securityImageContainer.left;
|
||||
anchors.right: securityImageContainer.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: parent.width/2;
|
||||
height: 80;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: securityContainer;
|
||||
anchors.top: securityImageContainer.bottom;
|
||||
anchors.top: usernameText.bottom;
|
||||
anchors.topMargin: 20;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: childrenRect.height;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
RalewayRegular {
|
||||
RalewaySemiBold {
|
||||
id: securityText;
|
||||
text: "Security";
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
anchors.right: parent.right;
|
||||
height: 30;
|
||||
// Text size
|
||||
size: 22;
|
||||
size: 18;
|
||||
// Style
|
||||
color: hifi.colors.blueHighlight;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: securityTextSeparator;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 1;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: securityText.bottom;
|
||||
anchors.topMargin: 8;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: changePassphraseContainer;
|
||||
anchors.top: securityText.bottom;
|
||||
anchors.topMargin: 16;
|
||||
anchors.top: securityTextSeparator.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 40;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 55;
|
||||
height: 75;
|
||||
|
||||
Image {
|
||||
HiFiGlyphs {
|
||||
id: changePassphraseImage;
|
||||
text: hifi.glyphs.passphrase;
|
||||
// Size
|
||||
size: 80;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
height: parent.height;
|
||||
width: height;
|
||||
source: "images/lockOverlay.png";
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
cache: false;
|
||||
visible: false;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
ColorOverlay {
|
||||
anchors.fill: changePassphraseImage;
|
||||
source: changePassphraseImage;
|
||||
color: "white"
|
||||
|
||||
RalewaySemiBold {
|
||||
text: "Passphrase";
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: changePassphraseImage.right;
|
||||
anchors.leftMargin: 30;
|
||||
width: 50;
|
||||
// Text size
|
||||
size: 18;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
|
||||
// "Change Passphrase" button
|
||||
HifiControlsUit.Button {
|
||||
id: changePassphraseButton;
|
||||
color: hifi.buttons.black;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.right: parent.right;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.left: changePassphraseImage.right;
|
||||
anchors.leftMargin: 16;
|
||||
width: 250;
|
||||
height: 50;
|
||||
text: "Change My Passphrase";
|
||||
width: 140;
|
||||
height: 40;
|
||||
text: "Change";
|
||||
onClicked: {
|
||||
sendSignalToWallet({method: 'walletSecurity_changePassphrase'});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: changeSecurityImageContainer;
|
||||
anchors.top: changePassphraseContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
Rectangle {
|
||||
id: changePassphraseSeparator;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 1;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: changePassphraseContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: changeSecurityImageContainer;
|
||||
anchors.top: changePassphraseSeparator.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 40;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 55;
|
||||
height: 75;
|
||||
|
||||
Image {
|
||||
HiFiGlyphs {
|
||||
id: changeSecurityImageImage;
|
||||
text: hifi.glyphs.securityImage;
|
||||
// Size
|
||||
size: 80;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
height: parent.height;
|
||||
width: height;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
cache: false;
|
||||
source: "image://security/securityImage";
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
// "Change Security Image" button
|
||||
|
||||
RalewaySemiBold {
|
||||
text: "Security Pic";
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: changeSecurityImageImage.right;
|
||||
anchors.leftMargin: 30;
|
||||
width: 50;
|
||||
// Text size
|
||||
size: 18;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
|
||||
// "Change Passphrase" button
|
||||
HifiControlsUit.Button {
|
||||
id: changeSecurityImageButton;
|
||||
color: hifi.buttons.black;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.right: parent.right;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.left: changeSecurityImageImage.right;
|
||||
anchors.leftMargin: 16;
|
||||
width: 250;
|
||||
height: 50;
|
||||
text: "Change My Security Image";
|
||||
width: 140;
|
||||
height: 40;
|
||||
text: "Change";
|
||||
onClicked: {
|
||||
sendSignalToWallet({method: 'walletSecurity_changeSecurityImage'});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: yourPrivateKeysContainer;
|
||||
anchors.top: securityContainer.bottom;
|
||||
anchors.topMargin: 20;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: childrenRect.height;
|
||||
|
||||
RalewaySemiBold {
|
||||
id: yourPrivateKeysText;
|
||||
text: "Your Private Keys";
|
||||
Rectangle {
|
||||
id: privateKeysSeparator;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 1;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 30;
|
||||
// Text size
|
||||
size: 22;
|
||||
anchors.top: changeSecurityImageContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
}
|
||||
|
||||
// Text below "your private keys"
|
||||
RalewayRegular {
|
||||
id: explanitoryText;
|
||||
text: "Your money and purchases are secured with private keys that only you " +
|
||||
"have access to. <b>If they are lost, you will not be able to access your money or purchases. " +
|
||||
"To safeguard your private keys, back up this file regularly:</b>";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: yourPrivateKeysText.bottom;
|
||||
anchors.topMargin: 10;
|
||||
Item {
|
||||
id: yourPrivateKeysContainer;
|
||||
anchors.top: privateKeysSeparator.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 40;
|
||||
anchors.right: parent.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
HifiControlsUit.TextField {
|
||||
id: keyFilePath;
|
||||
anchors.top: explanitoryText.bottom;
|
||||
anchors.topMargin: 10;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: clipboardButton.left;
|
||||
height: 40;
|
||||
readOnly: true;
|
||||
anchors.rightMargin: 55;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
}
|
||||
}
|
||||
}
|
||||
HifiControlsUit.Button {
|
||||
id: clipboardButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: keyFilePath.top;
|
||||
anchors.bottom: keyFilePath.bottom;
|
||||
width: height;
|
||||
HiFiGlyphs {
|
||||
text: hifi.glyphs.question;
|
||||
id: yourPrivateKeysImage;
|
||||
text: hifi.glyphs.walletKey;
|
||||
// Size
|
||||
size: parent.height*1.3;
|
||||
size: 80;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 20;
|
||||
anchors.left: parent.left;
|
||||
// Style
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
color: enabled ? hifi.colors.white : hifi.colors.faintGray;
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
Window.copyToClipboard(keyFilePath.text);
|
||||
RalewaySemiBold {
|
||||
id: yourPrivateKeysText;
|
||||
text: "Private Keys";
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 32;
|
||||
anchors.left: yourPrivateKeysImage.right;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.right: parent.right;
|
||||
height: 30;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
|
||||
// Text below "private keys"
|
||||
RalewayRegular {
|
||||
id: explanitoryText;
|
||||
text: "Your money and purchases are secured with private keys that only you have access to.";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: yourPrivateKeysText.bottom;
|
||||
anchors.topMargin: 10;
|
||||
anchors.left: yourPrivateKeysText.left;
|
||||
anchors.right: yourPrivateKeysText.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
HifiControlsUit.Button {
|
||||
id: backupInstructionsButton;
|
||||
text: "View Backup Instructions";
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.left: explanitoryText.left;
|
||||
anchors.right: explanitoryText.right;
|
||||
anchors.top: explanitoryText.bottom;
|
||||
anchors.topMargin: 16;
|
||||
height: 40;
|
||||
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://www.highfidelity.com/");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//
|
||||
// SecurityImageSelectionLightbox.qml
|
||||
// SecurityImageChange.qml
|
||||
// qml/hifi/commerce/wallet
|
||||
//
|
||||
// SecurityImageSelectionLightbox
|
||||
// SecurityImageChange
|
||||
//
|
||||
// Created by Zach Fox on 2017-08-18
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
|
@ -20,22 +20,26 @@ import "../../../controls" as HifiControls
|
|||
|
||||
// references XXX from root context
|
||||
|
||||
Rectangle {
|
||||
Item {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property bool justSubmitted: false;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
|
||||
SecurityImageModel {
|
||||
id: securityImageModel;
|
||||
}
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
|
||||
onSecurityImageResult: {
|
||||
securityImageChangePageSecurityImage.source = "";
|
||||
securityImageChangePageSecurityImage.source = "image://security/securityImage";
|
||||
if (exists) { // Success submitting new security image
|
||||
if (root.justSubmitted) {
|
||||
root.resetSubmitButton();
|
||||
root.visible = false;
|
||||
sendSignalToWallet({method: "walletSecurity_changeSecurityImageSuccess"});
|
||||
root.justSubmitted = false;
|
||||
}
|
||||
} else if (root.justSubmitted) {
|
||||
|
@ -45,71 +49,104 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Security Image
|
||||
Item {
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 25;
|
||||
width: 130;
|
||||
height: 150;
|
||||
Image {
|
||||
id: securityImageChangePageSecurityImage;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: iconAndTextContainer.top;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
source: "image://security/securityImage";
|
||||
cache: false;
|
||||
onVisibleChanged: {
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
Item {
|
||||
id: iconAndTextContainer;
|
||||
anchors.left: securityImageChangePageSecurityImage.left;
|
||||
anchors.right: securityImageChangePageSecurityImage.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
height: 22;
|
||||
// Lock icon
|
||||
HiFiGlyphs {
|
||||
id: lockIcon;
|
||||
text: hifi.glyphs.lock;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 10;
|
||||
size: 20;
|
||||
width: height;
|
||||
verticalAlignment: Text.AlignBottom;
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
// "Security image" text below pic
|
||||
RalewayRegular {
|
||||
id: securityImageText;
|
||||
text: "SECURITY PIC";
|
||||
// Text size
|
||||
size: 12;
|
||||
// Anchors
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: lockIcon.anchors.leftMargin;
|
||||
width: paintedWidth;
|
||||
height: 22;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignRight;
|
||||
verticalAlignment: Text.AlignBottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SECURITY IMAGE SELECTION START
|
||||
//
|
||||
Item {
|
||||
id: securityImageContainer;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 135;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
Item {
|
||||
id: securityImageTitle;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
||||
// Title Bar text
|
||||
RalewaySemiBold {
|
||||
text: "CHANGE SECURITY IMAGE";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
// Text below title bar
|
||||
// "Change Security Image" text
|
||||
RalewaySemiBold {
|
||||
id: securityImageTitleHelper;
|
||||
text: "Choose a Security Picture:";
|
||||
id: securityImageTitle;
|
||||
text: "Change Security Pic:";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: securityImageTitle.bottom;
|
||||
size: 18;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
height: 50;
|
||||
width: paintedWidth;
|
||||
anchors.leftMargin: 20;
|
||||
anchors.right: parent.right;
|
||||
height: 30;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
color: hifi.colors.blueHighlight;
|
||||
}
|
||||
|
||||
SecurityImageSelection {
|
||||
id: securityImageSelection;
|
||||
// Anchors
|
||||
anchors.top: securityImageTitleHelper.bottom;
|
||||
anchors.top: securityImageTitle.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 280;
|
||||
height: 300;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
|
@ -118,66 +155,43 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
// Text below security images
|
||||
RalewayRegular {
|
||||
text: "<b>Your security picture shows you that the service asking for your passphrase is authorized.</b> You can change your secure picture at any time.";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: securityImageSelection.bottom;
|
||||
anchors.topMargin: 40;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// Navigation Bar
|
||||
Item {
|
||||
id: securityImageNavBar;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 100;
|
||||
height: 40;
|
||||
// Anchors:
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 30;
|
||||
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.black;
|
||||
color: hifi.buttons.noneBorderlessWhite;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: 100;
|
||||
width: 150;
|
||||
text: "Cancel"
|
||||
onClicked: {
|
||||
root.visible = false;
|
||||
sendSignalToWallet({method: "walletSecurity_changeSecurityImageCancelled"});
|
||||
}
|
||||
}
|
||||
|
||||
// "Submit" button
|
||||
HifiControlsUit.Button {
|
||||
id: securityImageSubmitButton;
|
||||
color: hifi.buttons.black;
|
||||
enabled: securityImageSelection.currentIndex !== -1;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: 100;
|
||||
width: 150;
|
||||
text: "Submit";
|
||||
onClicked: {
|
||||
root.justSubmitted = true;
|
|
@ -24,6 +24,7 @@ Item {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property int currentIndex: securityImageGrid.currentIndex;
|
||||
|
||||
// This will cause a bug -- if you bring up security image selection in HUD mode while
|
||||
// in HMD while having HMD preview enabled, then move, then finish passphrase selection,
|
||||
|
@ -43,6 +44,7 @@ Item {
|
|||
|
||||
GridView {
|
||||
id: securityImageGrid;
|
||||
interactive: false;
|
||||
clip: true;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
|
@ -56,8 +58,8 @@ Item {
|
|||
Item {
|
||||
anchors.fill: parent;
|
||||
Image {
|
||||
width: parent.width - 8;
|
||||
height: parent.height - 8;
|
||||
width: parent.width - 12;
|
||||
height: parent.height - 12;
|
||||
source: sourcePath;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
|
|
|
@ -13,10 +13,12 @@
|
|||
|
||||
import Hifi 1.0 as Hifi
|
||||
import QtQuick 2.5
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 1.4
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
import "../common" as HifiCommerceCommon
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
|
@ -28,18 +30,14 @@ Rectangle {
|
|||
property string activeView: "initialize";
|
||||
property bool keyboardRaised: false;
|
||||
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
Image {
|
||||
anchors.fill: parent;
|
||||
source: "images/wallet-bg.jpg";
|
||||
}
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onAccountResult: {
|
||||
if (result.status === "success") {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
} else {
|
||||
// unsure how to handle a failure here. We definitely cannot proceed.
|
||||
}
|
||||
}
|
||||
onLoginStatusResult: {
|
||||
if (!isLoggedIn && root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
|
@ -49,25 +47,35 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
onAccountResult: {
|
||||
if (result.status === "success") {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
} else {
|
||||
// unsure how to handle a failure here. We definitely cannot proceed.
|
||||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
if (path === "" && root.activeView !== "notSetUp") {
|
||||
root.activeView = "notSetUp";
|
||||
if (path === "" && root.activeView !== "walletSetup") {
|
||||
root.activeView = "walletSetup";
|
||||
} else if (path !== "" && root.activeView === "initialize") {
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
|
||||
onSecurityImageResult: {
|
||||
if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up"
|
||||
root.activeView = "notSetUp";
|
||||
if (!exists && root.activeView !== "walletSetup") { // "If security image is not set up"
|
||||
root.activeView = "walletSetup";
|
||||
} else if (exists && root.activeView === "initialize") {
|
||||
commerce.getWalletAuthenticatedStatus();
|
||||
titleBarSecurityImage.source = "";
|
||||
titleBarSecurityImage.source = "image://security/securityImage";
|
||||
}
|
||||
}
|
||||
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
if (!isAuthenticated && passphraseModal && !passphraseModal.visible) {
|
||||
passphraseModal.visible = true;
|
||||
if (!isAuthenticated && passphraseModal && root.activeView !== "passphraseModal") {
|
||||
root.activeView = "passphraseModal";
|
||||
} else if (isAuthenticated) {
|
||||
root.activeView = "walletHome";
|
||||
}
|
||||
|
@ -78,74 +86,11 @@ Rectangle {
|
|||
id: securityImageModel;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: walletSetupLightboxContainer;
|
||||
visible: walletSetupLightbox.visible || passphraseSelectionLightbox.visible || securityImageSelectionLightbox.visible;
|
||||
z: 998;
|
||||
HifiCommerceCommon.CommerceLightbox {
|
||||
id: lightboxPopup;
|
||||
visible: false;
|
||||
anchors.fill: parent;
|
||||
color: "black";
|
||||
opacity: 0.5;
|
||||
}
|
||||
WalletSetupLightbox {
|
||||
id: walletSetupLightbox;
|
||||
visible: false;
|
||||
z: 998;
|
||||
anchors.centerIn: walletSetupLightboxContainer;
|
||||
width: walletSetupLightboxContainer.width - 50;
|
||||
height: walletSetupLightboxContainer.height - 50;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletSetup_cancelClicked') {
|
||||
walletSetupLightbox.visible = false;
|
||||
} else if (msg.method === 'walletSetup_finished') {
|
||||
root.activeView = "initialize";
|
||||
commerce.getLoginStatus();
|
||||
} else if (msg.method === 'walletSetup_raiseKeyboard') {
|
||||
root.keyboardRaised = true;
|
||||
} else if (msg.method === 'walletSetup_lowerKeyboard') {
|
||||
root.keyboardRaised = false;
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PassphraseSelectionLightbox {
|
||||
id: passphraseSelectionLightbox;
|
||||
visible: false;
|
||||
z: 998;
|
||||
anchors.centerIn: walletSetupLightboxContainer;
|
||||
width: walletSetupLightboxContainer.width - 50;
|
||||
height: walletSetupLightboxContainer.height - 50;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletSetup_raiseKeyboard') {
|
||||
root.keyboardRaised = true;
|
||||
} else if (msg.method === 'walletSetup_lowerKeyboard') {
|
||||
root.keyboardRaised = false;
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SecurityImageSelectionLightbox {
|
||||
id: securityImageSelectionLightbox;
|
||||
visible: false;
|
||||
z: 998;
|
||||
anchors.centerIn: walletSetupLightboxContainer;
|
||||
width: walletSetupLightboxContainer.width - 50;
|
||||
height: walletSetupLightboxContainer.height - 50;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// TITLE BAR START
|
||||
|
@ -160,6 +105,20 @@ Rectangle {
|
|||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
||||
// Wallet icon
|
||||
HiFiGlyphs {
|
||||
id: walletIcon;
|
||||
text: hifi.glyphs.wallet;
|
||||
// Size
|
||||
size: parent.height * 0.8;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
// Style
|
||||
color: hifi.colors.blueHighlight;
|
||||
}
|
||||
|
||||
// Title Bar text
|
||||
RalewaySemiBold {
|
||||
id: titleBarText;
|
||||
|
@ -168,28 +127,119 @@ Rectangle {
|
|||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.left: walletIcon.right;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
color: hifi.colors.white;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// Separator
|
||||
HifiControlsUit.Separator {
|
||||
anchors.left: parent.left;
|
||||
Image {
|
||||
id: titleBarSecurityImage;
|
||||
source: "";
|
||||
visible: titleBarSecurityImage.source !== "" && !securityImageChange.visible;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 6;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 6;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 6;
|
||||
width: height;
|
||||
mipmap: true;
|
||||
|
||||
MouseArea {
|
||||
enabled: titleBarSecurityImage.visible;
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
lightboxPopup.titleText = "Your Security Pic";
|
||||
lightboxPopup.bodyImageSource = titleBarSecurityImage.source;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// TITLE BAR END
|
||||
//
|
||||
|
||||
WalletSetup {
|
||||
id: walletSetup;
|
||||
visible: root.activeView === "walletSetup";
|
||||
z: 998;
|
||||
anchors.fill: parent;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletSetup_finished') {
|
||||
if (msg.referrer === '') {
|
||||
root.activeView = "initialize";
|
||||
commerce.getLoginStatus();
|
||||
} else if (msg.referrer === 'purchases') {
|
||||
sendToScript({method: 'goToPurchases'});
|
||||
}
|
||||
} else if (msg.method === 'walletSetup_raiseKeyboard') {
|
||||
root.keyboardRaised = true;
|
||||
} else if (msg.method === 'walletSetup_lowerKeyboard') {
|
||||
root.keyboardRaised = false;
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PassphraseChange {
|
||||
id: passphraseChange;
|
||||
visible: root.activeView === "passphraseChange";
|
||||
z: 998;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletSetup_raiseKeyboard') {
|
||||
root.keyboardRaised = true;
|
||||
} else if (msg.method === 'walletSetup_lowerKeyboard') {
|
||||
root.keyboardRaised = false;
|
||||
} else if (msg.method === 'walletSecurity_changePassphraseCancelled') {
|
||||
root.activeView = "security";
|
||||
} else if (msg.method === 'walletSecurity_changePassphraseSuccess') {
|
||||
root.activeView = "security";
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SecurityImageChange {
|
||||
id: securityImageChange;
|
||||
visible: root.activeView === "securityImageChange";
|
||||
z: 998;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletSecurity_changeSecurityImageCancelled') {
|
||||
root.activeView = "security";
|
||||
} else if (msg.method === 'walletSecurity_changeSecurityImageSuccess') {
|
||||
root.activeView = "security";
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TAB CONTENTS START
|
||||
//
|
||||
|
@ -231,31 +281,17 @@ Rectangle {
|
|||
|
||||
PassphraseModal {
|
||||
id: passphraseModal;
|
||||
visible: false;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
visible: root.activeView === "passphraseModal";
|
||||
anchors.fill: parent;
|
||||
titleBarText: "Wallet";
|
||||
titleBarIcon: hifi.glyphs.wallet;
|
||||
|
||||
Connections {
|
||||
onSendSignalToParent: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NotSetUp {
|
||||
id: notSetUp;
|
||||
visible: root.activeView === "notSetUp";
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.bottom: tabButtonsContainer.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'setUpClicked') {
|
||||
walletSetupLightbox.visible = true;
|
||||
if (msg.method === "authSuccess") {
|
||||
root.activeView = "walletHome";
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -265,47 +301,42 @@ Rectangle {
|
|||
id: walletHome;
|
||||
visible: root.activeView === "walletHome";
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: 16;
|
||||
anchors.bottom: tabButtonsContainer.top;
|
||||
anchors.bottomMargin: 16;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendMoney {
|
||||
id: sendMoney;
|
||||
visible: root.activeView === "sendMoney";
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: 16;
|
||||
anchors.bottom: tabButtonsContainer.top;
|
||||
anchors.bottomMargin: 16;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
}
|
||||
|
||||
Security {
|
||||
id: security;
|
||||
visible: root.activeView === "security";
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: 16;
|
||||
anchors.bottom: tabButtonsContainer.top;
|
||||
anchors.bottomMargin: 16;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
if (msg.method === 'walletSecurity_changePassphrase') {
|
||||
passphraseSelectionLightbox.visible = true;
|
||||
passphraseSelectionLightbox.clearPassphraseFields();
|
||||
root.activeView = "passphraseChange";
|
||||
passphraseChange.clearPassphraseFields();
|
||||
passphraseChange.resetSubmitButton();
|
||||
} else if (msg.method === 'walletSecurity_changeSecurityImage') {
|
||||
securityImageSelectionLightbox.visible = true;
|
||||
root.activeView = "securityImageChange";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -315,13 +346,9 @@ Rectangle {
|
|||
id: help;
|
||||
visible: root.activeView === "help";
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: 16;
|
||||
anchors.bottom: tabButtonsContainer.top;
|
||||
anchors.bottomMargin: 16;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
|
@ -342,11 +369,11 @@ Rectangle {
|
|||
//
|
||||
Item {
|
||||
id: tabButtonsContainer;
|
||||
visible: !needsLogIn.visible;
|
||||
visible: !needsLogIn.visible && root.activeView !== "passphraseChange" && root.activeView !== "securityImageChange";
|
||||
property int numTabs: 5;
|
||||
// Size
|
||||
width: root.width;
|
||||
height: 80;
|
||||
height: 90;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
@ -361,30 +388,46 @@ Rectangle {
|
|||
// "WALLET HOME" tab button
|
||||
Rectangle {
|
||||
id: walletHomeButtonContainer;
|
||||
visible: !notSetUp.visible;
|
||||
visible: !walletSetup.visible;
|
||||
color: root.activeView === "walletHome" ? hifi.colors.blueAccent : hifi.colors.black;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width / tabButtonsContainer.numTabs;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: homeTabIcon;
|
||||
text: hifi.glyphs.home2;
|
||||
// Size
|
||||
size: 50;
|
||||
// Anchors
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: -2;
|
||||
// Style
|
||||
color: root.activeView === "walletHome" || walletHomeTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
text: "WALLET HOME";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
anchors.bottom: parent.bottom;
|
||||
height: parent.height/2;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 4;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
color: root.activeView === "walletHome" || walletHomeTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
MouseArea {
|
||||
enabled: !walletSetupLightboxContainer.visible;
|
||||
id: walletHomeTabMouseArea;
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
|
@ -396,87 +439,136 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
// "SEND MONEY" tab button
|
||||
// "EXCHANGE MONEY" tab button
|
||||
Rectangle {
|
||||
id: sendMoneyButtonContainer;
|
||||
visible: !notSetUp.visible;
|
||||
id: exchangeMoneyButtonContainer;
|
||||
visible: !walletSetup.visible;
|
||||
color: hifi.colors.black;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: walletHomeButtonContainer.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width / tabButtonsContainer.numTabs;
|
||||
|
||||
RalewaySemiBold {
|
||||
text: "SEND MONEY";
|
||||
// Text size
|
||||
size: 14;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: exchangeMoneyTabIcon;
|
||||
text: hifi.glyphs.leftRightArrows;
|
||||
// Size
|
||||
size: 50;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.rightMargin: 4;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: -2;
|
||||
// Style
|
||||
color: hifi.colors.lightGray50;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
// "EXCHANGE MONEY" tab button
|
||||
Rectangle {
|
||||
id: exchangeMoneyButtonContainer;
|
||||
visible: !notSetUp.visible;
|
||||
color: hifi.colors.black;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: sendMoneyButtonContainer.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width / tabButtonsContainer.numTabs;
|
||||
|
||||
RalewaySemiBold {
|
||||
text: "EXCHANGE MONEY";
|
||||
// Text size
|
||||
size: 14;
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
anchors.bottom: parent.bottom;
|
||||
height: parent.height/2;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 4;
|
||||
// Style
|
||||
color: hifi.colors.lightGray50;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// "SEND MONEY" tab button
|
||||
Rectangle {
|
||||
id: sendMoneyButtonContainer;
|
||||
visible: !walletSetup.visible;
|
||||
color: hifi.colors.black;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: exchangeMoneyButtonContainer.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width / tabButtonsContainer.numTabs;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: sendMoneyTabIcon;
|
||||
text: hifi.glyphs.paperPlane;
|
||||
// Size
|
||||
size: 46;
|
||||
// Anchors
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: -2;
|
||||
// Style
|
||||
color: hifi.colors.lightGray50;
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
text: "SEND MONEY";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.bottom: parent.bottom;
|
||||
height: parent.height/2;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 4;
|
||||
// Style
|
||||
color: hifi.colors.lightGray50;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
}
|
||||
|
||||
// "SECURITY" tab button
|
||||
Rectangle {
|
||||
id: securityButtonContainer;
|
||||
visible: !notSetUp.visible;
|
||||
visible: !walletSetup.visible;
|
||||
color: root.activeView === "security" ? hifi.colors.blueAccent : hifi.colors.black;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: exchangeMoneyButtonContainer.right;
|
||||
anchors.left: sendMoneyButtonContainer.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width / tabButtonsContainer.numTabs;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: securityTabIcon;
|
||||
text: hifi.glyphs.lock;
|
||||
// Size
|
||||
size: 38;
|
||||
// Anchors
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 2;
|
||||
// Style
|
||||
color: root.activeView === "security" || securityTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
text: "SECURITY";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
anchors.bottom: parent.bottom;
|
||||
height: parent.height/2;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 4;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
color: root.activeView === "security" || securityTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
MouseArea {
|
||||
enabled: !walletSetupLightboxContainer.visible;
|
||||
id: securityTabMouseArea;
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
|
@ -487,34 +579,50 @@ Rectangle {
|
|||
onExited: parent.color = root.activeView === "security" ? hifi.colors.blueAccent : hifi.colors.black;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// "HELP" tab button
|
||||
Rectangle {
|
||||
id: helpButtonContainer;
|
||||
visible: !notSetUp.visible;
|
||||
visible: !walletSetup.visible;
|
||||
color: root.activeView === "help" ? hifi.colors.blueAccent : hifi.colors.black;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: securityButtonContainer.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width / tabButtonsContainer.numTabs;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: helpTabIcon;
|
||||
text: hifi.glyphs.question;
|
||||
// Size
|
||||
size: 55;
|
||||
// Anchors
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: -6;
|
||||
// Style
|
||||
color: root.activeView === "help" || helpTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
text: "HELP";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
anchors.bottom: parent.bottom;
|
||||
height: parent.height/2;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 4;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
color: root.activeView === "help" || helpTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
MouseArea {
|
||||
enabled: !walletSetupLightboxContainer.visible;
|
||||
id: helpTabMouseArea;
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
|
@ -526,6 +634,7 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
function resetTabButtonColors() {
|
||||
walletHomeButtonContainer.color = hifi.colors.black;
|
||||
sendMoneyButtonContainer.color = hifi.colors.black;
|
||||
|
@ -604,6 +713,9 @@ Rectangle {
|
|||
//
|
||||
function fromScript(message) {
|
||||
switch (message.method) {
|
||||
case 'updateWalletReferrer':
|
||||
walletSetup.referrer = message.referrer;
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from wallet.js:', JSON.stringify(message));
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
|
||||
import Hifi 1.0 as Hifi
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 2.2
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
|
@ -29,14 +30,6 @@ Item {
|
|||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onSecurityImageResult: {
|
||||
if (exists) {
|
||||
// just set the source again (to be sure the change was noticed)
|
||||
securityImage.source = "";
|
||||
securityImage.source = "image://security/securityImage";
|
||||
}
|
||||
}
|
||||
|
||||
onBalanceResult : {
|
||||
balanceText.text = result.data.balance;
|
||||
}
|
||||
|
@ -50,10 +43,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
SecurityImageModel {
|
||||
id: securityImageModel;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: GlobalServices
|
||||
onMyUsernameChanged: {
|
||||
|
@ -68,213 +57,195 @@ Item {
|
|||
// Text size
|
||||
size: 24;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
color: hifi.colors.white;
|
||||
elide: Text.ElideRight;
|
||||
// Anchors
|
||||
anchors.top: securityImageContainer.top;
|
||||
anchors.bottom: securityImageContainer.bottom;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: hfcBalanceContainer.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: parent.width/2;
|
||||
height: 80;
|
||||
}
|
||||
|
||||
// HFC Balance Container
|
||||
Item {
|
||||
id: hfcBalanceContainer;
|
||||
// Anchors
|
||||
anchors.top: securityImageContainer.top;
|
||||
anchors.right: securityImageContainer.left;
|
||||
anchors.rightMargin: 16;
|
||||
width: 175;
|
||||
height: 60;
|
||||
Rectangle {
|
||||
id: hfcBalanceField;
|
||||
color: hifi.colors.darkGray;
|
||||
anchors.right: parent.right;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
height: parent.height - 15;
|
||||
|
||||
// "HFC" balance label
|
||||
FiraSansRegular {
|
||||
id: balanceLabel;
|
||||
text: "HFC";
|
||||
// Text size
|
||||
size: 20;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: hfcBalanceField.right;
|
||||
anchors.rightMargin: 4;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.lightGrayText;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignRight;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
historyReceived = false;
|
||||
commerce.balance();
|
||||
commerce.history();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Balance Text
|
||||
FiraSansSemiBold {
|
||||
id: balanceText;
|
||||
text: "--";
|
||||
// Text size
|
||||
size: 28;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: balanceLabel.left;
|
||||
anchors.rightMargin: 4;
|
||||
// Style
|
||||
color: hifi.colors.lightGrayText;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignRight;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
// "balance" text above field
|
||||
RalewayRegular {
|
||||
text: "balance";
|
||||
// Text size
|
||||
size: 12;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: hfcBalanceField.top;
|
||||
anchors.bottomMargin: 4;
|
||||
anchors.left: hfcBalanceField.left;
|
||||
anchors.right: hfcBalanceField.right;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
// Security Image
|
||||
Item {
|
||||
id: securityImageContainer;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
width: 75;
|
||||
height: childrenRect.height;
|
||||
anchors.leftMargin: 20;
|
||||
width: parent.width/2;
|
||||
height: 80;
|
||||
|
||||
// "HFC" balance label
|
||||
HiFiGlyphs {
|
||||
id: balanceLabel;
|
||||
text: hifi.glyphs.hfc;
|
||||
// Size
|
||||
size: 40;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getSecurityImage();
|
||||
// Balance Text
|
||||
FiraSansRegular {
|
||||
id: balanceText;
|
||||
text: "--";
|
||||
// Text size
|
||||
size: 28;
|
||||
// Anchors
|
||||
anchors.top: balanceLabel.top;
|
||||
anchors.bottom: balanceLabel.bottom;
|
||||
anchors.left: balanceLabel.right;
|
||||
anchors.leftMargin: 10;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 4;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
// Alignment
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
historyReceived = false;
|
||||
commerce.balance();
|
||||
commerce.history();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: securityImage;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
height: parent.width - 10;
|
||||
width: height;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
cache: false;
|
||||
source: "image://security/securityImage";
|
||||
}
|
||||
Image {
|
||||
id: securityImageOverlay;
|
||||
source: "images/lockOverlay.png";
|
||||
width: securityImage.width * 0.45;
|
||||
height: securityImage.height * 0.45;
|
||||
anchors.bottom: securityImage.bottom;
|
||||
anchors.right: securityImage.right;
|
||||
mipmap: true;
|
||||
opacity: 0.9;
|
||||
}
|
||||
// "Security image" text below pic
|
||||
// "balance" text below field
|
||||
RalewayRegular {
|
||||
text: "security image";
|
||||
text: "BALANCE (HFC)";
|
||||
// Text size
|
||||
size: 12;
|
||||
size: 14;
|
||||
// Anchors
|
||||
anchors.top: securityImage.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: securityImageContainer.left;
|
||||
anchors.right: securityImageContainer.right;
|
||||
anchors.top: balanceLabel.top;
|
||||
anchors.topMargin: balanceText.paintedHeight + 20;
|
||||
anchors.bottom: balanceLabel.bottom;
|
||||
anchors.left: balanceText.left;
|
||||
anchors.right: balanceText.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
}
|
||||
|
||||
// Recent Activity
|
||||
Item {
|
||||
Rectangle {
|
||||
id: recentActivityContainer;
|
||||
anchors.top: securityImageContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
height: 440;
|
||||
|
||||
|
||||
LinearGradient {
|
||||
anchors.fill: parent;
|
||||
start: Qt.point(0, 0);
|
||||
end: Qt.point(0, height);
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: hifi.colors.white }
|
||||
GradientStop { position: 1.0; color: hifi.colors.faintGray }
|
||||
}
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
RalewaySemiBold {
|
||||
id: recentActivityText;
|
||||
text: "Recent Activity";
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 26;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: 30;
|
||||
// Text size
|
||||
size: 22;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
color: hifi.colors.baseGrayHighlight;
|
||||
}
|
||||
ListModel {
|
||||
id: transactionHistoryModel;
|
||||
}
|
||||
Rectangle {
|
||||
Item {
|
||||
anchors.top: recentActivityText.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.topMargin: 26;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
color: "white";
|
||||
|
||||
anchors.rightMargin: 24;
|
||||
|
||||
ListView {
|
||||
id: transactionHistory;
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
policy: transactionHistory.contentHeight > parent.parent.height ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded;
|
||||
parent: transactionHistory.parent;
|
||||
anchors.top: transactionHistory.top;
|
||||
anchors.left: transactionHistory.right;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.bottom: transactionHistory.bottom;
|
||||
width: 20;
|
||||
}
|
||||
anchors.centerIn: parent;
|
||||
width: parent.width - 12;
|
||||
height: parent.height - 12;
|
||||
height: parent.height;
|
||||
visible: transactionHistoryModel.count !== 0;
|
||||
clip: true;
|
||||
model: transactionHistoryModel;
|
||||
delegate: Item {
|
||||
width: parent.width;
|
||||
height: transactionText.height + 30;
|
||||
FiraSansRegular {
|
||||
id: transactionText;
|
||||
text: model.text;
|
||||
|
||||
HifiControlsUit.Separator {
|
||||
visible: index === 0;
|
||||
colorScheme: 1;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: parent.top;
|
||||
}
|
||||
|
||||
AnonymousProRegular {
|
||||
id: dateText;
|
||||
text: getFormattedDate(model.created_at * 1000);
|
||||
// Style
|
||||
size: 18;
|
||||
width: parent.width;
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 15;
|
||||
width: 118;
|
||||
height: paintedHeight;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
color: "black";
|
||||
color: hifi.colors.blueAccent;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
horizontalAlignment: Text.AlignRight;
|
||||
}
|
||||
|
||||
AnonymousProRegular {
|
||||
id: transactionText;
|
||||
text: model.text;
|
||||
size: 18;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 15;
|
||||
anchors.left: dateText.right;
|
||||
anchors.leftMargin: 20;
|
||||
anchors.right: parent.right;
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.baseGrayHighlight;
|
||||
wrapMode: Text.WordWrap;
|
||||
|
||||
onLinkActivated: {
|
||||
sendSignalToWallet({method: 'transactionHistory_linkClicked', marketplaceLink: link});
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Separator {
|
||||
colorScheme: 1;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
@ -304,6 +275,30 @@ Item {
|
|||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
|
||||
function getFormattedDate(timestamp) {
|
||||
var a = new Date(timestamp);
|
||||
var year = a.getFullYear();
|
||||
var month = a.getMonth();
|
||||
var day = a.getDate();
|
||||
var hour = a.getHours();
|
||||
var drawnHour = hour;
|
||||
if (hour === 0) {
|
||||
drawnHour = 12;
|
||||
} else if (hour > 12) {
|
||||
drawnHour -= 12;
|
||||
}
|
||||
|
||||
var amOrPm = "AM";
|
||||
if (hour >= 12) {
|
||||
amOrPm = "PM";
|
||||
}
|
||||
|
||||
var min = a.getMinutes();
|
||||
var sec = a.getSeconds();
|
||||
return year + '-' + month + '-' + day + '<br>' + drawnHour + ':' + min + amOrPm;
|
||||
}
|
||||
|
||||
//
|
||||
// Function Name: fromScript()
|
||||
//
|
||||
|
|
746
interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml
Normal file
|
@ -0,0 +1,746 @@
|
|||
//
|
||||
// modalContainer.qml
|
||||
// qml/hifi/commerce/wallet
|
||||
//
|
||||
// modalContainer
|
||||
//
|
||||
// Created by Zach Fox on 2017-08-17
|
||||
// Copyright 2017 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 QtQuick.Controls 1.4
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
import "../common" as HifiCommerceCommon
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
Item {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string activeView: "step_1";
|
||||
property string lastPage;
|
||||
property bool hasShownSecurityImageTip: false;
|
||||
property string referrer;
|
||||
|
||||
Image {
|
||||
anchors.fill: parent;
|
||||
source: "images/wallet-bg.jpg";
|
||||
}
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onSecurityImageResult: {
|
||||
if (!exists && root.lastPage === "step_2") {
|
||||
// ERROR! Invalid security image.
|
||||
root.activeView = "step_2";
|
||||
} else {
|
||||
titleBarSecurityImage.source = "";
|
||||
titleBarSecurityImage.source = "image://security/securityImage";
|
||||
}
|
||||
}
|
||||
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
if (isAuthenticated) {
|
||||
root.activeView = "step_4";
|
||||
} else {
|
||||
root.activeView = "step_3";
|
||||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
keyFilePath.text = path;
|
||||
}
|
||||
}
|
||||
|
||||
HifiCommerceCommon.CommerceLightbox {
|
||||
id: lightboxPopup;
|
||||
visible: false;
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
//
|
||||
// TITLE BAR START
|
||||
//
|
||||
Item {
|
||||
id: titleBarContainer;
|
||||
// Size
|
||||
height: 50;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
|
||||
// Wallet icon
|
||||
HiFiGlyphs {
|
||||
id: walletIcon;
|
||||
text: hifi.glyphs.wallet;
|
||||
// Size
|
||||
size: parent.height * 0.8;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
// Style
|
||||
color: hifi.colors.blueHighlight;
|
||||
}
|
||||
|
||||
// Title Bar text
|
||||
RalewayRegular {
|
||||
id: titleBarText;
|
||||
text: "Wallet Setup" + (securityImageTip.visible ? "" : " - Step " + root.activeView.split("_")[1] + " of 4");
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: walletIcon.right;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
Image {
|
||||
id: titleBarSecurityImage;
|
||||
source: "";
|
||||
visible: !securityImageTip.visible && titleBarSecurityImage.source !== "";
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 6;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 6;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 6;
|
||||
width: height;
|
||||
mipmap: true;
|
||||
|
||||
MouseArea {
|
||||
enabled: titleBarSecurityImage.visible;
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
lightboxPopup.titleText = "Your Security Pic";
|
||||
lightboxPopup.bodyImageSource = titleBarSecurityImage.source;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// TITLE BAR END
|
||||
//
|
||||
|
||||
//
|
||||
// FIRST PAGE START
|
||||
//
|
||||
Item {
|
||||
id: firstPageContainer;
|
||||
visible: root.activeView === "step_1";
|
||||
// Anchors
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: bigWalletIcon;
|
||||
text: hifi.glyphs.wallet;
|
||||
// Size
|
||||
size: 180;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 40;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: firstPage_text01;
|
||||
text: "Let's set up your wallet!";
|
||||
// Text size
|
||||
size: 26;
|
||||
// Anchors
|
||||
anchors.top: bigWalletIcon.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: paintedHeight;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: firstPage_text02;
|
||||
text: "Set up your wallet to claim your <b>free High Fidelity Coin (HFC)</b> and get items from the Marketplace.<br><br>" +
|
||||
"<b>No credit card is required.</b>";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: firstPage_text01.bottom;
|
||||
anchors.topMargin: 40;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 65;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 65;
|
||||
height: paintedHeight;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// "Set Up" button
|
||||
HifiControlsUit.Button {
|
||||
id: firstPage_setUpButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: firstPage_text02.bottom;
|
||||
anchors.topMargin: 40;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
width: parent.width/2;
|
||||
height: 50;
|
||||
text: "Set Up Wallet";
|
||||
onClicked: {
|
||||
root.activeView = "step_2";
|
||||
}
|
||||
}
|
||||
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.none;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: firstPage_setUpButton.bottom;
|
||||
anchors.topMargin: 20;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
width: parent.width/2;
|
||||
height: 50;
|
||||
text: "Cancel";
|
||||
onClicked: {
|
||||
sendSignalToWallet({method: 'walletSetup_cancelClicked'});
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// FIRST PAGE END
|
||||
//
|
||||
|
||||
//
|
||||
// SECURITY IMAGE SELECTION START
|
||||
//
|
||||
Item {
|
||||
id: securityImageContainer;
|
||||
visible: root.activeView === "step_2";
|
||||
// Anchors
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: 30;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
|
||||
// Text below title bar
|
||||
RalewayRegular {
|
||||
id: securityImageTitleHelper;
|
||||
text: "Choose a Security Pic:";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
height: 50;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
SecurityImageSelection {
|
||||
id: securityImageSelection;
|
||||
// Anchors
|
||||
anchors.top: securityImageTitleHelper.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 300;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
sendSignalToWallet(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Text below security images
|
||||
RalewayRegular {
|
||||
text: "<b>Your security picture shows you that the service asking for your passphrase is authorized.</b> You can change your secure picture at any time.";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: securityImageSelection.bottom;
|
||||
anchors.topMargin: 40;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// Navigation Bar
|
||||
Item {
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
// Anchors:
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 50;
|
||||
|
||||
// "Back" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.noneBorderlessWhite;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: 200;
|
||||
text: "Back"
|
||||
onClicked: {
|
||||
root.activeView = "step_1";
|
||||
}
|
||||
}
|
||||
|
||||
// "Next" button
|
||||
HifiControlsUit.Button {
|
||||
enabled: securityImageSelection.currentIndex !== -1;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: 200;
|
||||
text: "Next";
|
||||
onClicked: {
|
||||
root.lastPage = "step_2";
|
||||
var securityImagePath = securityImageSelection.getImagePathFromImageID(securityImageSelection.getSelectedImageIndex())
|
||||
commerce.chooseSecurityImage(securityImagePath);
|
||||
root.activeView = "step_3";
|
||||
passphraseSelection.clearPassphraseFields();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// SECURITY IMAGE SELECTION END
|
||||
//
|
||||
|
||||
//
|
||||
// SECURE PASSPHRASE SELECTION START
|
||||
//
|
||||
|
||||
Item {
|
||||
id: securityImageTip;
|
||||
visible: false;
|
||||
z: 999;
|
||||
anchors.fill: root;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
Image {
|
||||
source: "images/wallet-tip-bg.png";
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: tipText;
|
||||
text: '<font size="5">Tip:</font><br><br>When you see your security picture like this, you know ' +
|
||||
"the page asking for your passphrase is legitimate.";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 230;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 60;
|
||||
height: paintedHeight;
|
||||
width: 210;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
}
|
||||
|
||||
// "Got It" button
|
||||
HifiControlsUit.Button {
|
||||
id: tipGotItButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: tipText.bottom;
|
||||
anchors.topMargin: 20;
|
||||
anchors.horizontalCenter: tipText.horizontalCenter;
|
||||
height: 50;
|
||||
width: 150;
|
||||
text: "Got It";
|
||||
onClicked: {
|
||||
root.hasShownSecurityImageTip = true;
|
||||
securityImageTip.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
id: choosePassphraseContainer;
|
||||
visible: root.activeView === "step_3";
|
||||
// Anchors
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: 30;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getWalletAuthenticatedStatus();
|
||||
if (!root.hasShownSecurityImageTip) {
|
||||
securityImageTip.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Text below title bar
|
||||
RalewayRegular {
|
||||
id: passphraseTitleHelper;
|
||||
text: "Set Your Passphrase:";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 50;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
PassphraseSelection {
|
||||
id: passphraseSelection;
|
||||
isShowingTip: securityImageTip.visible;
|
||||
anchors.top: passphraseTitleHelper.bottom;
|
||||
anchors.topMargin: 30;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: passphraseNavBar.top;
|
||||
|
||||
Connections {
|
||||
onSendMessageToLightbox: {
|
||||
if (msg.method === 'statusResult') {
|
||||
} else {
|
||||
sendSignalToWallet(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation Bar
|
||||
Item {
|
||||
id: passphraseNavBar;
|
||||
visible: !securityImageTip.visible;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
// Anchors:
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 50;
|
||||
|
||||
// "Back" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.noneBorderlessWhite;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: 200;
|
||||
text: "Back"
|
||||
onClicked: {
|
||||
root.lastPage = "step_3";
|
||||
root.activeView = "step_2";
|
||||
}
|
||||
}
|
||||
|
||||
// "Next" button
|
||||
HifiControlsUit.Button {
|
||||
id: passphrasePageNextButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: 200;
|
||||
text: "Next";
|
||||
onClicked: {
|
||||
if (passphraseSelection.validateAndSubmitPassphrase()) {
|
||||
root.lastPage = "step_3";
|
||||
commerce.generateKeyPair();
|
||||
root.activeView = "step_4";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// SECURE PASSPHRASE SELECTION END
|
||||
//
|
||||
|
||||
//
|
||||
// PRIVATE KEYS READY START
|
||||
//
|
||||
Item {
|
||||
id: privateKeysReadyContainer;
|
||||
visible: root.activeView === "step_4";
|
||||
// Anchors
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: 30;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
||||
// Text below title bar
|
||||
RalewayRegular {
|
||||
id: keysReadyTitleHelper;
|
||||
text: "Back Up Your Private Keys";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 50;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: explanationText;
|
||||
text: "To protect your privacy, you control your private keys. High Fidelity has no access to your private keys and cannot " +
|
||||
"recover them for you.<br><br><b>If they are lost, you will not be able to access your money or purchases.</b>";
|
||||
// Text size
|
||||
size: 20;
|
||||
// Anchors
|
||||
anchors.top: keysReadyTitleHelper.bottom;
|
||||
anchors.topMargin: 24;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: pathAndInstructionsContainer;
|
||||
anchors.top: explanationText.bottom;
|
||||
anchors.topMargin: 24;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 240;
|
||||
color: Qt.rgba(0, 0, 0, 0.5);
|
||||
|
||||
Item {
|
||||
id: instructions01Container;
|
||||
anchors.fill: parent;
|
||||
|
||||
RalewaySemiBold {
|
||||
id: keyFilePathText;
|
||||
text: "Private Key File Location:";
|
||||
size: 18;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 40;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
|
||||
HifiControlsUit.Button {
|
||||
id: clipboardButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.top: keyFilePathText.bottom;
|
||||
anchors.topMargin: 8;
|
||||
height: 24;
|
||||
width: height;
|
||||
HiFiGlyphs {
|
||||
text: hifi.glyphs.folderLg;
|
||||
// Size
|
||||
size: parent.height;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
// Style
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
color: enabled ? hifi.colors.blueHighlight : hifi.colors.faintGray;
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("file:///" + keyFilePath.text.substring(0, keyFilePath.text.lastIndexOf('/')));
|
||||
}
|
||||
}
|
||||
RalewayRegular {
|
||||
id: keyFilePath;
|
||||
size: 18;
|
||||
anchors.top: clipboardButton.top;
|
||||
anchors.left: clipboardButton.right;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: paintedHeight;
|
||||
wrapMode: Text.WordWrap;
|
||||
color: hifi.colors.blueHighlight;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "Open Instructions" button
|
||||
HifiControlsUit.Button {
|
||||
id: openInstructionsButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: keyFilePath.bottom;
|
||||
anchors.topMargin: 30;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: 40;
|
||||
text: "Open Instructions for Later";
|
||||
onClicked: {
|
||||
instructions01Container.visible = false;
|
||||
instructions02Container.visible = true;
|
||||
keysReadyPageFinishButton.visible = true;
|
||||
Qt.openUrlExternally("https://www.highfidelity.com/");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: instructions02Container;
|
||||
anchors.fill: parent;
|
||||
visible: false;
|
||||
|
||||
RalewayRegular {
|
||||
text: "All set!<br>Instructions for backing up your keys have been opened on your desktop. " +
|
||||
"Be sure to look them over after your session.";
|
||||
size: 22;
|
||||
anchors.fill: parent;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.rightMargin: 30;
|
||||
wrapMode: Text.WordWrap;
|
||||
color: hifi.colors.white;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation Bar
|
||||
Item {
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
// Anchors:
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 50;
|
||||
// "Finish" button
|
||||
HifiControlsUit.Button {
|
||||
id: keysReadyPageFinishButton;
|
||||
visible: false;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: 200;
|
||||
text: "Finish";
|
||||
onClicked: {
|
||||
root.visible = false;
|
||||
sendSignalToWallet({method: 'walletSetup_finished', referrer: root.referrer ? root.referrer : ""});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// PRIVATE KEYS READY END
|
||||
//
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
signal sendSignalToWallet(var msg);
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
||||
}
|
|
@ -1,502 +0,0 @@
|
|||
//
|
||||
// WalletSetupLightbox.qml
|
||||
// qml/hifi/commerce/wallet
|
||||
//
|
||||
// WalletSetupLightbox
|
||||
//
|
||||
// Created by Zach Fox on 2017-08-17
|
||||
// Copyright 2017 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 QtQuick.Controls 1.4
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
Rectangle {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string lastPage: "initialize";
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onSecurityImageResult: {
|
||||
if (!exists && root.lastPage === "securityImage") {
|
||||
// ERROR! Invalid security image.
|
||||
securityImageContainer.visible = true;
|
||||
choosePassphraseContainer.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
securityImageContainer.visible = false;
|
||||
if (isAuthenticated) {
|
||||
privateKeysReadyContainer.visible = true;
|
||||
} else {
|
||||
choosePassphraseContainer.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
keyFilePath.text = path;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SECURITY IMAGE SELECTION START
|
||||
//
|
||||
Item {
|
||||
id: securityImageContainer;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
|
||||
Item {
|
||||
id: securityImageTitle;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
||||
// Title Bar text
|
||||
RalewaySemiBold {
|
||||
text: "WALLET SETUP - STEP 1 OF 3";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
// Text below title bar
|
||||
RalewaySemiBold {
|
||||
id: securityImageTitleHelper;
|
||||
text: "Choose a Security Picture:";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: securityImageTitle.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
height: 50;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
SecurityImageSelection {
|
||||
id: securityImageSelection;
|
||||
// Anchors
|
||||
anchors.top: securityImageTitleHelper.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 280;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
sendSignalToWallet(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Text below security images
|
||||
RalewayRegular {
|
||||
text: "<b>Your security picture shows you that the service asking for your passphrase is authorized.</b> You can change your secure picture at any time.";
|
||||
// Text size
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: securityImageSelection.bottom;
|
||||
anchors.topMargin: 40;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// Navigation Bar
|
||||
Item {
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 100;
|
||||
// Anchors:
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
// "Cancel" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: 100;
|
||||
text: "Cancel"
|
||||
onClicked: {
|
||||
sendSignalToWallet({method: 'walletSetup_cancelClicked'});
|
||||
}
|
||||
}
|
||||
|
||||
// "Next" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: 100;
|
||||
text: "Next";
|
||||
onClicked: {
|
||||
root.lastPage = "securityImage";
|
||||
var securityImagePath = securityImageSelection.getImagePathFromImageID(securityImageSelection.getSelectedImageIndex())
|
||||
commerce.chooseSecurityImage(securityImagePath);
|
||||
securityImageContainer.visible = false;
|
||||
choosePassphraseContainer.visible = true;
|
||||
passphraseSelection.clearPassphraseFields();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// SECURITY IMAGE SELECTION END
|
||||
//
|
||||
|
||||
//
|
||||
// SECURE PASSPHRASE SELECTION START
|
||||
//
|
||||
Item {
|
||||
id: choosePassphraseContainer;
|
||||
visible: false;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getWalletAuthenticatedStatus();
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: passphraseTitle;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
||||
// Title Bar text
|
||||
RalewaySemiBold {
|
||||
text: "WALLET SETUP - STEP 2 OF 3";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
// Text below title bar
|
||||
RalewaySemiBold {
|
||||
id: passphraseTitleHelper;
|
||||
text: "Choose a Secure Passphrase";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: passphraseTitle.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 50;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
PassphraseSelection {
|
||||
id: passphraseSelection;
|
||||
anchors.top: passphraseTitleHelper.bottom;
|
||||
anchors.topMargin: 30;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: passphraseNavBar.top;
|
||||
|
||||
Connections {
|
||||
onSendMessageToLightbox: {
|
||||
if (msg.method === 'statusResult') {
|
||||
} else {
|
||||
sendSignalToWallet(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation Bar
|
||||
Item {
|
||||
id: passphraseNavBar;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 100;
|
||||
// Anchors:
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
// "Back" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: 100;
|
||||
text: "Back"
|
||||
onClicked: {
|
||||
root.lastPage = "choosePassphrase";
|
||||
choosePassphraseContainer.visible = false;
|
||||
securityImageContainer.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
// "Next" button
|
||||
HifiControlsUit.Button {
|
||||
id: passphrasePageNextButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: 100;
|
||||
text: "Next";
|
||||
onClicked: {
|
||||
if (passphraseSelection.validateAndSubmitPassphrase()) {
|
||||
root.lastPage = "choosePassphrase";
|
||||
commerce.generateKeyPair();
|
||||
choosePassphraseContainer.visible = false;
|
||||
privateKeysReadyContainer.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// SECURE PASSPHRASE SELECTION END
|
||||
//
|
||||
|
||||
//
|
||||
// PRIVATE KEYS READY START
|
||||
//
|
||||
Item {
|
||||
id: privateKeysReadyContainer;
|
||||
visible: false;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
|
||||
Item {
|
||||
id: keysReadyTitle;
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 50;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
||||
// Title Bar text
|
||||
RalewaySemiBold {
|
||||
text: "WALLET SETUP - STEP 3 OF 3";
|
||||
// Text size
|
||||
size: hifi.fontSizes.overlayTitle;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
// Text below title bar
|
||||
RalewaySemiBold {
|
||||
id: keysReadyTitleHelper;
|
||||
text: "Your Private Keys are Ready";
|
||||
// Text size
|
||||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: keysReadyTitle.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: 50;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// Text below checkbox
|
||||
RalewayRegular {
|
||||
id: explanationText;
|
||||
text: "Your money and purchases are secured with private keys that only you have access to. " +
|
||||
"<b>If they are lost, you will not be able to access your money or purchases.</b><br><br>" +
|
||||
"<b>To protect your privacy, High Fidelity has no access to your private keys and cannot " +
|
||||
"recover them for any reason.<br><br>To safeguard your private keys, backup this file on a regular basis:</b>";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: keysReadyTitleHelper.bottom;
|
||||
anchors.topMargin: 16;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
HifiControlsUit.TextField {
|
||||
id: keyFilePath;
|
||||
anchors.top: explanationText.bottom;
|
||||
anchors.topMargin: 10;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: clipboardButton.left;
|
||||
height: 40;
|
||||
readOnly: true;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
}
|
||||
}
|
||||
}
|
||||
HifiControlsUit.Button {
|
||||
id: clipboardButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
anchors.top: keyFilePath.top;
|
||||
anchors.bottom: keyFilePath.bottom;
|
||||
width: height;
|
||||
HiFiGlyphs {
|
||||
text: hifi.glyphs.question;
|
||||
// Size
|
||||
size: parent.height*1.3;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
// Style
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
color: enabled ? hifi.colors.white : hifi.colors.faintGray;
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
Window.copyToClipboard(keyFilePath.text);
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation Bar
|
||||
Item {
|
||||
// Size
|
||||
width: parent.width;
|
||||
height: 100;
|
||||
// Anchors:
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
// "Next" button
|
||||
HifiControlsUit.Button {
|
||||
id: keysReadyPageNextButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: 100;
|
||||
text: "Finish";
|
||||
onClicked: {
|
||||
root.visible = false;
|
||||
sendSignalToWallet({method: 'walletSetup_finished'});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// PRIVATE KEYS READY END
|
||||
//
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
signal sendSignalToWallet(var msg);
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
||||
}
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 9.9 KiB |
After Width: | Height: | Size: 9 KiB |
After Width: | Height: | Size: 60 KiB |
|
@ -138,6 +138,7 @@ Item {
|
|||
id: colorSchemes
|
||||
readonly property int light: 0
|
||||
readonly property int dark: 1
|
||||
readonly property int faintGray: 2
|
||||
}
|
||||
|
||||
Item {
|
||||
|
@ -178,7 +179,7 @@ Item {
|
|||
readonly property real tableHeading: dimensions.largeScreen ? 12 : 10
|
||||
readonly property real tableHeadingIcon: dimensions.largeScreen ? 60 : 33
|
||||
readonly property real tableText: dimensions.largeScreen ? 15 : 12
|
||||
readonly property real buttonLabel: dimensions.largeScreen ? 13 : 9
|
||||
readonly property real buttonLabel: dimensions.largeScreen ? 14 : 9
|
||||
readonly property real iconButton: dimensions.largeScreen ? 13 : 9
|
||||
readonly property real listItem: dimensions.largeScreen ? 15 : 11
|
||||
readonly property real tabularData: dimensions.largeScreen ? 15 : 11
|
||||
|
@ -209,11 +210,15 @@ Item {
|
|||
readonly property int blue: 1
|
||||
readonly property int red: 2
|
||||
readonly property int black: 3
|
||||
readonly property var textColor: [ colors.darkGray, colors.white, colors.white, colors.white ]
|
||||
readonly property var colorStart: [ colors.white, colors.primaryHighlight, "#d42043", "#343434" ]
|
||||
readonly property var colorFinish: [ colors.lightGrayText, colors.blueAccent, "#94132e", colors.black ]
|
||||
readonly property var hoveredColor: [ colorStart[white], colorStart[blue], colorStart[red], colorFinish[black] ]
|
||||
readonly property var pressedColor: [ colorFinish[white], colorFinish[blue], colorFinish[red], colorStart[black] ]
|
||||
readonly property int none: 4
|
||||
readonly property int noneBorderless: 5
|
||||
readonly property int noneBorderlessWhite: 6
|
||||
readonly property int noneBorderlessGray: 7
|
||||
readonly property var textColor: [ colors.darkGray, colors.white, colors.white, colors.white, colors.white, colors.blueAccent, colors.white, colors.darkGray ]
|
||||
readonly property var colorStart: [ colors.white, colors.primaryHighlight, "#d42043", "#343434", Qt.rgba(0, 0, 0, 0), Qt.rgba(0, 0, 0, 0), Qt.rgba(0, 0, 0, 0), Qt.rgba(0, 0, 0, 0) ]
|
||||
readonly property var colorFinish: [ colors.lightGrayText, colors.blueAccent, "#94132e", colors.black, Qt.rgba(0, 0, 0, 0), Qt.rgba(0, 0, 0, 0), Qt.rgba(0, 0, 0, 0), Qt.rgba(0, 0, 0, 0) ]
|
||||
readonly property var hoveredColor: [ colorStart[white], colorStart[blue], colorStart[red], colorFinish[black], colorStart[none], colorStart[noneBorderless], colorStart[noneBorderlessWhite], colorStart[noneBorderlessGray] ]
|
||||
readonly property var pressedColor: [ colorFinish[white], colorFinish[blue], colorFinish[red], colorStart[black], colorStart[none], colorStart[noneBorderless], colorStart[noneBorderlessWhite], colorStart[noneBorderlessGray] ]
|
||||
readonly property var disabledColorStart: [ colorStart[white], colors.baseGrayHighlight]
|
||||
readonly property var disabledColorFinish: [ colorFinish[white], colors.baseGrayShadow]
|
||||
readonly property var disabledTextColor: [ colors.lightGrayText, colors.baseGrayShadow]
|
||||
|
@ -338,6 +343,15 @@ Item {
|
|||
readonly property string stop_square: "\ue01e"
|
||||
readonly property string avatarTPose: "\ue01f"
|
||||
readonly property string lock: "\ue006"
|
||||
readonly property string check_2_01: "\ue020"
|
||||
readonly property string checkmark: "\ue020"
|
||||
readonly property string leftRightArrows: "\ue021"
|
||||
readonly property string hfc: "\ue022"
|
||||
readonly property string home2: "\ue023"
|
||||
readonly property string walletKey: "\ue024"
|
||||
readonly property string lightning: "\ue025"
|
||||
readonly property string securityImage: "\ue026"
|
||||
readonly property string wallet: "\ue027"
|
||||
readonly property string paperPlane: "\ue028"
|
||||
readonly property string passphrase: "\ue029"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "Wallet.h"
|
||||
#include "Ledger.h"
|
||||
#include "CommerceLogging.h"
|
||||
#include <NetworkingConstants.h>
|
||||
|
||||
// inventory answers {status: 'success', data: {assets: [{id: "guid", title: "name", preview: "url"}....]}}
|
||||
// balance answers {status: 'success', data: {balance: integer}}
|
||||
|
@ -59,12 +60,16 @@ void Ledger::send(const QString& endpoint, const QString& success, const QString
|
|||
QJsonDocument(request).toJson());
|
||||
}
|
||||
|
||||
void Ledger::signedSend(const QString& propertyName, const QByteArray& text, const QString& key, const QString& endpoint, const QString& success, const QString& fail) {
|
||||
void Ledger::signedSend(const QString& propertyName, const QByteArray& text, const QString& key, const QString& endpoint, const QString& success, const QString& fail, const bool controlled_failure) {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
QString signature = key.isEmpty() ? "" : wallet->signWithKey(text, key);
|
||||
QJsonObject request;
|
||||
request[propertyName] = QString(text);
|
||||
request["signature"] = signature;
|
||||
if (!controlled_failure) {
|
||||
request["signature"] = signature;
|
||||
} else {
|
||||
request["signature"] = QString("controlled failure!");
|
||||
}
|
||||
send(endpoint, success, fail, QNetworkAccessManager::PutOperation, request);
|
||||
}
|
||||
|
||||
|
@ -75,16 +80,15 @@ void Ledger::keysQuery(const QString& endpoint, const QString& success, const QS
|
|||
send(endpoint, success, fail, QNetworkAccessManager::PostOperation, request);
|
||||
}
|
||||
|
||||
void Ledger::buy(const QString& hfc_key, int cost, const QString& asset_id, const QString& inventory_key, const QString& buyerUsername) {
|
||||
void Ledger::buy(const QString& hfc_key, int cost, const QString& asset_id, const QString& inventory_key, const bool controlled_failure) {
|
||||
QJsonObject transaction;
|
||||
transaction["hfc_key"] = hfc_key;
|
||||
transaction["cost"] = cost;
|
||||
transaction["asset_id"] = asset_id;
|
||||
transaction["inventory_key"] = inventory_key;
|
||||
transaction["inventory_buyer_username"] = buyerUsername;
|
||||
QJsonDocument transactionDoc{ transaction };
|
||||
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
|
||||
signedSend("transaction", transactionString, hfc_key, "buy", "buySuccess", "buyFailure");
|
||||
signedSend("transaction", transactionString, hfc_key, "buy", "buySuccess", "buyFailure", controlled_failure);
|
||||
}
|
||||
|
||||
bool Ledger::receiveAt(const QString& hfc_key, const QString& old_key) {
|
||||
|
@ -110,14 +114,15 @@ void Ledger::inventory(const QStringList& keys) {
|
|||
|
||||
QString nameFromKey(const QString& key, const QStringList& publicKeys) {
|
||||
if (key.isNull() || key.isEmpty()) {
|
||||
return "<b>Marketplace</b>";
|
||||
return "Marketplace";
|
||||
}
|
||||
if (publicKeys.contains(key)) {
|
||||
return "You";
|
||||
}
|
||||
return "<b>Someone</b>";
|
||||
return "Someone";
|
||||
}
|
||||
|
||||
static const QString MARKETPLACE_ITEMS_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace/items/";
|
||||
void Ledger::historySuccess(QNetworkReply& reply) {
|
||||
// here we send a historyResult with some extra stuff in it
|
||||
// Namely, the styled text we'd like to show. The issue is the
|
||||
|
@ -135,10 +140,27 @@ void Ledger::historySuccess(QNetworkReply& reply) {
|
|||
QJsonArray newHistoryArray;
|
||||
|
||||
// TODO: do this with 0 copies if possible
|
||||
for(auto it = historyArray.begin(); it != historyArray.end(); it++) {
|
||||
for (auto it = historyArray.begin(); it != historyArray.end(); it++) {
|
||||
auto valueObject = (*it).toObject();
|
||||
QString from = nameFromKey(valueObject["sender_key"].toString(), keys);
|
||||
QString to = nameFromKey(valueObject["recipient_key"].toString(), keys);
|
||||
bool isHfc = valueObject["asset_title"].toString() == "HFC";
|
||||
bool iAmReceiving = to == "You";
|
||||
QString coloredQuantityAndAssetTitle = QString::number(valueObject["quantity"].toInt()) + " " + valueObject["asset_title"].toString();
|
||||
if (isHfc) {
|
||||
if (iAmReceiving) {
|
||||
coloredQuantityAndAssetTitle = QString("<font color='#1FC6A6'>") + coloredQuantityAndAssetTitle + QString("</font>");
|
||||
} else {
|
||||
coloredQuantityAndAssetTitle = QString("<font color='#EA4C5F'>") + coloredQuantityAndAssetTitle + QString("</font>");
|
||||
}
|
||||
} else {
|
||||
coloredQuantityAndAssetTitle = QString("\"<font color='#0093C5'><a href='") +
|
||||
MARKETPLACE_ITEMS_BASE_URL +
|
||||
valueObject["asset_id"].toString() +
|
||||
QString("'>") +
|
||||
coloredQuantityAndAssetTitle +
|
||||
QString("</a></font>\"");
|
||||
}
|
||||
// turns out on my machine, toLocalTime convert to some weird timezone, yet the
|
||||
// systemTimeZone is correct. To avoid a strange bug with other's systems too, lets
|
||||
// be explicit
|
||||
|
@ -148,8 +170,8 @@ void Ledger::historySuccess(QNetworkReply& reply) {
|
|||
QDateTime createdAt = QDateTime::fromSecsSinceEpoch(valueObject["created_at"].toInt(), Qt::UTC);
|
||||
#endif
|
||||
QDateTime localCreatedAt = createdAt.toTimeZone(QTimeZone::systemTimeZone());
|
||||
valueObject["text"] = QString("%1 sent %2 <b>%3 %4</b> on %5 with message \"%6\"").
|
||||
arg(from, to, QString::number(valueObject["quantity"].toInt()), valueObject["asset_title"].toString(), localCreatedAt.toString(Qt::SystemLocaleShortDate), valueObject["message"].toString());
|
||||
valueObject["text"] = QString("%1 sent %2 %3 with message \"%4\"").
|
||||
arg(from, to, coloredQuantityAndAssetTitle, valueObject["message"].toString());
|
||||
newHistoryArray.push_back(valueObject);
|
||||
}
|
||||
// now copy the rest of the json -- this is inefficient
|
||||
|
@ -201,3 +223,18 @@ void Ledger::accountFailure(QNetworkReply& reply) {
|
|||
void Ledger::account() {
|
||||
send("hfc_account", "accountSuccess", "accountFailure", QNetworkAccessManager::PutOperation, QJsonObject());
|
||||
}
|
||||
|
||||
// The api/failResponse is called just for the side effect of logging.
|
||||
void Ledger::updateLocationSuccess(QNetworkReply& reply) { apiResponse("reset", reply); }
|
||||
void Ledger::updateLocationFailure(QNetworkReply& reply) { failResponse("reset", reply); }
|
||||
void Ledger::updateLocation(const QString& asset_id, const QString location, const bool controlledFailure) {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
QStringList keys = wallet->listPublicKeys();
|
||||
QString key = keys[0];
|
||||
QJsonObject transaction;
|
||||
transaction["asset_id"] = asset_id;
|
||||
transaction["location"] = location;
|
||||
QJsonDocument transactionDoc{ transaction };
|
||||
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
|
||||
signedSend("transaction", transactionString, key, "location", "updateLocationSuccess", "updateLocationFailure", controlledFailure);
|
||||
}
|
||||
|
|
|
@ -24,13 +24,14 @@ class Ledger : public QObject, public Dependency {
|
|||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
void buy(const QString& hfc_key, int cost, const QString& asset_id, const QString& inventory_key, const QString& buyerUsername = "");
|
||||
void buy(const QString& hfc_key, int cost, const QString& asset_id, const QString& inventory_key, const bool controlled_failure = false);
|
||||
bool receiveAt(const QString& hfc_key, const QString& old_key);
|
||||
void balance(const QStringList& keys);
|
||||
void inventory(const QStringList& keys);
|
||||
void history(const QStringList& keys);
|
||||
void account();
|
||||
void reset();
|
||||
void updateLocation(const QString& asset_id, const QString location, const bool controlledFailure = false);
|
||||
|
||||
signals:
|
||||
void buyResult(QJsonObject result);
|
||||
|
@ -39,6 +40,7 @@ signals:
|
|||
void inventoryResult(QJsonObject result);
|
||||
void historyResult(QJsonObject result);
|
||||
void accountResult(QJsonObject result);
|
||||
void locationUpdateResult(QJsonObject result);
|
||||
|
||||
public slots:
|
||||
void buySuccess(QNetworkReply& reply);
|
||||
|
@ -55,13 +57,15 @@ public slots:
|
|||
void resetFailure(QNetworkReply& reply);
|
||||
void accountSuccess(QNetworkReply& reply);
|
||||
void accountFailure(QNetworkReply& reply);
|
||||
void updateLocationSuccess(QNetworkReply& reply);
|
||||
void updateLocationFailure(QNetworkReply& reply);
|
||||
|
||||
private:
|
||||
QJsonObject apiResponse(const QString& label, QNetworkReply& reply);
|
||||
QJsonObject failResponse(const QString& label, QNetworkReply& reply);
|
||||
void send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, QJsonObject request);
|
||||
void keysQuery(const QString& endpoint, const QString& success, const QString& fail);
|
||||
void signedSend(const QString& propertyName, const QByteArray& text, const QString& key, const QString& endpoint, const QString& success, const QString& fail);
|
||||
void signedSend(const QString& propertyName, const QByteArray& text, const QString& key, const QString& endpoint, const QString& success, const QString& fail, const bool controlled_failure = false);
|
||||
};
|
||||
|
||||
#endif // hifi_Ledger_h
|
||||
|
|
|
@ -54,7 +54,7 @@ void QmlCommerce::chooseSecurityImage(const QString& imageFile) {
|
|||
wallet->chooseSecurityImage(imageFile);
|
||||
}
|
||||
|
||||
void QmlCommerce::buy(const QString& assetId, int cost, const QString& buyerUsername) {
|
||||
void QmlCommerce::buy(const QString& assetId, int cost, const bool controlledFailure) {
|
||||
auto ledger = DependencyManager::get<Ledger>();
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
QStringList keys = wallet->listPublicKeys();
|
||||
|
@ -64,7 +64,7 @@ void QmlCommerce::buy(const QString& assetId, int cost, const QString& buyerUser
|
|||
}
|
||||
QString key = keys[0];
|
||||
// For now, we receive at the same key that pays for it.
|
||||
ledger->buy(key, cost, assetId, key, buyerUsername);
|
||||
ledger->buy(key, cost, assetId, key, controlledFailure);
|
||||
}
|
||||
|
||||
void QmlCommerce::balance() {
|
||||
|
|
|
@ -50,7 +50,7 @@ protected:
|
|||
Q_INVOKABLE void chooseSecurityImage(const QString& imageFile);
|
||||
Q_INVOKABLE void setPassphrase(const QString& passphrase);
|
||||
|
||||
Q_INVOKABLE void buy(const QString& assetId, int cost, const QString& buyerUsername = "");
|
||||
Q_INVOKABLE void buy(const QString& assetId, int cost, const bool controlledFailure = false);
|
||||
Q_INVOKABLE void balance();
|
||||
Q_INVOKABLE void inventory();
|
||||
Q_INVOKABLE void history();
|
||||
|
|
|
@ -280,6 +280,13 @@ void initializeAESKeys(unsigned char* ivec, unsigned char* ckey, const QByteArra
|
|||
memcpy(ckey, wallet->getCKey(), 32);
|
||||
}
|
||||
|
||||
Wallet::Wallet() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
auto& packetReceiver = nodeList->getPacketReceiver();
|
||||
|
||||
packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "verifyOwnerChallenge");
|
||||
}
|
||||
|
||||
Wallet::~Wallet() {
|
||||
if (_securityImage) {
|
||||
delete _securityImage;
|
||||
|
@ -645,3 +652,30 @@ bool Wallet::changePassphrase(const QString& newPassphrase) {
|
|||
qCDebug(commerce) << "changing passphrase";
|
||||
return writeWallet(newPassphrase);
|
||||
}
|
||||
|
||||
void Wallet::handleChallengeOwnershipPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode) {
|
||||
QString decryptedText;
|
||||
quint64 encryptedTextSize;
|
||||
quint64 publicKeySize;
|
||||
|
||||
if (verifyOwnerChallenge(packet->read(packet->readPrimitive(&encryptedTextSize)), packet->read(packet->readPrimitive(&publicKeySize)), decryptedText)) {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
// setup the packet
|
||||
auto decryptedTextPacket = NLPacket::create(PacketType::ChallengeOwnership, NUM_BYTES_RFC4122_UUID + decryptedText.size(), true);
|
||||
|
||||
// write the decrypted text to the packet
|
||||
decryptedTextPacket->write(decryptedText.toUtf8());
|
||||
|
||||
qCDebug(commerce) << "Sending ChallengeOwnership Packet containing decrypted text";
|
||||
|
||||
nodeList->sendPacket(std::move(decryptedTextPacket), *sendingNode);
|
||||
} else {
|
||||
qCDebug(commerce) << "verifyOwnerChallenge() returned false";
|
||||
}
|
||||
}
|
||||
|
||||
bool Wallet::verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText) {
|
||||
// I have no idea how to do this yet, so here's some dummy code that may not even work.
|
||||
decryptedText = QString("hello");
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#define hifi_Wallet_h
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include <Node.h>
|
||||
#include <ReceivedMessage.h>
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
|
@ -23,7 +25,7 @@ class Wallet : public QObject, public Dependency {
|
|||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
|
||||
Wallet();
|
||||
~Wallet();
|
||||
// These are currently blocking calls, although they might take a moment.
|
||||
bool generateKeyPair();
|
||||
|
@ -52,6 +54,9 @@ signals:
|
|||
void securityImageResult(bool exists);
|
||||
void keyFilePathIfExistsResult(const QString& path);
|
||||
|
||||
private slots:
|
||||
void handleChallengeOwnershipPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode);
|
||||
|
||||
private:
|
||||
QStringList _publicKeys{};
|
||||
QPixmap* _securityImage { nullptr };
|
||||
|
@ -64,6 +69,8 @@ private:
|
|||
void updateImageProvider();
|
||||
bool writeSecurityImage(const QPixmap* pixmap, const QString& outputFilePath);
|
||||
bool readSecurityImage(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen);
|
||||
|
||||
bool verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText);
|
||||
};
|
||||
|
||||
#endif // hifi_Wallet_h
|
||||
|
|
|
@ -137,7 +137,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID&
|
|||
boundingBox.findRayIntersection(cameraPosition, direction, distance, face, normal);
|
||||
float offsetAngle = -CONTEXT_OVERLAY_OFFSET_ANGLE;
|
||||
if (event.getID() == LEFT_HAND_HW_ID) {
|
||||
offsetAngle *= -1;
|
||||
offsetAngle *= -1.0f;
|
||||
}
|
||||
contextOverlayPosition = (glm::quat(glm::radians(glm::vec3(0.0f, offsetAngle, 0.0f)))) *
|
||||
((cameraPosition + direction * (distance - CONTEXT_OVERLAY_OFFSET_DISTANCE)));
|
||||
|
@ -201,8 +201,12 @@ bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityIt
|
|||
void ContextOverlayInterface::contextOverlays_mousePressOnOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
if (overlayID == _contextOverlayID && event.getButton() == PointerEvent::PrimaryButton) {
|
||||
qCDebug(context_overlay) << "Clicked Context Overlay. Entity ID:" << _currentEntityWithContextOverlay << "Overlay ID:" << overlayID;
|
||||
openMarketplace();
|
||||
destroyContextOverlay(_currentEntityWithContextOverlay, PointerEvent());
|
||||
if (_commerceSettingSwitch.get()) {
|
||||
openInspectionCertificate();
|
||||
} else {
|
||||
openMarketplace();
|
||||
}
|
||||
emit contextOverlayClicked(_currentEntityWithContextOverlay);
|
||||
_contextOverlayJustClicked = true;
|
||||
}
|
||||
}
|
||||
|
@ -239,6 +243,16 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemI
|
|||
}
|
||||
}
|
||||
|
||||
static const QString INSPECTION_CERTIFICATE_QML_PATH = qApp->applicationDirPath() + "../../../qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml";
|
||||
void ContextOverlayInterface::openInspectionCertificate() {
|
||||
// lets open the tablet to the inspection certificate QML
|
||||
if (!_currentEntityWithContextOverlay.isNull() && _entityMarketplaceID.length() > 0) {
|
||||
auto tablet = dynamic_cast<TabletProxy*>(_tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
|
||||
tablet->loadQMLSource(INSPECTION_CERTIFICATE_QML_PATH);
|
||||
_hmdScriptingInterface->openTablet();
|
||||
}
|
||||
}
|
||||
|
||||
static const QString MARKETPLACE_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace/items/";
|
||||
|
||||
void ContextOverlayInterface::openMarketplace() {
|
||||
|
|
|
@ -56,6 +56,9 @@ public:
|
|||
bool getIsInMarketplaceInspectionMode() { return _isInMarketplaceInspectionMode; }
|
||||
void setIsInMarketplaceInspectionMode(bool mode) { _isInMarketplaceInspectionMode = mode; }
|
||||
|
||||
signals:
|
||||
void contextOverlayClicked(const QUuid& currentEntityWithContextOverlay);
|
||||
|
||||
public slots:
|
||||
bool createOrDestroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
bool destroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
|
@ -76,6 +79,9 @@ private:
|
|||
|
||||
bool _isInMarketplaceInspectionMode { false };
|
||||
|
||||
Setting::Handle<bool> _commerceSettingSwitch{ "commerce", false };
|
||||
|
||||
void openInspectionCertificate();
|
||||
void openMarketplace();
|
||||
void enableEntityHighlight(const EntityItemID& entityItemID);
|
||||
void disableEntityHighlight(const EntityItemID& entityItemID);
|
||||
|
|
|
@ -306,9 +306,6 @@ public:
|
|||
QString getMarketplaceID() const;
|
||||
void setMarketplaceID(const QString& value);
|
||||
|
||||
bool getShouldHighlight() const;
|
||||
void setShouldHighlight(const bool value);
|
||||
|
||||
// TODO: get rid of users of getRadius()...
|
||||
float getRadius() const;
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership
|
|||
connect(nodeList.data(), &NodeList::isAllowedEditorChanged, this, &EntityScriptingInterface::canAdjustLocksChanged);
|
||||
connect(nodeList.data(), &NodeList::canRezChanged, this, &EntityScriptingInterface::canRezChanged);
|
||||
connect(nodeList.data(), &NodeList::canRezTmpChanged, this, &EntityScriptingInterface::canRezTmpChanged);
|
||||
connect(nodeList.data(), &NodeList::canRezCertifiedChanged, this, &EntityScriptingInterface::canRezCertifiedChanged);
|
||||
connect(nodeList.data(), &NodeList::canRezTmpCertifiedChanged, this, &EntityScriptingInterface::canRezTmpCertifiedChanged);
|
||||
connect(nodeList.data(), &NodeList::canWriteAssetsChanged, this, &EntityScriptingInterface::canWriteAssetsChanged);
|
||||
}
|
||||
|
||||
|
@ -76,6 +78,16 @@ bool EntityScriptingInterface::canRezTmp() {
|
|||
return nodeList->getThisNodeCanRezTmp();
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::canRezCertified() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
return nodeList->getThisNodeCanRezCertified();
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::canRezTmpCertified() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
return nodeList->getThisNodeCanRezTmpCertified();
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::canWriteAssets() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
return nodeList->getThisNodeCanWriteAssets();
|
||||
|
|
|
@ -126,6 +126,18 @@ public slots:
|
|||
*/
|
||||
Q_INVOKABLE bool canRezTmp();
|
||||
|
||||
/**jsdoc
|
||||
* @function Entities.canRezCertified
|
||||
* @return {bool} `true` if the DomainServer will allow this Node/Avatar to rez new certified entities
|
||||
*/
|
||||
Q_INVOKABLE bool canRezCertified();
|
||||
|
||||
/**jsdoc
|
||||
* @function Entities.canRezTmpCertified
|
||||
* @return {bool} `true` if the DomainServer will allow this Node/Avatar to rez new temporary certified entities
|
||||
*/
|
||||
Q_INVOKABLE bool canRezTmpCertified();
|
||||
|
||||
/**jsdoc
|
||||
* @function Entities.canWriteAsseets
|
||||
* @return {bool} `true` if the DomainServer will allow this Node/Avatar to write to the asset server
|
||||
|
@ -380,6 +392,8 @@ signals:
|
|||
void canAdjustLocksChanged(bool canAdjustLocks);
|
||||
void canRezChanged(bool canRez);
|
||||
void canRezTmpChanged(bool canRez);
|
||||
void canRezCertifiedChanged(bool canRez);
|
||||
void canRezTmpCertifiedChanged(bool canRez);
|
||||
void canWriteAssetsChanged(bool canWriteAssets);
|
||||
|
||||
void mousePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event);
|
||||
|
|
|
@ -350,7 +350,8 @@ EntityItemPointer EntityTree::addEntity(const EntityItemID& entityID, const Enti
|
|||
}
|
||||
|
||||
if (!properties.getClientOnly() && getIsClient() &&
|
||||
!nodeList->getThisNodeCanRez() && !nodeList->getThisNodeCanRezTmp()) {
|
||||
!nodeList->getThisNodeCanRez() && !nodeList->getThisNodeCanRezTmp() &&
|
||||
!nodeList->getThisNodeCanRezCertified() && !nodeList->getThisNodeCanRezTmpCertified()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1076,7 +1077,8 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
|
|||
}
|
||||
|
||||
if ((isAdd || properties.lifetimeChanged()) &&
|
||||
!senderNode->getCanRez() && senderNode->getCanRezTmp()) {
|
||||
((!senderNode->getCanRez() && senderNode->getCanRezTmp()) ||
|
||||
(!senderNode->getCanRezCertified() && senderNode->getCanRezTmpCertified()))) {
|
||||
// this node is only allowed to rez temporary entities. if need be, cap the lifetime.
|
||||
if (properties.getLifetime() == ENTITY_ITEM_IMMORTAL_LIFETIME ||
|
||||
properties.getLifetime() > _maxTmpEntityLifetime) {
|
||||
|
@ -1146,8 +1148,11 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
|
|||
} else if (!senderNode->getCanRez() && !senderNode->getCanRezTmp()) {
|
||||
failedAdd = true;
|
||||
qCDebug(entities) << "User without 'rez rights' [" << senderNode->getUUID()
|
||||
<< "] attempted to add an entity ID:" << entityItemID;
|
||||
|
||||
<< "] attempted to add an entity ID:" << entityItemID;
|
||||
// FIXME after Cert ID property integrated
|
||||
} else if (/*!properties.getCertificateID().isNull() && */!senderNode->getCanRezCertified() && !senderNode->getCanRezTmpCertified()) {
|
||||
qCDebug(entities) << "User without 'certified rez rights' [" << senderNode->getUUID()
|
||||
<< "] attempted to add a certified entity with ID:" << entityItemID;
|
||||
} else {
|
||||
// this is a new entity... assign a new entityID
|
||||
properties.setCreated(properties.getLastEdited());
|
||||
|
|
|
@ -159,6 +159,14 @@ void LimitedNodeList::setPermissions(const NodePermissions& newPermissions) {
|
|||
newPermissions.can(NodePermissions::Permission::canRezTemporaryEntities)) {
|
||||
emit canRezTmpChanged(_permissions.can(NodePermissions::Permission::canRezTemporaryEntities));
|
||||
}
|
||||
if (originalPermissions.can(NodePermissions::Permission::canRezPermanentCertifiedEntities) !=
|
||||
newPermissions.can(NodePermissions::Permission::canRezPermanentCertifiedEntities)) {
|
||||
emit canRezCertifiedChanged(_permissions.can(NodePermissions::Permission::canRezPermanentCertifiedEntities));
|
||||
}
|
||||
if (originalPermissions.can(NodePermissions::Permission::canRezTemporaryCertifiedEntities) !=
|
||||
newPermissions.can(NodePermissions::Permission::canRezTemporaryCertifiedEntities)) {
|
||||
emit canRezTmpCertifiedChanged(_permissions.can(NodePermissions::Permission::canRezTemporaryCertifiedEntities));
|
||||
}
|
||||
if (originalPermissions.can(NodePermissions::Permission::canWriteToAssetServer) !=
|
||||
newPermissions.can(NodePermissions::Permission::canWriteToAssetServer)) {
|
||||
emit canWriteAssetsChanged(_permissions.can(NodePermissions::Permission::canWriteToAssetServer));
|
||||
|
|
|
@ -113,6 +113,8 @@ public:
|
|||
bool isAllowedEditor() const { return _permissions.can(NodePermissions::Permission::canAdjustLocks); }
|
||||
bool getThisNodeCanRez() const { return _permissions.can(NodePermissions::Permission::canRezPermanentEntities); }
|
||||
bool getThisNodeCanRezTmp() const { return _permissions.can(NodePermissions::Permission::canRezTemporaryEntities); }
|
||||
bool getThisNodeCanRezCertified() const { return _permissions.can(NodePermissions::Permission::canRezPermanentCertifiedEntities); }
|
||||
bool getThisNodeCanRezTmpCertified() const { return _permissions.can(NodePermissions::Permission::canRezTemporaryCertifiedEntities); }
|
||||
bool getThisNodeCanWriteAssets() const { return _permissions.can(NodePermissions::Permission::canWriteToAssetServer); }
|
||||
bool getThisNodeCanKick() const { return _permissions.can(NodePermissions::Permission::canKick); }
|
||||
bool getThisNodeCanReplaceContent() const { return _permissions.can(NodePermissions::Permission::canReplaceDomainContent); }
|
||||
|
@ -330,6 +332,8 @@ signals:
|
|||
void isAllowedEditorChanged(bool isAllowedEditor);
|
||||
void canRezChanged(bool canRez);
|
||||
void canRezTmpChanged(bool canRezTmp);
|
||||
void canRezCertifiedChanged(bool canRez);
|
||||
void canRezTmpCertifiedChanged(bool canRezTmp);
|
||||
void canWriteAssetsChanged(bool canWriteAssets);
|
||||
void canKickChanged(bool canKick);
|
||||
void canReplaceContentChanged(bool canReplaceContent);
|
||||
|
|
|
@ -72,6 +72,8 @@ public:
|
|||
bool isAllowedEditor() const { return _permissions.can(NodePermissions::Permission::canAdjustLocks); }
|
||||
bool getCanRez() const { return _permissions.can(NodePermissions::Permission::canRezPermanentEntities); }
|
||||
bool getCanRezTmp() const { return _permissions.can(NodePermissions::Permission::canRezTemporaryEntities); }
|
||||
bool getCanRezCertified() const { return _permissions.can(NodePermissions::Permission::canRezPermanentCertifiedEntities); }
|
||||
bool getCanRezTmpCertified() const { return _permissions.can(NodePermissions::Permission::canRezTemporaryCertifiedEntities); }
|
||||
bool getCanWriteToAssetServer() const { return _permissions.can(NodePermissions::Permission::canWriteToAssetServer); }
|
||||
bool getCanKick() const { return _permissions.can(NodePermissions::Permission::canKick); }
|
||||
bool getCanReplaceContent() const { return _permissions.can(NodePermissions::Permission::canReplaceDomainContent); }
|
||||
|
|
|
@ -60,6 +60,8 @@ NodePermissions::NodePermissions(QMap<QString, QVariant> perms) {
|
|||
permissions |= perms["id_can_adjust_locks"].toBool() ? Permission::canAdjustLocks : Permission::none;
|
||||
permissions |= perms["id_can_rez"].toBool() ? Permission::canRezPermanentEntities : Permission::none;
|
||||
permissions |= perms["id_can_rez_tmp"].toBool() ? Permission::canRezTemporaryEntities : Permission::none;
|
||||
permissions |= perms["id_can_rez_certified"].toBool() ? Permission::canRezPermanentCertifiedEntities : Permission::none;
|
||||
permissions |= perms["id_can_rez_tmp_certified"].toBool() ? Permission::canRezTemporaryCertifiedEntities : Permission::none;
|
||||
permissions |= perms["id_can_write_to_asset_server"].toBool() ? Permission::canWriteToAssetServer : Permission::none;
|
||||
permissions |= perms["id_can_connect_past_max_capacity"].toBool() ?
|
||||
Permission::canConnectPastMaxCapacity : Permission::none;
|
||||
|
@ -86,6 +88,8 @@ QVariant NodePermissions::toVariant(QHash<QUuid, GroupRank> groupRanks) {
|
|||
values["id_can_adjust_locks"] = can(Permission::canAdjustLocks);
|
||||
values["id_can_rez"] = can(Permission::canRezPermanentEntities);
|
||||
values["id_can_rez_tmp"] = can(Permission::canRezTemporaryEntities);
|
||||
values["id_can_rez_certified"] = can(Permission::canRezPermanentCertifiedEntities);
|
||||
values["id_can_rez_tmp_certified"] = can(Permission::canRezTemporaryCertifiedEntities);
|
||||
values["id_can_write_to_asset_server"] = can(Permission::canWriteToAssetServer);
|
||||
values["id_can_connect_past_max_capacity"] = can(Permission::canConnectPastMaxCapacity);
|
||||
values["id_can_kick"] = can(Permission::canKick);
|
||||
|
@ -144,6 +148,12 @@ QDebug operator<<(QDebug debug, const NodePermissions& perms) {
|
|||
if (perms.can(NodePermissions::Permission::canRezTemporaryEntities)) {
|
||||
debug << " rez-tmp";
|
||||
}
|
||||
if (perms.can(NodePermissions::Permission::canRezPermanentCertifiedEntities)) {
|
||||
debug << " rez-certified";
|
||||
}
|
||||
if (perms.can(NodePermissions::Permission::canRezTemporaryCertifiedEntities)) {
|
||||
debug << " rez-tmp-certified";
|
||||
}
|
||||
if (perms.can(NodePermissions::Permission::canWriteToAssetServer)) {
|
||||
debug << " asset-server";
|
||||
}
|
||||
|
|
|
@ -73,7 +73,9 @@ public:
|
|||
canWriteToAssetServer = 16,
|
||||
canConnectPastMaxCapacity = 32,
|
||||
canKick = 64,
|
||||
canReplaceDomainContent = 128
|
||||
canReplaceDomainContent = 128,
|
||||
canRezPermanentCertifiedEntities = 256,
|
||||
canRezTemporaryCertifiedEntities = 512
|
||||
};
|
||||
Q_DECLARE_FLAGS(Permissions, Permission)
|
||||
Permissions permissions;
|
||||
|
|
|
@ -122,6 +122,7 @@ public:
|
|||
ReplicatedKillAvatar,
|
||||
ReplicatedBulkAvatarData,
|
||||
OctreeFileReplacementFromUrl,
|
||||
ChallengeOwnership,
|
||||
NUM_PACKET_TYPE
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
// -WALLET_QML_SOURCE: The path to the Wallet QML
|
||||
// -onWalletScreen: true/false depending on whether we're looking at the app.
|
||||
var WALLET_QML_SOURCE = Script.resourcesPath() + "qml/hifi/commerce/wallet/Wallet.qml";
|
||||
var MARKETPLACE_PURCHASES_QML_PATH = Script.resourcesPath() + "qml/hifi/commerce/purchases/Purchases.qml";
|
||||
var onWalletScreen = false;
|
||||
function onButtonClicked() {
|
||||
if (!tablet) {
|
||||
|
@ -54,6 +55,7 @@
|
|||
// -Called when a message is received from SpectatorCamera.qml. The "message" argument is what is sent from the QML
|
||||
// in the format "{method, params}", like json-rpc. See also sendToQml().
|
||||
var isHmdPreviewDisabled = true;
|
||||
var MARKETPLACES_INJECT_SCRIPT_URL = Script.resolvePath("../html/js/marketplacesInject.js");
|
||||
function fromQml(message) {
|
||||
switch (message.method) {
|
||||
case 'passphrasePopup_cancelClicked':
|
||||
|
@ -79,6 +81,12 @@
|
|||
onButtonClicked();
|
||||
onButtonClicked();
|
||||
break;
|
||||
case 'transactionHistory_linkClicked':
|
||||
tablet.gotoWebScreen(message.marketplaceLink, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
break;
|
||||
case 'goToPurchases':
|
||||
tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH);
|
||||
break;
|
||||
default:
|
||||
print('Unrecognized message from QML:', JSON.stringify(message));
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
var isPreparing = false; // Explicitly track download request status.
|
||||
|
||||
var confirmAllPurchases = false; // Set this to "true" to cause Checkout.qml to popup for all items, even if free
|
||||
var userIsLoggedIn = false;
|
||||
|
||||
function injectCommonCode(isDirectoryPage) {
|
||||
|
||||
|
@ -90,23 +91,77 @@
|
|||
});
|
||||
}
|
||||
|
||||
function addPurchasesButton() {
|
||||
// Why isn't this an id?! This really shouldn't be a class on the website, but it is.
|
||||
var navbarBrandElement = document.getElementsByClassName('navbar-brand')[0];
|
||||
var purchasesElement = document.createElement('a');
|
||||
purchasesElement.classList.add("btn");
|
||||
purchasesElement.classList.add("btn-default");
|
||||
purchasesElement.id = "purchasesButton";
|
||||
purchasesElement.setAttribute('href', "#");
|
||||
purchasesElement.innerHTML = "PURCHASES";
|
||||
purchasesElement.style = "height:100%;margin-top:0;padding:15px 15px;";
|
||||
navbarBrandElement.parentNode.insertAdjacentElement('beforeend', purchasesElement);
|
||||
$('#purchasesButton').on('click', function () {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "PURCHASES",
|
||||
referrerURL: window.location.href
|
||||
}));
|
||||
});
|
||||
function maybeAddLogInButton() {
|
||||
if (!userIsLoggedIn) {
|
||||
var resultsElement = document.getElementById('results');
|
||||
var logInElement = document.createElement('div');
|
||||
logInElement.classList.add("row");
|
||||
logInElement.id = "logInDiv";
|
||||
logInElement.style = "height:60px;margin:20px 10px 10px 10px;padding:5px;" +
|
||||
"background-color:#D6F4D8;border-color:#aee9b2;border-width:2px;border-style:solid;border-radius:5px;";
|
||||
|
||||
var button = document.createElement('a');
|
||||
button.classList.add("btn");
|
||||
button.classList.add("btn-default");
|
||||
button.id = "logInButton";
|
||||
button.setAttribute('href', "#");
|
||||
button.innerHTML = "LOG IN";
|
||||
button.style = "width:80px;height:100%;margin-top:0;margin-left:10px;padding:13px;font-weight:bold;background:linear-gradient(white, #ccc);";
|
||||
button.onclick = function () {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "LOGIN"
|
||||
}));
|
||||
};
|
||||
|
||||
var span = document.createElement('span');
|
||||
span.style = "margin:10px;color:#1b6420;font-size:15px;";
|
||||
span.innerHTML = "to purchase items from the Marketplace.";
|
||||
|
||||
var xButton = document.createElement('a');
|
||||
xButton.id = "xButton";
|
||||
xButton.setAttribute('href', "#");
|
||||
xButton.style = "width:50px;height:100%;margin:0;color:#ccc;font-size:20px;";
|
||||
xButton.innerHTML = "X";
|
||||
xButton.onclick = function () {
|
||||
logInElement.remove();
|
||||
dummyRow.remove();
|
||||
};
|
||||
|
||||
logInElement.appendChild(button);
|
||||
logInElement.appendChild(span);
|
||||
logInElement.appendChild(xButton);
|
||||
|
||||
resultsElement.insertBefore(logInElement, resultsElement.firstChild);
|
||||
|
||||
// Dummy row for padding
|
||||
var dummyRow = document.createElement('div');
|
||||
dummyRow.classList.add("row");
|
||||
dummyRow.style = "height:15px;";
|
||||
resultsElement.insertBefore(dummyRow, resultsElement.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
function maybeAddPurchasesButton() {
|
||||
if (userIsLoggedIn) {
|
||||
// Why isn't this an id?! This really shouldn't be a class on the website, but it is.
|
||||
var navbarBrandElement = document.getElementsByClassName('navbar-brand')[0];
|
||||
var purchasesElement = document.createElement('a');
|
||||
var dropDownElement = document.getElementById('user-dropdown');
|
||||
purchasesElement.id = "purchasesButton";
|
||||
purchasesElement.setAttribute('href', "#");
|
||||
purchasesElement.innerHTML = "MY PURCHASES";
|
||||
// FRONTEND WEBDEV RANT: The username dropdown should REALLY not be programmed to be on the same
|
||||
// line as the search bar, overlaid on top of the search bar, floated right, and then relatively bumped up using "top:-50px".
|
||||
purchasesElement.style = "height:100%;margin-top:18px;font-weight:bold;float:right;margin-right:" + (dropDownElement.offsetWidth + 30) +
|
||||
"px;position:relative;z-index:999;";
|
||||
navbarBrandElement.parentNode.insertAdjacentElement('beforeend', purchasesElement);
|
||||
$('#purchasesButton').on('click', function () {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "PURCHASES",
|
||||
referrerURL: window.location.href
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function buyButtonClicked(id, name, author, price, href) {
|
||||
|
@ -123,6 +178,14 @@
|
|||
function injectBuyButtonOnMainPage() {
|
||||
var cost;
|
||||
|
||||
// Unbind original mouseenter and mouseleave behavior
|
||||
$('body').off('mouseenter', '#price-or-edit .price');
|
||||
$('body').off('mouseleave', '#price-or-edit .price');
|
||||
|
||||
$('.grid-item').find('#price-or-edit').each(function () {
|
||||
$(this).css({ "margin-top": "0" });
|
||||
});
|
||||
|
||||
$('.grid-item').find('#price-or-edit').find('a').each(function() {
|
||||
$(this).attr('data-href', $(this).attr('href'));
|
||||
$(this).attr('href', '#');
|
||||
|
@ -131,14 +194,36 @@
|
|||
$(this).closest('.col-xs-3').prev().attr("class", 'col-xs-6');
|
||||
$(this).closest('.col-xs-3').attr("class", 'col-xs-6');
|
||||
|
||||
var priceElement = $(this).find('.price')
|
||||
priceElement.css({
|
||||
"padding": "3px 5px",
|
||||
"height": "40px",
|
||||
"background": "linear-gradient(#00b4ef, #0093C5)",
|
||||
"color": "#FFF",
|
||||
"font-weight": "600",
|
||||
"line-height": "34px"
|
||||
});
|
||||
|
||||
if (parseInt(cost) > 0) {
|
||||
var priceElement = $(this).find('.price')
|
||||
priceElement.css({ "width": "auto", "padding": "3px 5px", "height": "26px" });
|
||||
priceElement.text(cost + ' HFC');
|
||||
priceElement.css({ "min-width": priceElement.width() + 10 });
|
||||
priceElement.css({ "width": "auto" });
|
||||
priceElement.html('<span class="hifi-glyph hifi-glyph-hfc" style="filter:invert(1);background-size:20px;' +
|
||||
'width:20px;height:20px;position:relative;top:5px;"></span> ' + cost);
|
||||
priceElement.css({ "min-width": priceElement.width() + 30 });
|
||||
}
|
||||
});
|
||||
|
||||
// change pricing to GET on button hover
|
||||
$('body').on('mouseenter', '#price-or-edit .price', function () {
|
||||
var $this = $(this);
|
||||
$this.data('initialHtml', $this.html());
|
||||
$this.text('GET');
|
||||
});
|
||||
|
||||
$('body').on('mouseleave', '#price-or-edit .price', function () {
|
||||
var $this = $(this);
|
||||
$this.html($this.data('initialHtml'));
|
||||
});
|
||||
|
||||
|
||||
$('.grid-item').find('#price-or-edit').find('a').on('click', function () {
|
||||
buyButtonClicked($(this).closest('.grid-item').attr('data-item-id'),
|
||||
|
@ -151,6 +236,9 @@
|
|||
|
||||
function injectHiFiCode() {
|
||||
if (confirmAllPurchases) {
|
||||
|
||||
maybeAddLogInButton();
|
||||
|
||||
var target = document.getElementById('templated-items');
|
||||
// MutationObserver is necessary because the DOM is populated after the page is loaded.
|
||||
// We're searching for changes to the element whose ID is '#templated-items' - this is
|
||||
|
@ -167,30 +255,41 @@
|
|||
// Try this here in case it works (it will if the user just pressed the "back" button,
|
||||
// since that doesn't trigger another AJAX request.
|
||||
injectBuyButtonOnMainPage();
|
||||
addPurchasesButton();
|
||||
maybeAddPurchasesButton();
|
||||
}
|
||||
}
|
||||
|
||||
function injectHiFiItemPageCode() {
|
||||
if (confirmAllPurchases) {
|
||||
var href = $('#side-info').find('.btn').first().attr('href');
|
||||
$('#side-info').find('.btn').first().attr('href', '#');
|
||||
|
||||
maybeAddLogInButton();
|
||||
|
||||
var purchaseButton = $('#side-info').find('.btn').first();
|
||||
|
||||
var href = purchaseButton.attr('href');
|
||||
purchaseButton.attr('href', '#');
|
||||
purchaseButton.css({
|
||||
"background": "linear-gradient(#00b4ef, #0093C5)",
|
||||
"color": "#FFF",
|
||||
"font-weight": "600",
|
||||
"padding-bottom": "10px"
|
||||
});
|
||||
|
||||
var cost = $('.item-cost').text();
|
||||
|
||||
if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) {
|
||||
$('#side-info').find('.btn').first().html('<span class="glyphicon glyphicon-download" id="buyItemButton"></span>Own Item: ' + cost + ' HFC');
|
||||
|
||||
purchaseButton.html('PURCHASE <span class="hifi-glyph hifi-glyph-hfc" style="filter:invert(1);background-size:20px;' +
|
||||
'width:20px;height:20px;position:relative;top:5px;"></span> ' + cost);
|
||||
}
|
||||
|
||||
$('#side-info').find('.btn').first().on('click', function () {
|
||||
purchaseButton.on('click', function () {
|
||||
buyButtonClicked(window.location.pathname.split("/")[3],
|
||||
$('#top-center').find('h1').text(),
|
||||
$('#creator').find('.value').text(),
|
||||
cost,
|
||||
href);
|
||||
});
|
||||
addPurchasesButton();
|
||||
maybeAddPurchasesButton();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,7 +550,8 @@
|
|||
|
||||
if (parsedJsonMessage.type === "marketplaces") {
|
||||
if (parsedJsonMessage.action === "commerceSetting") {
|
||||
confirmAllPurchases = !!parsedJsonMessage.data;
|
||||
confirmAllPurchases = !!parsedJsonMessage.data.commerceMode;
|
||||
userIsLoggedIn = !!parsedJsonMessage.data.userIsLoggedIn
|
||||
injectCode();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
var MARKETPLACE_CHECKOUT_QML_PATH = Script.resourcesPath() + "qml/hifi/commerce/checkout/Checkout.qml";
|
||||
var MARKETPLACE_PURCHASES_QML_PATH = Script.resourcesPath() + "qml/hifi/commerce/purchases/Purchases.qml";
|
||||
var MARKETPLACE_WALLET_QML_PATH = Script.resourcesPath() + "qml/hifi/commerce/wallet/Wallet.qml";
|
||||
var MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH = "commerce/inspectionCertificate/InspectionCertificate.qml";
|
||||
|
||||
var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
|
||||
// var HOME_BUTTON_TEXTURE = Script.resourcesPath() + "meshes/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
|
||||
|
@ -56,10 +57,26 @@
|
|||
Window.messageBoxClosed.connect(onMessageBoxClosed);
|
||||
|
||||
var onMarketplaceScreen = false;
|
||||
var onCommerceScreen = false;
|
||||
|
||||
var debugCheckout = false;
|
||||
function showMarketplace() {
|
||||
UserActivityLogger.openedMarketplace();
|
||||
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
if (!debugCheckout) {
|
||||
UserActivityLogger.openedMarketplace();
|
||||
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
} else {
|
||||
tablet.pushOntoStack(MARKETPLACE_CHECKOUT_QML_PATH);
|
||||
tablet.sendToQml({
|
||||
method: 'updateCheckoutQML', params: {
|
||||
itemId: '0d90d21c-ce7a-4990-ad18-e9d2cf991027',
|
||||
itemName: 'Test Flaregun',
|
||||
itemAuthor: 'hifiDave',
|
||||
itemPrice: 17,
|
||||
itemHref: 'http://mpassets.highfidelity.com/0d90d21c-ce7a-4990-ad18-e9d2cf991027-v1/flaregun.json',
|
||||
},
|
||||
canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
|
@ -76,7 +93,7 @@
|
|||
}
|
||||
|
||||
function onClick() {
|
||||
if (onMarketplaceScreen) {
|
||||
if (onMarketplaceScreen || onCommerceScreen) {
|
||||
// for toolbar-mode: go back to home screen, this will close the window.
|
||||
tablet.gotoHomeScreen();
|
||||
} else {
|
||||
|
@ -86,11 +103,24 @@
|
|||
}
|
||||
}
|
||||
|
||||
var referrerURL; // Used for updating Purchases QML
|
||||
var filterText; // Used for updating Purchases QML
|
||||
function onScreenChanged(type, url) {
|
||||
onMarketplaceScreen = type === "Web" && url === MARKETPLACE_URL_INITIAL;
|
||||
wireEventBridge(type === "QML" && (url === MARKETPLACE_CHECKOUT_QML_PATH || url === MARKETPLACE_PURCHASES_QML_PATH));
|
||||
onCommerceScreen = type === "QML" && (url === MARKETPLACE_CHECKOUT_QML_PATH || url === MARKETPLACE_PURCHASES_QML_PATH || url.indexOf(MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH) !== -1);
|
||||
wireEventBridge(onCommerceScreen);
|
||||
|
||||
if (url === MARKETPLACE_PURCHASES_QML_PATH) {
|
||||
tablet.sendToQml({
|
||||
method: 'updatePurchases',
|
||||
canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified,
|
||||
referrerURL: referrerURL,
|
||||
filterText: filterText
|
||||
});
|
||||
}
|
||||
|
||||
// for toolbar mode: change button to active when window is first openend, false otherwise.
|
||||
marketplaceButton.editProperties({ isActive: onMarketplaceScreen });
|
||||
marketplaceButton.editProperties({ isActive: onMarketplaceScreen || onCommerceScreen });
|
||||
if (type === "Web" && url.indexOf(MARKETPLACE_URL) !== -1) {
|
||||
ContextOverlay.isInMarketplaceInspectionMode = true;
|
||||
} else {
|
||||
|
@ -98,9 +128,36 @@
|
|||
}
|
||||
}
|
||||
|
||||
function setCertificateInfo(currentEntityWithContextOverlay, itemMarketplaceId, closeGoesToPurchases) {
|
||||
wireEventBridge(true);
|
||||
tablet.sendToQml({
|
||||
method: 'inspectionCertificate_setMarketplaceId',
|
||||
marketplaceId: itemMarketplaceId || Entities.getEntityProperties(currentEntityWithContextOverlay, ['marketplaceID']).marketplaceID,
|
||||
closeGoesToPurchases: closeGoesToPurchases
|
||||
});
|
||||
// ZRF FIXME! Make a call to the endpoint to get item info instead of this silliness
|
||||
Script.setTimeout(function () {
|
||||
var randomNumber = Math.floor((Math.random() * 150) + 1);
|
||||
tablet.sendToQml({
|
||||
method: 'inspectionCertificate_setItemInfo',
|
||||
itemName: "The Greatest Item",
|
||||
itemOwner: "ABCDEFG1234567",
|
||||
itemEdition: (Math.floor(Math.random() * randomNumber) + " / " + randomNumber)
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function onUsernameChanged() {
|
||||
if (onMarketplaceScreen) {
|
||||
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
}
|
||||
}
|
||||
|
||||
marketplaceButton.clicked.connect(onClick);
|
||||
tablet.screenChanged.connect(onScreenChanged);
|
||||
Entities.canWriteAssetsChanged.connect(onCanWriteAssetsChanged);
|
||||
ContextOverlay.contextOverlayClicked.connect(setCertificateInfo);
|
||||
GlobalServices.myUsernameChanged.connect(onUsernameChanged);
|
||||
|
||||
function onMessage(message) {
|
||||
|
||||
|
@ -133,20 +190,28 @@
|
|||
} else {
|
||||
var parsedJsonMessage = JSON.parse(message);
|
||||
if (parsedJsonMessage.type === "CHECKOUT") {
|
||||
wireEventBridge(true);
|
||||
tablet.pushOntoStack(MARKETPLACE_CHECKOUT_QML_PATH);
|
||||
tablet.sendToQml({ method: 'updateCheckoutQML', params: parsedJsonMessage });
|
||||
tablet.sendToQml({
|
||||
method: 'updateCheckoutQML',
|
||||
params: parsedJsonMessage,
|
||||
canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified
|
||||
});
|
||||
} else if (parsedJsonMessage.type === "REQUEST_SETTING") {
|
||||
tablet.emitScriptEvent(JSON.stringify({
|
||||
type: "marketplaces",
|
||||
action: "commerceSetting",
|
||||
data: Settings.getValue("commerce", false)
|
||||
data: {
|
||||
commerceMode: Settings.getValue("commerce", false),
|
||||
userIsLoggedIn: Account.loggedIn
|
||||
}
|
||||
}));
|
||||
} else if (parsedJsonMessage.type === "PURCHASES") {
|
||||
referrerURL = parsedJsonMessage.referrerURL;
|
||||
filterText = "";
|
||||
tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH);
|
||||
tablet.sendToQml({
|
||||
method: 'updatePurchases',
|
||||
referrerURL: parsedJsonMessage.referrerURL
|
||||
});
|
||||
} else if (parsedJsonMessage.type === "LOGIN") {
|
||||
openLoginWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,13 +219,15 @@
|
|||
tablet.webEventReceived.connect(onMessage);
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
if (onMarketplaceScreen) {
|
||||
if (onMarketplaceScreen || onCommerceScreen) {
|
||||
tablet.gotoHomeScreen();
|
||||
}
|
||||
tablet.removeButton(marketplaceButton);
|
||||
tablet.screenChanged.disconnect(onScreenChanged);
|
||||
ContextOverlay.contextOverlayClicked.disconnect(setCertificateInfo);
|
||||
tablet.webEventReceived.disconnect(onMessage);
|
||||
Entities.canWriteAssetsChanged.disconnect(onCanWriteAssetsChanged);
|
||||
GlobalServices.myUsernameChanged.disconnect(onUsernameChanged);
|
||||
});
|
||||
|
||||
|
||||
|
@ -200,22 +267,33 @@
|
|||
var isHmdPreviewDisabled = true;
|
||||
function fromQml(message) {
|
||||
switch (message.method) {
|
||||
case 'purchases_openWallet':
|
||||
case 'checkout_openWallet':
|
||||
case 'checkout_setUpClicked':
|
||||
tablet.pushOntoStack(MARKETPLACE_WALLET_QML_PATH);
|
||||
break;
|
||||
case 'purchases_walletNotSetUp':
|
||||
case 'checkout_walletNotSetUp':
|
||||
wireEventBridge(true);
|
||||
tablet.sendToQml({
|
||||
method: 'updateWalletReferrer',
|
||||
referrer: "purchases"
|
||||
});
|
||||
tablet.pushOntoStack(MARKETPLACE_WALLET_QML_PATH);
|
||||
break;
|
||||
case 'checkout_cancelClicked':
|
||||
tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.params, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
// TODO: Make Marketplace a QML app that's a WebView wrapper so we can use the app stack.
|
||||
// I don't think this is trivial to do since we also want to inject some JS into the DOM.
|
||||
//tablet.popFromStack();
|
||||
break;
|
||||
case 'header_goToPurchases':
|
||||
case 'checkout_goToPurchases':
|
||||
referrerURL = MARKETPLACE_URL_INITIAL;
|
||||
filterText = message.filterText;
|
||||
tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH);
|
||||
tablet.sendToQml({
|
||||
method: 'updatePurchases',
|
||||
referrerURL: MARKETPLACE_URL_INITIAL
|
||||
});
|
||||
break;
|
||||
case 'checkout_itemLinkClicked':
|
||||
case 'checkout_continueShopping':
|
||||
tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.itemId, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
//tablet.popFromStack();
|
||||
|
@ -226,6 +304,7 @@
|
|||
tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + itemId, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
}
|
||||
break;
|
||||
case 'header_marketplaceImageClicked':
|
||||
case 'purchases_backClicked':
|
||||
tablet.gotoWebScreen(message.referrerURL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
break;
|
||||
|
@ -246,6 +325,37 @@
|
|||
case 'maybeEnableHmdPreview':
|
||||
Menu.setIsOptionChecked("Disable Preview", isHmdPreviewDisabled);
|
||||
break;
|
||||
case 'purchases_getIsFirstUse':
|
||||
tablet.sendToQml({
|
||||
method: 'purchases_getIsFirstUseResult',
|
||||
isFirstUseOfPurchases: Settings.getValue("isFirstUseOfPurchases", true)
|
||||
});
|
||||
break;
|
||||
case 'purchases_setIsFirstUse':
|
||||
Settings.setValue("isFirstUseOfPurchases", false);
|
||||
break;
|
||||
case 'purchases_openGoTo':
|
||||
tablet.loadQMLSource("TabletAddressDialog.qml");
|
||||
break;
|
||||
case 'purchases_itemCertificateClicked':
|
||||
tablet.loadQMLSource("../commerce/inspectionCertificate/InspectionCertificate.qml");
|
||||
setCertificateInfo("", message.itemMarketplaceId, true);
|
||||
break;
|
||||
case 'inspectionCertificate_closeClicked':
|
||||
if (message.closeGoesToPurchases) {
|
||||
referrerURL = MARKETPLACE_URL_INITIAL;
|
||||
filterText = "";
|
||||
tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH);
|
||||
} else {
|
||||
tablet.gotoHomeScreen();
|
||||
}
|
||||
break;
|
||||
case 'inspectionCertificate_showInMarketplaceClicked':
|
||||
tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.itemId, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
break;
|
||||
case 'header_myItemsClicked':
|
||||
tablet.gotoWebScreen(MARKETPLACE_URL + '?view=mine', MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
break;
|
||||
default:
|
||||
print('Unrecognized message from Checkout.qml or Purchases.qml: ' + JSON.stringify(message));
|
||||
}
|
||||
|
|