started to work over currencies
This commit is contained in:
parent
5c4bd18cdc
commit
45f924a4cf
@ -4,11 +4,13 @@
|
|||||||
set(HEADERS
|
set(HEADERS
|
||||||
magpie.h
|
magpie.h
|
||||||
assets.h
|
assets.h
|
||||||
|
currencies.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
magpie.cpp
|
magpie.cpp
|
||||||
assets.cpp
|
assets.cpp
|
||||||
|
currencies.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(magpie PRIVATE ${SOURCES})
|
target_sources(magpie PRIVATE ${SOURCES})
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
|
|
||||||
#include "utils/helpers.h"
|
#include "utils/helpers.h"
|
||||||
|
|
||||||
|
const QHash<int, QByteArray> Models::Assets::roles({
|
||||||
|
{Title, "title"}, {Icon, "icon"}, {Balance, "balance"}, {Archived, "archived"}, {Color, "color"}, {Id, "assetId"}
|
||||||
|
});
|
||||||
|
|
||||||
Models::Assets::Assets (QObject* parent):
|
Models::Assets::Assets (QObject* parent):
|
||||||
QAbstractListModel(parent),
|
QAbstractListModel(parent),
|
||||||
records(),
|
records(),
|
||||||
@ -17,7 +21,7 @@ void Models::Assets::clear () {
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Models::Assets::addAsset (const Asset& asset) {
|
void Models::Assets::add (const Asset& asset) {
|
||||||
QModelIndex index = getIndex(asset.id);
|
QModelIndex index = getIndex(asset.id);
|
||||||
if (index.isValid())
|
if (index.isValid())
|
||||||
throw std::runtime_error("An attempt to insert a duplicating Asset to an asset model");
|
throw std::runtime_error("An attempt to insert a duplicating Asset to an asset model");
|
||||||
@ -27,7 +31,7 @@ void Models::Assets::addAsset (const Asset& asset) {
|
|||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Models::Assets::addAssets (const std::deque<Asset>& assets) {
|
void Models::Assets::add (const std::deque<Asset>& assets) {
|
||||||
if (assets.empty())
|
if (assets.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -42,7 +46,7 @@ void Models::Assets::addAssets (const std::deque<Asset>& assets) {
|
|||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Models::Assets::deleteAsset (unsigned int id) {
|
void Models::Assets::remove (unsigned int id) {
|
||||||
QModelIndex index = getIndex(id);
|
QModelIndex index = getIndex(id);
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
throw std::runtime_error("An attempt to delete non existing Asset from asset model");
|
throw std::runtime_error("An attempt to delete non existing Asset from asset model");
|
||||||
@ -64,10 +68,7 @@ int Models::Assets::rowCount (const QModelIndex& parent) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QHash<int, QByteArray> Models::Assets::roleNames () const {
|
QHash<int, QByteArray> Models::Assets::roleNames () const {
|
||||||
static const QHash<int, QByteArray> roleNames({
|
return roles;
|
||||||
{Title, "title"}, {Icon, "icon"}, {Balance, "balance"}, {Archived, "archived"}, {Color, "color"}, {Id, "assetId"}
|
|
||||||
});
|
|
||||||
return roleNames;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Models::Assets::canFetchMore (const QModelIndex& parent) const {
|
bool Models::Assets::canFetchMore (const QModelIndex& parent) const {
|
||||||
|
@ -37,10 +37,10 @@ public:
|
|||||||
Id
|
Id
|
||||||
};
|
};
|
||||||
|
|
||||||
void clear();
|
void clear ();
|
||||||
void addAsset(const Asset& asset);
|
void add (const Asset& asset);
|
||||||
void addAssets(const std::deque<Asset>& assets);
|
void add (const std::deque<Asset>& assets);
|
||||||
void deleteAsset(unsigned int id);
|
void remove (unsigned int id);
|
||||||
|
|
||||||
//Basic functionality:
|
//Basic functionality:
|
||||||
int rowCount (const QModelIndex& parent = QModelIndex()) const override;
|
int rowCount (const QModelIndex& parent = QModelIndex()) const override;
|
||||||
@ -51,16 +51,17 @@ public:
|
|||||||
void fetchMore (const QModelIndex& parent) override;
|
void fetchMore (const QModelIndex& parent) override;
|
||||||
QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
static bool deserialize(const QVariantList& from, std::deque<Asset>& out);
|
static bool deserialize (const QVariantList& from, std::deque<Asset>& out);
|
||||||
|
static const QHash<int, QByteArray> roles;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void requestAssets();
|
void requestAssets ();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void receivedAssets(const std::deque<Asset>& assets);
|
void receivedAssets (const std::deque<Asset>& assets);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QModelIndex getIndex(unsigned int id) const;
|
QModelIndex getIndex (unsigned int id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class State {
|
enum class State {
|
||||||
|
132
models/currencies.cpp
Normal file
132
models/currencies.cpp
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||||
|
//SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "currencies.h"
|
||||||
|
|
||||||
|
#include "utils/helpers.h"
|
||||||
|
|
||||||
|
const QHash<int, QByteArray> Models::Currencies::roles({
|
||||||
|
{Id, "id"}, {Code, "code"}, {Title, "title"}, {Type, "type"}, {Value, "value"}, {Description, "description"}, {Icon, "icon"}
|
||||||
|
});
|
||||||
|
|
||||||
|
Models::Currencies::Currencies (QObject* parent):
|
||||||
|
QAbstractListModel(parent),
|
||||||
|
order(),
|
||||||
|
index(),
|
||||||
|
map()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void Models::Currencies::clear () {
|
||||||
|
beginResetModel();
|
||||||
|
order.clear();
|
||||||
|
index.clear();
|
||||||
|
map.clear();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Models::Currencies::add (const Currency& currency) {
|
||||||
|
if (map.count(currency.id))
|
||||||
|
throw std::runtime_error("An attempt to insert a duplicating currency to a currency model");
|
||||||
|
|
||||||
|
beginInsertRows(QModelIndex(), index.size(), index.size());
|
||||||
|
Order::iterator itr = order.insert(order.end(), currency);
|
||||||
|
index.push_back(itr);
|
||||||
|
map.emplace(currency.id, itr);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Models::Currencies::add (const std::deque<Currency>& currencies) {
|
||||||
|
if (currencies.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const Currency& currency : currencies)
|
||||||
|
if (map.count(currency.id))
|
||||||
|
throw std::runtime_error("An attempt to insert a duplicating currency to a currency model (bulk)");
|
||||||
|
|
||||||
|
beginInsertRows(QModelIndex(), index.size(), index.size() + currencies.size() - 1);
|
||||||
|
for (const Currency& currency : currencies) {
|
||||||
|
Order::iterator itr = order.insert(order.end(), currency);
|
||||||
|
index.push_back(itr);
|
||||||
|
map.emplace(currency.id, itr);
|
||||||
|
}
|
||||||
|
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Models::Currencies::remove (Currency::ID id) {
|
||||||
|
Map::iterator mItr = map.find(id);
|
||||||
|
if (mItr == map.end())
|
||||||
|
throw std::runtime_error("An attempt to delete non existing currency from currency model");
|
||||||
|
|
||||||
|
Order::iterator itr = mItr->second;
|
||||||
|
Index::iterator iItr = std::find(index.begin(), index.end(), itr);
|
||||||
|
int row = std::distance(index.begin(), iItr);
|
||||||
|
|
||||||
|
beginRemoveRows(QModelIndex(), row, row);
|
||||||
|
map.erase(mItr);
|
||||||
|
index.erase(iItr);
|
||||||
|
order.erase(itr);
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Models::Currencies::rowCount (const QModelIndex& parent) const {
|
||||||
|
//For list models only the root node (an invalid parent) should return the
|
||||||
|
//list's size. For all other (valid) parents, rowCount() should return 0 so
|
||||||
|
//that it does not become a tree model.
|
||||||
|
if (parent.isValid())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return index.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> Models::Currencies::roleNames () const {
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant Models::Currencies::data (const QModelIndex& index, int role) const {
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
int row = index.row();
|
||||||
|
if (row >= 0 && row < Currencies::index.size()) {
|
||||||
|
const Order::iterator& itr = Currencies::index[row];
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
case Title:
|
||||||
|
return itr->title;
|
||||||
|
case Icon:
|
||||||
|
return itr->icon;
|
||||||
|
case Description:
|
||||||
|
return itr->description;
|
||||||
|
case Code:
|
||||||
|
return itr->code;
|
||||||
|
case Type:
|
||||||
|
return itr->type;
|
||||||
|
case Id:
|
||||||
|
return itr->id;
|
||||||
|
case Value:
|
||||||
|
return itr->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Models::Currencies::deserialize (const QVariantList& from, std::deque<Currency>& out) {
|
||||||
|
for (const QVariant& item : from) {
|
||||||
|
if (!item.canConvert<QVariantMap>())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QVariantMap& ser = qast<QVariantMap>(item);
|
||||||
|
Currency& currency = out.emplace_back();
|
||||||
|
currency.title = ser.value("title").toString();
|
||||||
|
currency.icon = ser.value("icon", "").toString();
|
||||||
|
currency.description = ser.value("archived", "").toString();
|
||||||
|
currency.id = ser.value("id").toUInt();
|
||||||
|
currency.code = ser.value("code").toString();
|
||||||
|
currency.value = ser.value("value").toDouble();
|
||||||
|
currency.type = ser.value("type", 1).toUInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
68
models/currencies.h
Normal file
68
models/currencies.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||||
|
//SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <qqmlregistration.h>
|
||||||
|
|
||||||
|
namespace Models {
|
||||||
|
struct Currency {
|
||||||
|
using ID = uint32_t;
|
||||||
|
|
||||||
|
ID id;
|
||||||
|
QString code;
|
||||||
|
QString title;
|
||||||
|
unsigned int type;
|
||||||
|
double value;
|
||||||
|
QString description;
|
||||||
|
QString icon;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Currencies : public QAbstractListModel {
|
||||||
|
Q_OBJECT
|
||||||
|
QML_ELEMENT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Currencies (QObject* parent = nullptr);
|
||||||
|
|
||||||
|
enum Roles {
|
||||||
|
Id = Qt::UserRole + 1,
|
||||||
|
Code,
|
||||||
|
Title,
|
||||||
|
Type,
|
||||||
|
Value,
|
||||||
|
Description,
|
||||||
|
Icon
|
||||||
|
};
|
||||||
|
|
||||||
|
void clear ();
|
||||||
|
void add (const Currency& currency);
|
||||||
|
void add (const std::deque<Currency>& currencies);
|
||||||
|
void remove (Currency::ID id);
|
||||||
|
|
||||||
|
//Basic functionality:
|
||||||
|
int rowCount (const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
QHash<int, QByteArray> roleNames () const override;
|
||||||
|
QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
static bool deserialize(const QVariantList& from, std::deque<Currency>& out);
|
||||||
|
static const QHash<int, QByteArray> roles;
|
||||||
|
|
||||||
|
private:
|
||||||
|
using Order = std::list<Currency>;
|
||||||
|
using Index = std::deque<Order::iterator>;
|
||||||
|
using Map = std::map<Currency::ID, Order::iterator>;
|
||||||
|
|
||||||
|
Order order;
|
||||||
|
Index index;
|
||||||
|
Map map;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -18,7 +18,8 @@ Models::Magpie::Magpie (QObject* parent):
|
|||||||
renewToken(),
|
renewToken(),
|
||||||
api(),
|
api(),
|
||||||
firstPoll(),
|
firstPoll(),
|
||||||
pollRequestId(API::none)
|
pollRequestId(API::none),
|
||||||
|
requestingCurrencies(false)
|
||||||
{
|
{
|
||||||
firstPoll.setSingleShot(true);
|
firstPoll.setSingleShot(true);
|
||||||
firstPoll.setInterval(2000);
|
firstPoll.setInterval(2000);
|
||||||
@ -89,6 +90,10 @@ Models::Assets* Models::Magpie::getAssets () {
|
|||||||
return &assets;
|
return &assets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Models::Currencies* Models::Magpie::getCurrencies () {
|
||||||
|
return ¤cies;
|
||||||
|
}
|
||||||
|
|
||||||
void Models::Magpie::requestAssets () {
|
void Models::Magpie::requestAssets () {
|
||||||
api->requestAssets(
|
api->requestAssets(
|
||||||
[this] (const QVariantList& list) {
|
[this] (const QVariantList& list) {
|
||||||
@ -101,10 +106,10 @@ void Models::Magpie::requestAssets () {
|
|||||||
qDebug() << "Assets successfully received";
|
qDebug() << "Assets successfully received";
|
||||||
}
|
}
|
||||||
|
|
||||||
assets.addAssets(result);
|
assets.add(result);
|
||||||
},
|
},
|
||||||
[this] (const QString& error, const std::optional<QVariantMap>& data) {
|
[this] (const QString& error, const std::optional<QVariantMap>& data) {
|
||||||
assets.addAssets({});
|
assets.add(std::deque<Asset>());
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -172,35 +177,55 @@ bool Models::Magpie::handleChanges (const QVariantMap& changes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool result = true;
|
||||||
itr = changes.constFind("assets");
|
itr = changes.constFind("assets");
|
||||||
if (itr != changes.constEnd() && itr.value().canConvert<QVariantMap>()) {
|
if (itr != changes.constEnd() && itr.value().canConvert<QVariantMap>())
|
||||||
const QVariantMap& assets = qast<QVariantMap>(itr.value());
|
result = handleAssetChanges(qast<QVariantMap>(itr.value()));
|
||||||
QVariantMap::ConstIterator aItr = assets.constFind("invalidate");
|
|
||||||
if (aItr != assets.constEnd()) {
|
itr = changes.constFind("currencies");
|
||||||
|
if (itr != changes.constEnd() && itr.value().canConvert<QVariantMap>())
|
||||||
|
result = result && handleCurrenciesChanges(qast<QVariantMap>(itr.value()));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Models::Magpie::handleAssetChanges (const QVariantMap& changes) {
|
||||||
|
QVariantMap::ConstIterator aItr = changes.constFind("invalidate");
|
||||||
|
if (aItr != changes.constEnd()) {
|
||||||
const QVariant& vinv = aItr.value();
|
const QVariant& vinv = aItr.value();
|
||||||
if (vinv.canConvert<bool>() && vinv.toBool())
|
if (vinv.canConvert<bool>() && vinv.toBool())
|
||||||
Magpie::assets.clear();
|
assets.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
aItr = assets.constFind("added");
|
aItr = changes.constFind("added");
|
||||||
if (aItr != assets.constEnd() && aItr.value().canConvert<QVariantList>()) {
|
if (aItr != changes.constEnd() && aItr.value().canConvert<QVariantList>()) {
|
||||||
std::deque<Models::Asset> added;
|
std::deque<Models::Asset> added;
|
||||||
if (!Models::Assets::deserialize(qast<QVariantList>(aItr.value()), added))
|
if (!Models::Assets::deserialize(qast<QVariantList>(aItr.value()), added))
|
||||||
qDebug() << "Error deserializng added assets";
|
qDebug() << "Error deserializng added assets";
|
||||||
else
|
else
|
||||||
Magpie::assets.addAssets(added);
|
assets.add(added);
|
||||||
}
|
}
|
||||||
|
|
||||||
aItr = assets.constFind("removed");
|
aItr = changes.constFind("removed");
|
||||||
if (aItr != assets.constEnd() && aItr.value().canConvert<QVariantList>()) {
|
if (aItr != changes.constEnd() && aItr.value().canConvert<QVariantList>()) {
|
||||||
const QVariantList rem = qast<QVariantList>(aItr.value());
|
const QVariantList rem = qast<QVariantList>(aItr.value());
|
||||||
for (const QVariant& vId : rem) {
|
for (const QVariant& vId : rem) {
|
||||||
if (vId.isValid() && vId.canConvert<unsigned int>())
|
if (vId.isValid() && vId.canConvert<unsigned int>())
|
||||||
Magpie::assets.deleteAsset(vId.toUInt());
|
assets.remove(vId.toUInt());
|
||||||
else
|
else
|
||||||
qDebug() << "Error deserializing removed assets";
|
qDebug() << "Error deserializing removed assets";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Models::Magpie::handleCurrenciesChanges (const QVariantMap& changes) {
|
||||||
|
QVariantMap::ConstIterator aItr = changes.constFind("invalidate");
|
||||||
|
if (aItr != changes.constEnd()) {
|
||||||
|
const QVariant& vinv = aItr.value();
|
||||||
|
if (vinv.canConvert<bool>() && vinv.toBool())
|
||||||
|
requestCurrencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -208,4 +233,12 @@ bool Models::Magpie::handleChanges (const QVariantMap& changes) {
|
|||||||
|
|
||||||
void Models::Magpie::resetAllModels () {
|
void Models::Magpie::resetAllModels () {
|
||||||
assets.clear();
|
assets.clear();
|
||||||
|
requestCurrencies();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Models::Magpie::requestCurrencies () {
|
||||||
|
if (requestingCurrencies)
|
||||||
|
return;
|
||||||
|
|
||||||
|
currencies.clear();
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "currencies.h"
|
||||||
#include "assets.h"
|
#include "assets.h"
|
||||||
|
|
||||||
class API;
|
class API;
|
||||||
@ -32,6 +33,7 @@ public:
|
|||||||
Q_PROPERTY(QUrl address READ getAddress NOTIFY addressChanged)
|
Q_PROPERTY(QUrl address READ getAddress NOTIFY addressChanged)
|
||||||
Q_PROPERTY(State state READ getState NOTIFY stateChanged)
|
Q_PROPERTY(State state READ getState NOTIFY stateChanged)
|
||||||
Q_PROPERTY(Assets* assets READ getAssets CONSTANT)
|
Q_PROPERTY(Assets* assets READ getAssets CONSTANT)
|
||||||
|
Q_PROPERTY(Currencies* currencies READ getCurrencies CONSTANT)
|
||||||
|
|
||||||
explicit Magpie(QObject *parent = nullptr);
|
explicit Magpie(QObject *parent = nullptr);
|
||||||
|
|
||||||
@ -46,6 +48,7 @@ public:
|
|||||||
void setTokens(const QString access, const QString& renew, bool notify = false);
|
void setTokens(const QString access, const QString& renew, bool notify = false);
|
||||||
void setState(State newState);
|
void setState(State newState);
|
||||||
Assets* getAssets();
|
Assets* getAssets();
|
||||||
|
Currencies* getCurrencies();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void addressChanged(const QUrl& path);
|
void addressChanged(const QUrl& path);
|
||||||
@ -56,6 +59,7 @@ signals:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Assets assets;
|
Assets assets;
|
||||||
|
Currencies currencies;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void requestAssets();
|
void requestAssets();
|
||||||
@ -67,7 +71,10 @@ private:
|
|||||||
void onPollSuccess(const QVariantMap& data);
|
void onPollSuccess(const QVariantMap& data);
|
||||||
void onPollError(const QString& err, const std::optional<QVariantMap>& data);
|
void onPollError(const QString& err, const std::optional<QVariantMap>& data);
|
||||||
bool handleChanges(const QVariantMap& changes);
|
bool handleChanges(const QVariantMap& changes);
|
||||||
|
bool handleAssetChanges(const QVariantMap& changes);
|
||||||
|
bool handleCurrenciesChanges(const QVariantMap& changes);
|
||||||
void resetAllModels();
|
void resetAllModels();
|
||||||
|
void requestCurrencies();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QUrl address;
|
QUrl address;
|
||||||
@ -77,6 +84,7 @@ private:
|
|||||||
std::shared_ptr<API> api;
|
std::shared_ptr<API> api;
|
||||||
QTimer firstPoll;
|
QTimer firstPoll;
|
||||||
unsigned int pollRequestId;
|
unsigned int pollRequestId;
|
||||||
|
bool requestingCurrencies;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user