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
new file mode 100644
index 00000000..3480959a
--- /dev/null
+++ b/src/popups/UserMentions.cpp
@@ -0,0 +1,161 @@
+#include <QPainter>
+#include <QStyleOption>
+#include <QTabWidget>
+#include <QTimer>
+
+#include "Cache.h"
+#include "ChatPage.h"
+#include "Logging.h"
+#include "UserMentions.h"
+#include "timeline/TimelineItem.h"
+
+using namespace popups;
+
+UserMentions::UserMentions(QWidget *parent)
+ : QWidget{parent}
+{
+ setAttribute(Qt::WA_ShowWithoutActivating, true);
+ setWindowFlags(Qt::FramelessWindowHint | Qt::Popup);
+
+ tab_layout_ = new QTabWidget(this);
+
+ top_layout_ = new QVBoxLayout(this);
+ top_layout_->setSpacing(0);
+ top_layout_->setMargin(0);
+
+ local_scroll_area_ = new QScrollArea(this);
+ local_scroll_area_->setWidgetResizable(true);
+ local_scroll_area_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ local_scroll_widget_ = new QWidget(this);
+ local_scroll_widget_->setObjectName("local_scroll_widget");
+
+ all_scroll_area_ = new QScrollArea(this);
+ all_scroll_area_->setWidgetResizable(true);
+ all_scroll_area_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ all_scroll_widget_ = new QWidget(this);
+ all_scroll_widget_->setObjectName("all_scroll_widget");
+
+ // Height of the typing display.
+ QFont f;
+ f.setPointSizeF(f.pointSizeF() * 0.9);
+ const int bottomMargin = QFontMetrics(f).height() + 6;
+
+ 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("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("allscrollarea");
+
+ local_scroll_area_->setWidget(local_scroll_widget_);
+ local_scroll_area_->setAlignment(Qt::AlignBottom);
+
+ all_scroll_area_->setWidget(all_scroll_widget_);
+ all_scroll_area_->setAlignment(Qt::AlignBottom);
+
+ tab_layout_->addTab(local_scroll_area_, tr("This Room"));
+ tab_layout_->addTab(all_scroll_area_, tr("All Rooms"));
+ top_layout_->addWidget(tab_layout_);
+
+ setLayout(top_layout_);
+}
+
+void
+UserMentions::initializeMentions(const QMap<QString, mtx::responses::Notifications> ¬ifs)
+{
+ nhlog::ui()->debug("Initializing " + std::to_string(notifs.size()) + " notifications.");
+
+ 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()
+{
+ for (auto widget : all_scroll_layout_->findChildren<QWidget *>()) {
+ delete widget;
+ }
+ for (auto widget : local_scroll_layout_->findChildren<QWidget *>()) {
+ delete widget;
+ }
+
+ auto notifs = cache::client()->getTimelineMentions();
+
+ initializeMentions(notifs);
+ show();
+}
+
+void
+UserMentions::pushItem(const QString &event_id,
+ const QString &user_id,
+ const QString &body,
+ const QString &room_id,
+ const QString ¤t_room_id)
+{
+ setUpdatesEnabled(false);
+
+ // Add to the 'all' section
+ TimelineItem *view_item = new TimelineItem(
+ mtx::events::MessageType::Text, user_id, body, true, room_id, all_scroll_widget_);
+ view_item->setEventId(event_id);
+ view_item->hide();
+
+ all_scroll_layout_->addWidget(view_item);
+ QTimer::singleShot(0, this, [view_item, this]() {
+ view_item->show();
+ view_item->adjustSize();
+ setUpdatesEnabled(true);
+ });
+
+ // if it matches the current room... add it to the current room as well.
+ if (QString::compare(room_id, current_room_id, Qt::CaseInsensitive) == 0) {
+ // Add to the 'local' section
+ TimelineItem *local_view_item = new TimelineItem(mtx::events::MessageType::Text,
+ user_id,
+ body,
+ true,
+ room_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]() {
+ local_view_item->show();
+ 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
new file mode 100644
index 00000000..d7dfc575
--- /dev/null
+++ b/src/popups/UserMentions.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <mtx/responses.hpp>
+
+#include <QApplication>
+#include <QEvent>
+#include <QMap>
+#include <QPaintEvent>
+#include <QScrollArea>
+#include <QScrollBar>
+#include <QString>
+#include <QTabWidget>
+#include <QVBoxLayout>
+#include <QWidget>
+#include <Qt>
+
+#include "Logging.h"
+
+namespace popups {
+
+class UserMentions : public QWidget
+{
+ Q_OBJECT
+public:
+ UserMentions(QWidget *parent = nullptr);
+
+ void initializeMentions(const QMap<QString, mtx::responses::Notifications> ¬ifs);
+ void showPopup();
+
+protected:
+ void paintEvent(QPaintEvent *) override;
+
+private:
+ void pushItem(const QString &event_id,
+ const QString &user_id,
+ const QString &body,
+ const QString &room_id,
+ const QString ¤t_room_id);
+ QTabWidget *tab_layout_;
+ QVBoxLayout *top_layout_;
+ QVBoxLayout *local_scroll_layout_;
+ QVBoxLayout *all_scroll_layout_;
+
+ QScrollArea *local_scroll_area_;
+ QWidget *local_scroll_widget_;
+
+ QScrollArea *all_scroll_area_;
+ QWidget *all_scroll_widget_;
+};
+
+}
\ No newline at end of file
|