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 <QCoreApplication>
#include <QFile>
#include <QHash>
+#include <QMap>
#include <QSettings>
#include <QStandardPaths>
@@ -1232,20 +1233,20 @@ Cache::roomMessages()
return msgs;
}
-std::map<QString, mtx::responses::Notifications>
+QMap<QString, mtx::responses::Notifications>
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<QString, mtx::responses::Notifications> notifs;
+ QMap<QString, mtx::responses::Notifications> 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<std::string, QList<mtx::responses::Notification>> 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<std::string, QList<mtx::responses::Notification>>::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<QString, mtx::responses::Timeline> roomMessages();
- std::map<QString, mtx::responses::Notifications> getTimelineMentions();
+ QMap<QString, mtx::responses::Notifications> getTimelineMentions();
//! Retrieve all the user ids from a room.
std::vector<std::string> 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> 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<int>(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<int>(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<QString, RoomInfo>);
void initializeViews(const mtx::responses::Rooms &rooms);
void initializeEmptyViews(const std::map<QString, mtx::responses::Timeline> &msgs);
- void initializeMentions(const std::map<QString, mtx::responses::Notifications> ¬ifs);
+ void initializeMentions(const QMap<QString, mtx::responses::Notifications> ¬ifs);
void syncUI(const mtx::responses::Rooms &rooms);
void syncRoomlist(const std::map<QString, RoomInfo> &updates);
void syncTags(const std::map<QString, RoomInfo> &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 <QTabWidget>
#include <QTimer>
+#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<QString, mtx::responses::Notifications> ¬ifs)
+UserMentions::initializeMentions(const QMap<QString, mtx::responses::Notifications> ¬ifs)
{
- Q_UNUSED(notifs);
- // Very TODO:
+ nhlog::ui()->debug("Initializing " + std::to_string(notifs.size()) + " notifications.");
+ for (auto widget : all_scroll_layout_->findChildren<QWidget *>()) {
+ delete widget;
+ }
+ for (auto widget : local_scroll_layout_->findChildren<QWidget *>()) {
+ 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()
+{
+ 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 <mtx/responses.hpp>
+#include <QMap>
#include <QScrollArea>
#include <QScrollBar>
#include <QString>
@@ -16,15 +17,16 @@ class UserMentions : public QWidget
Q_OBJECT
public:
UserMentions(QWidget *parent = nullptr);
+
+ void showPopup();
+ void initializeMentions(const QMap<QString, mtx::responses::Notifications> ¬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<QString, mtx::responses::Notifications> ¬ifs);
-
-private:
QTabWidget *tab_layout_;
QVBoxLayout *top_layout_;
QVBoxLayout *local_scroll_layout_;
|