[GUI] Add option to encrypt transfer memos
Also, refactor common unlocking finish/cancel buttons into a reusable component
This commit is contained in:
parent
8a8130f620
commit
02682e761c
6 changed files with 106 additions and 43 deletions
|
|
@ -28,12 +28,25 @@ TransferOperation* OperationBuilder::transfer(ObjectId sender, ObjectId receiver
|
|||
QString TransferOperation::memo() const {
|
||||
if (!m_op.memo)
|
||||
return QString::null;
|
||||
if (memoIsEncrypted())
|
||||
return tr("Encrypted Memo");
|
||||
QString memo = QString::fromStdString(m_op.memo->get_message({}, {}));
|
||||
while (memo.endsWith('\0'))
|
||||
memo.chop(1);
|
||||
return memo;
|
||||
}
|
||||
|
||||
bool TransferOperation::memoIsEncrypted() const
|
||||
{
|
||||
if (!m_op.memo)
|
||||
return false;
|
||||
if (m_op.memo->message.empty())
|
||||
return false;
|
||||
if (m_op.memo->from == public_key_type() && m_op.memo->to == public_key_type())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TransferOperation::canEncryptMemo(Wallet* wallet, ChainDataModel* model) const
|
||||
{
|
||||
if (!m_op.memo) return false;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class TransferOperation : public OperationBase {
|
|||
Q_PROPERTY(qint64 amount READ amount WRITE setAmount NOTIFY amountChanged)
|
||||
Q_PROPERTY(ObjectId amountType READ amountType WRITE setAmountType NOTIFY amountTypeChanged)
|
||||
Q_PROPERTY(QString memo READ memo WRITE setMemo NOTIFY memoChanged)
|
||||
Q_PROPERTY(bool memoIsEncrypted READ memoIsEncrypted NOTIFY memoChanged)
|
||||
|
||||
graphene::chain::transfer_operation m_op;
|
||||
|
||||
|
|
@ -60,6 +61,7 @@ public:
|
|||
/// performed by calling encryptMemo()
|
||||
QString memo() const;
|
||||
|
||||
bool memoIsEncrypted()const;
|
||||
Q_INVOKABLE bool canEncryptMemo(Wallet* wallet, ChainDataModel* model) const;
|
||||
Q_INVOKABLE bool canDecryptMemo(Wallet* wallet, ChainDataModel* model) const;
|
||||
Q_INVOKABLE QString decryptedMemo(Wallet* wallet, ChainDataModel* model) const;
|
||||
|
|
|
|||
|
|
@ -62,36 +62,19 @@ FormBase {
|
|||
Loader {
|
||||
sourceComponent: trx && Array.prototype.slice.call(trx.operations).length > 0? transactionDelegate : undefined
|
||||
}
|
||||
RowLayout {
|
||||
UnlockingFinishButtons {
|
||||
app: base.app
|
||||
Layout.fillWidth: true
|
||||
Item { Layout.fillWidth: true }
|
||||
Button {
|
||||
text: qsTr("Cancel")
|
||||
onClicked: {
|
||||
canceled({})
|
||||
trx = null
|
||||
}
|
||||
onLeftButtonClicked: {
|
||||
canceled({})
|
||||
trx = null
|
||||
}
|
||||
TextField {
|
||||
id: passwordField
|
||||
Layout.preferredWidth: app.wallet.isLocked? Scaling.cm(4) : 0
|
||||
echoMode: TextInput.Password
|
||||
placeholderText: qsTr("Wallet password")
|
||||
visible: width > 0
|
||||
onAccepted: finishButton.clicked()
|
||||
|
||||
Behavior on Layout.preferredWidth { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } }
|
||||
}
|
||||
Button {
|
||||
id: finishButton
|
||||
text: app.wallet.isLocked? qsTr("Unlock") : qsTr("Finish")
|
||||
onClicked: {
|
||||
if (app.wallet.isLocked)
|
||||
app.wallet.unlock(passwordField.text)
|
||||
else {
|
||||
app.wallet.sign(trx)
|
||||
completed(trx)
|
||||
}
|
||||
onRightButtonClicked: {
|
||||
if (app.wallet.isLocked)
|
||||
app.wallet.unlock(passwordField.text)
|
||||
else {
|
||||
app.wallet.sign(trx)
|
||||
completed(trx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Dialogs 1.2
|
||||
import QtQuick.Layouts 1.2
|
||||
|
||||
import Graphene.Client 0.1
|
||||
|
|
@ -19,7 +18,7 @@ FormBase {
|
|||
property alias receiverAccount: recipientPicker.account
|
||||
|
||||
function operation() {
|
||||
if (!transferButton.enabled) return app.operationBuilder.transfer(0,0,0,0, memoField.text, 0)
|
||||
if (!finishLine.rightButtonEnabled) return app.operationBuilder.transfer(0,0,0,0, memoField.text, 0)
|
||||
|
||||
return app.operationBuilder.transfer(senderPicker.account.id, recipientPicker.account.id,
|
||||
amountField.value * amountField.precisionAdjustment,
|
||||
|
|
@ -56,10 +55,18 @@ FormBase {
|
|||
placeholderText: qsTr("Recipient")
|
||||
layoutDirection: Qt.RightToLeft
|
||||
}
|
||||
TextField {
|
||||
id: memoField
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Memo")
|
||||
TextField {
|
||||
id: memoField
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Memo")
|
||||
}
|
||||
CheckBox {
|
||||
id: encryptMemoField
|
||||
text: qsTr("Encrypt Memo")
|
||||
checked: true
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -97,18 +104,25 @@ FormBase {
|
|||
return qsTr("Fee:<br/>") + amountField.maxBalance.type.formatAmount(operation().fee) + " CORE"
|
||||
}
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
Button {
|
||||
text: qsTr("Cancel")
|
||||
onClicked: canceled({})
|
||||
}
|
||||
Button {
|
||||
id: transferButton
|
||||
text: !senderAccount ||
|
||||
}
|
||||
UnlockingFinishButtons {
|
||||
id: finishLine
|
||||
app: base.app
|
||||
rightButtonText: {
|
||||
return !senderAccount ||
|
||||
!senderAccount.isLoaded ||
|
||||
senderPicker.accountControlLevel >= 1? qsTr("Transfer") : qsTr("Propose")
|
||||
enabled: senderPicker.account && recipientPicker.account && senderPicker.account !== recipientPicker.account && amountField.value
|
||||
onClicked: completed([operation()])
|
||||
}
|
||||
rightButtonEnabled: senderPicker.account && recipientPicker.account && senderPicker.account !== recipientPicker.account && amountField.value
|
||||
requiresUnlocking: encryptMemoField.checked
|
||||
Layout.fillWidth: true
|
||||
|
||||
onLeftButtonClicked: canceled({})
|
||||
onRightButtonClicked: {
|
||||
var op = operation()
|
||||
if (encryptMemoField.checked)
|
||||
op.encryptMemo(app.wallet, app.model)
|
||||
completed([op])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
50
programs/light_client/qml/UnlockingFinishButtons.qml
Normal file
50
programs/light_client/qml/UnlockingFinishButtons.qml
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Layouts 1.2
|
||||
|
||||
import "."
|
||||
|
||||
import Graphene.Client 0.1
|
||||
|
||||
RowLayout {
|
||||
property string leftButtonText: qsTr("Cancel")
|
||||
property string unlockButtonText: qsTr("Unlock")
|
||||
property string rightButtonText: qsTr("Finish")
|
||||
property bool leftButtonEnabled: true
|
||||
property bool rightButtonEnabled: true
|
||||
property bool requiresUnlocking: true
|
||||
property GrapheneApplication app
|
||||
|
||||
signal leftButtonClicked
|
||||
signal rightButtonClicked
|
||||
|
||||
Item { Layout.fillWidth: true }
|
||||
Button {
|
||||
text: leftButtonText
|
||||
onClicked: leftButtonClicked()
|
||||
}
|
||||
TextField {
|
||||
id: passwordField
|
||||
property bool shown: requiresUnlocking && app.wallet.isLocked
|
||||
property real desiredWidth: shown? Scaling.cm(4) : 0
|
||||
Layout.preferredWidth: desiredWidth
|
||||
echoMode: TextInput.Password
|
||||
placeholderText: qsTr("Wallet password")
|
||||
visible: desiredWidth > 0
|
||||
onAccepted: rightButton.clicked()
|
||||
|
||||
Behavior on desiredWidth { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } }
|
||||
}
|
||||
Button {
|
||||
id: rightButton
|
||||
text: passwordField.shown? unlockButtonText : rightButtonText
|
||||
enabled: rightButtonEnabled
|
||||
onClicked: {
|
||||
if (passwordField.visible)
|
||||
return app.wallet.unlock(passwordField.text)
|
||||
|
||||
rightButtonClicked()
|
||||
}
|
||||
Behavior on implicitWidth { NumberAnimation {} }
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
<file>TransactionConfirmationForm.qml</file>
|
||||
<file>FormBox.qml</file>
|
||||
<file>FormFlipper.qml</file>
|
||||
<file>UnlockingFinishButtons.qml</file>
|
||||
<file>Scaling.qml</file>
|
||||
<file>Identicon.qml</file>
|
||||
<file>AccountPicker.qml</file>
|
||||
|
|
|
|||
Loading…
Reference in a new issue