diff --git a/resources/styles/nheko-dark.qss b/resources/styles/nheko-dark.qss index 1e1333b2..1271e39f 100644 --- a/resources/styles/nheko-dark.qss +++ b/resources/styles/nheko-dark.qss @@ -24,6 +24,17 @@ TimelineView > * { border: none; } +UserMentionsWidget, +UserMentionsWidget > * { + background-color: #202228; + border: none; +} + +UserMentionsWidget > TimelineItem { + qproperty-backgroundColor: #202228; + qproperty-hoverColor: rgba(45, 49, 57, 120); +} + #scroll_widget { background-color: #202228; } diff --git a/resources/styles/nheko.qss b/resources/styles/nheko.qss index a70441be..3c7f3b71 100644 --- a/resources/styles/nheko.qss +++ b/resources/styles/nheko.qss @@ -24,6 +24,17 @@ TimelineView > * { border: none; } +UserMentionsWidget, +UserMentionsWidget > * { + background-color: white; + border: none; +} + +UserMentionsWidget > TimelineItem { + qproperty-backgroundColor: white; + qproperty-hoverColor: rgba(192, 193, 195, 120); +} + #scroll_widget { background-color: white; } diff --git a/resources/styles/system.qss b/resources/styles/system.qss index dfb8ce65..0a8c4b21 100644 --- a/resources/styles/system.qss +++ b/resources/styles/system.qss @@ -12,6 +12,16 @@ TimelineView > * { border: none; } +UserMentionsWidget, +UserMentionsWidget > * { + border: none; +} + +UserMentionsWidget > TimelineItem { + qproperty-backgroundColor: palette(window); + qproperty-hoverColor: palette(base); +} + TextInputWidget { border: none; border-top: 1px solid palette(mid); diff --git a/src/AvatarProvider.cpp b/src/AvatarProvider.cpp index 57b61c75..ec745c04 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" +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 e2204ceb..5b41794b 100644 --- a/src/RoomInfoListItem.cpp +++ b/src/RoomInfoListItem.cpp @@ -22,6 +22,7 @@ #include #include +#include "AvatarProvider.h" #include "Cache.h" #include "Config.h" #include "RoomInfoListItem.h" @@ -442,10 +443,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 cc0c0a82..7a910340 100644 --- a/src/UserInfoWidget.cpp +++ b/src/UserInfoWidget.cpp @@ -53,10 +53,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); @@ -135,14 +134,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) { @@ -161,6 +152,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/popups/UserMentions.cpp b/src/popups/UserMentions.cpp index 152cd82d..3480959a 100644 --- a/src/popups/UserMentions.cpp +++ b/src/popups/UserMentions.cpp @@ -1,3 +1,5 @@ +#include +#include #include #include @@ -140,7 +142,6 @@ UserMentions::pushItem(const QString &event_id, local_scroll_widget_); local_view_item->setEventId(event_id); local_view_item->hide(); - local_scroll_layout_->addWidget(local_view_item); QTimer::singleShot(0, this, [local_view_item]() { @@ -148,4 +149,13 @@ UserMentions::pushItem(const QString &event_id, local_view_item->adjustSize(); }); } +} + +void +UserMentions::paintEvent(QPaintEvent *) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } \ No newline at end of file diff --git a/src/popups/UserMentions.h b/src/popups/UserMentions.h index a74bf2ec..d7dfc575 100644 --- a/src/popups/UserMentions.h +++ b/src/popups/UserMentions.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,9 @@ public: void initializeMentions(const QMap ¬ifs); void showPopup(); +protected: + void paintEvent(QPaintEvent *) override; + private: void pushItem(const QString &event_id, const QString &user_id, 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 df649e1b..51068424 100644 --- a/src/ui/Avatar.cpp +++ b/src/ui/Avatar.cpp @@ -1,15 +1,16 @@ #include #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"; + type_ = ui::AvatarType::Letter; + letter_ = "A"; QFont _font(font()); _font.setPointSizeF(ui::FontSize); @@ -61,21 +62,6 @@ Avatar::setBackgroundColor(const QColor &color) background_color_ = color; } -void -Avatar::setSize(int size) -{ - size_ = size; - - if (!image_.isNull()) - pixmap_ = utils::scaleImageToPixmap(image_, size_); - - QFont _font(font()); - _font.setPointSizeF(size_ * (ui::FontSize) / 40); - - setFont(_font); - update(); -} - void Avatar::setLetter(const QString &letter) { @@ -85,12 +71,23 @@ Avatar::setLetter(const QString &letter) } void -Avatar::setImage(const QImage &image) +Avatar::setImage(const QString &avatar_url) { - image_ = image; - type_ = ui::AvatarType::Image; - pixmap_ = utils::scaleImageToPixmap(image_, size_); - update(); + AvatarProvider::resolve(avatar_url, size_, this, [this](QPixmap pm) { + type_ = ui::AvatarType::Image; + pixmap_ = pm; + update(); + }); +} + +void +Avatar::setImage(const QString &room, const QString &user) +{ + 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..a643c8c4 100644 --- a/src/ui/Avatar.h +++ b/src/ui/Avatar.h @@ -15,13 +15,13 @@ 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 setTextColor(const QColor &color); QColor backgroundColor() const; @@ -41,7 +41,6 @@ private: QColor background_color_; QColor text_color_; QIcon icon_; - QImage image_; QPixmap pixmap_; int size_; };