aboutsummaryrefslogtreecommitdiff
path: root/user.cpp
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2017-10-26 19:53:24 +0300
committerKitsune Ral <Kitsune-Ral@users.sf.net>2017-10-26 19:53:24 +0300
commit0ce284eeca96ac92524a390837b551bebb5431cc (patch)
treeacf2e096f3ce6082ea20eb81416d32b55f52e70f /user.cpp
parent2fb03272a8bc7da4943347ea7ecca6070f667bd6 (diff)
downloadlibquotient-0ce284eeca96ac92524a390837b551bebb5431cc.tar.gz
libquotient-0ce284eeca96ac92524a390837b551bebb5431cc.zip
Move out the avatar code from User
Avatars are also a property of rooms, and the supporting code is basically the same. The only thing different will be emitted signals, and the cleanest thing to support that (aside from making Avatar a QObject) seems to be to parameterise the thumbnail-updating logic with a continuation invoked upon completion of the thumbnail job.
Diffstat (limited to 'user.cpp')
-rw-r--r--user.cpp93
1 files changed, 12 insertions, 81 deletions
diff --git a/user.cpp b/user.cpp
index aa1aa447..b2c0dc1e 100644
--- a/user.cpp
+++ b/user.cpp
@@ -19,14 +19,12 @@
#include "user.h"
#include "connection.h"
+#include "avatar.h"
#include "events/event.h"
#include "events/roommemberevent.h"
-#include "jobs/mediathumbnailjob.h"
#include "jobs/generated/profile.h"
#include <QtCore/QTimer>
-#include <QtCore/QDebug>
-#include <QtGui/QIcon>
#include <QtCore/QRegularExpression>
using namespace QMatrixClient;
@@ -35,35 +33,20 @@ class User::Private
{
public:
Private(QString userId, Connection* connection)
- : q(nullptr), userId(std::move(userId)), connection(connection)
- , defaultIcon(QIcon::fromTheme(QStringLiteral("user-available")))
- , avatarValid(false) , avatarOngoingRequest(false)
+ : userId(std::move(userId)), connection(connection)
+ , avatar(connection, QIcon::fromTheme(QStringLiteral("user-available")))
{ }
- User* q;
QString userId;
QString name;
- QUrl avatarUrl;
- Connection* connection;
-
- QPixmap avatar;
- QIcon defaultIcon;
- QSize requestedSize;
- bool avatarValid;
- bool avatarOngoingRequest;
- /// Map of requested size to the actual pixmap used for it
- /// (it's a shame that QSize has no predefined qHash()).
- QHash<QPair<int,int>, QPixmap> scaledAvatars;
QString bridged;
-
- void requestAvatar();
+ Connection* connection;
+ Avatar avatar;
};
User::User(QString userId, Connection* connection)
- : QObject(connection), d(new Private(userId, connection))
-{
- d->q = this; // Initialization finished
-}
+ : QObject(connection), d(new Private(std::move(userId), connection))
+{ }
User::~User()
{
@@ -109,43 +92,12 @@ QString User::bridged() const {
QPixmap User::avatar(int width, int height)
{
- QSize size(width, height);
-
- // FIXME: Alternating between longer-width and longer-height requests
- // is a sure way to trick the below code into constantly getting another
- // image from the server because the existing one is alleged unsatisfactory.
- // This is plain abuse by the client, though; so not critical for now.
- if( (!d->avatarValid && d->avatarUrl.isValid() && !d->avatarOngoingRequest)
- || width > d->requestedSize.width()
- || height > d->requestedSize.height() )
- {
- qCDebug(MAIN) << "Getting avatar for" << id()
- << "from" << d->avatarUrl.toString();
- d->requestedSize = size;
- d->avatarOngoingRequest = true;
- QTimer::singleShot(0, this, SLOT(requestAvatar()));
- }
-
- if( d->avatar.isNull() )
- {
- if (d->defaultIcon.isNull())
- return d->avatar;
-
- d->avatar = d->defaultIcon.pixmap(size);
- }
-
- auto& pixmap = d->scaledAvatars[{width, height}]; // Create the entry if needed
- if (pixmap.isNull())
- {
- pixmap = d->avatar.scaled(width, height,
- Qt::KeepAspectRatio, Qt::SmoothTransformation);
- }
- return pixmap;
+ return d->avatar.get(width, height, [=] { emit avatarChanged(this); });
}
-const QUrl& User::avatarUrl() const
+QUrl User::avatarUrl() const
{
- return d->avatarUrl;
+ return d->avatar.url();
}
void User::processEvent(Event* event)
@@ -165,28 +117,7 @@ void User::processEvent(Event* event)
newName.truncate(match.capturedStart(0));
}
updateName(newName);
- if( d->avatarUrl != e->avatarUrl() )
- {
- d->avatarUrl = e->avatarUrl();
- d->avatarValid = false;
- }
+ if (d->avatar.updateUrl(e->avatarUrl()))
+ emit avatarChanged(this);
}
}
-
-void User::requestAvatar()
-{
- d->requestAvatar();
-}
-
-void User::Private::requestAvatar()
-{
- auto* job = connection->callApi<MediaThumbnailJob>(avatarUrl, requestedSize);
- connect( job, &MediaThumbnailJob::success, [=]() {
- avatarOngoingRequest = false;
- avatarValid = true;
- avatar = job->scaledThumbnail(requestedSize);
- scaledAvatars.clear();
- emit q->avatarChanged(q);
- });
-}
-