[GUI] Add support for balance update notifications
TODO: Figure out why maximum value in transfer form doesn't update
This commit is contained in:
parent
d0b8c66aad
commit
6bdc0f69b6
2 changed files with 88 additions and 5 deletions
|
|
@ -52,6 +52,50 @@ Asset* ChainDataModel::getAsset(QString symbol)
|
||||||
return *itr;
|
return *itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChainDataModel::processUpdatedObject(const fc::variant& update)
|
||||||
|
{
|
||||||
|
if (update.is_null())
|
||||||
|
return;
|
||||||
|
if (&fc::thread::current() == m_rpc_thread)
|
||||||
|
{
|
||||||
|
ilog("Proxying object update to app thread.");
|
||||||
|
Q_EMIT queueExecute([this,update]{processUpdatedObject(update);});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
idump((update));
|
||||||
|
try {
|
||||||
|
auto id = update.as<variant_object>()["id"].as<object_id_type>();
|
||||||
|
if (id.space() == protocol_ids) {
|
||||||
|
switch (id.type()) {
|
||||||
|
default:
|
||||||
|
wlog("Update procedure for ${update} is not yet implemented.", ("update", update));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (id.space() == implementation_ids) {
|
||||||
|
switch (id.type()) {
|
||||||
|
case impl_account_balance_object_type: {
|
||||||
|
account_balance_object balance = update.as<account_balance_object>();
|
||||||
|
auto owner = m_accounts.find(balance.owner.instance.value);
|
||||||
|
if (owner != m_accounts.end())
|
||||||
|
(*owner)->update(balance);
|
||||||
|
else
|
||||||
|
elog("Got unexpected balance update:\n${u}\nfor an account I don't have.",
|
||||||
|
("u", update));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
wlog("Update procedure for ${update} is not yet implemented.", ("update", update));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
wlog("Update procedure for ${update} is not yet implemented.", ("update", update));
|
||||||
|
} catch (const fc::exception& e) {
|
||||||
|
elog("Caught exception while updating object: ${e}", ("e", e.to_detail_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChainDataModel::getAssetImpl(QString assetIdentifier, Asset* const * assetInContainer)
|
void ChainDataModel::getAssetImpl(QString assetIdentifier, Asset* const * assetInContainer)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
@ -86,8 +130,8 @@ void ChainDataModel::getAccountImpl(QString accountIdentifier, Account* const *
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
ilog("Fetching account ${acct}", ("acct", accountIdentifier.toStdString()));
|
ilog("Fetching account ${acct}", ("acct", accountIdentifier.toStdString()));
|
||||||
auto result = m_db_api->get_full_accounts([](const fc::variant& v) {
|
auto result = m_db_api->get_full_accounts([this](const fc::variant& v) {
|
||||||
idump((v));
|
processUpdatedObject(v);
|
||||||
}, {accountIdentifier.toStdString()});
|
}, {accountIdentifier.toStdString()});
|
||||||
fc::optional<full_account> accountPackage;
|
fc::optional<full_account> accountPackage;
|
||||||
|
|
||||||
|
|
@ -203,6 +247,27 @@ QQmlListProperty<Balance> Account::balances()
|
||||||
return QQmlListProperty<Balance>(this, this, count, at);
|
return QQmlListProperty<Balance>(this, this, count, at);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Account::update(const account_balance_object& balance)
|
||||||
|
{
|
||||||
|
auto balanceItr = std::find_if(m_balances.begin(), m_balances.end(),
|
||||||
|
[&balance](Balance* b) { return b->type()->id() == balance.asset_type.instance.value; });
|
||||||
|
|
||||||
|
if (balanceItr != m_balances.end()) {
|
||||||
|
ilog("Updating ${a}'s balance: ${b}", ("a", m_name.toStdString())("b", balance));
|
||||||
|
(*balanceItr)->update(balance);
|
||||||
|
Q_EMIT balancesChanged();
|
||||||
|
} else {
|
||||||
|
ilog("Adding to ${a}'s new balance: ${b}", ("a", m_name.toStdString())("b", balance));
|
||||||
|
Balance* newBalance = new Balance;
|
||||||
|
newBalance->setParent(this);
|
||||||
|
auto model = qobject_cast<ChainDataModel*>(parent());
|
||||||
|
newBalance->setProperty("type", QVariant::fromValue(model->getAsset(balance.asset_type.instance.value)));
|
||||||
|
newBalance->setProperty("amount", QVariant::fromValue(balance.balance.value));
|
||||||
|
m_balances.append(newBalance);
|
||||||
|
Q_EMIT balancesChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GrapheneApplication::GrapheneApplication(QObject* parent)
|
GrapheneApplication::GrapheneApplication(QObject* parent)
|
||||||
:QObject(parent),m_thread("app")
|
:QObject(parent),m_thread("app")
|
||||||
{
|
{
|
||||||
|
|
@ -268,3 +333,11 @@ Q_SLOT void GrapheneApplication::execute(const std::function<void()>& func)const
|
||||||
{
|
{
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Balance::update(const account_balance_object& update)
|
||||||
|
{
|
||||||
|
if (update.balance != amount) {
|
||||||
|
amount = update.balance.value;
|
||||||
|
emit amountChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,18 +97,24 @@ typedef multi_index_container<
|
||||||
class Balance : public GrapheneObject {
|
class Balance : public GrapheneObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(Asset* type MEMBER type NOTIFY typeChanged)
|
Q_PROPERTY(Asset* type MEMBER m_type READ type NOTIFY typeChanged)
|
||||||
Q_PROPERTY(qint64 amount MEMBER amount NOTIFY amountChanged)
|
Q_PROPERTY(qint64 amount MEMBER amount NOTIFY amountChanged)
|
||||||
|
|
||||||
Asset* type;
|
Asset* m_type;
|
||||||
qint64 amount;
|
qint64 amount;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// This ultimately needs to be replaced with a string equivalent
|
// This ultimately needs to be replaced with a string equivalent
|
||||||
Q_INVOKABLE qreal amountReal() const {
|
Q_INVOKABLE qreal amountReal() const {
|
||||||
return amount / qreal(type->precisionPower());
|
return amount / qreal(m_type->precisionPower());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Asset* type()const {
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(const graphene::app::account_balance_object& update);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void typeChanged();
|
void typeChanged();
|
||||||
void amountChanged();
|
void amountChanged();
|
||||||
|
|
@ -138,6 +144,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update(const graphene::app::account_balance_object& balance);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void nameChanged();
|
void nameChanged();
|
||||||
void balancesChanged();
|
void balancesChanged();
|
||||||
|
|
@ -155,6 +163,8 @@ typedef multi_index_container<
|
||||||
class ChainDataModel : public QObject {
|
class ChainDataModel : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
void processUpdatedObject(const fc::variant& update);
|
||||||
|
|
||||||
void getAssetImpl(QString assetIdentifier, Asset* const * assetInContainer);
|
void getAssetImpl(QString assetIdentifier, Asset* const * assetInContainer);
|
||||||
void getAccountImpl(QString accountIdentifier, Account* const * accountInContainer);
|
void getAccountImpl(QString accountIdentifier, Account* const * accountInContainer);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue