Initial progress

This commit is contained in:
Zach Fox 2017-08-17 15:01:25 -07:00
parent a4123e3024
commit eab16fc28c
9 changed files with 865 additions and 4 deletions

View file

@ -0,0 +1,102 @@
//
// SecurityImageSelection.qml
// qml/hifi/commerce/wallet
//
// SecurityImageSelection
//
// 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
Item {
HifiConstants { id: hifi; }
id: root;
anchors.fill: parent;
visible: false;
Hifi.QmlCommerce {
id: commerce;
onSecurityImageResult: {
if (imageID > 0) {
for (var itr = 0; itr < gridModel.count; itr++) {
var thisValue = gridModel.get(itr).securityImageEnumValue;
if (thisValue === imageID) {
securityImageGrid.currentIndex = itr;
break;
}
}
}
}
}
Component.onCompleted: {
commerce.getSecurityImage();
}
SecurityImageModel {
id: gridModel;
}
GridView {
id: securityImageGrid;
clip: true;
// Anchors
anchors.fill: parent;
currentIndex: -1;
cellWidth: width / 3;
cellHeight: height / 2;
model: gridModel;
delegate: Item {
width: securityImageGrid.cellWidth;
height: securityImageGrid.cellHeight;
Item {
anchors.fill: parent;
Image {
width: parent.width - 8;
height: parent.height - 8;
source: sourcePath;
anchors.horizontalCenter: parent.horizontalCenter;
anchors.verticalCenter: parent.verticalCenter;
fillMode: Image.PreserveAspectFit;
mipmap: true;
}
}
MouseArea {
anchors.fill: parent;
onClicked: {
securityImageGrid.currentIndex = index;
}
}
}
highlight: Rectangle {
width: securityImageGrid.cellWidth;
height: securityImageGrid.cellHeight;
color: hifi.colors.blueHighlight;
}
}
//
// FUNCTION DEFINITIONS START
//
signal sendToScript(var message);
function getImagePathFromImageID(imageID) {
return (imageID ? gridModel.get(imageID - 1).sourcePath : "");
}
//
// FUNCTION DEFINITIONS END
//
}

View file

@ -0,0 +1,199 @@
//
// Wallet.qml
// qml/hifi/commerce/wallet
//
// Wallet
//
// 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;
// Style
color: hifi.colors.baseGray;
Hifi.QmlCommerce {
id: commerce;
onBalanceResult: {
if (failureMessage.length) {
console.log("Failed to get balance", failureMessage);
} else {
hfcBalanceText.text = balance;
}
}
onSecurityImageResult: {
securityImage.source = securityImageSelection.getImagePathFromImageID(imageID);
}
}
//
// TITLE BAR START
//
Item {
id: titleBarContainer;
// Size
width: parent.width;
height: 50;
// Anchors
anchors.left: parent.left;
anchors.top: parent.top;
// Title Bar text
RalewaySemiBold {
id: titleBarText;
text: "WALLET";
// 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.lightGrayText;
// Alignment
horizontalAlignment: Text.AlignHLeft;
verticalAlignment: Text.AlignVCenter;
}
// Separator
HifiControlsUit.Separator {
anchors.left: parent.left;
anchors.right: parent.right;
anchors.bottom: parent.bottom;
}
}
//
// TITLE BAR END
//
//
// TAB CONTENTS START
//
//
// TAB CONTENTS END
//
//
// TAB BUTTONS START
//
Item {
id: tabButtonsContainer;
property int numTabs: 4;
// Size
width: root.width;
height: 80;
// Anchors
anchors.left: parent.left;
anchors.bottom: parent.bottom;
anchors.bottomMargin: 8;
// Separator
HifiControlsUit.Separator {
anchors.left: parent.left;
anchors.right: parent.right;
anchors.top: parent.top;
}
// "ACCOUNT HOME" tab button
Rectangle {
id: accountHomeButtonContainer;
color: hifi.buttons.black;
anchors.top: parent.top;
anchors.left: parent.left;
anchors.bottom: parent.bottom;
width: parent.width / tabButtonsContainer.numTabs;
onClicked: {
// Show this tab
}
}
// "SEND MONEY" tab button
Rectangle {
id: sendMoneyButtonContainer;
color: hifi.buttons.black;
anchors.top: parent.top;
anchors.left: accountHomeButtonContainer.right;
anchors.bottom: parent.bottom;
width: parent.width / tabButtonsContainer.numTabs;
onClicked: {
// Show this tab
}
}
// "SECURITY" tab button
Rectangle {
id: securityButtonContainer;
color: hifi.buttons.black;
anchors.top: parent.top;
anchors.left: sendMoneyButtonContainer.right;
anchors.bottom: parent.bottom;
width: parent.width / tabButtonsContainer.numTabs;
onClicked: {
// Show this tab
}
}
// "HELP" tab button
Rectangle {
id: helpButtonContainer;
color: hifi.buttons.black;
anchors.top: parent.top;
anchors.left: securityButtonContainer.right;
anchors.bottom: parent.bottom;
width: parent.width / tabButtonsContainer.numTabs;
onClicked: {
// Show this tab
}
}
}
//
// TAB BUTTONS 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 sendToScript(var message);
//
// FUNCTION DEFINITIONS END
//
}

View file

@ -0,0 +1,413 @@
//
// 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 int stepNumber: 0;
// Style
color: hifi.colors.white;
Hifi.QmlCommerce {
id: commerce;
onLoginStatusResult: {
if (isLoggedIn) {
loginPageContainer.visible = false;
commerce.getSecurityImage();
} else {
loginPageContainer.visible = true;
}
}
onSecurityImageResult: {
loginPageContainer.visible = false;
if (imageID !== 0) { // "If security image is set up"
commerce.getPassphraseSetupStatus();
passphrasePageSecurityImage.source = securityImageSelection.getImagePathFromImageID(imageID);
} else {
securityImageContainer.visible = true;
}
}
onPassphraseSetupStatusResult: {
securityImageContainer.visible = false;
if (passphraseIsSetup) {
privateKeysReadyContainer.visible = true;
} else {
choosePassphraseContainer.visible = true;
}
}
}
//
// LOGIN PAGE START
//
Item {
id: loginPageContainer;
visible: false;
// Anchors
anchors.fill: parent;
Component.onCompleted: {
commerce.getLoginStatus();
}
Item {
// Size
width: parent.width;
height: 50;
// Anchors
anchors.left: parent.left;
anchors.top: parent.top;
// Title Bar text
RalewaySemiBold {
text: "WALLET SETUP - LOGIN";
// 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.lightGrayText;
// 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: {
}
}
}
}
//
// LOGIN PAGE END
//
//
// SECURITY IMAGE SELECTION START
//
Item {
id: securityImageContainer;
visible: false;
// 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.lightGrayText;
// Alignment
horizontalAlignment: Text.AlignHLeft;
verticalAlignment: Text.AlignVCenter;
}
}
// Text below title bar
RalewaySemiBold {
id: securityImageTitleHelper;
text: "Choose a Security Picture";
// Text size
size: hifi.fontSizes.overlayTitle;
// Anchors
anchors.top: securityImageTitle.bottom;
anchors.left: parent.left;
anchors.leftMargin: 16;
height: 50;
width: paintedWidth;
// Style
color: hifi.colors.lightGrayText;
// Alignment
horizontalAlignment: Text.AlignHLeft;
verticalAlignment: Text.AlignVCenter;
}
SecurityImageSelection {
id: securityImageSelection;
// Anchors
anchors.top: securityImageTitleHelper.bottom;
anchors.left: parent.left;
anchors.right: parent.right;
height: 350;
}
// 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: {
}
}
// "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: {
}
}
}
}
//
// SECURITY IMAGE SELECTION END
//
//
// SECURE PASSPHRASE SELECTION START
//
Item {
id: choosePassphraseContainer;
visible: false;
// Anchors
anchors.fill: parent;
Item {
// 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.lightGrayText;
// 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;
// "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: {
}
}
// Security Image
Image {
id: passphrasePageSecurityImage;
// Anchors
anchors.top: parent.top;
anchors.topMargin: 3;
anchors.right: passphrasePageNextButton.left;
height: passphrasePageNextButton.height;
width: height;
anchors.verticalCenter: parent.verticalCenter;
fillMode: Image.PreserveAspectFit;
mipmap: 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: {
}
}
}
}
//
// SECURE PASSPHRASE SELECTION END
//
//
// PRIVATE KEYS READY START
//
Item {
id: privateKeysReadyContainer;
visible: false;
// Anchors
anchors.fill: parent;
Item {
// 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.lightGrayText;
// Alignment
horizontalAlignment: Text.AlignHLeft;
verticalAlignment: Text.AlignVCenter;
}
}
}
//
// PRIVATE KEYS READY 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 sendToScript(var message);
//
// FUNCTION DEFINITIONS END
//
}

View file

@ -14,6 +14,7 @@
#include "DependencyManager.h"
#include "Ledger.h"
#include "Wallet.h"
#include <AccountManager.h>
HIFI_QML_DEF(QmlCommerce)
@ -59,4 +60,10 @@ void QmlCommerce::chooseSecurityImage(uint imageID) {
void QmlCommerce::getSecurityImage() {
auto wallet = DependencyManager::get<Wallet>();
wallet->getSecurityImage();
}
}
void QmlCommerce::getLoginStatus() {
emit loginStatusResult(DependencyManager::get<AccountManager>()->isLoggedIn());
}
void QmlCommerce::getPassphraseSetupStatus() {
emit passphraseSetupStatusResult(false);
}

View file

@ -31,6 +31,8 @@ signals:
void balanceResult(int balance, const QString& failureMessage);
void inventoryResult(QJsonObject inventory, const QString& failureMessage);
void securityImageResult(uint imageID);
void loginStatusResult(bool isSetup);
void passphraseSetupStatusResult(bool passphraseIsSetup);
protected:
Q_INVOKABLE void buy(const QString& assetId, int cost, const QString& buyerUsername = "");
@ -38,6 +40,8 @@ protected:
Q_INVOKABLE void inventory();
Q_INVOKABLE void chooseSecurityImage(uint imageID);
Q_INVOKABLE void getSecurityImage();
Q_INVOKABLE void getLoginStatus();
Q_INVOKABLE void getPassphraseSetupStatus();
};
#endif // hifi_QmlCommerce_h

View file

@ -36,7 +36,7 @@ void HFTabletWebEngineRequestInterceptor::interceptRequest(QWebEngineUrlRequestI
}
static const QString USER_AGENT = "User-Agent";
QString tokenString = "Chrome/48.0 (HighFidelityInterface)";
QString tokenString = "Chrome/48.0 (HighFidelityInterface WithHFC)";
info.setHttpHeader(USER_AGENT.toLocal8Bit(), tokenString.toLocal8Bit());
} else {
static const QString USER_AGENT = "User-Agent";

View file

@ -28,7 +28,8 @@ var DEFAULT_SCRIPTS_COMBINED = [
"system/notifications.js",
"system/dialTone.js",
"system/firstPersonHMD.js",
"system/tablet-ui/tabletUI.js"
"system/tablet-ui/tabletUI.js",
"system/commerce/wallet.js"
];
var DEFAULT_SCRIPTS_SEPARATE = [
"system/controllers/controllerScripts.js",

View file

@ -0,0 +1,135 @@
"use strict";
/*jslint vars:true, plusplus:true, forin:true*/
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
//
// wallet.js
//
// 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
//
/*global XXX */
(function () { // BEGIN LOCAL_SCOPE
// Function Name: buttonClicked()
//
// Description:
// -Fired when the app button is pressed.
//
// Relevant Variables:
// -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 onWalletScreen = false;
function buttonClicked() {
if (!tablet) {
print("Warning in buttonClicked(): 'tablet' undefined!");
return;
}
if (onWalletScreen) {
// for toolbar-mode: go back to home screen, this will close the window.
tablet.gotoHomeScreen();
} else {
tablet.loadQMLSource(WALLET_QML_SOURCE);
}
}
// Function Name: sendToQml()
//
// Description:
// -Use this function to send a message to the QML (i.e. to change appearances). The "message" argument is what is sent to
// the QML in the format "{method, params}", like json-rpc. See also fromQml().
function sendToQml(message) {
tablet.sendToQml(message);
}
// Function Name: fromQml()
//
// Description:
// -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().
function fromQml(message) {
switch (message.method) {
default:
print('Unrecognized message from QML:', JSON.stringify(message));
}
}
// Function Name: wireEventBridge()
//
// Description:
// -Used to connect/disconnect the script's response to the tablet's "fromQml" signal. Set the "on" argument to enable or
// disable to event bridge.
//
// Relevant Variables:
// -hasEventBridge: true/false depending on whether we've already connected the event bridge.
var hasEventBridge = false;
function wireEventBridge(on) {
if (!tablet) {
print("Warning in wireEventBridge(): 'tablet' undefined!");
return;
}
if (on) {
if (!hasEventBridge) {
tablet.fromQml.connect(fromQml);
hasEventBridge = true;
}
} else {
if (hasEventBridge) {
tablet.fromQml.disconnect(fromQml);
hasEventBridge = false;
}
}
}
// Function Name: onTabletScreenChanged()
//
// Description:
// -Called when the TabletScriptingInterface::screenChanged() signal is emitted. The "type" argument can be either the string
// value of "Home", "Web", "Menu", "QML", or "Closed". The "url" argument is only valid for Web and QML.
function onTabletScreenChanged(type, url) {
onWalletScreen = (type === "QML" && url === SPECTATOR_CAMERA_QML_SOURCE);
wireEventBridge(onWalletScreen);
// Change button to active when window is first openend, false otherwise.
if (button) {
button.editProperties({ isActive: onWalletScreen });
}
}
//
// Manage the connection between the button and the window.
//
var button;
var buttonName = "WALLET";
var tablet = null;
function startup() {
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
button = tablet.addButton({
text: buttonName
});
button.clicked.connect(onButtonClicked);
tablet.screenChanged.connect(onTabletScreenChanged);
}
function shutdown() {
button.clicked.disconnect(onButtonClicked);
tablet.removeButton(button);
if (tablet) {
tablet.screenChanged.disconnect(onTabletScreenChanged);
if (onWalletScreen) {
tablet.gotoHomeScreen();
}
}
}
//
// Run the functions.
//
startup();
Script.scriptEnding.connect(shutdown);
}()); // END LOCAL_SCOPE

View file

@ -153,7 +153,7 @@
// -showSpectatorInDesktop: Set to "true" to show the "SPECTATOR" app in desktop mode.
var button = false;
var buttonName = "SPECTATOR";
var showSpectatorInDesktop = false;
var showSpectatorInDesktop = true;
function addOrRemoveButton(isShuttingDown, isHMDMode) {
if (!tablet) {
print("Warning in addOrRemoveButton(): 'tablet' undefined!");