diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-09-29 22:48:37 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-29 22:48:37 +0900 |
commit | 547170c8eb03f3b8477f131724e028ef38ed16fa (patch) | |
tree | b78b2feab486bb83688749f0c76bd8a4e7228314 /lib | |
parent | b55334ac0fe89f780776bc4eab90ffe1ca3c57bb (diff) | |
parent | 70a56b2f525442bf5b8ad20953ab43c12ad00b7f (diff) | |
download | libquotient-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.cpp | 72 |
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; } - |