From a6259a5ef5cbc4af133ac9ccfcfd6f43207542fa Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 9 Jan 2018 13:39:28 -0800 Subject: [PATCH 01/26] Initial progress --- .../qml/hifi/commerce/wallet/SendMoney.qml | 73 ----- .../qml/hifi/commerce/wallet/Wallet.qml | 26 +- .../commerce/wallet/sendMoney/SendMoney.qml | 286 ++++++++++++++++++ interface/src/Application.cpp | 2 +- 4 files changed, 306 insertions(+), 81 deletions(-) delete mode 100644 interface/resources/qml/hifi/commerce/wallet/SendMoney.qml create mode 100644 interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml diff --git a/interface/resources/qml/hifi/commerce/wallet/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/SendMoney.qml deleted file mode 100644 index 11a6c99b0c..0000000000 --- a/interface/resources/qml/hifi/commerce/wallet/SendMoney.qml +++ /dev/null @@ -1,73 +0,0 @@ -// -// SendMoney.qml -// qml/hifi/commerce/wallet -// -// SendMoney -// -// 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; - - Connections { - target: Commerce; - } - - // "Unavailable" - RalewayRegular { - text: "You currently cannot send money to other High Fidelity users."; - // Anchors - anchors.fill: parent; - // Text size - size: 24; - // Style - color: hifi.colors.faintGray; - wrapMode: Text.WordWrap; - // Alignment - horizontalAlignment: Text.AlignHCenter; - verticalAlignment: Text.AlignVCenter; - } - - // - // 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 - // -} diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index ef2b007dc8..c2ac2e19a1 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -19,6 +19,7 @@ import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls import "../common" as HifiCommerceCommon +import "./sendMoney" // references XXX from root context @@ -324,10 +325,9 @@ Rectangle { SendMoney { id: sendMoney; visible: root.activeView === "sendMoney"; - anchors.top: titleBarContainer.bottom; - anchors.bottom: tabButtonsContainer.top; - anchors.left: parent.left; - anchors.right: parent.right; + anchors.fill: parent; + parentAppTitleBarHeight: titleBarContainer.height; + parentAppNavBarHeight: tabButtonsContainer.height; } Security { @@ -497,7 +497,7 @@ Rectangle { Rectangle { id: sendMoneyButtonContainer; visible: !walletSetup.visible; - color: hifi.colors.black; + color: root.activeView === "sendMoney" ? hifi.colors.blueAccent : hifi.colors.black; anchors.top: parent.top; anchors.left: exchangeMoneyButtonContainer.right; anchors.bottom: parent.bottom; @@ -513,7 +513,7 @@ Rectangle { anchors.top: parent.top; anchors.topMargin: -2; // Style - color: hifi.colors.lightGray50; + color: root.activeView === "sendMoney" || sendMoneyTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight; } RalewaySemiBold { @@ -528,12 +528,24 @@ Rectangle { anchors.right: parent.right; anchors.rightMargin: 4; // Style - color: hifi.colors.lightGray50; + color: root.activeView === "sendMoney" || sendMoneyTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight; wrapMode: Text.WordWrap; // Alignment horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignTop; } + + MouseArea { + id: sendMoneyTabMouseArea; + anchors.fill: parent; + hoverEnabled: enabled; + onClicked: { + root.activeView = "sendMoney"; + tabButtonsContainer.resetTabButtonColors(); + } + onEntered: parent.color = hifi.colors.blueHighlight; + onExited: parent.color = root.activeView === "sendMoney" ? hifi.colors.blueAccent : hifi.colors.black; + } } // "SECURITY" tab button diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml new file mode 100644 index 0000000000..e8339266f7 --- /dev/null +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -0,0 +1,286 @@ +// +// SendMoney.qml +// qml/hifi/commerce/wallet/sendMoney +// +// SendMoney +// +// Created by Zach Fox on 2018-01-09 +// Copyright 2018 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 "../../common" as HifiCommerceCommon + +// references XXX from root context + +Item { + HifiConstants { id: hifi; } + + id: root; + + property int parentAppTitleBarHeight; + property int parentAppNavBarHeight; + property string activeView: "sendMoneyHome"; + + Connections { + target: Commerce; + + onBalanceResult : { + balanceText.text = result.data.balance; + } + } + + Connections { + target: GlobalServices + onMyUsernameChanged: { + transactionHistoryModel.clear(); + usernameText.text = Account.username; + } + } + + // Send Money Home BEGIN + Item { + id: sendMoneyHome; + visible: root.activeView === "sendMoneyHome"; + anchors.fill: parent; + anchors.topMargin: parentAppTitleBarHeight; + anchors.bottomMargin: parentAppNavBarHeight; + + // 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; + } + + // HFC Balance Container + Item { + id: hfcBalanceContainer; + // Anchors + anchors.top: parent.top; + anchors.right: parent.right; + 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; + } + + // 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) { + Commerce.balance(); + } + } + } + + // "balance" text below field + RalewayRegular { + text: "BALANCE (HFC)"; + // Text size + size: 14; + // Anchors + 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.white; + } + } + + // Send Money + Rectangle { + id: sendMoneyContainer; + anchors.left: parent.left; + anchors.right: parent.right; + anchors.bottom: parent.bottom; + height: 440; + + + RalewaySemiBold { + id: sendMoneyText; + text: "Send Money To:"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 26; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: paintedWidth; + height: 30; + // Text size + size: 22; + // Style + color: hifi.colors.baseGrayHighlight; + } + + Item { + id: connectionButton; + // Anchors + anchors.top: sendMoneyText.bottom; + anchors.topMargin: 40; + anchors.left: parent.left; + anchors.leftMargin: 75; + height: 95; + width: 95; + + Image { + anchors.top: parent.top; + source: "../images/wallet-bg.jpg"; + height: 60; + width: parent.width; + fillMode: Image.PreserveAspectFit; + horizontalAlignment: Image.AlignHCenter; + verticalAlignment: Image.AlignTop; + } + + RalewaySemiBold { + text: "Connection"; + // Anchors + anchors.bottom: parent.bottom; + height: 15; + width: parent.width; + // Text size + size: 18; + // Style + color: hifi.colors.baseGrayHighlight; + horizontalAlignment: Text.AlignHCenter; + } + + MouseArea { + anchors.fill: parent; + onClicked: { + root.activeView = "chooseRecipientConnection"; + } + } + } + + Item { + id: nearbyButton; + // Anchors + anchors.top: sendMoneyText.bottom; + anchors.topMargin: connectionButton.anchors.topMargin; + anchors.right: parent.right; + anchors.rightMargin: connectionButton.anchors.leftMargin; + height: connectionButton.height; + width: connectionButton.width; + + Image { + anchors.top: parent.top; + source: "../images/wallet-bg.jpg"; + height: 60; + width: parent.width; + fillMode: Image.PreserveAspectFit; + horizontalAlignment: Image.AlignHCenter; + verticalAlignment: Image.AlignTop; + } + + RalewaySemiBold { + text: "Someone Nearby"; + // Anchors + anchors.bottom: parent.bottom; + height: 15; + width: parent.width; + // Text size + size: 18; + // Style + color: hifi.colors.baseGrayHighlight; + horizontalAlignment: Text.AlignHCenter; + } + + MouseArea { + anchors.fill: parent; + onClicked: { + root.activeView = "chooseRecipientNearby"; + } + } + } + } + } + // Send Money Home END + + // Choose Recipient Connection BEGIN + Item { + id: chooseRecipientConnection; + visible: root.activeView === "chooseRecipientConnection"; + anchors.fill: parent; + } + // Choose Recipient Connection 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 + // +} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f3c41565f8..db2b778cc3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2284,7 +2284,7 @@ void Application::initializeUi() { QUrl{ "hifi/commerce/wallet/SecurityImageChange.qml" }, QUrl{ "hifi/commerce/wallet/SecurityImageModel.qml" }, QUrl{ "hifi/commerce/wallet/SecurityImageSelection.qml" }, - QUrl{ "hifi/commerce/wallet/SendMoney.qml" }, + QUrl{ "hifi/commerce/wallet/sendMoney/SendMoney.qml" }, QUrl{ "hifi/commerce/wallet/Wallet.qml" }, QUrl{ "hifi/commerce/wallet/WalletHome.qml" }, QUrl{ "hifi/commerce/wallet/WalletSetup.qml" }, From 40a3f8b31bd6b5058d07593e41ab378a64c5f958 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 9 Jan 2018 14:13:36 -0800 Subject: [PATCH 02/26] Progress --- .../qml/hifi/commerce/wallet/Wallet.qml | 1 + .../commerce/wallet/sendMoney/SendMoney.qml | 125 +++++++++++++++++- 2 files changed, 121 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index c2ac2e19a1..ba7a43cb1e 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -324,6 +324,7 @@ Rectangle { SendMoney { id: sendMoney; + z: 997; visible: root.activeView === "sendMoney"; anchors.fill: parent; parentAppTitleBarHeight: titleBarContainer.height; diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index e8339266f7..87a40b497f 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -29,6 +29,14 @@ Item { property int parentAppTitleBarHeight; property int parentAppNavBarHeight; property string activeView: "sendMoneyHome"; + + // This object is always used in a popup or full-screen Wallet section. + // This MouseArea is used to prevent a user from being + // able to click on a button/mouseArea underneath the popup/section. + MouseArea { + anchors.fill: parent; + propagateComposedEvents: false; + } Connections { target: Commerce; @@ -145,7 +153,6 @@ Item { anchors.bottom: parent.bottom; height: 440; - RalewaySemiBold { id: sendMoneyText; text: "Send Money To:"; @@ -159,7 +166,7 @@ Item { // Text size size: 22; // Style - color: hifi.colors.baseGrayHighlight; + color: hifi.colors.baseGray; } Item { @@ -191,7 +198,7 @@ Item { // Text size size: 18; // Style - color: hifi.colors.baseGrayHighlight; + color: hifi.colors.baseGray; horizontalAlignment: Text.AlignHCenter; } @@ -232,7 +239,7 @@ Item { // Text size size: 18; // Style - color: hifi.colors.baseGrayHighlight; + color: hifi.colors.baseGray; horizontalAlignment: Text.AlignHCenter; } @@ -248,10 +255,108 @@ Item { // Send Money Home END // Choose Recipient Connection BEGIN - Item { + Rectangle { id: chooseRecipientConnection; visible: root.activeView === "chooseRecipientConnection"; anchors.fill: parent; + color: "#AAAAAA"; + + onVisibleChanged: { + if (visible) { + // Refresh connections model + connectionsLoading.visible = false; + connectionsLoading.visible = true; + pal.sendToScript({method: 'refreshConnections'}); + } + } + + ListModel { + id: connectionsModel; + } + ListModel { + id: filteredConnectionsModel; + } + + Rectangle { + anchors.centerIn: parent; + width: parent.width - 30; + height: parent.height - 30; + + RalewaySemiBold { + id: chooseRecipientText; + text: "Choose Recipient:"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 26; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: paintedWidth; + height: 30; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + } + + HiFiGlyphs { + id: closeGlyphButton; + text: hifi.glyphs.close; + size: 26; + anchors.top: parent.top; + anchors.topMargin: 10; + anchors.right: parent.right; + anchors.rightMargin: 10; + MouseArea { + anchors.fill: parent; + hoverEnabled: true; + onEntered: { + parent.text = hifi.glyphs.closeInverted; + } + onExited: { + parent.text = hifi.glyphs.close; + } + onClicked: { + root.activeView = "sendMoneyHome"; + } + } + } + + // + // FILTER BAR START + // + Item { + id: filterBarContainer; + // Size + height: 40; + // Anchors + anchors.left: parent.left; + anchors.leftMargin: 16; + anchors.right: parent.right; + anchors.rightMargin: 16; + anchors.top: chooseRecipientText.bottom; + anchors.topMargin: 12; + + HifiControlsUit.TextField { + id: filterBar; + colorScheme: hifi.colorSchemes.faintGray; + hasClearButton: true; + hasRoundedBorder: true; + anchors.fill: parent; + placeholderText: "filter recipients"; + + onTextChanged: { + buildFilteredConnectionsModel(); + } + + onAccepted: { + focus = false; + } + } + } + // + // FILTER BAR END + // + } } // Choose Recipient Connection END @@ -260,6 +365,16 @@ Item { // // FUNCTION DEFINITIONS START // + + function buildFilteredConnectionsModel() { + filteredConnectionsModel.clear(); + for (var i = 0; i < connectionsModel.count; i++) { + if (connectionsModel.get(i).displayName.toLowerCase().indexOf(filterBar.text.toLowerCase()) !== -1) { + filteredConnectionsModel.insert(0, connectionsModel.get(i)); + } + } + } + // // Function Name: fromScript() // From 530df5447d769e6bec6488a0eb78d5911ef9cc12 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 9 Jan 2018 15:19:50 -0800 Subject: [PATCH 03/26] Even more proress --- .../qml/hifi/commerce/wallet/Wallet.qml | 9 ++ .../wallet/sendMoney/ConnectionItem.qml | 111 ++++++++++++++++++ .../commerce/wallet/sendMoney/SendMoney.qml | 59 +++++++++- scripts/system/commerce/wallet.js | 83 +++++++++++++ 4 files changed, 259 insertions(+), 3 deletions(-) create mode 100644 interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index ba7a43cb1e..fa3e8a16f6 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -329,6 +329,12 @@ Rectangle { anchors.fill: parent; parentAppTitleBarHeight: titleBarContainer.height; parentAppNavBarHeight: tabButtonsContainer.height; + + Connections { + onSendSignalToWallet: { + sendToScript(msg); + } + } } Security { @@ -726,6 +732,9 @@ Rectangle { case 'inspectionCertificate_resetCert': // NOP break; + case 'updateConnections': + sendMoney.updateConnections(message.connections); + break; default: console.log('Unrecognized message from wallet.js:', JSON.stringify(message)); } diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml new file mode 100644 index 0000000000..604f006353 --- /dev/null +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml @@ -0,0 +1,111 @@ +// +// ConnectionItem.qml +// qml/hifi/commerce/wallet/sendMoney +// +// ConnectionItem +// +// Created by Zach Fox on 2018-01-09 +// Copyright 2018 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 QtQuick.Controls.Styles 1.4 +import "../../../../styles-uit" +import "../../../../controls-uit" as HifiControlsUit +import "../../../../controls" as HifiControls +import "../../wallet" as HifiWallet + +// references XXX from root context + +Item { + HifiConstants { id: hifi; } + + id: root; + property bool isSelected: false; + property string userName; + property string profilePicUrl; + + height: 65; + width: parent.width; + + Rectangle { + id: mainContainer; + // Style + color: root.isSelected ? hifi.colors.faintGray : hifi.colors.white; + // Size + anchors.left: parent.left; + anchors.right: parent.right; + anchors.top: parent.top; + height: root.height; + + Item { + id: avatarImage; + visible: profileUrl !== "" && userName !== ""; + // Size + anchors.verticalCenter: parent.verticalCenter; + anchors.left: parent.left; + anchors.leftMargin: 36; + height: root.height - 15; + width: visible ? height : 0; + clip: true; + Image { + id: userImage; + source: root.profilePicUrl !== "" ? ((0 === root.profilePicUrl.indexOf("http")) ? + root.profilePicUrl : (Account.metaverseServerURL + root.profilePicUrl)) : ""; + mipmap: true; + // Anchors + anchors.fill: parent + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Item { + width: userImage.width; + height: userImage.height; + Rectangle { + anchors.centerIn: parent; + width: userImage.width; // This works because userImage is square + height: width; + radius: width; + } + } + } + } + AnimatedImage { + source: "../../../../../icons/profilePicLoading.gif" + anchors.fill: parent; + visible: userImage.status != Image.Ready; + } + } + + RalewaySemiBold { + id: userName; + anchors.left: avatarImage.right; + anchors.leftMargin: 14; + anchors.top: parent.top; + anchors.bottom: parent.bottom; + anchors.right: parent.right; + // Text size + size: 24; + // Style + color: hifi.colors.baseGray; + text: root.userName; + elide: Text.ElideRight; + // Alignment + horizontalAlignment: Text.AlignLeft; + verticalAlignment: Text.AlignVCenter; + } + } + + // + // FUNCTION DEFINITIONS START + // + signal sendToSendMoney(var msg); + // + // FUNCTION DEFINITIONS END + // +} diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 87a40b497f..10e35f1179 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -266,7 +266,7 @@ Item { // Refresh connections model connectionsLoading.visible = false; connectionsLoading.visible = true; - pal.sendToScript({method: 'refreshConnections'}); + sendSignalToWallet({method: 'refreshConnections'}); } } @@ -356,6 +356,52 @@ Item { // // FILTER BAR END // + + Item { + id: connectionsContainer; + anchors.top: filterBarContainer.bottom; + anchors.topMargin: 16; + anchors.left: parent.left; + anchors.right: parent.right; + anchors.bottom: parent.bottom; + + Rectangle { + id: connectionsLoading; + anchors.fill: parent; + color: "red"; + } + + ListView { + id: connectionsList; + visible: !connectionsLoading.visible; + clip: true; + model: filteredConnectionsModel; + snapMode: ListView.SnapToItem; + // Anchors + anchors.fill: parent; + delegate: ConnectionItem { + isSelected: connectionsList.currentIndex === index; + userName: userName; + profilePicUrl: profileUrl; + anchors.topMargin: 6; + anchors.bottomMargin: 6; + + Connections { + onSendToSendMoney: { + // TODO + } + } + + MouseArea { + anchors.fill: parent; + propagateComposedEvents: false; + onClicked: { + connectionsList.currentIndex = index; + } + } + } + } + } } } // Choose Recipient Connection END @@ -366,11 +412,18 @@ Item { // FUNCTION DEFINITIONS START // + function updateConnections(connections) { + connectionsModel.clear(); + connectionsModel.append(connections); + buildFilteredConnectionsModel(); + connectionsLoading.visible = false; + } + function buildFilteredConnectionsModel() { filteredConnectionsModel.clear(); for (var i = 0; i < connectionsModel.count; i++) { - if (connectionsModel.get(i).displayName.toLowerCase().indexOf(filterBar.text.toLowerCase()) !== -1) { - filteredConnectionsModel.insert(0, connectionsModel.get(i)); + if (connectionsModel.get(i).userName.toLowerCase().indexOf(filterBar.text.toLowerCase()) !== -1) { + filteredConnectionsModel.append(connectionsModel.get(i)); } } } diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index b3e3134380..6e210582b1 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -15,6 +15,7 @@ (function () { // BEGIN LOCAL_SCOPE Script.include("/~/system/libraries/accountUtils.js"); + var request = Script.require('request').request; var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace"; @@ -51,6 +52,84 @@ tablet.sendToQml(message); } + // Function Names: + // - requestJSON + // - getAvailableConnections + // - getInfoAboutUser + // - getConnectionData + // + // Description: + // - Update all the usernames that I am entitled to see, using my login but not dependent on canKick. + var METAVERSE_BASE = Account.metaverseServerURL; + function requestJSON(url, callback) { // callback(data) if successfull. Logs otherwise. + request({ + uri: url + }, function (error, response) { + if (error || (response.status !== 'success')) { + print("Error: unable to get", url, error || response.status); + return; + } + callback(response.data); + }); + } + function getAvailableConnections(domain, callback) { // callback([{usename, location}...]) if successful. (Logs otherwise) + url = METAVERSE_BASE + '/api/v1/users?' + if (domain) { + url += 'status=' + domain.slice(1, -1); // without curly braces + } else { + url += 'filter=connections'; // regardless of whether online + } + requestJSON(url, function (connectionsData) { + callback(connectionsData.users); + }); + } + function getInfoAboutUser(specificUsername, callback) { + url = METAVERSE_BASE + '/api/v1/users?filter=connections' + requestJSON(url, function (connectionsData) { + for (user in connectionsData.users) { + if (connectionsData.users[user].username === specificUsername) { + callback(connectionsData.users[user]); + return; + } + } + callback(false); + }); + } + function getConnectionData(specificUsername, domain) { + function frob(user) { // get into the right format + var formattedSessionId = user.location.node_id || ''; + if (formattedSessionId !== '' && formattedSessionId.indexOf("{") != 0) { + formattedSessionId = "{" + formattedSessionId + "}"; + } + return { + sessionId: formattedSessionId, + userName: user.username, + connection: user.connection, + profileUrl: user.images.thumbnail, + placeName: (user.location.root || user.location.domain || {}).name || '' + }; + } + if (specificUsername) { + getInfoAboutUser(specificUsername, function (user) { + if (user) { + updateUser(frob(user)); + } else { + print('Error: Unable to find information about ' + specificUsername + ' in connectionsData!'); + } + }); + } else { + getAvailableConnections(domain, function (users) { + if (domain) { + users.forEach(function (user) { + updateUser(frob(user)); + }); + } else { + sendToQml({ method: 'updateConnections', connections: users.map(frob) }); + } + }); + } + } + // Function Name: fromQml() // // Description: @@ -110,6 +189,10 @@ case 'goToMarketplaceItemPage': tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.itemId, MARKETPLACES_INJECT_SCRIPT_URL); break; + case 'refreshConnections': + print('Refreshing Connections...'); + getConnectionData(false); + break; default: print('Unrecognized message from QML:', JSON.stringify(message)); } From 54690251132287b12b929112d5674e127bb7b0a2 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 9 Jan 2018 15:38:54 -0800 Subject: [PATCH 04/26] More more more --- .../qml/hifi/commerce/wallet/WalletHome.qml | 20 +++++----- .../wallet/sendMoney/ConnectionItem.qml | 24 ++++++++++-- .../commerce/wallet/sendMoney/SendMoney.qml | 38 ++++++++++++++----- scripts/system/marketplaces/marketplaces.js | 3 ++ 4 files changed, 62 insertions(+), 23 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml index 42ee44d584..889a743c23 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml @@ -28,6 +28,16 @@ Item { property bool historyReceived: false; property int pendingCount: 0; + onVisibleChanged: { + if (visible) { + historyReceived = false; + Commerce.balance(); + Commerce.history(); + } else { + refreshTimer.stop(); + } + } + Connections { target: Commerce; @@ -131,16 +141,6 @@ Item { color: hifi.colors.white; // Alignment verticalAlignment: Text.AlignVCenter; - - onVisibleChanged: { - if (visible) { - historyReceived = false; - Commerce.balance(); - Commerce.history(); - } else { - refreshTimer.stop(); - } - } } // "balance" text below field diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml index 604f006353..d9adbee710 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml @@ -85,12 +85,13 @@ Item { RalewaySemiBold { id: userName; anchors.left: avatarImage.right; - anchors.leftMargin: 14; + anchors.leftMargin: 16; anchors.top: parent.top; anchors.bottom: parent.bottom; - anchors.right: parent.right; + anchors.right: chooseButton.visible ? chooseButton.left : parent.right; + anchors.rightMargin: chooseButton.visible ? 10 : 0; // Text size - size: 24; + size: 20; // Style color: hifi.colors.baseGray; text: root.userName; @@ -99,6 +100,23 @@ Item { horizontalAlignment: Text.AlignLeft; verticalAlignment: Text.AlignVCenter; } + + // "Choose" button + HifiControlsUit.Button { + id: chooseButton; + visible: root.isSelected; + color: hifi.buttons.blue; + colorScheme: hifi.colorSchemes.dark; + anchors.verticalCenter: parent.verticalCenter; + anchors.right: parent.right; + anchors.rightMargin: 24; + height: root.height - 20; + width: 110; + text: "CHOOSE"; + onClicked: { + + } + } } // diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 10e35f1179..6497f32995 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -13,7 +13,7 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.2 import "../../../../styles-uit" import "../../../../controls-uit" as HifiControlsUit import "../../../../controls" as HifiControls @@ -29,12 +29,17 @@ Item { property int parentAppTitleBarHeight; property int parentAppNavBarHeight; property string activeView: "sendMoneyHome"; + property bool isCurrentlyFullScreen: chooseRecipientConnection.visible; // This object is always used in a popup or full-screen Wallet section. // This MouseArea is used to prevent a user from being // able to click on a button/mouseArea underneath the popup/section. MouseArea { - anchors.fill: parent; + anchors.top: parent.top; + anchors.left: parent.left; + anchors.right: parent.right; + y: root.isCurrentlyFullScreen ? root.parentAppTitleBarHeight : 0; + height: root.isCurrentlyFullScreen ? parent.height : parent.height - root.parentAppTitleBarHeight - root.parentAppNavBarHeight; propagateComposedEvents: false; } @@ -59,8 +64,8 @@ Item { id: sendMoneyHome; visible: root.activeView === "sendMoneyHome"; anchors.fill: parent; - anchors.topMargin: parentAppTitleBarHeight; - anchors.bottomMargin: parentAppNavBarHeight; + anchors.topMargin: root.parentAppTitleBarHeight; + anchors.bottomMargin: root.parentAppNavBarHeight; // Username Text RalewayRegular { @@ -364,15 +369,27 @@ Item { anchors.left: parent.left; anchors.right: parent.right; anchors.bottom: parent.bottom; - - Rectangle { + + AnimatedImage { id: connectionsLoading; - anchors.fill: parent; - color: "red"; + source: "../../../../../icons/profilePicLoading.gif" + width: 120; + height: width; + anchors.top: parent.top; + anchors.topMargin: 185; + anchors.horizontalCenter: parent.horizontalCenter; } ListView { id: connectionsList; + ScrollBar.vertical: ScrollBar { + policy: connectionsList.contentHeight > parent.parent.height ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded; + parent: connectionsList.parent; + anchors.top: connectionsList.top; + anchors.right: connectionsList.right; + anchors.bottom: connectionsList.bottom; + width: 20; + } visible: !connectionsLoading.visible; clip: true; model: filteredConnectionsModel; @@ -381,8 +398,8 @@ Item { anchors.fill: parent; delegate: ConnectionItem { isSelected: connectionsList.currentIndex === index; - userName: userName; - profilePicUrl: profileUrl; + userName: model.userName; + profilePicUrl: model.profileUrl; anchors.topMargin: 6; anchors.bottomMargin: 6; @@ -393,6 +410,7 @@ Item { } MouseArea { + enabled: connectionsList.currentIndex !== index; anchors.fill: parent; propagateComposedEvents: false; onClicked: { diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index a5360974f6..3b9c639d91 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -565,6 +565,9 @@ var selectionDisplay = null; // for gridTool.js to ignore method: 'purchases_showMyItems' }); break; + case 'refreshConnections': + // NOP + break; default: print('Unrecognized message from Checkout.qml or Purchases.qml: ' + JSON.stringify(message)); } From f366fdf6951625a19eb65b12ee7640b58e6d03fa Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 9 Jan 2018 17:53:24 -0800 Subject: [PATCH 05/26] Beginnings of nearby --- .../commerce/wallet/sendMoney/SendMoney.qml | 129 +++++- scripts/system/commerce/wallet.js | 368 ++++++++++++++++++ 2 files changed, 493 insertions(+), 4 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 6497f32995..3ff02f95ac 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -29,7 +29,7 @@ Item { property int parentAppTitleBarHeight; property int parentAppNavBarHeight; property string activeView: "sendMoneyHome"; - property bool isCurrentlyFullScreen: chooseRecipientConnection.visible; + property bool isCurrentlyFullScreen: chooseRecipientConnection.visible || chooseRecipientNearby.visible; // This object is always used in a popup or full-screen Wallet section. // This MouseArea is used to prevent a user from being @@ -288,7 +288,7 @@ Item { height: parent.height - 30; RalewaySemiBold { - id: chooseRecipientText; + id: chooseRecipientText_connections; text: "Choose Recipient:"; // Anchors anchors.top: parent.top; @@ -304,7 +304,7 @@ Item { } HiFiGlyphs { - id: closeGlyphButton; + id: closeGlyphButton_connections; text: hifi.glyphs.close; size: 26; anchors.top: parent.top; @@ -338,7 +338,7 @@ Item { anchors.leftMargin: 16; anchors.right: parent.right; anchors.rightMargin: 16; - anchors.top: chooseRecipientText.bottom; + anchors.top: chooseRecipientText_connections.bottom; anchors.topMargin: 12; HifiControlsUit.TextField { @@ -423,6 +423,120 @@ Item { } } // Choose Recipient Connection END + + // Choose Recipient Nearby BEGIN + Rectangle { + id: chooseRecipientNearby; + + property string selectedRecipient; + + visible: root.activeView === "chooseRecipientNearby"; + anchors.fill: parent; + color: "#AAAAAA"; + + onVisibleChanged: { + if (visible) { + sendSignalToWallet({method: 'enable_ChooseRecipientNearbyMode'}); + } else { + selectedRecipient = ""; + sendSignalToWallet({method: 'disable_ChooseRecipientNearbyMode'}); + } + } + + Rectangle { + anchors.centerIn: parent; + width: parent.width - 30; + height: parent.height - 30; + + RalewaySemiBold { + id: chooseRecipientText_nearby; + text: "Choose Recipient:"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 26; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: paintedWidth; + height: 30; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + } + + HiFiGlyphs { + id: closeGlyphButton_nearby; + text: hifi.glyphs.close; + size: 26; + anchors.top: parent.top; + anchors.topMargin: 10; + anchors.right: parent.right; + anchors.rightMargin: 10; + MouseArea { + anchors.fill: parent; + hoverEnabled: true; + onEntered: { + parent.text = hifi.glyphs.closeInverted; + } + onExited: { + parent.text = hifi.glyphs.close; + } + onClicked: { + root.activeView = "sendMoneyHome"; + } + } + } + + Item { + id: selectionInstructionsContainer; + visible: chooseRecipientNearby.selectedRecipient === ""; + anchors.fill: parent; + + RalewaySemiBold { + id: selectionInstructions; + text: "Click/trigger on an avatar nearby to select them..."; + // Anchors + anchors.bottom: parent.bottom; + anchors.bottomMargin: 100; + anchors.left: parent.left; + anchors.leftMargin: 50; + anchors.right: parent.right; + anchors.rightMargin: anchors.leftMargin; + height: paintedHeight; + // Text size + size: 20; + // Style + color: hifi.colors.baseGray; + horizontalAlignment: Text.AlignHCenter; + } + } + + Item { + id: selectionMadeContainer; + visible: !selectionInstructionsContainer.visible; + anchors.fill: parent; + + RalewaySemiBold { + id: selectionInstructions; + text: "Click/trigger on another avatar nearby to select them...\n\nor press 'Next' to continue."; + // Anchors + anchors.bottom: parent.bottom; + anchors.bottomMargin: 100; + anchors.left: parent.left; + anchors.leftMargin: 50; + anchors.right: parent.right; + anchors.rightMargin: anchors.leftMargin; + height: paintedHeight; + // Text size + size: 20; + // Style + color: hifi.colors.baseGray; + horizontalAlignment: Text.AlignHCenter; + } + } + } + } + // Choose Recipient Nearby END @@ -461,6 +575,13 @@ Item { // function fromScript(message) { switch (message.method) { + case 'selectRecipient': + if (message.isSelected) { + chooseRecipientNearby.selectedRecipient = message.id; + } else { + chooseRecipientNearby.selectedRecipient = ""; + } + break; default: console.log('Unrecognized message from wallet.js:', JSON.stringify(message)); } diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index 6e210582b1..48cdf961c4 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -52,6 +52,11 @@ tablet.sendToQml(message); } + //*********************************************** + // + // BEGIN Connection logic + // + //*********************************************** // Function Names: // - requestJSON // - getAvailableConnections @@ -129,6 +134,352 @@ }); } } + //*********************************************** + // + // END Connection logic + // + //*********************************************** + + //*********************************************** + // + // BEGIN Avatar Selector logic + // + //*********************************************** + var UNSELECTED_TEXTURES = { + "idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png"), + "idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png") + }; + var SELECTED_TEXTURES = { + "idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-selected.png"), + "idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-selected.png") + }; + var HOVER_TEXTURES = { + "idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-hover.png"), + "idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-hover.png") + }; + + var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6 }; + var SELECTED_COLOR = { red: 0xF3, green: 0x91, blue: 0x29 }; + var HOVER_COLOR = { red: 0xD0, green: 0xD0, blue: 0xD0 }; + var conserveResources = true; + + var overlays = {}; // Keeps track of all our extended overlay data objects, keyed by target identifier. + + function ExtendedOverlay(key, type, properties, selected, hasModel) { // A wrapper around overlays to store the key it is associated with. + overlays[key] = this; + if (hasModel) { + var modelKey = key + "-m"; + this.model = new ExtendedOverlay(modelKey, "model", { + url: Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx"), + textures: textures(selected), + ignoreRayIntersection: true + }, false, false); + } else { + this.model = undefined; + } + this.key = key; + this.selected = selected || false; // not undefined + this.hovering = false; + this.activeOverlay = Overlays.addOverlay(type, properties); // We could use different overlays for (un)selected... + } + // Instance methods: + ExtendedOverlay.prototype.deleteOverlay = function () { // remove display and data of this overlay + Overlays.deleteOverlay(this.activeOverlay); + delete overlays[this.key]; + }; + + ExtendedOverlay.prototype.editOverlay = function (properties) { // change display of this overlay + Overlays.editOverlay(this.activeOverlay, properties); + }; + + function color(selected, hovering) { + var base = hovering ? HOVER_COLOR : selected ? SELECTED_COLOR : UNSELECTED_COLOR; + function scale(component) { + var delta = 0xFF - component; + return component; + } + return { red: scale(base.red), green: scale(base.green), blue: scale(base.blue) }; + } + + function textures(selected, hovering) { + return hovering ? HOVER_TEXTURES : selected ? SELECTED_TEXTURES : UNSELECTED_TEXTURES; + } + // so we don't have to traverse the overlays to get the last one + var lastHoveringId = 0; + ExtendedOverlay.prototype.hover = function (hovering) { + this.hovering = hovering; + if (this.key === lastHoveringId) { + if (hovering) { + return; + } + lastHoveringId = 0; + } + this.editOverlay({ color: color(this.selected, hovering) }); + if (this.model) { + this.model.editOverlay({ textures: textures(this.selected, hovering) }); + } + if (hovering) { + // un-hover the last hovering overlay + if (lastHoveringId && lastHoveringId !== this.key) { + ExtendedOverlay.get(lastHoveringId).hover(false); + } + lastHoveringId = this.key; + } + }; + ExtendedOverlay.prototype.select = function (selected) { + if (this.selected === selected) { + return; + } + + this.editOverlay({ color: color(selected, this.hovering) }); + if (this.model) { + this.model.editOverlay({ textures: textures(selected) }); + } + this.selected = selected; + }; + // Class methods: + var selectedIds = []; + ExtendedOverlay.isSelected = function (id) { + return -1 !== selectedIds.indexOf(id); + }; + ExtendedOverlay.get = function (key) { // answer the extended overlay data object associated with the given avatar identifier + return overlays[key]; + }; + ExtendedOverlay.some = function (iterator) { // Bails early as soon as iterator returns truthy. + var key; + for (key in overlays) { + if (iterator(ExtendedOverlay.get(key))) { + return; + } + } + }; + ExtendedOverlay.unHover = function () { // calls hover(false) on lastHoveringId (if any) + if (lastHoveringId) { + ExtendedOverlay.get(lastHoveringId).hover(false); + } + }; + + // hit(overlay) on the one overlay intersected by pickRay, if any. + // noHit() if no ExtendedOverlay was intersected (helps with hover) + ExtendedOverlay.applyPickRay = function (pickRay, hit, noHit) { + var pickedOverlay = Overlays.findRayIntersection(pickRay); // Depends on nearer coverOverlays to extend closer to us than farther ones. + if (!pickedOverlay.intersects) { + if (noHit) { + return noHit(); + } + return; + } + ExtendedOverlay.some(function (overlay) { // See if pickedOverlay is one of ours. + if ((overlay.activeOverlay) === pickedOverlay.overlayID) { + hit(overlay); + return true; + } + }); + }; + + function HighlightedEntity(id, entityProperties) { + this.id = id; + this.overlay = Overlays.addOverlay('cube', { + position: entityProperties.position, + rotation: entityProperties.rotation, + dimensions: entityProperties.dimensions, + solid: false, + color: { + red: 0xF3, + green: 0x91, + blue: 0x29 + }, + ignoreRayIntersection: true, + drawInFront: false // Arguable. For now, let's not distract with mysterious wires around the scene. + }); + HighlightedEntity.overlays.push(this); + } + HighlightedEntity.overlays = []; + HighlightedEntity.clearOverlays = function clearHighlightedEntities() { + HighlightedEntity.overlays.forEach(function (highlighted) { + Overlays.deleteOverlay(highlighted.overlay); + }); + HighlightedEntity.overlays = []; + }; + HighlightedEntity.updateOverlays = function updateHighlightedEntities() { + HighlightedEntity.overlays.forEach(function (highlighted) { + var properties = Entities.getEntityProperties(highlighted.id, ['position', 'rotation', 'dimensions']); + Overlays.editOverlay(highlighted.overlay, { + position: properties.position, + rotation: properties.rotation, + dimensions: properties.dimensions + }); + }); + }; + + + function addAvatarNode(id) { + var selected = ExtendedOverlay.isSelected(id); + return new ExtendedOverlay(id, "sphere", { + drawInFront: true, + solid: true, + alpha: 0.8, + color: color(selected, false), + ignoreRayIntersection: false + }, selected, !conserveResources); + } + + var pingPong = true; + function updateOverlays() { + var eye = Camera.position; + AvatarList.getAvatarIdentifiers().forEach(function (id) { + if (!id) { + return; // don't update ourself, or avatars we're not interested in + } + var avatar = AvatarList.getAvatar(id); + if (!avatar) { + return; // will be deleted below if there had been an overlay. + } + var overlay = ExtendedOverlay.get(id); + if (!overlay) { // For now, we're treating this as a temporary loss, as from the personal space bubble. Add it back. + overlay = addAvatarNode(id); + } + var target = avatar.position; + var distance = Vec3.distance(target, eye); + var offset = 0.2; + var diff = Vec3.subtract(target, eye); // get diff between target and eye (a vector pointing to the eye from avatar position) + var headIndex = avatar.getJointIndex("Head"); // base offset on 1/2 distance from hips to head if we can + if (headIndex > 0) { + offset = avatar.getAbsoluteJointTranslationInObjectFrame(headIndex).y / 2; + } + + // move a bit in front, towards the camera + target = Vec3.subtract(target, Vec3.multiply(Vec3.normalize(diff), offset)); + + // now bump it up a bit + target.y = target.y + offset; + + overlay.ping = pingPong; + overlay.editOverlay({ + color: color(ExtendedOverlay.isSelected(id), overlay.hovering), + position: target, + dimensions: 0.032 * distance + }); + if (overlay.model) { + overlay.model.ping = pingPong; + overlay.model.editOverlay({ + position: target, + scale: 0.2 * distance, // constant apparent size + rotation: Camera.orientation + }); + } + }); + pingPong = !pingPong; + ExtendedOverlay.some(function (overlay) { // Remove any that weren't updated. (User is gone.) + if (overlay.ping === pingPong) { + overlay.deleteOverlay(); + } + }); + // We could re-populateNearbyUserList if anything added or removed, but not for now. + HighlightedEntity.updateOverlays(); + } + function removeOverlays() { + selectedIds = []; + lastHoveringId = 0; + HighlightedEntity.clearOverlays(); + ExtendedOverlay.some(function (overlay) { + overlay.deleteOverlay(); + }); + } + + // + // Clicks. + // + function handleClick(pickRay) { + ExtendedOverlay.applyPickRay(pickRay, function (overlay) { + var message = { method: 'selectRecipient', id: [overlay.key], isSelected: !overlay.selected }; + sendToQml(message); + return true; + }); + } + function handleMouseEvent(mousePressEvent) { // handleClick if we get one. + if (!mousePressEvent.isLeftButton) { + return; + } + handleClick(Camera.computePickRay(mousePressEvent.x, mousePressEvent.y)); + } + function handleMouseMove(pickRay) { // given the pickRay, just do the hover logic + ExtendedOverlay.applyPickRay(pickRay, function (overlay) { + overlay.hover(true); + }, function () { + ExtendedOverlay.unHover(); + }); + } + + // handy global to keep track of which hand is the mouse (if any) + var currentHandPressed = 0; + var TRIGGER_CLICK_THRESHOLD = 0.85; + var TRIGGER_PRESS_THRESHOLD = 0.05; + + function handleMouseMoveEvent(event) { // find out which overlay (if any) is over the mouse position + var pickRay; + if (HMD.active) { + if (currentHandPressed !== 0) { + pickRay = controllerComputePickRay(currentHandPressed); + } else { + // nothing should hover, so + ExtendedOverlay.unHover(); + return; + } + } else { + pickRay = Camera.computePickRay(event.x, event.y); + } + handleMouseMove(pickRay); + } + function handleTriggerPressed(hand, value) { + // The idea is if you press one trigger, it is the one + // we will consider the mouse. Even if the other is pressed, + // we ignore it until this one is no longer pressed. + var isPressed = value > TRIGGER_PRESS_THRESHOLD; + if (currentHandPressed === 0) { + currentHandPressed = isPressed ? hand : 0; + return; + } + if (currentHandPressed === hand) { + currentHandPressed = isPressed ? hand : 0; + return; + } + // otherwise, the other hand is still triggered + // so do nothing. + } + + // We get mouseMoveEvents from the handControllers, via handControllerPointer. + // But we don't get mousePressEvents. + var triggerMapping = Controller.newMapping(Script.resolvePath('') + '-click'); + var triggerPressMapping = Controller.newMapping(Script.resolvePath('') + '-press'); + function controllerComputePickRay(hand) { + var controllerPose = getControllerWorldLocation(hand, true); + if (controllerPose.valid) { + return { origin: controllerPose.position, direction: Quat.getUp(controllerPose.orientation) }; + } + } + function makeClickHandler(hand) { + return function (clicked) { + if (clicked > TRIGGER_CLICK_THRESHOLD) { + var pickRay = controllerComputePickRay(hand); + handleClick(pickRay); + } + }; + } + function makePressHandler(hand) { + return function (value) { + handleTriggerPressed(hand, value); + }; + } + triggerMapping.from(Controller.Standard.RTClick).peek().to(makeClickHandler(Controller.Standard.RightHand)); + triggerMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand)); + triggerPressMapping.from(Controller.Standard.RT).peek().to(makePressHandler(Controller.Standard.RightHand)); + triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand)); + //*********************************************** + // + // END Avatar Selector logic + // + //*********************************************** // Function Name: fromQml() // @@ -193,6 +544,13 @@ print('Refreshing Connections...'); getConnectionData(false); break; + case 'enable_ChooseRecipientNearbyMode': + Script.update.connect(updateOverlays); + break; + case 'disable_ChooseRecipientNearbyMode': + Script.update.disconnect(updateOverlays); + removeOverlays(); + break; default: print('Unrecognized message from QML:', JSON.stringify(message)); } @@ -257,6 +615,10 @@ }); button.clicked.connect(onButtonClicked); tablet.screenChanged.connect(onTabletScreenChanged); + Controller.mousePressEvent.connect(handleMouseEvent); + Controller.mouseMoveEvent.connect(handleMouseMoveEvent); + triggerMapping.enable(); + triggerPressMapping.enable(); } } function shutdown() { @@ -268,6 +630,12 @@ tablet.gotoHomeScreen(); } } + Script.update.disconnect(updateOverlays); + Controller.mousePressEvent.disconnect(handleMouseEvent); + Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent); + triggerMapping.disable(); // It's ok if we disable twice. + triggerPressMapping.disable(); // see above + removeOverlays(); } // From c5a5bddbc92f876a7642d5c2fcdbc63f74151b78 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 10 Jan 2018 12:12:02 -0800 Subject: [PATCH 06/26] More progress --- .../qml/hifi/commerce/wallet/Wallet.qml | 3 + .../commerce/wallet/sendMoney/SendMoney.qml | 158 +++++++++++++----- scripts/system/commerce/wallet.js | 54 +++++- scripts/system/marketplaces/marketplaces.js | 2 + 4 files changed, 167 insertions(+), 50 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index fa3e8a16f6..5340f0e202 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -735,6 +735,9 @@ Rectangle { case 'updateConnections': sendMoney.updateConnections(message.connections); break; + case 'selectRecipient': + sendMoney.fromScript(message); + break; default: console.log('Unrecognized message from wallet.js:', JSON.stringify(message)); } diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 3ff02f95ac..4b7f7b4033 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -28,16 +28,15 @@ Item { property int parentAppTitleBarHeight; property int parentAppNavBarHeight; - property string activeView: "sendMoneyHome"; + property string currentActiveView: "sendMoneyHome"; + property string nextActiveView: ""; property bool isCurrentlyFullScreen: chooseRecipientConnection.visible || chooseRecipientNearby.visible; // This object is always used in a popup or full-screen Wallet section. // This MouseArea is used to prevent a user from being // able to click on a button/mouseArea underneath the popup/section. MouseArea { - anchors.top: parent.top; - anchors.left: parent.left; - anchors.right: parent.right; + x: 0; y: root.isCurrentlyFullScreen ? root.parentAppTitleBarHeight : 0; height: root.isCurrentlyFullScreen ? parent.height : parent.height - root.parentAppTitleBarHeight - root.parentAppNavBarHeight; propagateComposedEvents: false; @@ -59,10 +58,34 @@ Item { } } + Component.onCompleted: { + Commerce.balance(); + } + + onNextActiveViewChanged: { + root.currentActiveView = root.nextActiveView; + if (root.currentActiveView === 'chooseRecipientConnection') { + // Refresh connections model + connectionsLoading.visible = false; + connectionsLoading.visible = true; + sendSignalToWallet({method: 'refreshConnections'}); + } + + if (root.currentActiveView === 'chooseRecipientNearby') { + sendSignalToWallet({method: 'enable_ChooseRecipientNearbyMode'}); + } else { + sendSignalToWallet({method: 'disable_ChooseRecipientNearbyMode'}); + } + + if (root.currentActiveView === 'sendMoneyHome') { + Commerce.balance(); + } + } + // Send Money Home BEGIN Item { id: sendMoneyHome; - visible: root.activeView === "sendMoneyHome"; + visible: root.currentActiveView === "sendMoneyHome"; anchors.fill: parent; anchors.topMargin: root.parentAppTitleBarHeight; anchors.bottomMargin: root.parentAppNavBarHeight; @@ -125,12 +148,6 @@ Item { color: hifi.colors.white; // Alignment verticalAlignment: Text.AlignVCenter; - - onVisibleChanged: { - if (visible) { - Commerce.balance(); - } - } } // "balance" text below field @@ -210,7 +227,7 @@ Item { MouseArea { anchors.fill: parent; onClicked: { - root.activeView = "chooseRecipientConnection"; + root.nextActiveView = "chooseRecipientConnection"; } } } @@ -251,7 +268,7 @@ Item { MouseArea { anchors.fill: parent; onClicked: { - root.activeView = "chooseRecipientNearby"; + root.nextActiveView = "chooseRecipientNearby"; } } } @@ -262,18 +279,9 @@ Item { // Choose Recipient Connection BEGIN Rectangle { id: chooseRecipientConnection; - visible: root.activeView === "chooseRecipientConnection"; + visible: root.currentActiveView === "chooseRecipientConnection"; anchors.fill: parent; color: "#AAAAAA"; - - onVisibleChanged: { - if (visible) { - // Refresh connections model - connectionsLoading.visible = false; - connectionsLoading.visible = true; - sendSignalToWallet({method: 'refreshConnections'}); - } - } ListModel { id: connectionsModel; @@ -321,7 +329,7 @@ Item { parent.text = hifi.glyphs.close; } onClicked: { - root.activeView = "sendMoneyHome"; + root.nextActiveView = "sendMoneyHome"; } } } @@ -430,19 +438,10 @@ Item { property string selectedRecipient; - visible: root.activeView === "chooseRecipientNearby"; + visible: root.currentActiveView === "chooseRecipientNearby"; anchors.fill: parent; color: "#AAAAAA"; - onVisibleChanged: { - if (visible) { - sendSignalToWallet({method: 'enable_ChooseRecipientNearbyMode'}); - } else { - selectedRecipient = ""; - sendSignalToWallet({method: 'disable_ChooseRecipientNearbyMode'}); - } - } - Rectangle { anchors.centerIn: parent; width: parent.width - 30; @@ -482,7 +481,8 @@ Item { parent.text = hifi.glyphs.close; } onClicked: { - root.activeView = "sendMoneyHome"; + root.nextActiveView = "sendMoneyHome"; + chooseRecipientNearby.selectedRecipient = ""; } } } @@ -493,13 +493,13 @@ Item { anchors.fill: parent; RalewaySemiBold { - id: selectionInstructions; + id: selectionInstructions_deselected; text: "Click/trigger on an avatar nearby to select them..."; // Anchors anchors.bottom: parent.bottom; - anchors.bottomMargin: 100; + anchors.bottomMargin: 200; anchors.left: parent.left; - anchors.leftMargin: 50; + anchors.leftMargin: 58; anchors.right: parent.right; anchors.rightMargin: anchors.leftMargin; height: paintedHeight; @@ -508,6 +508,7 @@ Item { // Style color: hifi.colors.baseGray; horizontalAlignment: Text.AlignHCenter; + wrapMode: Text.WordWrap; } } @@ -517,13 +518,47 @@ Item { anchors.fill: parent; RalewaySemiBold { - id: selectionInstructions; + id: sendToText; + text: "Send To:"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 120; + anchors.left: parent.left; + anchors.leftMargin: 12; + width: paintedWidth; + height: paintedHeight; + // Text size + size: 20; + // Style + color: hifi.colors.baseGray; + } + + RalewaySemiBold { + id: avatarNodeID; + text: chooseRecipientNearby.selectedRecipient; + // Anchors + anchors.top: sendToText.bottom; + anchors.topMargin: 60; + anchors.left: parent.left; + anchors.leftMargin: 30; + anchors.right: parent.right; + anchors.rightMargin: 30; + height: paintedHeight; + // Text size + size: 18; + // Style + horizontalAlignment: Text.AlignHCenter; + color: hifi.colors.baseGray; + } + + RalewaySemiBold { + id: selectionInstructions_selected; text: "Click/trigger on another avatar nearby to select them...\n\nor press 'Next' to continue."; // Anchors anchors.bottom: parent.bottom; - anchors.bottomMargin: 100; + anchors.bottomMargin: 200; anchors.left: parent.left; - anchors.leftMargin: 50; + anchors.leftMargin: 58; anchors.right: parent.right; anchors.rightMargin: anchors.leftMargin; height: paintedHeight; @@ -532,6 +567,43 @@ Item { // Style color: hifi.colors.baseGray; horizontalAlignment: Text.AlignHCenter; + wrapMode: Text.WordWrap; + } + } + + // "Cancel" button + HifiControlsUit.Button { + id: cancelButton; + color: hifi.buttons.noneBorderless; + colorScheme: hifi.colorSchemes.dark; + anchors.left: parent.left; + anchors.leftMargin: 60; + anchors.bottom: parent.bottom; + anchors.bottomMargin: 80; + height: 50; + width: 120; + text: "Cancel"; + onClicked: { + root.nextActiveView = "sendMoneyHome"; + chooseRecipientNearby.selectedRecipient = ""; + } + } + + // "Next" button + HifiControlsUit.Button { + id: nextButton; + enabled: chooseRecipientNearby.selectedRecipient !== ""; + color: hifi.buttons.blue; + colorScheme: hifi.colorSchemes.dark; + anchors.right: parent.right; + anchors.rightMargin: 60; + anchors.bottom: parent.bottom; + anchors.bottomMargin: 80; + height: 50; + width: 120; + text: "Next"; + onClicked: { + } } } @@ -577,13 +649,13 @@ Item { switch (message.method) { case 'selectRecipient': if (message.isSelected) { - chooseRecipientNearby.selectedRecipient = message.id; + chooseRecipientNearby.selectedRecipient = message.id[0]; } else { chooseRecipientNearby.selectedRecipient = ""; } break; default: - console.log('Unrecognized message from wallet.js:', JSON.stringify(message)); + console.log('SendMoney: Unrecognized message from wallet.js:', JSON.stringify(message)); } } signal sendSignalToWallet(var msg); diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index 48cdf961c4..e8156ae5fc 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -392,8 +392,35 @@ // function handleClick(pickRay) { ExtendedOverlay.applyPickRay(pickRay, function (overlay) { - var message = { method: 'selectRecipient', id: [overlay.key], isSelected: !overlay.selected }; + var nextSelectedStatus = !overlay.selected; + var message = { method: 'selectRecipient', id: [overlay.key], isSelected: nextSelectedStatus }; sendToQml(message); + + selectedIds = nextSelectedStatus ? [overlay.key] : []; + ExtendedOverlay.some(function (overlay) { + var id = overlay.key; + var selected = ExtendedOverlay.isSelected(id); + overlay.select(selected); + }); + + HighlightedEntity.clearOverlays(); + if (selectedIds.length) { + Entities.findEntitiesInFrustum(Camera.frustum).forEach(function (id) { + // Because lastEditedBy is per session, the vast majority of entities won't match, + // so it would probably be worth reducing marshalling costs by asking for just we need. + // However, providing property name(s) is advisory and some additional properties are + // included anyway. As it turns out, asking for 'lastEditedBy' gives 'position', 'rotation', + // and 'dimensions', too, so we might as well make use of them instead of making a second + // getEntityProperties call. + // It would be nice if we could harden this against future changes by specifying all + // and only these four in an array, but see + // https://highfidelity.fogbugz.com/f/cases/2728/Entities-getEntityProperties-id-lastEditedBy-name-lastEditedBy-doesn-t-work + var properties = Entities.getEntityProperties(id, 'lastEditedBy'); + if (ExtendedOverlay.isSelected(properties.lastEditedBy)) { + new HighlightedEntity(id, properties); + } + }); + } return true; }); } @@ -595,6 +622,12 @@ if (button) { button.editProperties({ isActive: onWalletScreen }); } + + if (onWalletScreen) { + isWired = true; + } else { + off(); + } } // @@ -621,6 +654,18 @@ triggerPressMapping.enable(); } } + var isWired = false; + function off() { + if (isWired) { // It is not ok to disconnect these twice, hence guard. + Script.update.disconnect(updateOverlays); + Controller.mousePressEvent.disconnect(handleMouseEvent); + Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent); + isWired = false; + } + triggerMapping.disable(); // It's ok if we disable twice. + triggerPressMapping.disable(); // see above + removeOverlays(); + } function shutdown() { button.clicked.disconnect(onButtonClicked); tablet.removeButton(button); @@ -630,12 +675,7 @@ tablet.gotoHomeScreen(); } } - Script.update.disconnect(updateOverlays); - Controller.mousePressEvent.disconnect(handleMouseEvent); - Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent); - triggerMapping.disable(); // It's ok if we disable twice. - triggerPressMapping.disable(); // see above - removeOverlays(); + off(); } // diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 594b6c5509..ee3a9ce7ec 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -576,6 +576,8 @@ var selectionDisplay = null; // for gridTool.js to ignore }); break; case 'refreshConnections': + case 'enable_ChooseRecipientNearbyMode': + case 'disable_ChooseRecipientNearbyMode': // NOP break; default: From 22631065e451274a0d71c534582d554c3551db93 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 10 Jan 2018 15:09:15 -0800 Subject: [PATCH 07/26] Serious flow state --- .../resources/qml/controls-uit/TextField.qml | 15 +- .../commerce/wallet/sendMoney/SendMoney.qml | 319 +++++++++++++++++- 2 files changed, 329 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/controls-uit/TextField.qml b/interface/resources/qml/controls-uit/TextField.qml index e636bfc27f..b942c8b4ab 100644 --- a/interface/resources/qml/controls-uit/TextField.qml +++ b/interface/resources/qml/controls-uit/TextField.qml @@ -27,10 +27,12 @@ TextField { property bool hasRoundedBorder: false property bool error: false; property bool hasClearButton: false; + property string leftPlaceholderGlyph: ""; placeholderText: textField.placeholderText FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; } + FontLoader { id: hifiGlyphs; source: "../../fonts/hifi-glyphs.ttf"; } font.family: firaSansSemiBold.name font.pixelSize: hifi.fontSizes.textFieldInput font.italic: textField.text == "" @@ -54,6 +56,7 @@ TextField { } style: TextFieldStyle { + id: style; textColor: { if (isLightColorScheme) { if (textField.activeFocus) { @@ -102,6 +105,16 @@ TextField { border.width: textField.activeFocus || hasRoundedBorder || textField.error ? 1 : 0 radius: isSearchField ? textField.height / 2 : (hasRoundedBorder ? 4 : 0) + HiFiGlyphs { + text: textField.leftPlaceholderGlyph; + color: textColor; + size: hifi.fontSizes.textFieldSearchIcon; + anchors.left: parent.left; + anchors.verticalCenter: parent.verticalCenter; + anchors.leftMargin: hifi.dimensions.textPadding - 2; + visible: text; + } + HiFiGlyphs { text: hifi.glyphs.search color: textColor @@ -132,7 +145,7 @@ TextField { 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.left: ((isSearchField || textField.leftPlaceholderGlyph !== "") ? textField.height - 2 : 0) + hifi.dimensions.textPadding padding.right: (hasClearButton ? textField.height - 2 : 0) + hifi.dimensions.textPadding } diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 4b7f7b4033..e7cdc0dd4d 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -12,7 +12,7 @@ // import Hifi 1.0 as Hifi -import QtQuick 2.5 +import QtQuick 2.6 import QtQuick.Controls 2.2 import "../../../../styles-uit" import "../../../../controls-uit" as HifiControlsUit @@ -30,7 +30,8 @@ Item { property int parentAppNavBarHeight; property string currentActiveView: "sendMoneyHome"; property string nextActiveView: ""; - property bool isCurrentlyFullScreen: chooseRecipientConnection.visible || chooseRecipientNearby.visible; + property bool isCurrentlyFullScreen: chooseRecipientConnection.visible || chooseRecipientNearby.visible || sendMoneyStep.visible; + property bool isCurrentlySendingMoney: false; // This object is always used in a popup or full-screen Wallet section. // This MouseArea is used to prevent a user from being @@ -603,12 +604,322 @@ Item { width: 120; text: "Next"; onClicked: { - + sendMoneyStep.referrer = "nearby"; + sendMoneyStep.selectedRecipientNodeID = chooseRecipientNearby.selectedRecipient; + sendMoneyStep.selectedRecipientDisplayName = ""; + sendMoneyStep.selectedRecipientUserName = ""; + chooseRecipientNearby.selectedRecipient = ""; + + root.nextActiveView = "sendMoneyStep"; } } } } - // Choose Recipient Nearby END + // Choose Recipient Nearby + + // Send Money Screen BEGIN + Rectangle { + id: sendMoneyStep; + z: 997; + + property string referrer; // either "connections" or "nearby" + property string selectedRecipientNodeID; + property string selectedRecipientDisplayName; + property string selectedRecipientUserName; + + visible: root.currentActiveView === "sendMoneyStep"; + anchors.fill: parent; + color: "#AAAAAA"; + + Rectangle { + anchors.centerIn: parent; + width: parent.width - 30; + height: parent.height - 30; + + RalewaySemiBold { + id: sendMoneyText_sendMoneyStep; + text: "Send Money To:"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 26; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: paintedWidth; + height: 30; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + } + + Item { + id: sendToContainer; + anchors.top: sendMoneyText_sendMoneyStep.bottom; + anchors.topMargin: 20; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + RalewaySemiBold { + id: sendToText_sendMoneyStep; + text: "Send To:"; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.bottom: parent.bottom; + width: 90; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + RalewaySemiBold { + id: recipientDisplayName; + text: '"ZRF Changeme"'; + // Anchors + anchors.top: parent.top; + anchors.left: sendToText_sendMoneyStep.right; + anchors.right: changeButton.left; + anchors.rightMargin: 12; + height: parent.height/2; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignBottom; + } + + RalewaySemiBold { + id: recipientUsername; + text: "unknown username"; + // Anchors + anchors.bottom: parent.bottom; + anchors.left: recipientDisplayName.anchors.left; + anchors.leftMargin: recipientDisplayName.anchors.leftMargin; + anchors.right: recipientDisplayName.anchors.right; + anchors.rightMargin: recipientDisplayName.anchors.rightMargin; + height: parent.height/2; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignTop; + } + + // "CHANGE" button + HifiControlsUit.Button { + id: changeButton; + color: hifi.buttons.black; + colorScheme: hifi.colorSchemes.dark; + anchors.right: parent.right; + anchors.verticalCenter: parent.verticalCenter; + height: 35; + width: 120; + text: "CHANGE"; + onClicked: { + root.nextActiveView = "chooseRecipientNearby"; + } + } + } + + Item { + id: amountContainer; + anchors.top: sendToContainer.bottom; + anchors.topMargin: 16; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + RalewaySemiBold { + id: amountText; + text: "Amount:"; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.bottom: parent.bottom; + width: 90; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + HifiControlsUit.TextField { + id: amountTextField; + colorScheme: hifi.colorSchemes.light; + inputMethodHints: Qt.ImhDigitsOnly; + // Anchors + anchors.verticalCenter: parent.verticalCenter; + anchors.left: amountText.right; + anchors.right: parent.right; + height: 50; + // Style + leftPlaceholderGlyph: hifi.glyphs.hfc; + activeFocusOnPress: true; + activeFocusOnTab: true; + + onAccepted: { + optionalMessage.focus = true; + } + } + } + + Item { + id: messageContainer; + anchors.top: amountContainer.bottom; + anchors.topMargin: 16; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 180; + + FontLoader { id: firaSansSemiBold; source: "../../../../../fonts/FiraSans-SemiBold.ttf"; } + TextArea { + id: optionalMessage; + property int maximumLength: 255; + property string previousText: text; + placeholderText: "Optional Message"; + font.family: firaSansSemiBold.name; + font.pixelSize: 20; + // Anchors + anchors.fill: parent; + // Style + background: Rectangle { + anchors.fill: parent; + color: optionalMessage.activeFocus ? hifi.colors.white : hifi.colors.textFieldLightBackground; + border.width: optionalMessage.activeFocus ? 1 : 0; + border.color: optionalMessage.activeFocus ? hifi.colors.primaryHighlight : hifi.colors.textFieldLightBackground; + } + color: hifi.colors.black; + textFormat: TextEdit.PlainText; + wrapMode: TextEdit.Wrap; + activeFocusOnPress: true; + activeFocusOnTab: true; + // Workaround for no max length on TextAreas + onTextChanged: { + if (text.length > maximumLength) { + var cursor = cursorPosition; + text = previousText; + if (cursor > text.length) { + cursorPosition = text.length; + } else { + cursorPosition = cursor-1; + } + } + previousText = text; + } + } + } + + Item { + id: bottomBarContainer; + anchors.top: messageContainer.bottom; + anchors.topMargin: 30; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + HifiControlsUit.CheckBox { + id: sendPubliclyCheckbox; + text: "Send Publicly" + // Anchors + anchors.verticalCenter: parent.verticalCenter; + anchors.left: parent.left; + anchors.right: cancelButton_sendMoneyStep.left; + anchors.rightMargin: 16; + boxSize: 24; + } + + // "CANCEL" button + HifiControlsUit.Button { + id: cancelButton_sendMoneyStep; + color: hifi.buttons.noneBorderless; + colorScheme: hifi.colorSchemes.dark; + anchors.right: sendButton.left; + anchors.rightMargin: 16; + anchors.verticalCenter: parent.verticalCenter; + height: 35; + width: 100; + text: "CANCEL"; + onClicked: { + sendMoneyStep.selectedRecipientNodeID = ""; + sendMoneyStep.selectedRecipientDisplayName = ""; + sendMoneyStep.selectedRecipientUserName = ""; + root.nextActiveView = "sendMoneyHome"; + } + } + + // "SEND" button + HifiControlsUit.Button { + id: sendButton; + color: hifi.buttons.blue; + colorScheme: hifi.colorSchemes.dark; + anchors.right: parent.right; + anchors.verticalCenter: parent.verticalCenter; + height: 35; + width: 100; + text: "SEND"; + onClicked: { + root.isCurrentlySendingMoney = true; + } + } + } + } + } + // Send Money Screen END + + // Sending Money Overlay START + Rectangle { + id: sendingMoneyOverlay; + z: 998; + + visible: root.isCurrentlySendingMoney; + anchors.fill: parent; + color: Qt.rgba(0.0, 0.0, 0.0, 0.5); + + // This object is always used in a popup or full-screen Wallet section. + // This MouseArea is used to prevent a user from being + // able to click on a button/mouseArea underneath the popup/section. + MouseArea { + anchors.fill: parent; + propagateComposedEvents: false; + } + + AnimatedImage { + id: sendingMoneyImage; + source: "../../../../../icons/profilePicLoading.gif" + width: 160; + height: width; + anchors.top: parent.top; + anchors.topMargin: 185; + anchors.horizontalCenter: parent.horizontalCenter; + } + + RalewaySemiBold { + text: "Sending"; + // Anchors + anchors.top: sendingMoneyImage.bottom; + anchors.topMargin: 22; + anchors.horizontalCenter: parent.horizontalCenter; + width: paintedWidth; + // Text size + size: 24; + // Style + color: hifi.colors.white; + verticalAlignment: Text.AlignVCenter; + } + } + // Sending Money Overlay END From 68120106608c24a0113789b73936e24762c6b7b4 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 10 Jan 2018 15:33:18 -0800 Subject: [PATCH 08/26] The skeleton is there --- .../commerce/wallet/sendMoney/SendMoney.qml | 243 +++++++++++++++++- 1 file changed, 231 insertions(+), 12 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index e7cdc0dd4d..6c04bb946d 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -30,7 +30,8 @@ Item { property int parentAppNavBarHeight; property string currentActiveView: "sendMoneyHome"; property string nextActiveView: ""; - property bool isCurrentlyFullScreen: chooseRecipientConnection.visible || chooseRecipientNearby.visible || sendMoneyStep.visible; + property bool isCurrentlyFullScreen: chooseRecipientConnection.visible || + chooseRecipientNearby.visible || sendMoneyStep.visible || paymentSuccess.visible; property bool isCurrentlySendingMoney: false; // This object is always used in a popup or full-screen Wallet section. @@ -449,7 +450,6 @@ Item { height: parent.height - 30; RalewaySemiBold { - id: chooseRecipientText_nearby; text: "Choose Recipient:"; // Anchors anchors.top: parent.top; @@ -483,7 +483,7 @@ Item { } onClicked: { root.nextActiveView = "sendMoneyHome"; - chooseRecipientNearby.selectedRecipient = ""; + resetSendMoneyData(); } } } @@ -586,7 +586,7 @@ Item { text: "Cancel"; onClicked: { root.nextActiveView = "sendMoneyHome"; - chooseRecipientNearby.selectedRecipient = ""; + resetSendMoneyData(); } } @@ -606,8 +606,8 @@ Item { onClicked: { sendMoneyStep.referrer = "nearby"; sendMoneyStep.selectedRecipientNodeID = chooseRecipientNearby.selectedRecipient; - sendMoneyStep.selectedRecipientDisplayName = ""; - sendMoneyStep.selectedRecipientUserName = ""; + sendMoneyStep.selectedRecipientDisplayName = '"ZRF Changeme"'; + sendMoneyStep.selectedRecipientUserName = 'unknown username'; chooseRecipientNearby.selectedRecipient = ""; root.nextActiveView = "sendMoneyStep"; @@ -615,7 +615,7 @@ Item { } } } - // Choose Recipient Nearby + // Choose Recipient Nearby END // Send Money Screen BEGIN Rectangle { @@ -679,7 +679,7 @@ Item { RalewaySemiBold { id: recipientDisplayName; - text: '"ZRF Changeme"'; + text: sendMoneyStep.selectedRecipientDisplayName; // Anchors anchors.top: parent.top; anchors.left: sendToText_sendMoneyStep.right; @@ -695,7 +695,7 @@ Item { RalewaySemiBold { id: recipientUsername; - text: "unknown username"; + text: sendMoneyStep.selectedRecipientUserName; // Anchors anchors.bottom: parent.bottom; anchors.left: recipientDisplayName.anchors.left; @@ -852,9 +852,7 @@ Item { width: 100; text: "CANCEL"; onClicked: { - sendMoneyStep.selectedRecipientNodeID = ""; - sendMoneyStep.selectedRecipientDisplayName = ""; - sendMoneyStep.selectedRecipientUserName = ""; + resetSendMoneyData(); root.nextActiveView = "sendMoneyHome"; } } @@ -871,6 +869,18 @@ Item { text: "SEND"; onClicked: { root.isCurrentlySendingMoney = true; + amountTextField.focus = false; + optionalMessage.focus = false; + tempTimer.interval = 250; + tempTimer.start(); + } + } + + Timer { + id: tempTimer; + onTriggered: { + root.isCurrentlySendingMoney = false; + root.nextActiveView = "paymentSuccess"; } } } @@ -920,7 +930,209 @@ Item { } } // Sending Money Overlay END + + // Payment Success BEGIN + Rectangle { + id: paymentSuccess; + visible: root.currentActiveView === "paymentSuccess"; + anchors.fill: parent; + color: "#AAAAAA"; + + Rectangle { + anchors.centerIn: parent; + width: parent.width - 30; + height: parent.height - 30; + + RalewaySemiBold { + id: paymentSentText; + text: "Payment Sent"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 26; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: paintedWidth; + height: 30; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + } + + HiFiGlyphs { + id: closeGlyphButton_paymentSuccess; + text: hifi.glyphs.close; + size: 26; + anchors.top: parent.top; + anchors.topMargin: 10; + anchors.right: parent.right; + anchors.rightMargin: 10; + MouseArea { + anchors.fill: parent; + hoverEnabled: true; + onEntered: { + parent.text = hifi.glyphs.closeInverted; + } + onExited: { + parent.text = hifi.glyphs.close; + } + onClicked: { + root.nextActiveView = "sendMoneyHome"; + resetSendMoneyData(); + } + } + } + + Item { + id: sendToContainer_paymentSuccess; + anchors.top: paymentSentText.bottom; + anchors.topMargin: 20; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + RalewaySemiBold { + id: sendToText_paymentSuccess; + text: "Sent To:"; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.bottom: parent.bottom; + width: 90; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + RalewaySemiBold { + id: recipientDisplayName_paymentSuccess; + text: sendMoneyStep.selectedRecipientDisplayName; + // Anchors + anchors.top: parent.top; + anchors.left: sendToText_paymentSuccess.right; + anchors.right: parent.right; + height: parent.height/2; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignBottom; + } + + RalewaySemiBold { + id: recipientUsername_paymentSuccess; + text: sendMoneyStep.selectedRecipientUserName; + // Anchors + anchors.bottom: parent.bottom; + anchors.left: recipientDisplayName_paymentSuccess.anchors.left; + anchors.leftMargin: recipientDisplayName_paymentSuccess.anchors.leftMargin; + anchors.right: recipientDisplayName_paymentSuccess.anchors.right; + anchors.rightMargin: recipientDisplayName_paymentSuccess.anchors.rightMargin; + height: parent.height/2; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignTop; + } + } + + Item { + id: amountContainer_paymentSuccess; + anchors.top: sendToContainer_paymentSuccess.bottom; + anchors.topMargin: 16; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + RalewaySemiBold { + id: amountText_paymentSuccess; + text: "Amount:"; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.bottom: parent.bottom; + width: 90; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + // "HFC" balance label + HiFiGlyphs { + id: amountSentLabel; + text: hifi.glyphs.hfc; + // Size + size: 32; + // Anchors + anchors.left: amountText_paymentSuccess.right; + anchors.verticalCenter: parent.verticalCenter; + height: 50; + // Style + color: hifi.colors.baseGray; + } + + RalewaySemiBold { + id: amountSentText; + text: amountTextField.text; + // Anchors + anchors.verticalCenter: parent.verticalCenter; + anchors.left: amountSentLabel.right; + anchors.leftMargin: 20; + anchors.right: parent.right; + height: 50; + // Style + size: 22; + color: hifi.colors.baseGray; + } + } + + RalewaySemiBold { + id: optionalMessage_paymentSuccess; + text: optionalMessage.text; + // Anchors + anchors.top: amountContainer_paymentSuccess.bottom; + anchors.left: parent.left; + anchors.leftMargin: 110; + anchors.right: parent.right; + anchors.bottom: closeButton.top; + anchors.bottomMargin: 40; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + wrapMode: Text.WordWrap; + verticalAlignment: Text.AlignTop; + } + + // "Close" button + HifiControlsUit.Button { + id: closeButton; + color: hifi.buttons.blue; + colorScheme: hifi.colorSchemes.dark; + anchors.horizontalCenter: parent.horizontalCenter; + anchors.bottom: parent.bottom; + anchors.bottomMargin: 80; + height: 50; + width: 120; + text: "Close"; + onClicked: { + root.nextActiveView = "sendMoneyHome"; + resetSendMoneyData(); + } + } + } + } + // Payment Success END // @@ -943,6 +1155,13 @@ Item { } } + function resetSendMoneyData() { + chooseRecipientNearby.selectedRecipient = ""; + sendMoneyStep.selectedRecipientNodeID = ""; + sendMoneyStep.selectedRecipientDisplayName = ""; + sendMoneyStep.selectedRecipientUserName = ""; + } + // // Function Name: fromScript() // From 93b15c0aa6a70e96fbe9980719bfa703b0d9eba2 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 10 Jan 2018 15:53:13 -0800 Subject: [PATCH 09/26] Payment Failure --- .../commerce/wallet/sendMoney/SendMoney.qml | 250 +++++++++++++++++- 1 file changed, 245 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 6c04bb946d..e24cbda07d 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -31,7 +31,7 @@ Item { property string currentActiveView: "sendMoneyHome"; property string nextActiveView: ""; property bool isCurrentlyFullScreen: chooseRecipientConnection.visible || - chooseRecipientNearby.visible || sendMoneyStep.visible || paymentSuccess.visible; + chooseRecipientNearby.visible || sendMoneyStep.visible || paymentSuccess.visible || paymentFailure.visible; property bool isCurrentlySendingMoney: false; // This object is always used in a popup or full-screen Wallet section. @@ -509,7 +509,7 @@ Item { // Style color: hifi.colors.baseGray; horizontalAlignment: Text.AlignHCenter; - wrapMode: Text.WordWrap; + wrapMode: Text.Wrap; } } @@ -568,7 +568,7 @@ Item { // Style color: hifi.colors.baseGray; horizontalAlignment: Text.AlignHCenter; - wrapMode: Text.WordWrap; + wrapMode: Text.Wrap; } } @@ -880,7 +880,7 @@ Item { id: tempTimer; onTriggered: { root.isCurrentlySendingMoney = false; - root.nextActiveView = "paymentSuccess"; + root.nextActiveView = "paymentFailure"; } } } @@ -1104,13 +1104,14 @@ Item { anchors.left: parent.left; anchors.leftMargin: 110; anchors.right: parent.right; + anchors.rightMargin: 16; anchors.bottom: closeButton.top; anchors.bottomMargin: 40; // Text size size: 22; // Style color: hifi.colors.baseGray; - wrapMode: Text.WordWrap; + wrapMode: Text.Wrap; verticalAlignment: Text.AlignTop; } @@ -1133,6 +1134,243 @@ Item { } } // Payment Success END + + // Payment Failure BEGIN + Rectangle { + id: paymentFailure; + + visible: root.currentActiveView === "paymentFailure"; + anchors.fill: parent; + color: "#AAAAAA"; + + Rectangle { + anchors.centerIn: parent; + width: parent.width - 30; + height: parent.height - 30; + + RalewaySemiBold { + id: paymentFailureText; + text: "Payment Failed"; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 26; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: paintedWidth; + height: 30; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + } + + HiFiGlyphs { + id: closeGlyphButton_paymentFailure; + text: hifi.glyphs.close; + size: 26; + anchors.top: parent.top; + anchors.topMargin: 10; + anchors.right: parent.right; + anchors.rightMargin: 10; + MouseArea { + anchors.fill: parent; + hoverEnabled: true; + onEntered: { + parent.text = hifi.glyphs.closeInverted; + } + onExited: { + parent.text = hifi.glyphs.close; + } + onClicked: { + root.nextActiveView = "sendMoneyHome"; + resetSendMoneyData(); + } + } + } + + RalewaySemiBold { + id: paymentFailureDetailText; + text: "The recipient you specified was unable to receive your payment."; + anchors.top: paymentFailureText.bottom; + anchors.topMargin: 20; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + Item { + id: sendToContainer_paymentFailure; + anchors.top: paymentFailureDetailText.bottom; + anchors.topMargin: 20; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + RalewaySemiBold { + id: paymentFailureText_paymentFailure; + text: "Sent To:"; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.bottom: parent.bottom; + width: 90; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + RalewaySemiBold { + id: recipientDisplayName_paymentFailure; + text: sendMoneyStep.selectedRecipientDisplayName; + // Anchors + anchors.top: parent.top; + anchors.left: sendToText_paymentFailure.right; + anchors.right: parent.right; + height: parent.height/2; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignBottom; + } + + RalewaySemiBold { + id: recipientUsername_paymentFailure; + text: sendMoneyStep.selectedRecipientUserName; + // Anchors + anchors.bottom: parent.bottom; + anchors.left: recipientDisplayName_paymentFailure.anchors.left; + anchors.leftMargin: recipientDisplayName_paymentFailure.anchors.leftMargin; + anchors.right: recipientDisplayName_paymentFailure.anchors.right; + anchors.rightMargin: recipientDisplayName_paymentFailure.anchors.rightMargin; + height: parent.height/2; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignTop; + } + } + + Item { + id: amountContainer_paymentFailure; + anchors.top: sendToContainer_paymentFailure.bottom; + anchors.topMargin: 16; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 80; + + RalewaySemiBold { + id: amountText_paymentFailure; + text: "Amount:"; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.bottom: parent.bottom; + width: 90; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } + + // "HFC" balance label + HiFiGlyphs { + id: amountSentLabel_paymentFailure; + text: hifi.glyphs.hfc; + // Size + size: 32; + // Anchors + anchors.left: amountText_paymentFailure.right; + anchors.verticalCenter: parent.verticalCenter; + height: 50; + // Style + color: hifi.colors.baseGray; + } + + RalewaySemiBold { + id: amountSentText_paymentFailure; + text: amountTextField.text; + // Anchors + anchors.verticalCenter: parent.verticalCenter; + anchors.left: amountSentLabel_paymentFailure.right; + anchors.leftMargin: 20; + anchors.right: parent.right; + height: 50; + // Style + size: 22; + color: hifi.colors.baseGray; + } + } + + RalewaySemiBold { + id: optionalMessage_paymentFailuire; + text: optionalMessage.text; + // Anchors + anchors.top: amountContainer_paymentFailure.bottom; + anchors.left: parent.left; + anchors.leftMargin: 110; + anchors.right: parent.right; + anchors.rightMargin: 16; + anchors.bottom: closeButton.top; + anchors.bottomMargin: 40; + // Text size + size: 22; + // Style + color: hifi.colors.baseGray; + wrapMode: Text.Wrap; + verticalAlignment: Text.AlignTop; + } + + // "Close" button + HifiControlsUit.Button { + id: closeButton_paymentFailure; + color: hifi.buttons.blue; + colorScheme: hifi.colorSchemes.dark; + anchors.horizontalCenter: parent.horizontalCenter; + anchors.bottom: parent.bottom; + anchors.bottomMargin: 80; + height: 50; + width: 120; + text: "Cancel"; + onClicked: { + root.nextActiveView = "sendMoneyHome"; + resetSendMoneyData(); + } + } + + // "Retry" button + HifiControlsUit.Button { + id: retryButton_paymentFailure; + color: hifi.buttons.blue; + colorScheme: hifi.colorSchemes.dark; + anchors.right: parent.right; + anchors.bottom: parent.bottom; + anchors.bottomMargin: 80; + height: 50; + width: 120; + text: "Retry"; + onClicked: { + + } + } + } + } + // Payment Failure END // @@ -1160,6 +1398,8 @@ Item { sendMoneyStep.selectedRecipientNodeID = ""; sendMoneyStep.selectedRecipientDisplayName = ""; sendMoneyStep.selectedRecipientUserName = ""; + amountTextField.text = ""; + optionalMessage.text = ""; } // From 260aee42a87d0a5a3b6231bda3c622384dbb347f Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 10 Jan 2018 16:18:34 -0800 Subject: [PATCH 10/26] Improvements --- .../wallet/sendMoney/ConnectionItem.qml | 3 +- .../commerce/wallet/sendMoney/SendMoney.qml | 68 +++++++++++++++---- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml index d9adbee710..80c87e307b 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml @@ -114,7 +114,8 @@ Item { width: 110; text: "CHOOSE"; onClicked: { - + var msg = { method: 'chooseConnection', userName: root.userName }; + sendToSendMoney(msg); } } } diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index e24cbda07d..38d3259b49 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -415,7 +415,12 @@ Item { Connections { onSendToSendMoney: { - // TODO + sendMoneyStep.referrer = "connections"; + sendMoneyStep.selectedRecipientNodeID = ''; + sendMoneyStep.selectedRecipientDisplayName = msg.userName; + sendMoneyStep.selectedRecipientUserName = 'connection'; + + root.nextActiveView = "sendMoneyStep"; } } @@ -721,7 +726,12 @@ Item { width: 120; text: "CHANGE"; onClicked: { - root.nextActiveView = "chooseRecipientNearby"; + if (sendMoneyStep.referrer === "connections") { + root.nextActiveView = "chooseRecipientConnection"; + } else if (sendMoneyStep.referrer === "nearby") { + root.nextActiveView = "chooseRecipientNearby"; + } + resetSendMoneyData(); } } } @@ -765,10 +775,28 @@ Item { activeFocusOnPress: true; activeFocusOnTab: true; + validator: IntValidator { bottom: 0; } + onAccepted: { optionalMessage.focus = true; } } + + RalewaySemiBold { + id: amountTextFieldError; + // Anchors + anchors.top: amountTextField.bottom; + anchors.topMargin: 2; + anchors.left: amountTextField.left; + anchors.right: amountTextField.right; + height: 40; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignTop; + horizontalAlignment: Text.AlignRight; + } } Item { @@ -868,11 +896,19 @@ Item { width: 100; text: "SEND"; onClicked: { - root.isCurrentlySendingMoney = true; - amountTextField.focus = false; - optionalMessage.focus = false; - tempTimer.interval = 250; - tempTimer.start(); + if (parseInt(amountTextField.text) > parseInt(balanceText.text)) { + amountTextField.focus = true; + amountTextField.error = true; + amountTextFieldError.text = "amount exceeds available funds"; + } else { + amountTextFieldError.text = ""; + amountTextField.error = false; + root.isCurrentlySendingMoney = true; + amountTextField.focus = false; + optionalMessage.focus = false; + tempTimer.interval = 250; + tempTimer.start(); + } } } @@ -1203,12 +1239,13 @@ Item { // Style color: hifi.colors.baseGray; verticalAlignment: Text.AlignVCenter; + wrapMode: Text.Wrap; } Item { id: sendToContainer_paymentFailure; anchors.top: paymentFailureDetailText.bottom; - anchors.topMargin: 20; + anchors.topMargin: 8; anchors.left: parent.left; anchors.leftMargin: 20; anchors.right: parent.right; @@ -1216,7 +1253,7 @@ Item { height: 80; RalewaySemiBold { - id: paymentFailureText_paymentFailure; + id: sentToText_paymentFailure; text: "Sent To:"; // Anchors anchors.top: parent.top; @@ -1235,7 +1272,7 @@ Item { text: sendMoneyStep.selectedRecipientDisplayName; // Anchors anchors.top: parent.top; - anchors.left: sendToText_paymentFailure.right; + anchors.left: sentToText_paymentFailure.right; anchors.right: parent.right; height: parent.height/2; // Text size @@ -1339,7 +1376,7 @@ Item { // "Close" button HifiControlsUit.Button { id: closeButton_paymentFailure; - color: hifi.buttons.blue; + color: hifi.buttons.noneBorderless; colorScheme: hifi.colorSchemes.dark; anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom; @@ -1359,13 +1396,16 @@ Item { color: hifi.buttons.blue; colorScheme: hifi.colorSchemes.dark; anchors.right: parent.right; + anchors.rightMargin: 12; anchors.bottom: parent.bottom; anchors.bottomMargin: 80; height: 50; width: 120; text: "Retry"; onClicked: { - + root.isCurrentlySendingMoney = true; + tempTimer.interval = 250; + tempTimer.start(); } } } @@ -1394,6 +1434,10 @@ Item { } function resetSendMoneyData() { + amountTextField.focus = false; + optionalMessage.focus = false; + amountTextFieldError.text = ""; + amountTextField.error = false; chooseRecipientNearby.selectedRecipient = ""; sendMoneyStep.selectedRecipientNodeID = ""; sendMoneyStep.selectedRecipientDisplayName = ""; From b3e3af4ee777db12631fed12080418de1ebfca2d Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 10 Jan 2018 16:23:29 -0800 Subject: [PATCH 11/26] Add character count :) --- .../hifi/commerce/wallet/sendMoney/SendMoney.qml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 38d3259b49..cf80ef3816 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -833,6 +833,7 @@ Item { activeFocusOnTab: true; // Workaround for no max length on TextAreas onTextChanged: { + optionalMessageCharacterCount.text = optionalMessage.text.length + "/" + optionalMessage.maximumLength; if (text.length > maximumLength) { var cursor = cursorPosition; text = previousText; @@ -845,6 +846,20 @@ Item { previousText = text; } } + RalewaySemiBold { + id: optionalMessageCharacterCount; + // Anchors + anchors.top: optionalMessage.bottom; + anchors.topMargin: 2; + anchors.right: optionalMessage.right; + height: paintedHeight; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignTop; + horizontalAlignment: Text.AlignRight; + } } Item { From 0d137d62c833d76a5af3ed72b1c977b09b5db7d9 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 10 Jan 2018 16:37:47 -0800 Subject: [PATCH 12/26] HMD tweaks --- .../qml/hifi/commerce/wallet/sendMoney/SendMoney.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index cf80ef3816..eb6aa3bb0d 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -739,7 +739,7 @@ Item { Item { id: amountContainer; anchors.top: sendToContainer.bottom; - anchors.topMargin: 16; + anchors.topMargin: 2; anchors.left: parent.left; anchors.leftMargin: 20; anchors.right: parent.right; @@ -807,7 +807,7 @@ Item { anchors.leftMargin: 20; anchors.right: parent.right; anchors.rightMargin: 20; - height: 180; + height: 140; FontLoader { id: firaSansSemiBold; source: "../../../../../fonts/FiraSans-SemiBold.ttf"; } TextArea { @@ -833,7 +833,6 @@ Item { activeFocusOnTab: true; // Workaround for no max length on TextAreas onTextChanged: { - optionalMessageCharacterCount.text = optionalMessage.text.length + "/" + optionalMessage.maximumLength; if (text.length > maximumLength) { var cursor = cursorPosition; text = previousText; @@ -848,6 +847,7 @@ Item { } RalewaySemiBold { id: optionalMessageCharacterCount; + text: optionalMessage.text.length + "/" + optionalMessage.maximumLength; // Anchors anchors.top: optionalMessage.bottom; anchors.topMargin: 2; From 939012a2d0454fdda76bfeae32820dedd9e91744 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 10 Jan 2018 17:10:05 -0800 Subject: [PATCH 13/26] Hook up the endpoints! --- .../commerce/wallet/sendMoney/SendMoney.qml | 38 +++++++++++++------ interface/src/commerce/Ledger.cpp | 24 ++++++++++++ interface/src/commerce/Ledger.h | 8 ++++ interface/src/commerce/QmlCommerce.cpp | 26 +++++++++++++ interface/src/commerce/QmlCommerce.h | 6 +++ 5 files changed, 90 insertions(+), 12 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index eb6aa3bb0d..a7ca8e2194 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -50,6 +50,26 @@ Item { onBalanceResult : { balanceText.text = result.data.balance; } + + onTransferHfcToNodeResult: { + root.isCurrentlySendingMoney = false; + + if (result.status === 'success') { + root.nextActiveView = 'paymentSuccess'; + } else { + root.nextActiveView = 'paymentFailure'; + } + } + + onTransferHfcToUsernameResult: { + root.isCurrentlySendingMoney = false; + + if (result.status === 'success') { + root.nextActiveView = 'paymentSuccess'; + } else { + root.nextActiveView = 'paymentFailure'; + } + } } Connections { @@ -874,6 +894,7 @@ Item { HifiControlsUit.CheckBox { id: sendPubliclyCheckbox; + visible: false; // FIXME ONCE PARTICLE EFFECTS ARE IN text: "Send Publicly" // Anchors anchors.verticalCenter: parent.verticalCenter; @@ -921,19 +942,14 @@ Item { root.isCurrentlySendingMoney = true; amountTextField.focus = false; optionalMessage.focus = false; - tempTimer.interval = 250; - tempTimer.start(); + if (sendMoneyStep.referrer = "connections") { + + } else if (sendMoneyStep.referrer = "nearby") { + + } } } } - - Timer { - id: tempTimer; - onTriggered: { - root.isCurrentlySendingMoney = false; - root.nextActiveView = "paymentFailure"; - } - } } } } @@ -1419,8 +1435,6 @@ Item { text: "Retry"; onClicked: { root.isCurrentlySendingMoney = true; - tempTimer.interval = 250; - tempTimer.start(); } } } diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 51658ddef8..98df9e4997 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -46,6 +46,8 @@ Handler(buy) Handler(receiveAt) Handler(balance) Handler(inventory) +Handler(transferHfcToNode) +Handler(transferHfcToUsername) void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request) { auto accountManager = DependencyManager::get(); @@ -268,3 +270,25 @@ void Ledger::certificateInfo(const QString& certificateId) { request["certificate_id"] = certificateId; send(endpoint, "certificateInfoSuccess", "certificateInfoFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::None, request); } + +void Ledger::transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage) { + QJsonObject transaction; + transaction["hfc_key"] = hfc_key; + transaction["node_id"] = nodeID; + transaction["quantity"] = amount; + transaction["message"] = optionalMessage; + QJsonDocument transactionDoc{ transaction }; + auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); + signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_node", "transferHfcToNodeSuccess", "transferHfcToNodeFailure"); +} + +void Ledger::transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage) { + QJsonObject transaction; + transaction["hfc_key"] = hfc_key; + transaction["username"] = username; + transaction["quantity"] = amount; + transaction["message"] = optionalMessage; + QJsonDocument transactionDoc{ transaction }; + auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); + signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_user", "transferHfcToUsernameSuccess", "transferHfcToUsernameFailure"); +} diff --git a/interface/src/commerce/Ledger.h b/interface/src/commerce/Ledger.h index 5d90aa0808..9a781978e4 100644 --- a/interface/src/commerce/Ledger.h +++ b/interface/src/commerce/Ledger.h @@ -34,6 +34,8 @@ public: void reset(); void updateLocation(const QString& asset_id, const QString location, const bool controlledFailure = false); void certificateInfo(const QString& certificateId); + void transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage); + void transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage); enum CertificateStatus { CERTIFICATE_STATUS_UNKNOWN = 0, @@ -52,6 +54,8 @@ signals: void accountResult(QJsonObject result); void locationUpdateResult(QJsonObject result); void certificateInfoResult(QJsonObject result); + void transferHfcToNodeResult(QJsonObject result); + void transferHfcToUsernameResult(QJsonObject result); void updateCertificateStatus(const QString& certID, uint certStatus); @@ -74,6 +78,10 @@ public slots: void updateLocationFailure(QNetworkReply& reply); void certificateInfoSuccess(QNetworkReply& reply); void certificateInfoFailure(QNetworkReply& reply); + void transferHfcToNodeSuccess(QNetworkReply& reply); + void transferHfcToNodeFailure(QNetworkReply& reply); + void transferHfcToUsernameSuccess(QNetworkReply& reply); + void transferHfcToUsernameFailure(QNetworkReply& reply); private: QJsonObject apiResponse(const QString& label, QNetworkReply& reply); diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index 320c7e041c..963028ccdf 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -29,6 +29,8 @@ QmlCommerce::QmlCommerce() { connect(wallet.data(), &Wallet::walletStatusResult, this, &QmlCommerce::walletStatusResult); connect(ledger.data(), &Ledger::certificateInfoResult, this, &QmlCommerce::certificateInfoResult); connect(ledger.data(), &Ledger::updateCertificateStatus, this, &QmlCommerce::updateCertificateStatus); + connect(ledger.data(), &Ledger::transferHfcToNodeResult, this, &QmlCommerce::transferHfcToNodeResult); + connect(ledger.data(), &Ledger::transferHfcToUsernameResult, this, &QmlCommerce::transferHfcToUsernameResult); auto accountManager = DependencyManager::get(); connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() { @@ -149,3 +151,27 @@ void QmlCommerce::certificateInfo(const QString& certificateId) { auto ledger = DependencyManager::get(); ledger->certificateInfo(certificateId); } + +void QmlCommerce::transferHfcToNode(const QString& nodeID, const int& amount, const QString& optionalMessage) { + auto ledger = DependencyManager::get(); + auto wallet = DependencyManager::get(); + QStringList keys = wallet->listPublicKeys(); + if (keys.count() == 0) { + QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } }; + return emit buyResult(result); + } + QString key = keys[0]; + ledger->transferHfcToNode(key, nodeID, amount, optionalMessage); +} + +void QmlCommerce::transferHfcToUsername(const QString& username, const int& amount, const QString& optionalMessage) { + auto ledger = DependencyManager::get(); + auto wallet = DependencyManager::get(); + QStringList keys = wallet->listPublicKeys(); + if (keys.count() == 0) { + QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } }; + return emit buyResult(result); + } + QString key = keys[0]; + ledger->transferHfcToUsername(key, username, amount, optionalMessage); +} diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index f2e6c82021..791097d7cf 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -45,6 +45,9 @@ signals: void updateCertificateStatus(const QString& certID, uint certStatus); + void transferHfcToNodeResult(QJsonObject result); + void transferHfcToUsernameResult(QJsonObject result); + protected: Q_INVOKABLE void getWalletStatus(); @@ -67,6 +70,9 @@ protected: Q_INVOKABLE void account(); Q_INVOKABLE void certificateInfo(const QString& certificateId); + + Q_INVOKABLE void transferHfcToNode(const QString& nodeID, const int& amount, const QString& optionalMessage); + Q_INVOKABLE void transferHfcToUsername(const QString& username, const int& amount, const QString& optionalMessage); }; #endif // hifi_QmlCommerce_h From d577b2e9e887b59f793c9ce1dc90cb01f43ce6e7 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 11 Jan 2018 11:45:43 -0800 Subject: [PATCH 14/26] Actually add the API calls --- .../qml/hifi/commerce/wallet/sendMoney/SendMoney.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index a7ca8e2194..b3bdbab96d 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -943,9 +943,9 @@ Item { amountTextField.focus = false; optionalMessage.focus = false; if (sendMoneyStep.referrer = "connections") { - + Commerce.transferHfcToUsername(sendMoneyStep.selectedRecipientUserName, parseInt(amountTextField.text), optionalMessage.text); } else if (sendMoneyStep.referrer = "nearby") { - + Commerce.transferHfcToNode(sendMoneyStep.selectedRecipientNodeID, parseInt(amountTextField.text), optionalMessage.text); } } } From 81ab5ac81c9afb9a1c443d8a01731ee0ba8641ef Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 11 Jan 2018 12:50:25 -0800 Subject: [PATCH 15/26] hfc_key -> public_key --- interface/src/commerce/Ledger.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 98df9e4997..1e46fb3436 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -273,7 +273,7 @@ void Ledger::certificateInfo(const QString& certificateId) { void Ledger::transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage) { QJsonObject transaction; - transaction["hfc_key"] = hfc_key; + transaction["public_key"] = hfc_key; transaction["node_id"] = nodeID; transaction["quantity"] = amount; transaction["message"] = optionalMessage; @@ -284,7 +284,7 @@ void Ledger::transferHfcToNode(const QString& hfc_key, const QString& nodeID, co void Ledger::transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage) { QJsonObject transaction; - transaction["hfc_key"] = hfc_key; + transaction["public_key"] = hfc_key; transaction["username"] = username; transaction["quantity"] = amount; transaction["message"] = optionalMessage; From df58065e757d6d8e3463e5f959e1a77dca14c487 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 11 Jan 2018 13:02:00 -0800 Subject: [PATCH 16/26] Silly bug --- .../resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 851e8903bc..9e21cb7289 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -39,7 +39,8 @@ Item { // able to click on a button/mouseArea underneath the popup/section. MouseArea { x: 0; - y: root.isCurrentlyFullScreen ? root.parentAppTitleBarHeight : 0; + y: root.isCurrentlyFullScreen ? 0 : root.parentAppTitleBarHeight; + width: parent.width; height: root.isCurrentlyFullScreen ? parent.height : parent.height - root.parentAppTitleBarHeight - root.parentAppNavBarHeight; propagateComposedEvents: false; } From 1e608b13b2b869aeedb7d7cc2efe84faa44f1495 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 11 Jan 2018 14:45:43 -0800 Subject: [PATCH 17/26] Show username when admin (this probably isn't the way to get username --- .../qml/hifi/commerce/wallet/Wallet.qml | 1 + .../wallet/sendMoney/ConnectionItem.qml | 2 +- .../commerce/wallet/sendMoney/SendMoney.qml | 162 ++++++++++++++---- libraries/avatars/src/AvatarData.h | 3 +- libraries/avatars/src/ScriptAvatarData.cpp | 1 + libraries/avatars/src/ScriptAvatarData.h | 3 +- scripts/system/commerce/wallet.js | 35 +++- scripts/system/pal.js | 4 +- 8 files changed, 169 insertions(+), 42 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 5340f0e202..6b350f9f93 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -736,6 +736,7 @@ Rectangle { sendMoney.updateConnections(message.connections); break; case 'selectRecipient': + case 'updateSelectedRecipientUsername': sendMoney.fromScript(message); break; default: diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml index 80c87e307b..84d6b304f6 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml @@ -114,7 +114,7 @@ Item { width: 110; text: "CHOOSE"; onClicked: { - var msg = { method: 'chooseConnection', userName: root.userName }; + var msg = { method: 'chooseConnection', userName: root.userName, profilePicUrl: root.profilePicUrl }; sendToSendMoney(msg); } } diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 9e21cb7289..0d948bbe4b 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -14,6 +14,7 @@ import Hifi 1.0 as Hifi import QtQuick 2.6 import QtQuick.Controls 2.2 +import QtGraphicalEffects 1.0 import "../../../../styles-uit" import "../../../../controls-uit" as HifiControlsUit import "../../../../controls" as HifiControls @@ -440,6 +441,7 @@ Item { sendMoneyStep.selectedRecipientNodeID = ''; sendMoneyStep.selectedRecipientDisplayName = msg.userName; sendMoneyStep.selectedRecipientUserName = 'connection'; + sendMoneyStep.selectedRecipientProfilePic = msg.profilePicUrl; root.nextActiveView = "sendMoneyStep"; } @@ -561,8 +563,8 @@ Item { } RalewaySemiBold { - id: avatarNodeID; - text: chooseRecipientNearby.selectedRecipient; + id: avatarDisplayName; + text: '"' + AvatarList.getAvatar(chooseRecipientNearby.selectedRecipient).sessionDisplayName + '"'; // Anchors anchors.top: sendToText.bottom; anchors.topMargin: 60; @@ -572,7 +574,43 @@ Item { anchors.rightMargin: 30; height: paintedHeight; // Text size - size: 18; + size: 22; + // Style + horizontalAlignment: Text.AlignHCenter; + color: hifi.colors.baseGray; + } + + RalewaySemiBold { + id: avatarNodeID; + text: chooseRecipientNearby.selectedRecipient; + // Anchors + anchors.top: avatarDisplayName.bottom; + anchors.topMargin: 6; + anchors.left: parent.left; + anchors.leftMargin: 30; + anchors.right: parent.right; + anchors.rightMargin: 30; + height: paintedHeight; + // Text size + size: 14; + // Style + horizontalAlignment: Text.AlignHCenter; + color: hifi.colors.lightGrayText; + } + + RalewaySemiBold { + id: avatarUserName; + text: sendMoneyStep.selectedRecipientUserName; + // Anchors + anchors.top: avatarNodeID.bottom; + anchors.topMargin: 12; + anchors.left: parent.left; + anchors.leftMargin: 30; + anchors.right: parent.right; + anchors.rightMargin: 30; + height: paintedHeight; + // Text size + size: 22; // Style horizontalAlignment: Text.AlignHCenter; color: hifi.colors.baseGray; @@ -632,8 +670,6 @@ Item { onClicked: { sendMoneyStep.referrer = "nearby"; sendMoneyStep.selectedRecipientNodeID = chooseRecipientNearby.selectedRecipient; - sendMoneyStep.selectedRecipientDisplayName = '"ZRF Changeme"'; - sendMoneyStep.selectedRecipientUserName = 'unknown username'; chooseRecipientNearby.selectedRecipient = ""; root.nextActiveView = "sendMoneyStep"; @@ -652,6 +688,7 @@ Item { property string selectedRecipientNodeID; property string selectedRecipientDisplayName; property string selectedRecipientUserName; + property string selectedRecipientProfilePic; visible: root.currentActiveView === "sendMoneyStep"; anchors.fill: parent; @@ -703,37 +740,94 @@ Item { verticalAlignment: Text.AlignVCenter; } - RalewaySemiBold { - id: recipientDisplayName; - text: sendMoneyStep.selectedRecipientDisplayName; - // Anchors + Item { + id: recipientIsNearby; + visible: sendMoneyStep.referrer === "nearby"; anchors.top: parent.top; anchors.left: sendToText_sendMoneyStep.right; anchors.right: changeButton.left; anchors.rightMargin: 12; - height: parent.height/2; - // Text size - size: 18; - // Style - color: hifi.colors.baseGray; - verticalAlignment: Text.AlignBottom; + height: parent.height; + + RalewaySemiBold { + id: recipientDisplayName; + text: sendMoneyStep.selectedRecipientDisplayName; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.right: parent.right; + anchors.rightMargin: 12; + height: parent.height/2; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignBottom; + } + + RalewaySemiBold { + text: sendMoneyStep.selectedRecipientUserName; + // Anchors + anchors.bottom: parent.bottom; + anchors.left: recipientDisplayName.anchors.left; + anchors.leftMargin: recipientDisplayName.anchors.leftMargin; + anchors.right: recipientDisplayName.anchors.right; + anchors.rightMargin: recipientDisplayName.anchors.rightMargin; + height: parent.height/2; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignTop; + } } - RalewaySemiBold { - id: recipientUsername; - text: sendMoneyStep.selectedRecipientUserName; - // Anchors - anchors.bottom: parent.bottom; - anchors.left: recipientDisplayName.anchors.left; - anchors.leftMargin: recipientDisplayName.anchors.leftMargin; - anchors.right: recipientDisplayName.anchors.right; - anchors.rightMargin: recipientDisplayName.anchors.rightMargin; - height: parent.height/2; - // Text size - size: 16; - // Style - color: hifi.colors.baseGray; - verticalAlignment: Text.AlignTop; + Item { + id: recipientIsConnection; + visible: sendMoneyStep.referrer === "connections"; + anchors.top: parent.top; + anchors.left: sendToText_sendMoneyStep.right; + anchors.right: changeButton.left; + anchors.rightMargin: 12; + height: parent.height; + + Image { + id: userImage; + source: sendMoneyStep.selectedRecipientProfilePic !== "" ? ((0 === sendMoneyStep.selectedRecipientProfilePic.indexOf("http")) ? + sendMoneyStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendMoneyStep.selectedRecipientProfilePic)) : ""; + mipmap: true; + // Anchors + anchors.left: parent.left; + anchors.verticalCenter: parent.verticalCenter; + height: parent.height - 4; + layer.enabled: true; + layer.effect: OpacityMask { + maskSource: Item { + width: userImage.width; + height: userImage.height; + Rectangle { + anchors.centerIn: parent; + width: userImage.width; // This works because userImage is square + height: width; + radius: width; + } + } + } + } + + RalewaySemiBold { + text: sendMoneyStep.selectedRecipientUserName; + // Anchors + anchors.left: userImage.right; + anchors.leftMargin: 8; + anchors.verticalCenter: parent.verticalCenter; + height: parent.height - 4; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + } } // "CHANGE" button @@ -1472,6 +1566,7 @@ Item { sendMoneyStep.selectedRecipientNodeID = ""; sendMoneyStep.selectedRecipientDisplayName = ""; sendMoneyStep.selectedRecipientUserName = ""; + sendMoneyStep.selectedRecipientProfilePic = ""; amountTextField.text = ""; optionalMessage.text = ""; } @@ -1494,10 +1589,17 @@ Item { case 'selectRecipient': if (message.isSelected) { chooseRecipientNearby.selectedRecipient = message.id[0]; + sendMoneyStep.selectedRecipientDisplayName = message.displayName; + sendMoneyStep.selectedRecipientUserName = message.userName; } else { chooseRecipientNearby.selectedRecipient = ""; + sendMoneyStep.selectedRecipientDisplayName = ''; + sendMoneyStep.selectedRecipientUserName = ''; } break; + case 'updateSelectedRecipientUsername': + sendMoneyStep.selectedRecipientUserName = message.userName; + break; default: console.log('SendMoney: Unrecognized message from wallet.js:', JSON.stringify(message)); } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index d7dd2837cb..00cc760658 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -358,7 +358,7 @@ class AvatarData : public QObject, public SpatiallyNestable { Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged) // sessionDisplayName is sanitized, defaulted version displayName that is defined by the AvatarMixer rather than by Interface clients. // The result is unique among all avatars present at the time. - Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName WRITE setSessionDisplayName) + Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName WRITE setSessionDisplayName NOTIFY sessionDisplayNameChanged) Q_PROPERTY(bool lookAtSnappingEnabled MEMBER _lookAtSnappingEnabled NOTIFY lookAtSnappingChanged) Q_PROPERTY(QString skeletonModelURL READ getSkeletonModelURLFromScript WRITE setSkeletonModelURLFromScript) Q_PROPERTY(QVector attachmentData READ getAttachmentData WRITE setAttachmentData) @@ -685,6 +685,7 @@ public: signals: void displayNameChanged(); + void sessionDisplayNameChanged(); void lookAtSnappingChanged(bool enabled); void sessionUUIDChanged(); diff --git a/libraries/avatars/src/ScriptAvatarData.cpp b/libraries/avatars/src/ScriptAvatarData.cpp index 64cd534c8b..1fd001e536 100644 --- a/libraries/avatars/src/ScriptAvatarData.cpp +++ b/libraries/avatars/src/ScriptAvatarData.cpp @@ -15,6 +15,7 @@ ScriptAvatarData::ScriptAvatarData(AvatarSharedPointer avatarData) : _avatarData(avatarData) { QObject::connect(avatarData.get(), &AvatarData::displayNameChanged, this, &ScriptAvatarData::displayNameChanged); + QObject::connect(avatarData.get(), &AvatarData::sessionDisplayNameChanged, this, &ScriptAvatarData::sessionDisplayNameChanged); QObject::connect(avatarData.get(), &AvatarData::lookAtSnappingChanged, this, &ScriptAvatarData::lookAtSnappingChanged); } diff --git a/libraries/avatars/src/ScriptAvatarData.h b/libraries/avatars/src/ScriptAvatarData.h index 46dfb5325f..68074b838d 100644 --- a/libraries/avatars/src/ScriptAvatarData.h +++ b/libraries/avatars/src/ScriptAvatarData.h @@ -44,7 +44,7 @@ class ScriptAvatarData : public QObject { // Q_PROPERTY(QUuid sessionUUID READ getSessionUUID) Q_PROPERTY(QString displayName READ getDisplayName NOTIFY displayNameChanged) - Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName) + Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName NOTIFY sessionDisplayNameChanged) Q_PROPERTY(bool isReplicated READ getIsReplicated) Q_PROPERTY(bool lookAtSnappingEnabled READ getLookAtSnappingEnabled NOTIFY lookAtSnappingChanged) @@ -131,6 +131,7 @@ public: signals: void displayNameChanged(); + void sessionDisplayNameChanged(); void lookAtSnappingChanged(bool enabled); public slots: diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index e8156ae5fc..0826325a57 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -390,13 +390,32 @@ // // Clicks. // + function usernameFromIDReply(id, username, machineFingerprint, isAdmin) { + if (selectedIds[0] === id) { + var message = { + method: 'updateSelectedRecipientUsername', + userName: username === "" ? "unknown username" : username + }; + sendToQml(message); + } + } function handleClick(pickRay) { ExtendedOverlay.applyPickRay(pickRay, function (overlay) { var nextSelectedStatus = !overlay.selected; - var message = { method: 'selectRecipient', id: [overlay.key], isSelected: nextSelectedStatus }; + var avatarId = overlay.key; + selectedIds = nextSelectedStatus ? [avatarId] : []; + if (nextSelectedStatus) { + Users.requestUsernameFromID(avatarId); + } + var message = { + method: 'selectRecipient', + id: [avatarId], + isSelected: nextSelectedStatus, + displayName: '"' + AvatarList.getAvatar(avatarId).sessionDisplayName + '"', + userName: '' + }; sendToQml(message); - - selectedIds = nextSelectedStatus ? [overlay.key] : []; + ExtendedOverlay.some(function (overlay) { var id = overlay.key; var selected = ExtendedOverlay.isSelected(id); @@ -625,6 +644,11 @@ if (onWalletScreen) { isWired = true; + Users.usernameFromIDReply.connect(usernameFromIDReply); + Controller.mousePressEvent.connect(handleMouseEvent); + Controller.mouseMoveEvent.connect(handleMouseMoveEvent); + triggerMapping.enable(); + triggerPressMapping.enable(); } else { off(); } @@ -648,15 +672,12 @@ }); button.clicked.connect(onButtonClicked); tablet.screenChanged.connect(onTabletScreenChanged); - Controller.mousePressEvent.connect(handleMouseEvent); - Controller.mouseMoveEvent.connect(handleMouseMoveEvent); - triggerMapping.enable(); - triggerPressMapping.enable(); } } var isWired = false; function off() { if (isWired) { // It is not ok to disconnect these twice, hence guard. + Users.usernameFromIDReply.disconnect(usernameFromIDReply); Script.update.disconnect(updateOverlays); Controller.mousePressEvent.disconnect(handleMouseEvent); Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent); diff --git a/scripts/system/pal.js b/scripts/system/pal.js index ed7059f9f3..1b93bdde32 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -685,7 +685,6 @@ function startup() { }); button.clicked.connect(onTabletButtonClicked); tablet.screenChanged.connect(onTabletScreenChanged); - Users.usernameFromIDReply.connect(usernameFromIDReply); Window.domainChanged.connect(clearLocalQMLDataAndClosePAL); Window.domainConnectionRefused.connect(clearLocalQMLDataAndClosePAL); Messages.subscribe(CHANNEL); @@ -708,6 +707,7 @@ function off() { Controller.mousePressEvent.disconnect(handleMouseEvent); Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent); tablet.tabletShownChanged.disconnect(tabletVisibilityChanged); + Users.usernameFromIDReply.disconnect(usernameFromIDReply); isWired = false; ContextOverlay.enabled = true } @@ -744,6 +744,7 @@ function onTabletButtonClicked() { Script.update.connect(updateOverlays); Controller.mousePressEvent.connect(handleMouseEvent); Controller.mouseMoveEvent.connect(handleMouseMoveEvent); + Users.usernameFromIDReply.connect(usernameFromIDReply); triggerMapping.enable(); triggerPressMapping.enable(); audioTimer = createAudioInterval(conserveResources ? AUDIO_LEVEL_CONSERVED_UPDATE_INTERVAL_MS : AUDIO_LEVEL_UPDATE_INTERVAL_MS); @@ -890,7 +891,6 @@ function shutdown() { button.clicked.disconnect(onTabletButtonClicked); tablet.removeButton(button); tablet.screenChanged.disconnect(onTabletScreenChanged); - Users.usernameFromIDReply.disconnect(usernameFromIDReply); Window.domainChanged.disconnect(clearLocalQMLDataAndClosePAL); Window.domainConnectionRefused.disconnect(clearLocalQMLDataAndClosePAL); Messages.subscribe(CHANNEL); From 464bbe5d438496b971421cf5d080a19efbdd14a2 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 11 Jan 2018 15:26:51 -0800 Subject: [PATCH 18/26] Bugfixes, refactoring, and improvements --- .../wallet/sendMoney/RecipientDisplay.qml | 118 +++++++++++ .../commerce/wallet/sendMoney/SendMoney.qml | 188 ++++-------------- 2 files changed, 159 insertions(+), 147 deletions(-) create mode 100644 interface/resources/qml/hifi/commerce/wallet/sendMoney/RecipientDisplay.qml diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/RecipientDisplay.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/RecipientDisplay.qml new file mode 100644 index 0000000000..f9613bea92 --- /dev/null +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/RecipientDisplay.qml @@ -0,0 +1,118 @@ +// +// RecipientDisplay.qml +// qml/hifi/commerce/wallet/sendMoney +// +// RecipientDisplay +// +// Created by Zach Fox on 2018-01-11 +// Copyright 2018 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.6 +import QtQuick.Controls 2.2 +import QtGraphicalEffects 1.0 +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 bool isDisplayingNearby; // as opposed to 'connections' + property string displayName; + property string userName; + property string profilePic; + + Item { + visible: root.isDisplayingNearby; + anchors.fill: parent; + + RalewaySemiBold { + id: recipientDisplayName; + text: root.displayName; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.right: parent.right; + anchors.rightMargin: 12; + height: parent.height/2; + // Text size + size: 18; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignBottom; + elide: Text.ElideRight; + } + + RalewaySemiBold { + text: root.userName; + // Anchors + anchors.bottom: parent.bottom; + anchors.left: recipientDisplayName.anchors.left; + anchors.leftMargin: recipientDisplayName.anchors.leftMargin; + anchors.right: recipientDisplayName.anchors.right; + anchors.rightMargin: recipientDisplayName.anchors.rightMargin; + height: parent.height/2; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignTop; + elide: Text.ElideRight; + } + } + + Item { + visible: !root.isDisplayingNearby; + anchors.fill: parent; + + Image { + id: userImage; + source: root.profilePic; + mipmap: true; + // Anchors + anchors.left: parent.left; + anchors.verticalCenter: parent.verticalCenter; + height: parent.height - 36; + width: height; + layer.enabled: true; + layer.effect: OpacityMask { + maskSource: Item { + width: userImage.width; + height: userImage.height; + Rectangle { + anchors.centerIn: parent; + width: userImage.width; // This works because userImage is square + height: width; + radius: width; + } + } + } + } + + RalewaySemiBold { + text: root.userName; + // Anchors + anchors.left: userImage.right; + anchors.leftMargin: 8; + anchors.right: parent.right; + anchors.verticalCenter: parent.verticalCenter; + height: parent.height - 4; + // Text size + size: 16; + // Style + color: hifi.colors.baseGray; + verticalAlignment: Text.AlignVCenter; + elide: Text.ElideRight; + } + } +} diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 0d948bbe4b..9812de057f 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -87,22 +87,21 @@ Item { } onNextActiveViewChanged: { + if (root.currentActiveView === 'chooseRecipientNearby') { + sendSignalToWallet({method: 'disable_ChooseRecipientNearbyMode'}); + } + root.currentActiveView = root.nextActiveView; - if (root.currentActiveView === 'chooseRecipientConnection') { + + if (root.nextActiveView === 'chooseRecipientConnection') { // Refresh connections model connectionsLoading.visible = false; connectionsLoading.visible = true; sendSignalToWallet({method: 'refreshConnections'}); - } - - if (root.currentActiveView === 'chooseRecipientNearby') { - sendSignalToWallet({method: 'enable_ChooseRecipientNearbyMode'}); - } else { - sendSignalToWallet({method: 'disable_ChooseRecipientNearbyMode'}); - } - - if (root.currentActiveView === 'sendMoneyHome') { + } else if (root.nextActiveView === 'sendMoneyHome') { Commerce.balance(); + } else if (root.nextActiveView === 'chooseRecipientNearby') { + sendSignalToWallet({method: 'enable_ChooseRecipientNearbyMode'}); } } @@ -439,8 +438,8 @@ Item { onSendToSendMoney: { sendMoneyStep.referrer = "connections"; sendMoneyStep.selectedRecipientNodeID = ''; - sendMoneyStep.selectedRecipientDisplayName = msg.userName; - sendMoneyStep.selectedRecipientUserName = 'connection'; + sendMoneyStep.selectedRecipientDisplayName = 'connection'; + sendMoneyStep.selectedRecipientUserName = msg.userName; sendMoneyStep.selectedRecipientProfilePic = msg.profilePicUrl; root.nextActiveView = "sendMoneyStep"; @@ -740,94 +739,18 @@ Item { verticalAlignment: Text.AlignVCenter; } - Item { - id: recipientIsNearby; - visible: sendMoneyStep.referrer === "nearby"; + RecipientDisplay { anchors.top: parent.top; anchors.left: sendToText_sendMoneyStep.right; anchors.right: changeButton.left; anchors.rightMargin: 12; height: parent.height; - RalewaySemiBold { - id: recipientDisplayName; - text: sendMoneyStep.selectedRecipientDisplayName; - // Anchors - anchors.top: parent.top; - anchors.left: parent.left; - anchors.right: parent.right; - anchors.rightMargin: 12; - height: parent.height/2; - // Text size - size: 18; - // Style - color: hifi.colors.baseGray; - verticalAlignment: Text.AlignBottom; - } - - RalewaySemiBold { - text: sendMoneyStep.selectedRecipientUserName; - // Anchors - anchors.bottom: parent.bottom; - anchors.left: recipientDisplayName.anchors.left; - anchors.leftMargin: recipientDisplayName.anchors.leftMargin; - anchors.right: recipientDisplayName.anchors.right; - anchors.rightMargin: recipientDisplayName.anchors.rightMargin; - height: parent.height/2; - // Text size - size: 16; - // Style - color: hifi.colors.baseGray; - verticalAlignment: Text.AlignTop; - } - } - - Item { - id: recipientIsConnection; - visible: sendMoneyStep.referrer === "connections"; - anchors.top: parent.top; - anchors.left: sendToText_sendMoneyStep.right; - anchors.right: changeButton.left; - anchors.rightMargin: 12; - height: parent.height; - - Image { - id: userImage; - source: sendMoneyStep.selectedRecipientProfilePic !== "" ? ((0 === sendMoneyStep.selectedRecipientProfilePic.indexOf("http")) ? - sendMoneyStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendMoneyStep.selectedRecipientProfilePic)) : ""; - mipmap: true; - // Anchors - anchors.left: parent.left; - anchors.verticalCenter: parent.verticalCenter; - height: parent.height - 4; - layer.enabled: true; - layer.effect: OpacityMask { - maskSource: Item { - width: userImage.width; - height: userImage.height; - Rectangle { - anchors.centerIn: parent; - width: userImage.width; // This works because userImage is square - height: width; - radius: width; - } - } - } - } - - RalewaySemiBold { - text: sendMoneyStep.selectedRecipientUserName; - // Anchors - anchors.left: userImage.right; - anchors.leftMargin: 8; - anchors.verticalCenter: parent.verticalCenter; - height: parent.height - 4; - // Text size - size: 16; - // Style - color: hifi.colors.baseGray; - verticalAlignment: Text.AlignVCenter; - } + displayName: sendMoneyStep.selectedRecipientDisplayName; + userName: sendMoneyStep.selectedRecipientUserName; + profilePic: sendMoneyStep.selectedRecipientProfilePic !== "" ? ((0 === sendMoneyStep.selectedRecipientProfilePic.indexOf("http")) ? + sendMoneyStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendMoneyStep.selectedRecipientProfilePic)) : ""; + isDisplayingNearby: sendMoneyStep.referrer === "nearby"; } // "CHANGE" button @@ -1031,6 +954,10 @@ Item { amountTextField.focus = true; amountTextField.error = true; amountTextFieldError.text = "amount exceeds available funds"; + } else if (amountTextField.text === "" || parseInt(amountTextField.text) < 1) { + amountTextField.focus = true; + amountTextField.error = true; + amountTextFieldError.text = "invalid amount"; } else { amountTextFieldError.text = ""; amountTextField.error = false; @@ -1171,36 +1098,17 @@ Item { verticalAlignment: Text.AlignVCenter; } - RalewaySemiBold { - id: recipientDisplayName_paymentSuccess; - text: sendMoneyStep.selectedRecipientDisplayName; - // Anchors + RecipientDisplay { anchors.top: parent.top; anchors.left: sendToText_paymentSuccess.right; anchors.right: parent.right; - height: parent.height/2; - // Text size - size: 18; - // Style - color: hifi.colors.baseGray; - verticalAlignment: Text.AlignBottom; - } + height: parent.height; - RalewaySemiBold { - id: recipientUsername_paymentSuccess; - text: sendMoneyStep.selectedRecipientUserName; - // Anchors - anchors.bottom: parent.bottom; - anchors.left: recipientDisplayName_paymentSuccess.anchors.left; - anchors.leftMargin: recipientDisplayName_paymentSuccess.anchors.leftMargin; - anchors.right: recipientDisplayName_paymentSuccess.anchors.right; - anchors.rightMargin: recipientDisplayName_paymentSuccess.anchors.rightMargin; - height: parent.height/2; - // Text size - size: 16; - // Style - color: hifi.colors.baseGray; - verticalAlignment: Text.AlignTop; + displayName: sendMoneyStep.selectedRecipientDisplayName; + userName: sendMoneyStep.selectedRecipientUserName; + profilePic: sendMoneyStep.selectedRecipientProfilePic !== "" ? ((0 === sendMoneyStep.selectedRecipientProfilePic.indexOf("http")) ? + sendMoneyStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendMoneyStep.selectedRecipientProfilePic)) : ""; + isDisplayingNearby: sendMoneyStep.referrer === "nearby"; } } @@ -1393,36 +1301,17 @@ Item { verticalAlignment: Text.AlignVCenter; } - RalewaySemiBold { - id: recipientDisplayName_paymentFailure; - text: sendMoneyStep.selectedRecipientDisplayName; - // Anchors + RecipientDisplay { anchors.top: parent.top; anchors.left: sentToText_paymentFailure.right; anchors.right: parent.right; - height: parent.height/2; - // Text size - size: 18; - // Style - color: hifi.colors.baseGray; - verticalAlignment: Text.AlignBottom; - } + height: parent.height; - RalewaySemiBold { - id: recipientUsername_paymentFailure; - text: sendMoneyStep.selectedRecipientUserName; - // Anchors - anchors.bottom: parent.bottom; - anchors.left: recipientDisplayName_paymentFailure.anchors.left; - anchors.leftMargin: recipientDisplayName_paymentFailure.anchors.leftMargin; - anchors.right: recipientDisplayName_paymentFailure.anchors.right; - anchors.rightMargin: recipientDisplayName_paymentFailure.anchors.rightMargin; - height: parent.height/2; - // Text size - size: 16; - // Style - color: hifi.colors.baseGray; - verticalAlignment: Text.AlignTop; + displayName: sendMoneyStep.selectedRecipientDisplayName; + userName: sendMoneyStep.selectedRecipientUserName; + profilePic: sendMoneyStep.selectedRecipientProfilePic !== "" ? ((0 === sendMoneyStep.selectedRecipientProfilePic.indexOf("http")) ? + sendMoneyStep.selectedRecipientProfilePic : (Account.metaverseServerURL + sendMoneyStep.selectedRecipientProfilePic)) : ""; + isDisplayingNearby: sendMoneyStep.referrer === "nearby"; } } @@ -1489,7 +1378,7 @@ Item { anchors.leftMargin: 110; anchors.right: parent.right; anchors.rightMargin: 16; - anchors.bottom: closeButton.top; + anchors.bottom: closeButton_paymentFailure.top; anchors.bottomMargin: 40; // Text size size: 22; @@ -1530,6 +1419,11 @@ Item { text: "Retry"; onClicked: { root.isCurrentlySendingMoney = true; + if (sendMoneyStep.referrer === "connections") { + Commerce.transferHfcToUsername(sendMoneyStep.selectedRecipientUserName, parseInt(amountTextField.text), optionalMessage.text); + } else if (sendMoneyStep.referrer === "nearby") { + Commerce.transferHfcToNode(sendMoneyStep.selectedRecipientNodeID, parseInt(amountTextField.text), optionalMessage.text); + } } } } From c216144015168521bc405ccdc698b8fe4c6aacaa Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 11 Jan 2018 16:21:59 -0800 Subject: [PATCH 19/26] Remove unnecessary comments --- interface/resources/qml/hifi/commerce/wallet/Wallet.qml | 2 -- interface/resources/qml/hifi/commerce/wallet/WalletHome.qml | 2 -- .../qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml | 2 -- .../qml/hifi/commerce/wallet/sendMoney/RecipientDisplay.qml | 2 -- .../resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml | 2 -- 5 files changed, 10 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 6b350f9f93..7b453f4cb3 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -21,8 +21,6 @@ import "../../../controls" as HifiControls import "../common" as HifiCommerceCommon import "./sendMoney" -// references XXX from root context - Rectangle { HifiConstants { id: hifi; } diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml index 12d119e012..e761f3e510 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml @@ -19,8 +19,6 @@ import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls -// references XXX from root context - Item { HifiConstants { id: hifi; } diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml index 84d6b304f6..c2d9ef3b19 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/ConnectionItem.qml @@ -21,8 +21,6 @@ import "../../../../controls-uit" as HifiControlsUit import "../../../../controls" as HifiControls import "../../wallet" as HifiWallet -// references XXX from root context - Item { HifiConstants { id: hifi; } diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/RecipientDisplay.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/RecipientDisplay.qml index f9613bea92..267cf0ed51 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/RecipientDisplay.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/RecipientDisplay.qml @@ -20,8 +20,6 @@ import "../../../../controls-uit" as HifiControlsUit import "../../../../controls" as HifiControls import "../../common" as HifiCommerceCommon -// references XXX from root context - Item { HifiConstants { id: hifi; } diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 9812de057f..5d2d05047f 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -20,8 +20,6 @@ import "../../../../controls-uit" as HifiControlsUit import "../../../../controls" as HifiControls import "../../common" as HifiCommerceCommon -// references XXX from root context - Item { HifiConstants { id: hifi; } From 6cedc016c49d80d468f32e1bc3449a51ae70ea61 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 12 Jan 2018 16:08:52 -0700 Subject: [PATCH 20/26] Adding sender/recipient to transaction history for hfc transfers --- interface/src/commerce/Ledger.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 64875c43a8..269e8b5e06 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -118,7 +118,7 @@ void Ledger::inventory(const QStringList& keys) { keysQuery("inventory", "inventorySuccess", "inventoryFailure"); } -QString amountString(const QString& label, const QString&color, const QJsonValue& moneyValue, const QJsonValue& certsValue) { +QString amountString(const QString& label, const QString&color, const QJsonValue& moneyValue, const QJsonValue& certsValue, const QJsonValue& usernameValue) { int money = moneyValue.toInt(); int certs = certsValue.toInt(); if (money <= 0 && certs <= 0) { @@ -134,7 +134,15 @@ QString amountString(const QString& label, const QString&color, const QJsonValue } result += QString((certs == 1) ? " %1 certificate" : " %1 certificates").arg(certs); } - return result + QString(""); + result += QString(""); + + // the only time we put the username in is when the money value is > 0 + // and the certificate value == 0, as we only want this for hfc transfers + // Also - we don't bother if the username is 'highfidelity' or 'marketplace' + if (money > 0 && certs == 0) { + result += QString(" %1 %2").arg(label == "sent" ? "to" : "from", usernameValue.toString()); + } + return result; } static const QString MARKETPLACE_ITEMS_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/marketplace/items/"; @@ -158,8 +166,8 @@ void Ledger::historySuccess(QNetworkReply& reply) { // TODO: do this with 0 copies if possible for (auto it = historyArray.begin(); it != historyArray.end(); it++) { auto valueObject = (*it).toObject(); - QString sent = amountString("sent", "EA4C5F", valueObject["sent_money"], valueObject["sent_certs"]); - QString received = amountString("received", "1FC6A6", valueObject["received_money"], valueObject["received_certs"]); + QString sent = amountString("sent", "EA4C5F", valueObject["sent_money"], valueObject["sent_certs"], valueObject["recipient_name"]); + QString received = amountString("received", "1FC6A6", valueObject["received_money"], valueObject["received_certs"], valueObject["sender_name"]); // 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 From 6b90ceaeb4c7573f8632fc82ab04b7f1d919d3ff Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 16 Jan 2018 10:40:51 -0800 Subject: [PATCH 21/26] Quick bugfix and code change for clarity --- .../qml/hifi/commerce/wallet/sendMoney/SendMoney.qml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 5d2d05047f..9164ba7a8c 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -75,7 +75,6 @@ Item { Connections { target: GlobalServices onMyUsernameChanged: { - transactionHistoryModel.clear(); usernameText.text = Account.username; } } @@ -91,14 +90,14 @@ Item { root.currentActiveView = root.nextActiveView; - if (root.nextActiveView === 'chooseRecipientConnection') { + if (root.currentActiveView === 'chooseRecipientConnection') { // Refresh connections model connectionsLoading.visible = false; connectionsLoading.visible = true; sendSignalToWallet({method: 'refreshConnections'}); - } else if (root.nextActiveView === 'sendMoneyHome') { + } else if (root.currentActiveView === 'sendMoneyHome') { Commerce.balance(); - } else if (root.nextActiveView === 'chooseRecipientNearby') { + } else if (root.currentActiveView === 'chooseRecipientNearby') { sendSignalToWallet({method: 'enable_ChooseRecipientNearbyMode'}); } } @@ -848,7 +847,7 @@ Item { FontLoader { id: firaSansSemiBold; source: "../../../../../fonts/FiraSans-SemiBold.ttf"; } TextArea { id: optionalMessage; - property int maximumLength: 255; + property int maximumLength: 70; property string previousText: text; placeholderText: "Optional Message"; font.family: firaSansSemiBold.name; From d8f8f9ff1a765956e5cc11f9c68dd66463feafed Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 16 Jan 2018 11:19:10 -0800 Subject: [PATCH 22/26] First cut at alan's new design --- .../qml/hifi/commerce/wallet/WalletHome.qml | 11 +-- interface/src/commerce/Ledger.cpp | 83 ++++++++++++------- 2 files changed, 61 insertions(+), 33 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml index e761f3e510..b2b6f7b8fe 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml @@ -382,8 +382,8 @@ Item { height: visible ? parent.height : 0; AnonymousProRegular { - id: dateText; - text: model.created_at ? getFormattedDate(model.created_at * 1000) : ""; + id: hfcText; + text: model.hfc_text; // Style size: 18; anchors.left: parent.left; @@ -391,23 +391,24 @@ Item { anchors.topMargin: 15; width: 118; height: paintedHeight; - color: hifi.colors.blueAccent; wrapMode: Text.WordWrap; + font.bold: true; // Alignment horizontalAlignment: Text.AlignRight; } AnonymousProRegular { id: transactionText; - text: model.text ? (model.status === "invalidated" ? ("INVALIDATED: " + model.text) : model.text) : ""; + text: model.transaction_text ? (model.status === "invalidated" ? ("INVALIDATED: " + model.transaction_text) : model.transaction_text) : ""; size: 18; anchors.top: parent.top; anchors.topMargin: 15; - anchors.left: dateText.right; + anchors.left: hfcText.right; anchors.leftMargin: 20; anchors.right: parent.right; height: paintedHeight; color: model.status === "invalidated" ? hifi.colors.redAccent : hifi.colors.baseGrayHighlight; + linkColor: hifi.colors.blueAccent; wrapMode: Text.WordWrap; font.strikeout: model.status === "invalidated"; diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 269e8b5e06..ba27b397f8 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -118,30 +118,60 @@ void Ledger::inventory(const QStringList& keys) { keysQuery("inventory", "inventorySuccess", "inventoryFailure"); } -QString amountString(const QString& label, const QString&color, const QJsonValue& moneyValue, const QJsonValue& certsValue, const QJsonValue& usernameValue) { - int money = moneyValue.toInt(); - int certs = certsValue.toInt(); - if (money <= 0 && certs <= 0) { - return QString(); +QString hfcString(const QJsonValue& sentValue, const QJsonValue& receivedValue) { + int sent = sentValue.toInt(); + int received = receivedValue.toInt(); + if (sent <= 0 && received <= 0) { + return QString("-"); } - QString result(QString(" %2").arg(color, label)); - if (money > 0) { - result += QString(" %1 HFC").arg(money); - } - if (certs > 0) { - if (money > 0) { - result += QString(","); + QString result; + if (sent > 0) { + result += QString("-%1 HFC").arg(sent); + if (received > 0) { + result += QString("
"); } - result += QString((certs == 1) ? " %1 certificate" : " %1 certificates").arg(certs); } - result += QString("
"); + if (received > 0) { + result += QString("%1 HFC").arg(received); + } + return result; +} +static const QString USER_PAGE_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/users/"; +QString userLink(const QString& username) { + if (username.isEmpty()) { + return QString("someone"); + } + return QString("%2").arg(USER_PAGE_BASE_URL, username); +} - // the only time we put the username in is when the money value is > 0 - // and the certificate value == 0, as we only want this for hfc transfers - // Also - we don't bother if the username is 'highfidelity' or 'marketplace' - if (money > 0 && certs == 0) { - result += QString(" %1 %2").arg(label == "sent" ? "to" : "from", usernameValue.toString()); +QString transactionString(const QJsonObject& valueObject) { + int sentCerts = valueObject["sent_certs"].toInt(); + int receivedCerts = valueObject["received_certs"].toInt(); + int sent = valueObject["sent_money"].toInt(); + int received = valueObject["received_money"].toInt(); + int dateInteger = valueObject["created_at"].toInt(); + QString message = valueObject["message"].toString(); + QDateTime createdAt(QDateTime::fromSecsSinceEpoch(dateInteger, Qt::UTC)); + QString result; + + if (sentCerts <= 0 && receivedCerts <= 0) { + // this is an hfc transfer. + if (sent > 0) { + QString recipient = userLink(valueObject["recipient_name"].toString()); + result += QString("Money sent to %1").arg(recipient); + } else { + QString sender = userLink(valueObject["sender_name"].toString()); + result += QString("Money from %1").arg(sender); + } + if (!message.isEmpty()) { + result += QString("
with memo: \"%1\"").arg(message); + } + } else { + result += valueObject["message"].toString(); } + // no matter what we append a smaller date to the bottom of this... + + result += QString("
%1").arg(createdAt.toLocalTime().toString()); return result; } @@ -165,16 +195,13 @@ void Ledger::historySuccess(QNetworkReply& reply) { // TODO: do this with 0 copies if possible for (auto it = historyArray.begin(); it != historyArray.end(); it++) { + // We have 2 text fields to synthesize, the one on the left is a listing + // of the HFC in/out of your wallet. The one on the right contains an explaination + // of the transaction. That could be just the memo (if it is a regular purchase), or + // more text (plus the optional memo) if an hfc transfer auto valueObject = (*it).toObject(); - QString sent = amountString("sent", "EA4C5F", valueObject["sent_money"], valueObject["sent_certs"], valueObject["recipient_name"]); - QString received = amountString("received", "1FC6A6", valueObject["received_money"], valueObject["received_certs"], valueObject["sender_name"]); - - // 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 - QDateTime createdAt = QDateTime::fromSecsSinceEpoch(valueObject["created_at"].toInt(), Qt::UTC); - QDateTime localCreatedAt = createdAt.toTimeZone(QTimeZone::systemTimeZone()); - valueObject["text"] = QString("%1%2%3").arg(valueObject["message"].toString(), sent, received); + valueObject["hfc_text"] = hfcString(valueObject["sent_money"], valueObject["received_money"]); + valueObject["transaction_text"] = transactionString(valueObject); newHistoryArray.push_back(valueObject); } // now copy the rest of the json -- this is inefficient From 929760c2263a3f1987e5e244826f4ff666bf881f Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 16 Jan 2018 14:52:26 -0800 Subject: [PATCH 23/26] fix time display --- interface/src/commerce/Ledger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index ba27b397f8..31c29d8397 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -171,7 +171,7 @@ QString transactionString(const QJsonObject& valueObject) { } // no matter what we append a smaller date to the bottom of this... - result += QString("
%1").arg(createdAt.toLocalTime().toString()); + result += QString("
%1").arg(createdAt.toLocalTime().toString(Qt::DefaultLocaleShortDate)); return result; } From a9fc63da4c19daf9a8c77c9de4538e52c855f0d1 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 16 Jan 2018 15:04:05 -0800 Subject: [PATCH 24/26] fix error when pending --- interface/resources/qml/hifi/commerce/wallet/WalletHome.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml index b2b6f7b8fe..efa927749d 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml @@ -383,7 +383,7 @@ Item { AnonymousProRegular { id: hfcText; - text: model.hfc_text; + text: model.hfc_text || ''; // Style size: 18; anchors.left: parent.left; From 8cc5a0a7cb3423a8ad1aebb1c091dbebf4a30bdb Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 16 Jan 2018 15:06:51 -0800 Subject: [PATCH 25/26] Add UserInfoViewer --- .../qml/hifi/commerce/wallet/Wallet.qml | 16 ++++++++++++++-- .../qml/hifi/commerce/wallet/WalletHome.qml | 6 +++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 7b453f4cb3..da67569bc3 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -315,7 +315,12 @@ Rectangle { Connections { onSendSignalToWallet: { - sendToScript(msg); + if (msg.method === 'transactionHistory_usernameLinkClicked') { + userInfoViewer.url = msg.usernameLink; + userInfoViewer.visible = true; + } else { + sendToScript(msg); + } } } } @@ -682,9 +687,16 @@ Rectangle { // TAB BUTTONS END // + HifiControls.TabletWebView { + id: userInfoViewer; + z: 998; + anchors.fill: parent; + visible: false; + } + Item { id: keyboardContainer; - z: 998; + z: 999; visible: keyboard.raised; property bool punctuationMode: false; anchors { diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml index b2b6f7b8fe..31096a517d 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml @@ -413,7 +413,11 @@ Item { font.strikeout: model.status === "invalidated"; onLinkActivated: { - sendSignalToWallet({method: 'transactionHistory_linkClicked', marketplaceLink: link}); + if (link.indexOf("users/") !== -1) { + sendSignalToWallet({method: 'transactionHistory_usernameLinkClicked', usernameLink: link}); + } else { + sendSignalToWallet({method: 'transactionHistory_linkClicked', marketplaceLink: link}); + } } } From e700ff91d0b9e6125093b26e05d463d1de4f7067 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 16 Jan 2018 15:58:17 -0800 Subject: [PATCH 26/26] Remove warning --- interface/src/commerce/Ledger.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 31c29d8397..d38eea74d5 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -148,7 +148,6 @@ QString transactionString(const QJsonObject& valueObject) { int sentCerts = valueObject["sent_certs"].toInt(); int receivedCerts = valueObject["received_certs"].toInt(); int sent = valueObject["sent_money"].toInt(); - int received = valueObject["received_money"].toInt(); int dateInteger = valueObject["created_at"].toInt(); QString message = valueObject["message"].toString(); QDateTime createdAt(QDateTime::fromSecsSinceEpoch(dateInteger, Qt::UTC));