diff --git a/src/AvatarProvider.cc b/src/AvatarProvider.cc
index 9f861fdb..c7745239 100644
--- a/src/AvatarProvider.cc
+++ b/src/AvatarProvider.cc
@@ -15,12 +15,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <QBuffer>
+#include <QtConcurrent>
+
#include "AvatarProvider.h"
#include "Cache.h"
#include "MatrixClient.h"
QSharedPointer<MatrixClient> AvatarProvider::client_;
-QHash<QString, QImage> AvatarProvider::avatars_;
+QSharedPointer<Cache> AvatarProvider::cache_;
void
AvatarProvider::resolve(const QString &room_id,
@@ -28,21 +31,22 @@ AvatarProvider::resolve(const QString &room_id,
QObject *receiver,
std::function<void(QImage)> callback)
{
- const auto key = QString("%1 %2").arg(room_id).arg(user_id);
+ const auto key = QString("%1 %2").arg(room_id).arg(user_id);
+ const auto avatarUrl = Cache::avatarUrl(room_id, user_id);
- if (!Cache::AvatarUrls.contains(key))
+ if (!Cache::AvatarUrls.contains(key) || cache_.isNull())
return;
- if (avatars_.contains(key)) {
- auto img = avatars_[key];
+ if (avatarUrl.isEmpty())
+ return;
- if (!img.isNull()) {
- callback(img);
- return;
- }
+ auto data = cache_->image(avatarUrl);
+ if (!data.isNull()) {
+ callback(QImage::fromData(data));
+ return;
}
- auto proxy = client_->fetchUserAvatar(Cache::avatarUrl(room_id, user_id));
+ auto proxy = client_->fetchUserAvatar(avatarUrl);
if (proxy.isNull())
return;
@@ -50,9 +54,16 @@ AvatarProvider::resolve(const QString &room_id,
connect(proxy.data(),
&DownloadMediaProxy::avatarDownloaded,
receiver,
- [user_id, proxy, callback, key](const QImage &img) {
+ [user_id, proxy, callback, avatarUrl](const QImage &img) {
proxy->deleteLater();
- avatars_.insert(key, img);
+ QtConcurrent::run([img, avatarUrl]() {
+ QByteArray data;
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::WriteOnly);
+ img.save(&buffer, "PNG");
+
+ cache_->saveImage(avatarUrl, data);
+ });
callback(img);
});
}
diff --git a/src/Cache.cc b/src/Cache.cc
index 2afd3080..1155a40a 100644
--- a/src/Cache.cc
+++ b/src/Cache.cc
@@ -144,6 +144,9 @@ Cache::saveImage(const QString &url, const QByteArray &image)
QByteArray
Cache::image(const QString &url) const
{
+ if (url.isEmpty())
+ return QByteArray();
+
auto key = url.toUtf8();
try {
@@ -160,7 +163,7 @@ Cache::image(const QString &url) const
return QByteArray(image.data(), image.size());
} catch (const lmdb::error &e) {
- qCritical() << "image:" << e.what();
+ qCritical() << "image:" << e.what() << url;
}
return QByteArray();
diff --git a/src/ChatPage.cc b/src/ChatPage.cc
index a37cc9f0..280ae399 100644
--- a/src/ChatPage.cc
+++ b/src/ChatPage.cc
@@ -399,8 +399,6 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client,
this,
&ChatPage::setGroupViewState);
- AvatarProvider::init(client);
-
connect(this, &ChatPage::continueSync, this, [this](const QString &next_batch) {
syncTimeoutTimer_->start(SYNC_RETRY_TIMEOUT);
client_->setNextBatchToken(next_batch);
@@ -461,7 +459,6 @@ ChatPage::resetUI()
top_bar_->reset();
user_info_widget_->reset();
view_manager_->clearAll();
- AvatarProvider::clear();
showUnreadMessageNotification(0);
}
@@ -497,6 +494,8 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token)
room_list_->setCache(cache_);
text_input_->setCache(cache_);
+ AvatarProvider::init(client_, cache_);
+
try {
cache_->setup();
@@ -584,21 +583,30 @@ ChatPage::updateOwnProfileInfo(const QUrl &avatar_url, const QString &display_na
user_info_widget_->setUserId(userid);
user_info_widget_->setDisplayName(display_name);
- if (avatar_url.isValid()) {
- auto proxy = client_->fetchUserAvatar(avatar_url);
+ if (!avatar_url.isValid())
+ return;
- if (proxy.isNull())
+ if (!cache_.isNull()) {
+ auto data = cache_->image(avatar_url.toString());
+ if (!data.isNull()) {
+ user_info_widget_->setAvatar(QImage::fromData(data));
return;
-
- proxy->setParent(this);
- connect(proxy.data(),
- &DownloadMediaProxy::avatarDownloaded,
- this,
- [this, proxy](const QImage &img) {
- proxy->deleteLater();
- user_info_widget_->setAvatar(img);
- });
+ }
}
+
+ auto proxy = client_->fetchUserAvatar(avatar_url);
+
+ if (proxy.isNull())
+ return;
+
+ proxy->setParent(this);
+ connect(proxy.data(),
+ &DownloadMediaProxy::avatarDownloaded,
+ this,
+ [this, proxy](const QImage &img) {
+ proxy->deleteLater();
+ user_info_widget_->setAvatar(img);
+ });
}
void
@@ -661,8 +669,8 @@ ChatPage::loadStateFromCache()
try {
cache_->populateMembers();
- emit initializeRoomList(cache_->roomInfo());
emit initializeEmptyViews(cache_->joinedRooms());
+ emit initializeRoomList(cache_->roomInfo());
} catch (const lmdb::error &e) {
std::cout << "load cache error:" << e.what() << '\n';
// TODO Clear cache and restart.
diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc
index 17a34d96..e95f8b97 100644
--- a/src/MatrixClient.cc
+++ b/src/MatrixClient.cc
@@ -621,6 +621,9 @@ MatrixClient::fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url)
void
MatrixClient::fetchCommunityAvatar(const QString &communityId, const QUrl &avatar_url)
{
+ if (avatar_url.isEmpty())
+ return;
+
QList<QString> url_parts = avatar_url.toString().split("mxc://");
if (url_parts.size() != 2) {
|