aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2018-09-29 22:48:37 +0900
committerGitHub <noreply@github.com>2018-09-29 22:48:37 +0900
commit547170c8eb03f3b8477f131724e028ef38ed16fa (patch)
treeb78b2feab486bb83688749f0c76bd8a4e7228314 /lib
parentb55334ac0fe89f780776bc4eab90ffe1ca3c57bb (diff)
parent70a56b2f525442bf5b8ad20953ab43c12ad00b7f (diff)
downloadlibquotient-547170c8eb03f3b8477f131724e028ef38ed16fa.tar.gz
libquotient-547170c8eb03f3b8477f131724e028ef38ed16fa.zip
Merge pull request #247 from QMatrixClient/avatar-cache
WIP: Add avatar caching.
Diffstat (limited to 'lib')
-rw-r--r--lib/avatar.cpp72
1 files changed, 49 insertions, 23 deletions
diff --git a/lib/avatar.cpp b/lib/avatar.cpp
index 438268b6..35e736c4 100644
--- a/lib/avatar.cpp
+++ b/lib/avatar.cpp
@@ -26,6 +26,8 @@
#include <QtGui/QPainter>
#include <QtCore/QPointer>
+#include <QDir>
+#include <QStandardPaths>
using namespace QMatrixClient;
using std::move;
@@ -33,7 +35,8 @@ using std::move;
class Avatar::Private
{
public:
- explicit Private(QUrl url = {}) : _url(move(url)) { }
+ explicit Private(QUrl url = {}) : _url(move(url)), _localFile(urlToLocalFile(_url)) {
+ }
QImage get(Connection* connection, QSize size,
get_callback_t callback) const;
@@ -41,7 +44,11 @@ class Avatar::Private
bool checkUrl(QUrl url) const;
+ static QString urlToLocalFile(QUrl url);
+ static void checkCacheLocation();
+
QUrl _url;
+ QString _localFile;
// The below are related to image caching, hence mutable
mutable QImage _originalImage;
@@ -109,31 +116,39 @@ QImage Avatar::Private::get(Connection* connection, QSize size,
qCCritical(MAIN) << "Null callbacks are not allowed in Avatar::get";
Q_ASSERT(false);
}
+
// 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( ( !(_fetched || _thumbnailRequest)
- || size.width() > _requestedSize.width()
- || size.height() > _requestedSize.height() ) && checkUrl(_url) )
- {
- qCDebug(MAIN) << "Getting avatar from" << _url.toString();
- _requestedSize = size;
- if (isJobRunning(_thumbnailRequest))
- _thumbnailRequest->abandon();
- if (callback)
- callbacks.emplace_back(move(callback));
- _thumbnailRequest = connection->getThumbnail(_url, size);
- QObject::connect( _thumbnailRequest, &MediaThumbnailJob::success,
- _thumbnailRequest, [this] {
- _fetched = true;
- _originalImage =
- _thumbnailRequest->scaledThumbnail(_requestedSize);
- _scaledImages.clear();
- for (const auto& n: callbacks)
- n();
- callbacks.clear();
- });
+ if (checkUrl(_url) && !(_fetched || _thumbnailRequest)) {
+ if (_originalImage.load(_localFile) && !_originalImage.isNull() && size.width() <= _originalImage.width() && size.height() <= _originalImage.height()) {
+ _fetched = true;
+ _scaledImages.clear();
+ for (const auto& n: callbacks)
+ n();
+ callbacks.clear();
+ } else {
+ qCDebug(MAIN) << "Getting avatar from" << _url.toString();
+ _requestedSize = size;
+ if (isJobRunning(_thumbnailRequest))
+ _thumbnailRequest->abandon();
+ if (callback)
+ callbacks.emplace_back(move(callback));
+ _thumbnailRequest = connection->getThumbnail(_url, size);
+ QObject::connect( _thumbnailRequest, &MediaThumbnailJob::success,
+ _thumbnailRequest, [this] {
+ _fetched = true;
+ _originalImage =
+ _thumbnailRequest->scaledThumbnail(_requestedSize);
+ checkCacheLocation();
+ _originalImage.save(_localFile);
+ _scaledImages.clear();
+ for (const auto& n: callbacks)
+ n();
+ callbacks.clear();
+ });
+ }
}
for (const auto& p: _scaledImages)
@@ -170,6 +185,17 @@ bool Avatar::Private::checkUrl(QUrl url) const
return !_bannedUrl;
}
+QString Avatar::Private::urlToLocalFile(QUrl url) {
+ return QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/avatar/" + url.authority() + "_" + url.fileName() + ".png";
+}
+
+void Avatar::Private::checkCacheLocation() {
+ const QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/avatar/";
+ QDir dir;
+ if (!dir.exists(cachePath))
+ dir.mkpath(cachePath);
+}
+
QUrl Avatar::url() const { return d->_url; }
bool Avatar::updateUrl(const QUrl& newUrl)
@@ -178,9 +204,9 @@ bool Avatar::updateUrl(const QUrl& newUrl)
return false;
d->_url = newUrl;
+ d->_localFile = d->urlToLocalFile(newUrl);
d->_fetched = false;
if (isJobRunning(d->_thumbnailRequest))
d->_thumbnailRequest->abandon();
return true;
}
-