From 11ede88abc7c77619aebb275dcbc86a40252e020 Mon Sep 17 00:00:00 2001 From: Black Hat Date: Mon, 22 Apr 2019 21:16:33 +0800 Subject: [PATCH] Caching in image provider. Fix room filter. --- imports/Spectral/Panel/RoomListPanel.qml | 4 +-- src/imageprovider.cpp | 44 +++++++++++++++++++----- src/imageprovider.h | 13 ++++--- 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/imports/Spectral/Panel/RoomListPanel.qml b/imports/Spectral/Panel/RoomListPanel.qml index 560291c..e2d0700 100644 --- a/imports/Spectral/Panel/RoomListPanel.qml +++ b/imports/Spectral/Panel/RoomListPanel.qml @@ -71,11 +71,11 @@ Item { }, ExpressionFilter { enabled: filter === 2 - expression: category === 1 || category === 2 || category === 4 + expression: category === 1 || category === 2 || category === 3 }, ExpressionFilter { enabled: filter === 3 - expression: category === 3 || category === 5 + expression: category === 4 || category === 5 } ] } diff --git a/src/imageprovider.cpp b/src/imageprovider.cpp index c092b3e..be98de2 100644 --- a/src/imageprovider.cpp +++ b/src/imageprovider.cpp @@ -1,16 +1,26 @@ #include "imageprovider.h" +#include +#include +#include #include #include using QMatrixClient::BaseJob; ThumbnailResponse::ThumbnailResponse(QMatrixClient::Connection* c, - QString id, const QSize& size) - : c(c), - mediaId(std::move(id)), - requestedSize(size), - errorStr("Image request hasn't started") { + QString id, + const QSize& size) + : c(c), + mediaId(std::move(id)), + requestedSize(size), + localFile(QStringLiteral("%1/image_provider/%2-%3x%4.png") + .arg(QStandardPaths::writableLocation( + QStandardPaths::CacheLocation), + mediaId, + QString::number(requestedSize.width()), + QString::number(requestedSize.height()))), + errorStr("Image request hasn't started") { if (requestedSize.isEmpty()) { errorStr.clear(); emit finished(); @@ -18,11 +28,19 @@ ThumbnailResponse::ThumbnailResponse(QMatrixClient::Connection* c, } if (mediaId.count('/') != 1) { errorStr = - tr("Media id '%1' doesn't follow server/mediaId pattern") - .arg(mediaId); + tr("Media id '%1' doesn't follow server/mediaId pattern").arg(mediaId); emit finished(); return; } + + QImage cachedImage; + if (cachedImage.load(localFile)) { + image = cachedImage; + errorStr.clear(); + emit finished(); + return; + } + // Execute a request on the main thread asynchronously moveToThread(c->thread()); QMetaObject::invokeMethod(this, &ThumbnailResponse::startRequest, @@ -45,6 +63,14 @@ void ThumbnailResponse::prepareResult() { QWriteLocker _(&lock); if (job->error() == BaseJob::Success) { image = job->thumbnail(); + + QString localPath = QFileInfo(localFile).absolutePath(); + QDir dir; + if (!dir.exists(localPath)) + dir.mkpath(localPath); + + image.save(localFile); + errorStr.clear(); } else if (job->error() == BaseJob::Abandoned) { errorStr = tr("Image request has been cancelled"); @@ -83,7 +109,7 @@ void ThumbnailResponse::cancel() { } QQuickImageResponse* ImageProvider::requestImageResponse( - const QString& id, const QSize& requestedSize) { - qDebug() << "ImageProvider: requesting " << id << "of size" << requestedSize; + const QString& id, + const QSize& requestedSize) { return new ThumbnailResponse(m_connection.load(), id, requestedSize); } diff --git a/src/imageprovider.h b/src/imageprovider.h index 4d15b04..ed31e94 100644 --- a/src/imageprovider.h +++ b/src/imageprovider.h @@ -7,8 +7,8 @@ #include #include -#include #include +#include namespace QMatrixClient { class Connection; @@ -17,11 +17,12 @@ class Connection; class ThumbnailResponse : public QQuickImageResponse { Q_OBJECT public: - ThumbnailResponse(QMatrixClient::Connection* c, QString mediaId, + ThumbnailResponse(QMatrixClient::Connection* c, + QString mediaId, const QSize& requestedSize); ~ThumbnailResponse() override = default; -private slots: + private slots: void startRequest(); void prepareResult(); void doCancel(); @@ -30,11 +31,12 @@ private slots: QMatrixClient::Connection* c; const QString mediaId; const QSize requestedSize; + const QString localFile; QMatrixClient::MediaThumbnailJob* job = nullptr; QImage image; QString errorStr; - mutable QReadWriteLock lock; // Guards ONLY these two members above + mutable QReadWriteLock lock; // Guards ONLY these two members above QQuickTextureFactory* textureFactory() const override; QString errorString() const override; @@ -49,7 +51,8 @@ class ImageProvider : public QObject, public QQuickAsyncImageProvider { explicit ImageProvider() = default; QQuickImageResponse* requestImageResponse( - const QString& id, const QSize& requestedSize) override; + const QString& id, + const QSize& requestedSize) override; QMatrixClient::Connection* connection() { return m_connection; } void setConnection(QMatrixClient::Connection* connection) {