From 3f563e1e6e5e73b0eb50f53cc4568064a0f2f780 Mon Sep 17 00:00:00 2001 From: Joseph Donofry Date: Fri, 9 Aug 2019 23:34:44 -0400 Subject: Cache User Mentions Cache user mentions when they are retrieved from the server. This logic currently isn't being utilized by the UI. Additionally, the app should use a 'since' value to only get mentions newer than those stored in the DB, to avoid excessive web requests. This will be implemented in a future commit. --- src/ChatPage.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/ChatPage.h') diff --git a/src/ChatPage.h b/src/ChatPage.h index 3c97ba25..87876a09 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -33,6 +34,7 @@ #include "MatrixClient.h" #include "Utils.h" #include "notifications/Manager.h" +#include "popups/UserMentions.h" class OverlayModal; class QuickSwitcher; @@ -44,7 +46,6 @@ class TimelineViewManager; class TopRoomBar; class TypingDisplay; class UserInfoWidget; -class UserMentionsWidget; class UserSettings; class NotificationsManager; @@ -139,6 +140,7 @@ signals: void initializeRoomList(QMap); void initializeViews(const mtx::responses::Rooms &rooms); void initializeEmptyViews(const std::map &msgs); + void initializeMentions(const std::map ¬ifs); void syncUI(const mtx::responses::Rooms &rooms); void syncRoomlist(const std::map &updates); void syncTags(const std::map &updates); @@ -242,7 +244,7 @@ private: UserInfoWidget *user_info_widget_; - UserMentionsWidget *user_mentions_widget_; + popups::UserMentions *user_mentions_popup_; // Keeps track of the users currently typing on each room. std::map> typingUsers_; -- cgit 1.5.1 From 52a262177660da2d541236d597fe34212d078094 Mon Sep 17 00:00:00 2001 From: Joseph Donofry Date: Mon, 12 Aug 2019 22:09:40 -0400 Subject: Fix issues with caching and loading of mentions. Mentions are now loaded from the cache instead of directly from the web request. Mentions are also properly saved to the cache now (instead of as empty strings). Still lots of tweaks left on this feature. --- src/Cache.cpp | 31 +++++++++++++---------- src/Cache.h | 2 +- src/ChatPage.cpp | 62 ++++++++++++++++++++++++++------------------- src/ChatPage.h | 2 +- src/popups/UserMentions.cpp | 51 +++++++++++++++++++++++++++++++++---- src/popups/UserMentions.h | 10 +++++--- 6 files changed, 108 insertions(+), 50 deletions(-) (limited to 'src/ChatPage.h') diff --git a/src/Cache.cpp b/src/Cache.cpp index 799dd319..d264b541 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -1232,20 +1233,20 @@ Cache::roomMessages() return msgs; } -std::map +QMap Cache::getTimelineMentions() { // TODO: Should be read-only, but getMentionsDb will attempt to create a DB // if it doesn't exist, throwing an error. auto txn = lmdb::txn::begin(env_, nullptr); - std::map notifs; + QMap notifs; auto room_ids = getRoomIds(txn); for (const auto &room_id : room_ids) { - auto roomNotifs = getTimelineMentionsForRoom(txn, room_id); - notifs.emplace(QString::fromStdString(room_id), roomNotifs); + auto roomNotifs = getTimelineMentionsForRoom(txn, room_id); + notifs[QString::fromStdString(room_id)] = roomNotifs; } txn.commit(); @@ -1973,11 +1974,11 @@ Cache::getTimelineMentionsForRoom(lmdb::txn &txn, const std::string &room_id) while (cursor.get(event_id, msg, MDB_NEXT)) { auto obj = json::parse(msg); - if (obj.count("event") == 0 || obj.count("token") == 0) + if (obj.count("event") == 0) continue; mtx::responses::Notification notification; - mtx::responses::from_json(obj.at("notification"), notification); + mtx::responses::from_json(obj, notification); notif.notifications.push_back(notification); } @@ -1992,18 +1993,25 @@ Cache::getTimelineMentionsForRoom(lmdb::txn &txn, const std::string &room_id) void Cache::saveTimelineMentions(const mtx::responses::Notifications &res) { + json notif = res; + QMap> notifsByRoom; // Sort into room-specific 'buckets' for (const auto ¬if : res.notifications) { + json val = notif; notifsByRoom[notif.room_id].push_back(notif); } auto txn = lmdb::txn::begin(env_); // Insert the entire set of mentions for each room at a time. - for (const auto &room : notifsByRoom.keys()) { - nhlog::db()->debug("Storing notifications for " + room); - saveTimelineMentions(txn, room, notifsByRoom[room]); + QMap>::const_iterator it = + notifsByRoom.constBegin(); + auto end = notifsByRoom.constEnd(); + while (it != end) { + nhlog::db()->debug("Storing notifications for " + it.key()); + saveTimelineMentions(txn, it.key(), std::move(it.value())); + ++it; } txn.commit(); @@ -2019,10 +2027,7 @@ Cache::saveTimelineMentions(lmdb::txn &txn, using namespace mtx::events; using namespace mtx::events::state; - int i = 0; for (const auto ¬if : res) { - nhlog::db()->debug("Storing notification " + std::to_string(i++) + " for room " + - room_id); const auto event_id = utils::event_id(notif.event); // double check that we have the correct room_id... @@ -2030,7 +2035,7 @@ Cache::saveTimelineMentions(lmdb::txn &txn, return; } - json obj = json::object(); + json obj = notif; lmdb::dbi_put(txn, db, lmdb::val(event_id), lmdb::val(obj.dump())); } diff --git a/src/Cache.h b/src/Cache.h index 97b264fc..5ec79c3b 100644 --- a/src/Cache.h +++ b/src/Cache.h @@ -323,7 +323,7 @@ public: std::map roomMessages(); - std::map getTimelineMentions(); + QMap getTimelineMentions(); //! Retrieve all the user ids from a room. std::vector roomMembers(const std::string &room_id); diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 54562c82..58f23fef 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -153,21 +153,26 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) }); connect(top_bar_, &TopRoomBar::mentionsClicked, this, [this](const QPoint &mentionsPos) { - http::client()->notifications( - 1000, - "", - "highlight", - [this, mentionsPos](const mtx::responses::Notifications &res, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn("failed to retrieve notifications: {} ({})", - err->matrix_error.error, - static_cast(err->status_code)); - return; - } + if (user_mentions_popup_->isVisible()) { + user_mentions_popup_->hide(); + } else { + http::client()->notifications( + 1000, + "", + "highlight", + [this, mentionsPos](const mtx::responses::Notifications &res, + mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn( + "failed to retrieve notifications: {} ({})", + err->matrix_error.error, + static_cast(err->status_code)); + return; + } - emit highlightedNotifsRetrieved(std::move(res), mentionsPos); - }); + emit highlightedNotifsRetrieved(std::move(res), mentionsPos); + }); + } }); connectivityTimer_.setInterval(CHECK_CONNECTIVITY_INTERVAL); @@ -1001,28 +1006,32 @@ ChatPage::sendDesktopNotifications(const mtx::responses::Notifications &res) void ChatPage::showNotificationsDialog(const mtx::responses::Notifications &res, const QPoint &widgetPos) { + // TODO: Remove notifications from this function call. + Q_UNUSED(res); + auto notifDialog = user_mentions_popup_; - for (const auto &item : res.notifications) { - const auto event_id = QString::fromStdString(utils::event_id(item.event)); + // for (const auto &item : res.notifications) { + // const auto event_id = QString::fromStdString(utils::event_id(item.event)); - try { - const auto room_id = QString::fromStdString(item.room_id); - const auto user_id = utils::event_sender(item.event); - const auto body = utils::event_body(item.event); + // try { + // const auto room_id = QString::fromStdString(item.room_id); + // const auto user_id = utils::event_sender(item.event); + // const auto body = utils::event_body(item.event); - notifDialog->pushItem(event_id, user_id, body, room_id, current_room_); + // notifDialog->pushItem(event_id, user_id, body, room_id, current_room_); - } catch (const lmdb::error &e) { - nhlog::db()->warn("error while sending desktop notification: {}", e.what()); - } - } + // } catch (const lmdb::error &e) { + // nhlog::db()->warn("error while sending desktop notification: {}", + // e.what()); + // } + // } notifDialog->setGeometry( widgetPos.x() - (width() / 10), widgetPos.y() + 25, width() / 5, height() / 2); // notifDialog->move(widgetPos.x(), widgetPos.y()); // notifDialog->setFixedWidth(width() / 10); // notifDialog->setFixedHeight(height() / 2); notifDialog->raise(); - notifDialog->show(); + notifDialog->showPopup(); } void @@ -1292,6 +1301,7 @@ ChatPage::initialSyncHandler(const mtx::responses::Sync &res, mtx::http::Request emit initializeViews(std::move(res.rooms)); emit initializeRoomList(cache::client()->roomInfo()); + emit initializeMentions(cache::client()->getTimelineMentions()); cache::client()->calculateRoomReadStatus(); emit syncTags(cache::client()->roomInfo().toStdMap()); diff --git a/src/ChatPage.h b/src/ChatPage.h index 87876a09..fb6fbb06 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -140,7 +140,7 @@ signals: void initializeRoomList(QMap); void initializeViews(const mtx::responses::Rooms &rooms); void initializeEmptyViews(const std::map &msgs); - void initializeMentions(const std::map ¬ifs); + void initializeMentions(const QMap ¬ifs); void syncUI(const mtx::responses::Rooms &rooms); void syncRoomlist(const std::map &updates); void syncTags(const std::map &updates); diff --git a/src/popups/UserMentions.cpp b/src/popups/UserMentions.cpp index 77e5260e..267540cc 100644 --- a/src/popups/UserMentions.cpp +++ b/src/popups/UserMentions.cpp @@ -1,6 +1,8 @@ #include #include +#include "Cache.h" +#include "ChatPage.h" #include "UserMentions.h" #include "timeline/TimelineItem.h" @@ -9,6 +11,9 @@ using namespace popups; UserMentions::UserMentions(QWidget *parent) : QWidget{parent} { + setAttribute(Qt::WA_ShowWithoutActivating, true); + setWindowFlags(Qt::ToolTip | Qt::NoDropShadowWindowHint); + tab_layout_ = new QTabWidget(this); top_layout_ = new QVBoxLayout(this); @@ -37,12 +42,12 @@ UserMentions::UserMentions(QWidget *parent) local_scroll_layout_ = new QVBoxLayout(local_scroll_widget_); local_scroll_layout_->setContentsMargins(4, 0, 15, bottomMargin); local_scroll_layout_->setSpacing(0); - local_scroll_layout_->setObjectName("localcrollarea"); + local_scroll_layout_->setObjectName("localscrollarea"); all_scroll_layout_ = new QVBoxLayout(all_scroll_widget_); all_scroll_layout_->setContentsMargins(4, 0, 15, bottomMargin); all_scroll_layout_->setSpacing(0); - all_scroll_layout_->setObjectName("allcrollarea"); + all_scroll_layout_->setObjectName("allscrollarea"); local_scroll_area_->setWidget(local_scroll_widget_); local_scroll_area_->setAlignment(Qt::AlignBottom); @@ -58,10 +63,46 @@ UserMentions::UserMentions(QWidget *parent) } void -UserMentions::initializeMentions(const std::map ¬ifs) +UserMentions::initializeMentions(const QMap ¬ifs) +{ + nhlog::ui()->debug("Initializing " + std::to_string(notifs.size()) + " notifications."); + for (auto widget : all_scroll_layout_->findChildren()) { + delete widget; + } + for (auto widget : local_scroll_layout_->findChildren()) { + delete widget; + } + for (const auto &item : notifs) { + for (const auto notif : item.notifications) { + const auto event_id = QString::fromStdString(utils::event_id(notif.event)); + + try { + const auto room_id = QString::fromStdString(notif.room_id); + const auto user_id = utils::event_sender(notif.event); + const auto body = utils::event_body(notif.event); + + pushItem(event_id, + user_id, + body, + room_id, + ChatPage::instance()->currentRoom()); + + } catch (const lmdb::error &e) { + nhlog::db()->warn("error while sending desktop notification: {}", + e.what()); + } + } + } +} + +void +UserMentions::showPopup() { - Q_UNUSED(notifs); - // Very TODO: + auto notifs = cache::client()->getTimelineMentions(); + + initializeMentions(notifs); + + show(); } void diff --git a/src/popups/UserMentions.h b/src/popups/UserMentions.h index 5dc475bf..0029eedd 100644 --- a/src/popups/UserMentions.h +++ b/src/popups/UserMentions.h @@ -2,6 +2,7 @@ #include +#include #include #include #include @@ -16,15 +17,16 @@ class UserMentions : public QWidget Q_OBJECT public: UserMentions(QWidget *parent = nullptr); + + void showPopup(); + void initializeMentions(const QMap ¬ifs); + +private: void pushItem(const QString &event_id, const QString &user_id, const QString &body, const QString &room_id, const QString ¤t_room_id); - - void initializeMentions(const std::map ¬ifs); - -private: QTabWidget *tab_layout_; QVBoxLayout *top_layout_; QVBoxLayout *local_scroll_layout_; -- cgit 1.5.1 From bcdd97c85fb3b2aeb0cd46c05562f880792737aa Mon Sep 17 00:00:00 2001 From: Joseph Donofry Date: Mon, 19 Aug 2019 18:11:38 -0400 Subject: More updates to mentions functionality --- src/ChatPage.cpp | 27 ++++----------------------- src/ChatPage.h | 2 +- src/popups/UserMentions.cpp | 18 ++++++++++-------- src/popups/UserMentions.h | 7 ++++++- 4 files changed, 21 insertions(+), 33 deletions(-) (limited to 'src/ChatPage.h') diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 58f23fef..854d57d7 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -156,6 +156,7 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) if (user_mentions_popup_->isVisible()) { user_mentions_popup_->hide(); } else { + showNotificationsDialog(mentionsPos); http::client()->notifications( 1000, "", @@ -525,13 +526,12 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(this, &ChatPage::highlightedNotifsRetrieved, this, - [this](const mtx::responses::Notifications ¬if, const QPoint &widgetPos) { + [this](const mtx::responses::Notifications ¬if) { try { cache::client()->saveTimelineMentions(notif); } catch (const lmdb::error &e) { nhlog::db()->error("failed to save mentions: {}", e.what()); } - showNotificationsDialog(notif, widgetPos); }); connect(communitiesList_, @@ -1004,32 +1004,13 @@ ChatPage::sendDesktopNotifications(const mtx::responses::Notifications &res) } void -ChatPage::showNotificationsDialog(const mtx::responses::Notifications &res, const QPoint &widgetPos) +ChatPage::showNotificationsDialog(const QPoint &widgetPos) { - // TODO: Remove notifications from this function call. - Q_UNUSED(res); - auto notifDialog = user_mentions_popup_; - // for (const auto &item : res.notifications) { - // const auto event_id = QString::fromStdString(utils::event_id(item.event)); - - // try { - // const auto room_id = QString::fromStdString(item.room_id); - // const auto user_id = utils::event_sender(item.event); - // const auto body = utils::event_body(item.event); - // notifDialog->pushItem(event_id, user_id, body, room_id, current_room_); - - // } catch (const lmdb::error &e) { - // nhlog::db()->warn("error while sending desktop notification: {}", - // e.what()); - // } - // } notifDialog->setGeometry( widgetPos.x() - (width() / 10), widgetPos.y() + 25, width() / 5, height() / 2); - // notifDialog->move(widgetPos.x(), widgetPos.y()); - // notifDialog->setFixedWidth(width() / 10); - // notifDialog->setFixedHeight(height() / 2); + notifDialog->raise(); notifDialog->showPopup(); } diff --git a/src/ChatPage.h b/src/ChatPage.h index fb6fbb06..189af387 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -210,7 +210,7 @@ private: //! Send desktop notification for the received messages. void sendDesktopNotifications(const mtx::responses::Notifications &); - void showNotificationsDialog(const mtx::responses::Notifications &, const QPoint &point); + void showNotificationsDialog(const QPoint &point); QStringList generateTypingUsers(const QString &room_id, const std::vector &typing_users); diff --git a/src/popups/UserMentions.cpp b/src/popups/UserMentions.cpp index 267540cc..152cd82d 100644 --- a/src/popups/UserMentions.cpp +++ b/src/popups/UserMentions.cpp @@ -3,6 +3,7 @@ #include "Cache.h" #include "ChatPage.h" +#include "Logging.h" #include "UserMentions.h" #include "timeline/TimelineItem.h" @@ -12,7 +13,7 @@ UserMentions::UserMentions(QWidget *parent) : QWidget{parent} { setAttribute(Qt::WA_ShowWithoutActivating, true); - setWindowFlags(Qt::ToolTip | Qt::NoDropShadowWindowHint); + setWindowFlags(Qt::FramelessWindowHint | Qt::Popup); tab_layout_ = new QTabWidget(this); @@ -66,12 +67,7 @@ void UserMentions::initializeMentions(const QMap ¬ifs) { nhlog::ui()->debug("Initializing " + std::to_string(notifs.size()) + " notifications."); - for (auto widget : all_scroll_layout_->findChildren()) { - delete widget; - } - for (auto widget : local_scroll_layout_->findChildren()) { - delete widget; - } + for (const auto &item : notifs) { for (const auto notif : item.notifications) { const auto event_id = QString::fromStdString(utils::event_id(notif.event)); @@ -98,10 +94,16 @@ UserMentions::initializeMentions(const QMapfindChildren()) { + delete widget; + } + for (auto widget : local_scroll_layout_->findChildren()) { + delete widget; + } + auto notifs = cache::client()->getTimelineMentions(); initializeMentions(notifs); - show(); } diff --git a/src/popups/UserMentions.h b/src/popups/UserMentions.h index 0029eedd..a74bf2ec 100644 --- a/src/popups/UserMentions.h +++ b/src/popups/UserMentions.h @@ -2,6 +2,8 @@ #include +#include +#include #include #include #include @@ -9,6 +11,9 @@ #include #include #include +#include + +#include "Logging.h" namespace popups { @@ -18,8 +23,8 @@ class UserMentions : public QWidget public: UserMentions(QWidget *parent = nullptr); - void showPopup(); void initializeMentions(const QMap ¬ifs); + void showPopup(); private: void pushItem(const QString &event_id, -- cgit 1.5.1 From 52056a79fa94117ce0fc8f388458ceb48cc3be54 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 26 Aug 2019 01:24:56 +0200 Subject: Try to reduce memory usage by reusing avatar pixmaps --- src/AvatarProvider.cpp | 55 +++++++++++++++++++++++++++++++------ src/AvatarProvider.h | 12 ++++++-- src/Cache.cpp | 5 +--- src/Cache.h | 1 - src/ChatPage.cpp | 38 +++---------------------- src/ChatPage.h | 4 +-- src/Logging.cpp | 2 ++ src/Logging.h | 2 ++ src/RoomInfoListItem.cpp | 9 ++++-- src/RoomInfoListItem.h | 2 +- src/RoomList.cpp | 39 ++------------------------ src/RoomList.h | 6 ++-- src/TopRoomBar.cpp | 5 ++-- src/TopRoomBar.h | 2 +- src/UserInfoWidget.cpp | 19 ++++++------- src/UserInfoWidget.h | 2 +- src/dialogs/MemberList.cpp | 12 ++------ src/dialogs/ReadReceipts.cpp | 8 ++---- src/dialogs/RoomSettings.cpp | 17 ++++++------ src/dialogs/RoomSettings.h | 4 +-- src/dialogs/UserProfile.cpp | 6 ++-- src/popups/PopupItem.cpp | 26 ++++-------------- src/timeline/.TimelineItem.cpp.swp | Bin 0 -> 114688 bytes src/timeline/TimelineItem.cpp | 22 ++++++--------- src/timeline/TimelineItem.h | 8 ++---- src/ui/Avatar.cpp | 39 ++++++++++++-------------- src/ui/Avatar.h | 10 ++++--- 27 files changed, 148 insertions(+), 207 deletions(-) create mode 100644 src/timeline/.TimelineItem.cpp.swp (limited to 'src/ChatPage.h') diff --git a/src/AvatarProvider.cpp b/src/AvatarProvider.cpp index 57b61c75..277a4030 100644 --- a/src/AvatarProvider.cpp +++ b/src/AvatarProvider.cpp @@ -16,30 +16,44 @@ */ #include +#include #include +#include #include "AvatarProvider.h" #include "Cache.h" #include "Logging.h" #include "MatrixClient.h" -namespace AvatarProvider { +static QPixmapCache avatar_cache; +namespace AvatarProvider { void -resolve(const QString &room_id, const QString &user_id, QObject *receiver, AvatarCallback callback) +resolve(const QString &avatarUrl, int size, QObject *receiver, AvatarCallback callback) { - const auto key = QString("%1 %2").arg(room_id).arg(user_id); - const auto avatarUrl = Cache::avatarUrl(room_id, user_id); + avatar_cache.setCacheLimit(1024 * 1024); - if (!Cache::AvatarUrls.contains(key) || !cache::client()) + const auto cacheKey = avatarUrl + "_size_" + size; + + if (!cache::client()) return; if (avatarUrl.isEmpty()) return; + QPixmap pixmap; + if (avatar_cache.find(cacheKey, pixmap)) { + nhlog::net()->info("cached pixmap {}", avatarUrl.toStdString()); + callback(pixmap); + return; + } + auto data = cache::client()->image(avatarUrl); if (!data.isNull()) { - callback(QImage::fromData(data)); + pixmap.loadFromData(data); + avatar_cache.insert(cacheKey, pixmap); + nhlog::net()->info("loaded pixmap from disk cache {}", avatarUrl.toStdString()); + callback(pixmap); return; } @@ -47,7 +61,12 @@ resolve(const QString &room_id, const QString &user_id, QObject *receiver, Avata QObject::connect(proxy.get(), &AvatarProxy::avatarDownloaded, receiver, - [callback](const QByteArray &data) { callback(QImage::fromData(data)); }); + [callback, cacheKey](const QByteArray &data) { + QPixmap pm; + pm.loadFromData(data); + avatar_cache.insert(cacheKey, pm); + callback(pm); + }); mtx::http::ThumbOpts opts; opts.width = 256; @@ -67,8 +86,26 @@ resolve(const QString &room_id, const QString &user_id, QObject *receiver, Avata cache::client()->saveImage(opts.mxc_url, res); - auto data = QByteArray(res.data(), res.size()); - emit proxy->avatarDownloaded(data); + nhlog::net()->info("downloaded pixmap {}", opts.mxc_url); + + emit proxy->avatarDownloaded(QByteArray(res.data(), res.size())); }); } + +void +resolve(const QString &room_id, + const QString &user_id, + int size, + QObject *receiver, + AvatarCallback callback) +{ + const auto key = QString("%1 %2").arg(room_id).arg(user_id); + const auto avatarUrl = Cache::avatarUrl(room_id, user_id); + const auto cacheKey = avatarUrl + "_size_" + size; + + if (!Cache::AvatarUrls.contains(key) || !cache::client()) + return; + + resolve(avatarUrl, size, receiver, callback); +} } diff --git a/src/AvatarProvider.h b/src/AvatarProvider.h index 4b4e15e9..47ed028e 100644 --- a/src/AvatarProvider.h +++ b/src/AvatarProvider.h @@ -17,7 +17,7 @@ #pragma once -#include +#include #include class AvatarProxy : public QObject @@ -28,9 +28,15 @@ signals: void avatarDownloaded(const QByteArray &data); }; -using AvatarCallback = std::function; +using AvatarCallback = std::function; namespace AvatarProvider { void -resolve(const QString &room_id, const QString &user_id, QObject *receiver, AvatarCallback cb); +resolve(const QString &avatarUrl, int size, QObject *receiver, AvatarCallback cb); +void +resolve(const QString &room_id, + const QString &user_id, + int size, + QObject *receiver, + AvatarCallback cb); } diff --git a/src/Cache.cpp b/src/Cache.cpp index ef0f951e..083dbe89 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -1830,10 +1830,7 @@ Cache::searchRooms(const std::string &query, std::uint8_t max_items) std::vector results; for (auto it = items.begin(); it != end; it++) { - results.push_back( - RoomSearchResult{it->second.first, - it->second.second, - QImage::fromData(image(txn, it->second.second.avatar_url))}); + results.push_back(RoomSearchResult{it->second.first, it->second.second}); } txn.commit(); diff --git a/src/Cache.h b/src/Cache.h index 302bb65b..0da49793 100644 --- a/src/Cache.h +++ b/src/Cache.h @@ -153,7 +153,6 @@ struct RoomSearchResult { std::string room_id; RoomInfo info; - QImage img; }; Q_DECLARE_METATYPE(RoomSearchResult) diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 2ed64b6b..21ded4b3 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -774,12 +774,12 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token) } void -ChatPage::updateTopBarAvatar(const QString &roomid, const QPixmap &img) +ChatPage::updateTopBarAvatar(const QString &roomid, const QString &img) { if (current_room_ != roomid) return; - top_bar_->updateRoomAvatar(img.toImage()); + top_bar_->updateRoomAvatar(img); } void @@ -807,7 +807,7 @@ ChatPage::changeTopRoomInfo(const QString &room_id) if (img.isNull()) top_bar_->updateRoomAvatarFromName(name); else - top_bar_->updateRoomAvatar(img); + top_bar_->updateRoomAvatar(avatar_url); } catch (const lmdb::error &e) { nhlog::ui()->error("failed to change top bar room info: {}", e.what()); @@ -1337,37 +1337,7 @@ ChatPage::getProfileInfo() emit setUserDisplayName(QString::fromStdString(res.display_name)); - if (cache::client()) { - auto data = cache::client()->image(res.avatar_url); - if (!data.isNull()) { - emit setUserAvatar(QImage::fromData(data)); - return; - } - } - - if (res.avatar_url.empty()) - return; - - http::client()->download( - res.avatar_url, - [this, res](const std::string &data, - const std::string &, - const std::string &, - mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn( - "failed to download user avatar: {} - {}", - mtx::errors::to_string(err->matrix_error.errcode), - err->matrix_error.error); - return; - } - - if (cache::client()) - cache::client()->saveImage(res.avatar_url, data); - - emit setUserAvatar( - QImage::fromData(QByteArray(data.data(), data.size()))); - }); + emit setUserAvatar(QString::fromStdString(res.avatar_url)); }); http::client()->joined_groups( diff --git a/src/ChatPage.h b/src/ChatPage.h index 189af387..e41ae1ae 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -129,7 +129,7 @@ signals: void ownProfileOk(); void setUserDisplayName(const QString &name); - void setUserAvatar(const QImage &avatar); + void setUserAvatar(const QString &avatar); void loggedOut(); void trySyncCb(); @@ -159,7 +159,7 @@ signals: private slots: void showUnreadMessageNotification(int count); - void updateTopBarAvatar(const QString &roomid, const QPixmap &img); + void updateTopBarAvatar(const QString &roomid, const QString &img); void changeTopRoomInfo(const QString &room_id); void logout(); void removeRoom(const QString &room_id); diff --git a/src/Logging.cpp b/src/Logging.cpp index 686274d8..32287582 100644 --- a/src/Logging.cpp +++ b/src/Logging.cpp @@ -16,6 +16,8 @@ constexpr auto MAX_LOG_FILES = 3; } namespace nhlog { +bool enable_debug_log_from_commandline = false; + void init(const std::string &file_path) { diff --git a/src/Logging.h b/src/Logging.h index 2feae60d..e54f3c3f 100644 --- a/src/Logging.h +++ b/src/Logging.h @@ -18,4 +18,6 @@ db(); std::shared_ptr crypto(); + +extern bool enable_debug_log_from_commandline; } diff --git a/src/RoomInfoListItem.cpp b/src/RoomInfoListItem.cpp index 9bcce134..dbcd6806 100644 --- a/src/RoomInfoListItem.cpp +++ b/src/RoomInfoListItem.cpp @@ -21,6 +21,7 @@ #include #include +#include "AvatarProvider.h" #include "Cache.h" #include "Config.h" #include "RoomInfoListItem.h" @@ -434,10 +435,12 @@ RoomInfoListItem::mousePressEvent(QMouseEvent *event) } void -RoomInfoListItem::setAvatar(const QImage &img) +RoomInfoListItem::setAvatar(const QString &avatar_url) { - roomAvatar_ = utils::scaleImageToPixmap(img, IconSize); - update(); + AvatarProvider::resolve(avatar_url, IconSize, this, [this](const QPixmap &img) { + roomAvatar_ = img; + update(); + }); } void diff --git a/src/RoomInfoListItem.h b/src/RoomInfoListItem.h index 40c938c1..54e02a76 100644 --- a/src/RoomInfoListItem.h +++ b/src/RoomInfoListItem.h @@ -73,7 +73,7 @@ public: bool isPressed() const { return isPressed_; } int unreadMessageCount() const { return unreadMsgCount_; } - void setAvatar(const QImage &avatar_image); + void setAvatar(const QString &avatar_url); void setDescriptionMessage(const DescInfo &info); DescInfo lastMessageInfo() const { return lastMsgInfo_; } diff --git a/src/RoomList.cpp b/src/RoomList.cpp index 1abf3533..c5e05621 100644 --- a/src/RoomList.cpp +++ b/src/RoomList.cpp @@ -89,40 +89,7 @@ RoomList::updateAvatar(const QString &room_id, const QString &url) if (url.isEmpty()) return; - QByteArray savedImgData; - - if (cache::client()) - savedImgData = cache::client()->image(url); - - if (savedImgData.isEmpty()) { - mtx::http::ThumbOpts opts; - opts.mxc_url = url.toStdString(); - http::client()->get_thumbnail( - opts, [room_id, opts, this](const std::string &res, mtx::http::RequestErr err) { - if (err) { - nhlog::net()->warn( - "failed to download room avatar: {} {} {}", - opts.mxc_url, - mtx::errors::to_string(err->matrix_error.errcode), - err->matrix_error.error); - return; - } - - if (cache::client()) - cache::client()->saveImage(opts.mxc_url, res); - - auto data = QByteArray(res.data(), res.size()); - QPixmap pixmap; - pixmap.loadFromData(data); - - emit updateRoomAvatarCb(room_id, pixmap); - }); - } else { - QPixmap img; - img.loadFromData(savedImgData); - - updateRoomAvatar(room_id, img); - } + emit updateRoomAvatarCb(room_id, url); } void @@ -252,7 +219,7 @@ RoomList::highlightSelectedRoom(const QString &room_id) } void -RoomList::updateRoomAvatar(const QString &roomid, const QPixmap &img) +RoomList::updateRoomAvatar(const QString &roomid, const QString &img) { if (!roomExists(roomid)) { nhlog::ui()->warn("avatar update on non-existent room_id: {}", @@ -260,7 +227,7 @@ RoomList::updateRoomAvatar(const QString &roomid, const QPixmap &img) return; } - rooms_[roomid]->setAvatar(img.toImage()); + rooms_[roomid]->setAvatar(img); // Used to inform other widgets for the new image data. emit roomAvatarChanged(roomid, img); diff --git a/src/RoomList.h b/src/RoomList.h index 155a969c..95fc0d9b 100644 --- a/src/RoomList.h +++ b/src/RoomList.h @@ -61,12 +61,12 @@ signals: void totalUnreadMessageCountUpdated(int count); void acceptInvite(const QString &room_id); void declineInvite(const QString &room_id); - void roomAvatarChanged(const QString &room_id, const QPixmap &img); + void roomAvatarChanged(const QString &room_id, const QString &img); void joinRoom(const QString &room_id); - void updateRoomAvatarCb(const QString &room_id, const QPixmap &img); + void updateRoomAvatarCb(const QString &room_id, const QString &img); public slots: - void updateRoomAvatar(const QString &roomid, const QPixmap &img); + void updateRoomAvatar(const QString &roomid, const QString &img); void highlightSelectedRoom(const QString &room_id); void updateUnreadMessageCount(const QString &roomid, int count, int highlightedCount); void updateRoomDescription(const QString &roomid, const DescInfo &info); diff --git a/src/TopRoomBar.cpp b/src/TopRoomBar.cpp index a8049e3a..712fe9aa 100644 --- a/src/TopRoomBar.cpp +++ b/src/TopRoomBar.cpp @@ -46,9 +46,8 @@ TopRoomBar::TopRoomBar(QWidget *parent) topLayout_->setContentsMargins( 2 * widgetMargin, widgetMargin, 2 * widgetMargin, widgetMargin); - avatar_ = new Avatar(this); + avatar_ = new Avatar(this, fontHeight * 2); avatar_->setLetter(""); - avatar_->setSize(fontHeight * 2); textLayout_ = new QVBoxLayout(); textLayout_->setSpacing(0); @@ -183,7 +182,7 @@ TopRoomBar::reset() } void -TopRoomBar::updateRoomAvatar(const QImage &avatar_image) +TopRoomBar::updateRoomAvatar(const QString &avatar_image) { avatar_->setImage(avatar_image); update(); diff --git a/src/TopRoomBar.h b/src/TopRoomBar.h index 5f2c936e..3243064e 100644 --- a/src/TopRoomBar.h +++ b/src/TopRoomBar.h @@ -44,7 +44,7 @@ class TopRoomBar : public QWidget public: TopRoomBar(QWidget *parent = 0); - void updateRoomAvatar(const QImage &avatar_image); + void updateRoomAvatar(const QString &avatar_image); void updateRoomAvatar(const QIcon &icon); void updateRoomName(const QString &name); void updateRoomTopic(QString topic); diff --git a/src/UserInfoWidget.cpp b/src/UserInfoWidget.cpp index 5345fb2a..19d7478e 100644 --- a/src/UserInfoWidget.cpp +++ b/src/UserInfoWidget.cpp @@ -52,10 +52,9 @@ UserInfoWidget::UserInfoWidget(QWidget *parent) textLayout_->setSpacing(widgetMargin / 2); textLayout_->setContentsMargins(widgetMargin * 2, widgetMargin, widgetMargin, widgetMargin); - userAvatar_ = new Avatar(this); + userAvatar_ = new Avatar(this, fontHeight * 2.5); userAvatar_->setObjectName("userAvatar"); userAvatar_->setLetter(QChar('?')); - userAvatar_->setSize(fontHeight * 2.5); QFont nameFont; nameFont.setPointSizeF(nameFont.pointSizeF() * 1.1); @@ -134,14 +133,6 @@ UserInfoWidget::reset() userAvatar_->setLetter(QChar('?')); } -void -UserInfoWidget::setAvatar(const QImage &img) -{ - avatar_image_ = img; - userAvatar_->setImage(img); - update(); -} - void UserInfoWidget::setDisplayName(const QString &name) { @@ -160,6 +151,14 @@ UserInfoWidget::setUserId(const QString &userid) { user_id_ = userid; userIdLabel_->setText(userid); + update(); +} + +void +UserInfoWidget::setAvatar(const QString &url) +{ + userAvatar_->setImage(url); + update(); } void diff --git a/src/UserInfoWidget.h b/src/UserInfoWidget.h index 65de7be9..263dd0c2 100644 --- a/src/UserInfoWidget.h +++ b/src/UserInfoWidget.h @@ -33,9 +33,9 @@ class UserInfoWidget : public QWidget public: UserInfoWidget(QWidget *parent = 0); - void setAvatar(const QImage &img); void setDisplayName(const QString &name); void setUserId(const QString &userid); + void setAvatar(const QString &url); void reset(); diff --git a/src/dialogs/MemberList.cpp b/src/dialogs/MemberList.cpp index 88a95403..9e973efa 100644 --- a/src/dialogs/MemberList.cpp +++ b/src/dialogs/MemberList.cpp @@ -9,7 +9,6 @@ #include "dialogs/MemberList.h" -#include "AvatarProvider.h" #include "Cache.h" #include "ChatPage.h" #include "Config.h" @@ -28,17 +27,10 @@ MemberItem::MemberItem(const RoomMember &member, QWidget *parent) textLayout_->setMargin(0); textLayout_->setSpacing(0); - avatar_ = new Avatar(this); - avatar_->setSize(44); + avatar_ = new Avatar(this, 44); avatar_->setLetter(utils::firstChar(member.display_name)); - if (!member.avatar.isNull()) - avatar_->setImage(member.avatar); - else - AvatarProvider::resolve(ChatPage::instance()->currentRoom(), - member.user_id, - this, - [this](const QImage &img) { avatar_->setImage(img); }); + avatar_->setImage(ChatPage::instance()->currentRoom(), member.user_id); QFont nameFont; nameFont.setPointSizeF(nameFont.pointSizeF() * 1.1); diff --git a/src/dialogs/ReadReceipts.cpp b/src/dialogs/ReadReceipts.cpp index 5a0d98c7..58ad59c3 100644 --- a/src/dialogs/ReadReceipts.cpp +++ b/src/dialogs/ReadReceipts.cpp @@ -37,8 +37,7 @@ ReceiptItem::ReceiptItem(QWidget *parent, auto displayName = Cache::displayName(room_id, user_id); - avatar_ = new Avatar(this); - avatar_->setSize(44); + avatar_ = new Avatar(this, 44); avatar_->setLetter(utils::firstChar(displayName)); // If it's a matrix id we use the second letter. @@ -56,10 +55,7 @@ ReceiptItem::ReceiptItem(QWidget *parent, topLayout_->addWidget(avatar_); topLayout_->addLayout(textLayout_, 1); - AvatarProvider::resolve(ChatPage::instance()->currentRoom(), - user_id, - this, - [this](const QImage &img) { avatar_->setImage(img); }); + avatar_->setImage(ChatPage::instance()->currentRoom(), user_id); } void diff --git a/src/dialogs/RoomSettings.cpp b/src/dialogs/RoomSettings.cpp index 1fe5904b..00b034cc 100644 --- a/src/dialogs/RoomSettings.cpp +++ b/src/dialogs/RoomSettings.cpp @@ -350,12 +350,12 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent) keyRequestsToggle_->hide(); } - avatar_ = new Avatar(this); - avatar_->setSize(128); + avatar_ = new Avatar(this, 128); if (avatarImg_.isNull()) avatar_->setLetter(utils::firstChar(QString::fromStdString(info_.name))); else - avatar_->setImage(avatarImg_); + avatar_->setImage(room_id_, + QString::fromStdString(http::client()->user_id().to_string())); if (canChangeAvatar(room_id_.toStdString(), utils::localUser().toStdString())) { auto filter = new ClickableFilter(this); @@ -487,7 +487,7 @@ RoomSettings::retrieveRoomInfo() try { usesEncryption_ = cache::client()->isRoomEncrypted(room_id_.toStdString()); info_ = cache::client()->singleRoomInfo(room_id_.toStdString()); - setAvatar(QImage::fromData(cache::client()->image(info_.avatar_url))); + setAvatar(); } catch (const lmdb::error &e) { nhlog::db()->warn("failed to retrieve room info from cache: {}", room_id_.toStdString()); @@ -633,14 +633,13 @@ RoomSettings::displayErrorMessage(const QString &msg) } void -RoomSettings::setAvatar(const QImage &img) +RoomSettings::setAvatar() { stopLoadingSpinner(); - avatarImg_ = img; - if (avatar_) - avatar_->setImage(img); + avatar_->setImage(room_id_, + QString::fromStdString(http::client()->user_id().to_string())); } void @@ -733,7 +732,7 @@ RoomSettings::updateAvatar() return; } - emit proxy->avatarChanged(QImage::fromData(content)); + emit proxy->avatarChanged(); }); }); } diff --git a/src/dialogs/RoomSettings.h b/src/dialogs/RoomSettings.h index 6667b68b..e1807ba1 100644 --- a/src/dialogs/RoomSettings.h +++ b/src/dialogs/RoomSettings.h @@ -52,7 +52,7 @@ class ThreadProxy : public QObject signals: void error(const QString &msg); - void avatarChanged(const QImage &img); + void avatarChanged(); void nameEventSent(const QString &); void topicEventSent(); }; @@ -140,7 +140,7 @@ private: void resetErrorLabel(); void displayErrorMessage(const QString &msg); - void setAvatar(const QImage &img); + void setAvatar(); void setupEditButton(); //! Retrieve the current room information from cache. void retrieveRoomInfo(); diff --git a/src/dialogs/UserProfile.cpp b/src/dialogs/UserProfile.cpp index 6aea96a8..5ad3afa2 100644 --- a/src/dialogs/UserProfile.cpp +++ b/src/dialogs/UserProfile.cpp @@ -114,9 +114,8 @@ UserProfile::UserProfile(QWidget *parent) btnLayout->setSpacing(8); btnLayout->setMargin(0); - avatar_ = new Avatar(this); + avatar_ = new Avatar(this, 128); avatar_->setLetter("X"); - avatar_->setSize(128); QFont font; font.setPointSizeF(font.pointSizeF() * 2); @@ -210,8 +209,7 @@ UserProfile::init(const QString &userId, const QString &roomId) displayNameLabel_->setText(displayName); avatar_->setLetter(utils::firstChar(displayName)); - AvatarProvider::resolve( - roomId, userId, this, [this](const QImage &img) { avatar_->setImage(img); }); + avatar_->setImage(roomId, userId); auto localUser = utils::localUser(); diff --git a/src/popups/PopupItem.cpp b/src/popups/PopupItem.cpp index f905983a..c4d4327f 100644 --- a/src/popups/PopupItem.cpp +++ b/src/popups/PopupItem.cpp @@ -11,7 +11,7 @@ constexpr int PopupItemMargin = 3; PopupItem::PopupItem(QWidget *parent) : QWidget(parent) - , avatar_{new Avatar(this)} + , avatar_{new Avatar(this, conf::popup::avatar)} , hovering_{false} { setMouseTracking(true); @@ -40,7 +40,6 @@ UserItem::UserItem(QWidget *parent) : PopupItem(parent) { userName_ = new QLabel("Placeholder", this); - avatar_->setSize(conf::popup::avatar); avatar_->setLetter("P"); topLayout_->addWidget(avatar_); topLayout_->addWidget(userName_, 1); @@ -52,7 +51,6 @@ UserItem::UserItem(QWidget *parent, const QString &user_id) { auto displayName = Cache::displayName(ChatPage::instance()->currentRoom(), userId_); - avatar_->setSize(conf::popup::avatar); avatar_->setLetter(utils::firstChar(displayName)); // If it's a matrix id we use the second letter. @@ -87,16 +85,7 @@ UserItem::updateItem(const QString &user_id) void UserItem::resolveAvatar(const QString &user_id) { - AvatarProvider::resolve( - ChatPage::instance()->currentRoom(), userId_, this, [this, user_id](const QImage &img) { - // The user on the widget when the avatar is resolved, - // might be different from the user that made the call. - if (user_id == userId_) - avatar_->setImage(img); - else - // We try to resolve the avatar again. - resolveAvatar(userId_); - }); + avatar_->setImage(ChatPage::instance()->currentRoom(), user_id); } void @@ -116,7 +105,6 @@ RoomItem::RoomItem(QWidget *parent, const RoomSearchResult &res) auto name = QFontMetrics(QFont()).elidedText( QString::fromStdString(res.info.name), Qt::ElideRight, parentWidget()->width() - 10); - avatar_->setSize(conf::popup::avatar + 6); avatar_->setLetter(utils::firstChar(name)); roomName_ = new QLabel(name, this); @@ -125,8 +113,7 @@ RoomItem::RoomItem(QWidget *parent, const RoomSearchResult &res) topLayout_->addWidget(avatar_); topLayout_->addWidget(roomName_, 1); - if (!res.img.isNull()) - avatar_->setImage(res.img); + avatar_->setImage(QString::fromStdString(res.info.avatar_url)); } void @@ -141,10 +128,7 @@ RoomItem::updateItem(const RoomSearchResult &result) roomName_->setText(name); - if (!result.img.isNull()) - avatar_->setImage(result.img); - else - avatar_->setLetter(utils::firstChar(name)); + avatar_->setImage(QString::fromStdString(result.info.avatar_url)); } void @@ -154,4 +138,4 @@ RoomItem::mousePressEvent(QMouseEvent *event) emit clicked(selectedText()); QWidget::mousePressEvent(event); -} \ No newline at end of file +} diff --git a/src/timeline/.TimelineItem.cpp.swp b/src/timeline/.TimelineItem.cpp.swp new file mode 100644 index 00000000..75e03aeb Binary files /dev/null and b/src/timeline/.TimelineItem.cpp.swp differ diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp index dd3b48c3..7916bd80 100644 --- a/src/timeline/TimelineItem.cpp +++ b/src/timeline/TimelineItem.cpp @@ -326,8 +326,7 @@ TimelineItem::TimelineItem(mtx::events::MessageType ty, generateBody(userid, displayName, formatted_body); setupAvatarLayout(displayName); - AvatarProvider::resolve( - room_id_, userid, this, [this](const QImage &img) { setUserAvatar(img); }); + setUserAvatar(userid); } else { generateBody(formatted_body); setupSimpleLayout(); @@ -509,8 +508,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent generateBody(sender, displayName, formatted_body); setupAvatarLayout(displayName); - AvatarProvider::resolve( - room_id_, sender, this, [this](const QImage &img) { setUserAvatar(img); }); + setUserAvatar(sender); } else { generateBody(formatted_body); setupSimpleLayout(); @@ -607,8 +604,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent generateBody(sender, displayName, formatted_body); setupAvatarLayout(displayName); - AvatarProvider::resolve( - room_id_, sender, this, [this](const QImage &img) { setUserAvatar(img); }); + setUserAvatar(sender); } else { generateBody(formatted_body); setupSimpleLayout(); @@ -793,9 +789,8 @@ TimelineItem::setupAvatarLayout(const QString &userName) QFont f; f.setPointSizeF(f.pointSizeF()); - userAvatar_ = new Avatar(this); + userAvatar_ = new Avatar(this, QFontMetrics(f).height() * 2); userAvatar_->setLetter(QChar(userName[0]).toUpper()); - userAvatar_->setSize(QFontMetrics(f).height() * 2); // TODO: The provided user name should be a UserId class if (userName[0] == '@' && userName.size() > 1) @@ -822,12 +817,12 @@ TimelineItem::setupSimpleLayout() } void -TimelineItem::setUserAvatar(const QImage &avatar) +TimelineItem::setUserAvatar(const QString &userid) { if (userAvatar_ == nullptr) return; - userAvatar_->setImage(avatar); + userAvatar_->setImage(room_id_, userid); } void @@ -911,8 +906,7 @@ TimelineItem::addAvatar() setupAvatarLayout(displayName); - AvatarProvider::resolve( - room_id_, userid, this, [this](const QImage &img) { setUserAvatar(img); }); + setUserAvatar(userid); } void diff --git a/src/timeline/TimelineItem.h b/src/timeline/TimelineItem.h index fe354000..356976e5 100644 --- a/src/timeline/TimelineItem.h +++ b/src/timeline/TimelineItem.h @@ -215,7 +215,7 @@ public: void setBackgroundColor(const QColor &color) { backgroundColor_ = color; } QColor backgroundColor() const { return backgroundColor_; } - void setUserAvatar(const QImage &pixmap); + void setUserAvatar(const QString &userid); DescInfo descriptionMessage() const { return descriptionMsg_; } QString eventId() const { return event_id_; } void setEventId(const QString &event_id) { event_id_ = event_id; } @@ -336,8 +336,7 @@ TimelineItem::setupLocalWidgetLayout(Widget *widget, const QString &userid, bool generateBody(userid, displayName, ""); setupAvatarLayout(displayName); - AvatarProvider::resolve( - room_id_, userid, this, [this](const QImage &img) { setUserAvatar(img); }); + setUserAvatar(userid); } else { setupSimpleLayout(); } @@ -381,8 +380,7 @@ TimelineItem::setupWidgetLayout(Widget *widget, const Event &event, bool withSen generateBody(sender, displayName, ""); setupAvatarLayout(displayName); - AvatarProvider::resolve( - room_id_, sender, this, [this](const QImage &img) { setUserAvatar(img); }); + setUserAvatar(sender); } else { setupSimpleLayout(); } diff --git a/src/ui/Avatar.cpp b/src/ui/Avatar.cpp index 4b4cd272..98bf21c6 100644 --- a/src/ui/Avatar.cpp +++ b/src/ui/Avatar.cpp @@ -1,12 +1,13 @@ #include +#include "AvatarProvider.h" #include "Utils.h" #include "ui/Avatar.h" -Avatar::Avatar(QWidget *parent) +Avatar::Avatar(QWidget *parent, int size) : QWidget(parent) + , size_(size) { - size_ = ui::AvatarSize; type_ = ui::AvatarType::Letter; letter_ = "A"; @@ -61,35 +62,31 @@ Avatar::setBackgroundColor(const QColor &color) } void -Avatar::setSize(int size) +Avatar::setLetter(const QString &letter) { - size_ = size; - - if (!image_.isNull()) - pixmap_ = utils::scaleImageToPixmap(image_, size_); - - QFont _font(font()); - _font.setPointSizeF(size_ * (ui::FontSize) / 40); - - setFont(_font); + letter_ = letter; + type_ = ui::AvatarType::Letter; update(); } void -Avatar::setLetter(const QString &letter) +Avatar::setImage(const QString &avatar_url) { - letter_ = letter; - type_ = ui::AvatarType::Letter; - update(); + AvatarProvider::resolve(avatar_url, size_, this, [this](QPixmap pm) { + type_ = ui::AvatarType::Image; + pixmap_ = pm; + update(); + }); } void -Avatar::setImage(const QImage &image) +Avatar::setImage(const QString &room, const QString &user) { - image_ = image; - type_ = ui::AvatarType::Image; - pixmap_ = utils::scaleImageToPixmap(image_, size_); - update(); + AvatarProvider::resolve(room, user, size_, this, [this](QPixmap pm) { + type_ = ui::AvatarType::Image; + pixmap_ = pm; + update(); + }); } void diff --git a/src/ui/Avatar.h b/src/ui/Avatar.h index 41967af5..b9225dd1 100644 --- a/src/ui/Avatar.h +++ b/src/ui/Avatar.h @@ -15,13 +15,14 @@ class Avatar : public QWidget Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) public: - explicit Avatar(QWidget *parent = 0); + explicit Avatar(QWidget *parent = 0, int size = ui::AvatarSize); void setBackgroundColor(const QColor &color); void setIcon(const QIcon &icon); - void setImage(const QImage &image); + void setImage(const QString &avatar_url); + void setImage(const QString &room, const QString &user); void setLetter(const QString &letter); - void setSize(int size); + // void setSize(int size); void setTextColor(const QColor &color); QColor backgroundColor() const; @@ -41,7 +42,8 @@ private: QColor background_color_; QColor text_color_; QIcon icon_; - QImage image_; QPixmap pixmap_; + const std::string room; + const std::string user; int size_; }; -- cgit 1.5.1