tested currencies retrieval, now assets display the currency

This commit is contained in:
Blue 2024-03-29 19:00:17 -03:00
parent 45f924a4cf
commit cf2f387f58
Signed by: blue
GPG Key ID: 9B203B252A63EE38
14 changed files with 137 additions and 27 deletions

View File

@ -11,7 +11,8 @@
#include "requests/register.h" #include "requests/register.h"
#include "requests/login.h" #include "requests/login.h"
#include "requests/poll.h" #include "requests/poll.h"
#include "requests/listassets.h" #include "requests/assets.h"
#include "requests/currencies.h"
#include "requests/addasset.h" #include "requests/addasset.h"
#include "requests/deleteasset.h" #include "requests/deleteasset.h"
@ -93,10 +94,20 @@ API::RequestId API::sendLogin (const QString& login, const QString& password, co
API::RequestId API::requestAssets (const SuccessListHandler& success, const ErrorHandler& error) { API::RequestId API::requestAssets (const SuccessListHandler& success, const ErrorHandler& error) {
qDebug() << "Requesting assets..."; qDebug() << "Requesting assets...";
auto list = std::make_unique<Request::ListAssets>(magpie.getAddress()); auto list = std::make_unique<Request::Assets>(magpie.getAddress());
list->setAuthorizationToken(magpie.getAccessToken()); list->setAuthorizationToken(magpie.getAccessToken());
connect(list.get(), &Request::ListAssets::success, success); connect(list.get(), &Request::Assets::success, success);
connect(list.get(), &Request::ListAssets::error, error); connect(list.get(), &Request::Assets::error, error);
return registerAndSend(std::move(list));
}
API::RequestId API::requestCurrencies (const SuccessListHandler& success, const ErrorHandler& error) {
qDebug() << "Requesting currencies...";
auto list = std::make_unique<Request::Currencies>(magpie.getAddress());
list->setAuthorizationToken(magpie.getAccessToken());
connect(list.get(), &Request::Currencies::success, success);
connect(list.get(), &Request::Currencies::error, error);
return registerAndSend(std::move(list)); return registerAndSend(std::move(list));
} }

View File

@ -30,6 +30,7 @@ public:
explicit API(Models::Magpie& magpie, QObject* parent = nullptr); explicit API(Models::Magpie& magpie, QObject* parent = nullptr);
RequestId requestAssets(const SuccessListHandler& success, const ErrorHandler& error); RequestId requestAssets(const SuccessListHandler& success, const ErrorHandler& error);
RequestId requestCurrencies(const SuccessListHandler& success, const ErrorHandler& error);
RequestId poll(const SuccessMapHandler& success, const ErrorHandler& error, bool clear = false); RequestId poll(const SuccessMapHandler& success, const ErrorHandler& error, bool clear = false);
static const RequestId none = 0; static const RequestId none = 0;

View File

@ -8,7 +8,8 @@ set(HEADERS
register.h register.h
login.h login.h
poll.h poll.h
listassets.h assets.h
currencies.h
addasset.h addasset.h
deleteasset.h deleteasset.h
) )
@ -20,7 +21,8 @@ set(SOURCES
register.cpp register.cpp
login.cpp login.cpp
poll.cpp poll.cpp
listassets.cpp assets.cpp
currencies.cpp
addasset.cpp addasset.cpp
deleteasset.cpp deleteasset.cpp
) )

View File

@ -1,14 +1,14 @@
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me> //SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later //SPDX-License-Identifier: GPL-3.0-or-later
#include "listassets.h" #include "assets.h"
#include "utils/helpers.h" #include "utils/helpers.h"
Request::ListAssets::ListAssets (const QUrl& baseUrl): Request::Assets::Assets (const QUrl& baseUrl):
Request(createUrl(baseUrl, "/listAssets")) {} Request(createUrl(baseUrl, "/assets")) {}
void Request::ListAssets::onSuccess (const QVariantMap& data) { void Request::Assets::onSuccess (const QVariantMap& data) {
QVariantMap::ConstIterator itr = data.find("assets"); QVariantMap::ConstIterator itr = data.find("assets");
if (itr == data.constEnd() || !itr->canConvert<QVariantList>()) if (itr == data.constEnd() || !itr->canConvert<QVariantList>())
return Request::onError("Error receiving assets: assets are missing or not in an array", std::nullopt); return Request::onError("Error receiving assets: assets are missing or not in an array", std::nullopt);

View File

@ -7,11 +7,11 @@
namespace Request { namespace Request {
class ListAssets : public Request { class Assets : public Request {
Q_OBJECT Q_OBJECT
public: public:
ListAssets (const QUrl& baseUrl); Assets (const QUrl& baseUrl);
signals: signals:
void success(const QVariantList& assets); void success(const QVariantList& assets);

View File

@ -0,0 +1,18 @@
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#include "currencies.h"
#include "utils/helpers.h"
Request::Currencies::Currencies (const QUrl& baseUrl):
Request(createUrl(baseUrl, "/currencies")) {}
void Request::Currencies::onSuccess (const QVariantMap& data) {
QVariantMap::ConstIterator itr = data.find("currencies");
if (itr == data.constEnd() || !itr->canConvert<QVariantList>())
return Request::onError("Error receiving currencies: currencies are missing or not in an array", std::nullopt);
emit success(qast<QVariantList>(itr.value()));
emit done();
}

24
API/requests/currencies.h Normal file
View File

@ -0,0 +1,24 @@
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "request.h"
namespace Request {
class Currencies : public Request::Request {
Q_OBJECT
public:
Currencies (const QUrl& baseUrl);
signals:
void success(const QVariantList& assets);
protected:
void onSuccess (const QVariantMap& data) override;
};
}

View File

@ -6,13 +6,14 @@
#include "utils/helpers.h" #include "utils/helpers.h"
const QHash<int, QByteArray> Models::Assets::roles({ const QHash<int, QByteArray> Models::Assets::roles({
{Title, "title"}, {Icon, "icon"}, {Balance, "balance"}, {Archived, "archived"}, {Color, "color"}, {Id, "assetId"} {Title, "title"}, {Icon, "icon"}, {Balance, "balance"}, {Archived, "archived"}, {Color, "color"}, {Currency, "currency"}, {Id, "assetId"}
}); });
Models::Assets::Assets (QObject* parent): Models::Assets::Assets (Currencies& currencies, QObject* parent):
QAbstractListModel(parent), QAbstractListModel(parent),
records(), records(),
state(State::initial) state(State::initial),
currencies(currencies)
{} {}
void Models::Assets::clear () { void Models::Assets::clear () {
@ -101,6 +102,8 @@ QVariant Models::Assets::data (const QModelIndex& index, int role) const {
return records[row].archived; return records[row].archived;
case Color: case Color:
return records[row].color; return records[row].color;
case Currency:
return currencies.getCode(records[row].currency);
case Id: case Id:
return records[row].id; return records[row].id;
} }
@ -120,6 +123,7 @@ bool Models::Assets::deserialize (const QVariantList& from, std::deque<Asset>& o
asset.icon = ser.value("icon").toString(); asset.icon = ser.value("icon").toString();
asset.archived = ser.value("archived").toBool(); asset.archived = ser.value("archived").toBool();
asset.id = ser.value("id").toUInt(); asset.id = ser.value("id").toUInt();
asset.currency = ser.value("currency").toUInt();
uint32_t color = ser.value("color").toUInt(); uint32_t color = ser.value("color").toUInt();
asset.color = QColor::fromRgba(color); asset.color = QColor::fromRgba(color);

View File

@ -10,6 +10,8 @@
#include <QAbstractListModel> #include <QAbstractListModel>
#include <qqmlregistration.h> #include <qqmlregistration.h>
#include "currencies.h"
namespace Models { namespace Models {
struct Asset { struct Asset {
unsigned int id; unsigned int id;
@ -26,7 +28,7 @@ class Assets : public QAbstractListModel {
QML_ELEMENT QML_ELEMENT
public: public:
explicit Assets (QObject* parent = nullptr); explicit Assets (Currencies& currencies, QObject* parent = nullptr);
enum Roles { enum Roles {
Title = Qt::UserRole + 1, Title = Qt::UserRole + 1,
@ -34,6 +36,7 @@ public:
Balance, Balance,
Archived, Archived,
Color, Color,
Currency,
Id Id
}; };
@ -72,5 +75,6 @@ private:
State state; State state;
std::deque<Asset> records; std::deque<Asset> records;
Currencies& currencies;
}; };
} }

View File

@ -69,6 +69,15 @@ void Models::Currencies::remove (Currency::ID id) {
endRemoveRows(); endRemoveRows();
} }
QString Models::Currencies::getCode (Currency::ID id) {
Map::iterator mItr = map.find(id);
if (mItr != map.end())
return mItr->second->code;
//todo request;
return "Requesting...";
}
int Models::Currencies::rowCount (const QModelIndex& parent) const { int Models::Currencies::rowCount (const QModelIndex& parent) const {
//For list models only the root node (an invalid parent) should return the //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 //list's size. For all other (valid) parents, rowCount() should return 0 so

View File

@ -47,6 +47,8 @@ public:
void add (const std::deque<Currency>& currencies); void add (const std::deque<Currency>& currencies);
void remove (Currency::ID id); void remove (Currency::ID id);
QString getCode(Currency::ID id);
//Basic functionality: //Basic functionality:
int rowCount (const QModelIndex& parent = QModelIndex()) const override; int rowCount (const QModelIndex& parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames () const override; QHash<int, QByteArray> roleNames () const override;

View File

@ -11,7 +11,8 @@
Models::Magpie::Magpie (QObject* parent): Models::Magpie::Magpie (QObject* parent):
QObject(parent), QObject(parent),
assets(), currencies(),
assets(currencies),
address(), address(),
state(State::Offline), state(State::Offline),
accessToken(), accessToken(),
@ -23,7 +24,7 @@ Models::Magpie::Magpie (QObject* parent):
{ {
firstPoll.setSingleShot(true); firstPoll.setSingleShot(true);
firstPoll.setInterval(2000); firstPoll.setInterval(2000);
connect(&firstPoll, &QTimer::timeout, this, &Magpie::onFirstPollTimerSuccess); connect(&firstPoll, &QTimer::timeout, this, &Magpie::onPositivePoll);
connect(&assets, &Assets::requestAssets, this, &Magpie::requestAssets); connect(&assets, &Assets::requestAssets, this, &Magpie::requestAssets);
} }
@ -109,13 +110,14 @@ void Models::Magpie::requestAssets () {
assets.add(result); assets.add(result);
}, },
[this] (const QString& error, const std::optional<QVariantMap>& data) { [this] (const QString& error, const std::optional<QVariantMap>& data) {
assets.add(std::deque<Asset>()); qDebug() << "Error receiving assets:" << error;
} }
); );
} }
void Models::Magpie::onFirstPollTimerSuccess () { void Models::Magpie::onPositivePoll () {
setState(Authenticated); if (state == Authenticating)
requestCurrencies();
} }
void Models::Magpie::startPolling () { void Models::Magpie::startPolling () {
@ -149,8 +151,10 @@ void Models::Magpie::onPollSuccess (const QVariantMap& data) {
clear = handleChanges(qast<QVariantMap>(data.value("data"))); clear = handleChanges(qast<QVariantMap>(data.value("data")));
//todo handle the result //todo handle the result
case Codes::Poll::timeout: case Codes::Poll::timeout:
setState(Authenticated); onPositivePoll();
return sendPoll(clear); if (state == Authenticating || state == Authenticated)
return sendPoll(clear);
case Codes::Poll::tokenProblem: case Codes::Poll::tokenProblem:
case Codes::Poll::replace: case Codes::Poll::replace:
case Codes::Poll::unknownError: //todo this one doesn't actually mean that we can't work for now, the network may be temporarily down or something case Codes::Poll::unknownError: //todo this one doesn't actually mean that we can't work for now, the network may be temporarily down or something
@ -240,5 +244,27 @@ void Models::Magpie::requestCurrencies () {
if (requestingCurrencies) if (requestingCurrencies)
return; return;
requestingCurrencies = true;
currencies.clear(); currencies.clear();
api->requestCurrencies(
[this] (const QVariantList& list) {
std::deque<Currency> result;
bool res = Currencies::deserialize(list, result);
if (!res) {
qDebug() << "Error deserializer received currencies";
result.clear();
} else {
qDebug() << "Currencies successfully received";
}
currencies.add(result);
requestingCurrencies = false;
setState(Authenticated);
},
[this] (const QString& error, const std::optional<QVariantMap>& data) {
qDebug() << "Error receiving currencies:" << error;
requestingCurrencies = false;
setState(NotAuthenticated);
}
);
} }

View File

@ -58,12 +58,12 @@ signals:
void displayError(const QString& err); void displayError(const QString& err);
public: public:
Assets assets;
Currencies currencies; Currencies currencies;
Assets assets;
private slots: private slots:
void requestAssets(); void requestAssets();
void onFirstPollTimerSuccess(); void onPositivePoll();
private: private:
void startPolling(); void startPolling();

View File

@ -12,6 +12,7 @@ Item {
required property string icon required property string icon
required property color color required property color color
required property string balance required property string balance
required property string currency
required property int assetId required property int assetId
signal error (err:string) signal error (err:string)
@ -39,7 +40,7 @@ Item {
} }
Text { Text {
width: parent.freespace / 2 width: parent.freespace / 3
height: parent.height height: parent.height
text: title text: title
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
@ -48,13 +49,21 @@ Item {
} }
Text { Text {
width: parent.freespace / 2 width: parent.freespace / 3
height: parent.height height: parent.height
text: balance text: balance
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
color: palette.text color: palette.text
} }
Text {
width: parent.freespace / 3
height: parent.height
text: currency
verticalAlignment: Text.AlignVCenter
color: palette.text
}
Button { Button {
id: deleteButton id: deleteButton
text: qsTr("Delete") text: qsTr("Delete")