From 9e2bf87d84083be133688b488290e288e0837b69 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Tue, 25 Aug 2020 14:44:29 -0400 Subject: [PATCH] feat: add TransactionBubble for use with the chat commands Add only the UI component for the TransactionBubble Was not thoroughly tested since it was only developed in QT Designer --- .../MessageComponents/TransactionBubble.qml | 128 ++++++++++++++++++ .../AcceptTransaction.qml | 70 ++++++++++ .../SendTransactionButton.qml | 42 ++++++ .../TransactionComponents/StateBubble.qml | 82 +++++++++++ ui/app/img/dotsLoadings.svg | 5 + ui/app/img/exclamation.svg | 3 + ui/imports/Constants.qml | 10 ++ ui/nim-status-client.pro | 4 + 8 files changed, 344 insertions(+) create mode 100644 ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionBubble.qml create mode 100644 ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml create mode 100644 ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml create mode 100644 ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/StateBubble.qml create mode 100644 ui/app/img/dotsLoadings.svg create mode 100644 ui/app/img/exclamation.svg diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionBubble.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionBubble.qml new file mode 100644 index 0000000000..02933c1ce8 --- /dev/null +++ b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionBubble.qml @@ -0,0 +1,128 @@ +import QtQuick 2.3 +import "../../../../../shared" +import "../../../../../imports" +import "./TransactionComponents" + +Rectangle { + property string tokenAmount: "100" + property string token: "SNT" + property string fiatValue: "10 USD" + property bool outgoing: true + property string state: "addressReceived" + property string time: "9:41 AM" + + id: root + width: 170 + height: childrenRect.height + radius: 16 + color: Style.current.background + border.color: Style.current.border + border.width: 1 + + StyledText { + id: title + color: Style.current.secondaryText + text: outgoing ? qsTr("↑ Outgoing transaction") : qsTr("↓ Incoming transaction") + font.weight: Font.Medium + anchors.top: parent.top + anchors.topMargin: Style.current.halfPadding + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: 13 + } + + Item { + id: valueContainer + height: tokenText.height + fiatText.height + anchors.top: title.bottom + anchors.topMargin: 4 + anchors.right: parent.right + anchors.rightMargin: 12 + anchors.left: parent.left + anchors.leftMargin: 12 + + Image { + id: tokenImage + source: `../../../../img/tokens/${root.token}.png` + width: 24 + height: 24 + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + id: tokenText + color: Style.current.text + text: `${root.tokenAmount} ${root.token}` + anchors.left: tokenImage.right + anchors.leftMargin: Style.current.halfPadding + font.pixelSize: 22 + } + + StyledText { + id: fiatText + color: Style.current.secondaryText + text: root.fiatValue + anchors.top: tokenText.bottom + anchors.left: tokenText.left + font.pixelSize: 13 + } + } + + Loader { + id: bubbleLoader + active: root.state !== Constants.addressRequested || !outgoing + sourceComponent: stateBubbleComponent + anchors.top: valueContainer.bottom + anchors.topMargin: Style.current.halfPadding + width: parent.width + height: item.height + 12 + } + + Component { + id: stateBubbleComponent + + StateBubble { + state: root.state + } + } + + Loader { + id: buttonsLoader + active: (root.state === Constants.addressRequested && !root.outgoing) || + (root.state === Constants.addressReceived && root.outgoing) + sourceComponent: root.outgoing ? signAndSendComponent : acceptTransactionComponent + anchors.top: bubbleLoader.active ? bubbleLoader.bottom : valueContainer.bottom + anchors.topMargin: bubbleLoader.active ? 0 : Style.current.halfPadding + width: parent.width + height: item.height + } + + Component { + id: acceptTransactionComponent + + AcceptTransaction {} + } + + Component { + id: signAndSendComponent + + SendTransactionButton {} + } + + StyledText { + id: timeText + color: Style.current.secondaryText + text: root.time + anchors.bottom: parent.bottom + anchors.bottomMargin: 9 + anchors.right: parent.right + anchors.rightMargin: 12 + font.pixelSize: 10 + } + +} + +/*##^## +Designer { + D{i:0;formeditorColor:"#4c4e50";formeditorZoom:1.25} +} +##^##*/ diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml new file mode 100644 index 0000000000..319e898803 --- /dev/null +++ b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml @@ -0,0 +1,70 @@ +import QtQuick 2.3 +import "../../../../../../shared" +import "../../../../../../imports" + +Item { + width: parent.width + height: childrenRect.height + + Separator { + id: separator1 + } + + StyledText { + id: acceptText + color: Style.current.blue + text: qsTr("Accept and share address") + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + font.weight: Font.Medium + anchors.right: parent.right + anchors.left: parent.left + bottomPadding: Style.current.halfPadding + topPadding: Style.current.halfPadding + anchors.top: separator1.bottom + font.pixelSize: 15 + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + console.log('Accept') + } + } + } + + Separator { + id: separator2 + anchors.topMargin: 0 + anchors.top: acceptText.bottom + } + + StyledText { + id: declineText + color: Style.current.blue + text: qsTr("Decline") + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + font.weight: Font.Medium + anchors.right: parent.right + anchors.left: parent.left + bottomPadding: Style.current.padding + topPadding: Style.current.padding + anchors.top: separator2.bottom + font.pixelSize: 15 + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + console.log('Decline') + } + } + } +} + +/*##^## +Designer { + D{i:0;formeditorColor:"#ffffff";formeditorZoom:1.25} +} +##^##*/ diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml new file mode 100644 index 0000000000..9fc39f8f32 --- /dev/null +++ b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml @@ -0,0 +1,42 @@ +import QtQuick 2.3 +import "../../../../../../shared" +import "../../../../../../imports" + +Item { + width: parent.width + height: childrenRect.height + + Separator { + id: separator + } + + StyledText { + id: signText + color: Style.current.blue + text: qsTr("Sign and send") + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + font.weight: Font.Medium + anchors.right: parent.right + anchors.left: parent.left + bottomPadding: Style.current.halfPadding + topPadding: Style.current.halfPadding + anchors.top: separator1.bottom + font.pixelSize: 15 + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + console.log('Sign') + } + } + } +} + +/*##^## +Designer { + D{i:0;formeditorColor:"#ffffff";formeditorZoom:1.25} +} +##^##*/ + diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/StateBubble.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/StateBubble.qml new file mode 100644 index 0000000000..e0ce7e2737 --- /dev/null +++ b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/StateBubble.qml @@ -0,0 +1,82 @@ +import QtQuick 2.3 +import QtGraphicalEffects 1.13 +import "../../../../../../shared" +import "../../../../../../imports" + +Rectangle { + property string state: Constants.pending + + id: root + width: childrenRect.width + 12 + height: childrenRect.height + border.width: 1 + border.color: Style.current.border + radius: 24 + + SVGImage { + id: stateImage + source: { + switch (root.state) { + case Constants.pending: + case Constants.addressReceived: + case Constants.shared: + case Constants.addressRequested: return "../../../../../img/dotsLoadings.svg" + case Constants.confirmed: return "../../../../../img/check.svg" + case Constants.unknown: + case Constants.failure: + case Constants.declined: return "../../../../../img/exclamation.svg" + default: return "" + } + } + width: 16 + height: 16 + anchors.left: parent.left + anchors.leftMargin: Style.current.halfPadding + anchors.verticalCenter: stateText.verticalCenter + } + + ColorOverlay { + anchors.fill: stateImage + source: stateImage + color: state == Constants.confirmed ? Style.current.transparent : Style.current.text + } + + StyledText { + id: stateText + color: { + if (root.state === Constants.unknown || root.state === Constants.failure) { + return Style.current.danger + } + if (root.state === Constants.confirmed || root.state === Constants.declined) { + return Style.current.text + } + + return Style.current.secondaryText + } + text: { + switch (root.state) { + case Constants.pending: return qsTr("Pending") + case Constants.confirmed: return qsTr("Confirmed") + case Constants.unknown: return qsTr("Unknown token") + case Constants.addressRequested: return qsTr("Address requested") + case Constants.addressReceived: return qsTr("Address received") + case Constants.declined: return qsTr("Transaction declined") + case Constants.shared: return qsTr("Shared ‘Other Account’") + case Constants.failure: return qsTr("Failure") + default: return qsTr("Unknown state") + } + } + font.weight: Font.Medium + anchors.left: stateImage.right + anchors.leftMargin: 4 + bottomPadding: Style.current.halfPadding + topPadding: Style.current.halfPadding + font.pixelSize: 13 + } +} + +/*##^## +Designer { + D{i:0;formeditorColor:"#808080";formeditorZoom:2} +} +##^##*/ diff --git a/ui/app/img/dotsLoadings.svg b/ui/app/img/dotsLoadings.svg new file mode 100644 index 0000000000..f85f1e73cb --- /dev/null +++ b/ui/app/img/dotsLoadings.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/ui/app/img/exclamation.svg b/ui/app/img/exclamation.svg new file mode 100644 index 0000000000..831f628a69 --- /dev/null +++ b/ui/app/img/exclamation.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/imports/Constants.qml b/ui/imports/Constants.qml index 7d6452b899..2079807462 100644 --- a/ui/imports/Constants.qml +++ b/ui/imports/Constants.qml @@ -23,6 +23,16 @@ QtObject { readonly property string seedWalletType: "seed" readonly property string generatedWalletType: "generated" + // Transaction states + readonly property string pending: "pending" + readonly property string confirmed: "confirmed" + readonly property string unknown: "unknown" + readonly property string addressRequested: "addressRequested" + readonly property string addressReceived: "addressReceived" + readonly property string declined: "declined" + readonly property string shared: "shared" + readonly property string failure: "failure" + readonly property var accountColors: [ "#9B832F", "#D37EF4", diff --git a/ui/nim-status-client.pro b/ui/nim-status-client.pro index ac98932625..e90da0d97a 100644 --- a/ui/nim-status-client.pro +++ b/ui/nim-status-client.pro @@ -133,6 +133,10 @@ DISTFILES += \ app/AppLayouts/Chat/ChatColumn/MessageComponents/RectangleCorner.qml \ app/AppLayouts/Chat/ChatColumn/MessageComponents/SentMessage.qml \ app/AppLayouts/Chat/ChatColumn/MessageComponents/Sticker.qml \ + app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionBubble.qml \ + app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml \ + app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml \ + app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/StateBubble.qml \ app/AppLayouts/Chat/ChatColumn/MessageComponents/UserImage.qml \ app/AppLayouts/Chat/ChatColumn/MessageComponents/UsernameLabel.qml \ app/AppLayouts/Chat/ChatColumn/MessageComponents/qmldir \