chore(CPP): watch only account int the POC UI

Updates #6321
This commit is contained in:
Stefan 2022-07-26 13:20:59 +02:00 committed by Stefan Dunca
parent 3fad95ea0e
commit f3dcdf636a
8 changed files with 215 additions and 67 deletions

View File

@ -7,11 +7,10 @@ TextInput {
font.pointSize: 23 font.pointSize: 23
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter
clip: true
Rectangle { Rectangle {
anchors { anchors.fill: parent
fill: parent
margins: -1
}
border.width: 1 border.width: 1
z: parent.z - 1 z: parent.z - 1
} }

View File

@ -16,7 +16,9 @@ qt6_add_qml_module(Wallet
VERSION 1.0 VERSION 1.0
QML_FILES QML_FILES
qml/Status/Wallet/NewAccount/AddWatchOnlyAccountView.qml
qml/Status/Wallet/NewAccount/NewWalletAccountView.qml qml/Status/Wallet/NewAccount/NewWalletAccountView.qml
qml/Status/Wallet/NewAccount/TmpColorComboBox.qml
qml/Status/Wallet/AssetsPanel.qml qml/Status/Wallet/AssetsPanel.qml
qml/Status/Wallet/AssetView.qml qml/Status/Wallet/AssetView.qml
qml/Status/Wallet/WalletContentView.qml qml/Status/Wallet/WalletContentView.qml

View File

@ -50,6 +50,10 @@ public:
const QColor &color, const QString &path, const QColor &color, const QString &path,
const Status::Wallet::WalletAccount *derivedFrom); const Status::Wallet::WalletAccount *derivedFrom);
/// \see \c accountCreatedStatus for async result
Q_INVOKABLE void addWatchOnlyAccountAsync(const QString &address, const QString &name,
const QColor &color);
/// \returns \c false if fails (due to incomplete user input) /// \returns \c false if fails (due to incomplete user input)
Q_INVOKABLE bool retrieveAndUpdateDerivedAddresses(const QString &password, Q_INVOKABLE bool retrieveAndUpdateDerivedAddresses(const QString &password,
@ -76,6 +80,8 @@ private:
WalletAccountPtr findMissingAccount(); WalletAccountPtr findMissingAccount();
AccountsModel::ObjectContainer filterMainAccounts(const AccountsModel &accounts); AccountsModel::ObjectContainer filterMainAccounts(const AccountsModel &accounts);
/// Logs a debug message if it fails
void addNewlyCreatedAccount(WalletAccountPtr newAccount);
std::shared_ptr<AccountsModel> m_accounts; std::shared_ptr<AccountsModel> m_accounts;
/// \todo make it a proxy filter on top of \c m_accounts /// \todo make it a proxy filter on top of \c m_accounts

View File

@ -109,32 +109,72 @@ Item {
onClicked: newAccountLoader.active = true onClicked: newAccountLoader.active = true
} }
Loader { ColumnLayout {
id: newAccountLoader visible: !errorLayout.visible && newAccountLoader.active
Layout.fillWidth: true Rectangle {
color: "blue"
visible: !errorLayout.visible && active Layout.fillWidth: true
active: false Layout.preferredHeight: 2
Layout.margins: 5
}
sourceComponent: Component { ComboBox {
NewWalletAccountView { id: accountTypeComboBox
controller: root.controller.createNewWalletAccountController()
onCancel: newAccountLoader.active = false textRole: "title"
onAccountCreated: newAccountLoader.active = false valueRole: "sourceComponent"
Connections { Layout.fillWidth: true
target: controller
function onAccountCreatedStatus(createdSuccessfully) { component NewAccountEntry: ItemDelegate {
if(createdSuccessfully) required property string title
newAccountLoader.active = false required property Component sourceComponent
else
errorLayout.visible = true text: title
width: accountTypeComboBox.width
}
model: ObjectModel {
NewAccountEntry {
title: "New Account"
sourceComponent: NewWalletAccountView {
controller: root.controller.createNewWalletAccountController()
}
}
NewAccountEntry {
title: "Watch Only Account"
sourceComponent: AddWatchOnlyAccountView {
controller: root.controller.createNewWalletAccountController()
} }
} }
} }
} }
Loader {
id: newAccountLoader
Layout.fillWidth: true
active: false
sourceComponent: accountTypeComboBox.currentValue
}
Connections {
target: newAccountLoader.item ? newAccountLoader.item.controller : null
function onAccountCreatedStatus(createdSuccessfully) {
if(createdSuccessfully)
newAccountLoader.active = false
else
errorLayout.visible = true
}
}
Connections {
target: newAccountLoader.item
function onCancel() { newAccountLoader.active = false }
function onAccountCreated() { newAccountLoader.active = false }
}
} }
ColumnLayout { ColumnLayout {

View File

@ -0,0 +1,82 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Status.Wallet
import Status.Onboarding
import Status.Containers
Item {
id: root
/// NewWalletAccountController
required property var controller
signal accountCreated()
signal cancel()
implicitWidth: mainLayout.implicitWidth
implicitHeight: mainLayout.implicitHeight
ColumnLayout {
id: mainLayout
anchors.fill: parent
Label {
text: "Name"
Layout.margins: 5
}
TempTextInput {
id: nameInput
text: "Test Watch Account"
Layout.fillWidth: true
Layout.margins: 5
}
Label {
text: "Address"
Layout.margins: 5
}
TempTextInput {
id: addressInput
text: "0xdb5ac1a559b02e12f29fc0ec0e37be8e046def49"
Layout.fillWidth: true
Layout.margins: 5
}
Label {
text: "Color"
Layout.margins: 5
}
TmpColorComboBox {
id: colorCombo
Layout.fillWidth: true
Layout.margins: 5
}
RowLayout {
Button {
text: qsTr("Add Watch Only Account")
enabled: nameInput.text.length > 5 && addressInput.text.length > 22 && addressInput.text.startsWith("0x")
onClicked: controller.addWatchOnlyAccountAsync(addressInput.text, nameInput.text,
colorCombo.currentValue);
Layout.margins: 5
}
Button {
text: qsTr("V")
onClicked: root.cancel()
Layout.margins: 5
}
}
}
}

View File

@ -35,14 +35,6 @@ Item {
anchors.fill: parent anchors.fill: parent
Rectangle {
color: "blue"
Layout.fillWidth: true
Layout.preferredHeight: 2
Layout.margins: 5
}
Label { Label {
text: "Name" text: "Name"
@ -77,40 +69,11 @@ Item {
Layout.margins: 5 Layout.margins: 5
} }
ComboBox { TmpColorComboBox {
id: colorCombo id: colorCombo
model: ListModel {
ListElement { colorText: "Red"; colorValue: "red" }
ListElement { colorText: "Green"; colorValue: "green" }
ListElement { colorText: "Blue"; colorValue: "blue" }
ListElement { colorText: "Orange"; colorValue: "orange" }
ListElement { colorText: "Pink"; colorValue: "pink" }
ListElement { colorText: "Fuchsia"; colorValue: "fuchsia" }
}
textRole: "colorText"
valueRole: "colorValue"
currentIndex: 0
Layout.fillWidth: true Layout.fillWidth: true
Layout.margins: 5 Layout.margins: 5
delegate: ItemDelegate {
required property string colorText
required property color colorValue
required property int index
width: colorCombo.width
contentItem: Text {
text: colorText
color: colorValue
font: colorCombo.font
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
highlighted: colorCombo.highlightedIndex === index
}
} }
Label { Label {
@ -220,8 +183,8 @@ Item {
Button { Button {
text: qsTr("Create") text: qsTr("Create")
enabled: nameInput.text.length > 5 && passwordInput.length > 5 enabled: nameInput.text.length > 5 && passwordInput.text.length > 5
&& pathInput.length > 0 && pathInput.text.length > 0
onClicked: root.controller.createAccountAsync(passwordInput.text, nameInput.text, onClicked: root.controller.createAccountAsync(passwordInput.text, nameInput.text,
colorCombo.currentValue, pathInput.text, colorCombo.currentValue, pathInput.text,

View File

@ -0,0 +1,36 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
ComboBox {
id: colorCombo
model: ListModel {
ListElement { colorText: "Red"; colorValue: "red" }
ListElement { colorText: "Green"; colorValue: "green" }
ListElement { colorText: "Blue"; colorValue: "blue" }
ListElement { colorText: "Orange"; colorValue: "orange" }
ListElement { colorText: "Pink"; colorValue: "pink" }
ListElement { colorText: "Fuchsia"; colorValue: "fuchsia" }
}
textRole: "colorText"
valueRole: "colorValue"
currentIndex: 0
delegate: ItemDelegate {
required property string colorText
required property color colorValue
required property int index
width: colorCombo.width
contentItem: Text {
text: colorText
color: colorValue
font: colorCombo.font
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
highlighted: colorCombo.highlightedIndex === index
}
}

View File

@ -72,16 +72,26 @@ void NewWalletAccountController::createAccountAsync(const QString &password, con
GoAccounts::generateAccountWithDerivedPath(StatusGo::HashedPassword(UtilsSG::hashPassword(password)), GoAccounts::generateAccountWithDerivedPath(StatusGo::HashedPassword(UtilsSG::hashPassword(password)),
name, color, "", GoAccounts::DerivationPath(path), name, color, "", GoAccounts::DerivationPath(path),
derivedFrom->data().derivedFrom.value()); derivedFrom->data().derivedFrom.value());
auto found = findMissingAccount();
if(found)
m_accounts->push_back(found);
else
qWarning() << "Failed to create account. No new account found by this->findMissingAccount";
emit accountCreatedStatus(found != nullptr); addNewlyCreatedAccount(findMissingAccount());
} }
catch(const StatusGo::CallPrivateRpcError& e) { catch(const StatusGo::CallPrivateRpcError& e) {
qWarning() << "StatusGoQt.generateAccountWithDerivedPath error: " << e.errorResponse().error.message.c_str(); qWarning() << "StatusGoQt.generateAccountWithDerivedPath error: " << e.errorResponse().error.message.c_str();
emit accountCreatedStatus(false);
}
}
void NewWalletAccountController::addWatchOnlyAccountAsync(const QString &address, const QString &name, const QColor &color)
{
try {
GoAccounts::addAccountWatch(Accounts::EOAddress(address), name, color, u""_qs);
addNewlyCreatedAccount(findMissingAccount());
}
catch(const StatusGo::CallPrivateRpcError& e) {
qWarning() << "StatusGoQt.generateAccountWithDerivedPath error: " << e.errorResponse().error.message.c_str();
emit accountCreatedStatus(false); emit accountCreatedStatus(false);
} }
} }
@ -149,6 +159,16 @@ NewWalletAccountController::filterMainAccounts(const AccountsModel &accounts)
return out; return out;
} }
void NewWalletAccountController::addNewlyCreatedAccount(WalletAccountPtr newAccount)
{
if(newAccount)
m_accounts->push_back(newAccount);
else
qWarning() << "No new account to add. Creation failed";
emit accountCreatedStatus(newAccount != nullptr);
}
DerivedWalletAddress *NewWalletAccountController::selectedDerivedAddress() const DerivedWalletAddress *NewWalletAccountController::selectedDerivedAddress() const
{ {
return m_selectedDerivedAddress.get(); return m_selectedDerivedAddress.get();