summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJoseph Donofry <joedonofry@gmail.com>2019-08-12 22:09:40 -0400
committerJoseph Donofry <joedonofry@gmail.com>2019-08-12 22:09:40 -0400
commit52a262177660da2d541236d597fe34212d078094 (patch)
tree13e81d0b1015e21b9ed227edf8f8166f7c681e00 /src
parentUpdate mtxclient version (diff)
downloadnheko-52a262177660da2d541236d597fe34212d078094.tar.xz
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.
Diffstat (limited to 'src')
-rw-r--r--src/Cache.cpp31
-rw-r--r--src/Cache.h2
-rw-r--r--src/ChatPage.cpp62
-rw-r--r--src/ChatPage.h2
-rw-r--r--src/popups/UserMentions.cpp51
-rw-r--r--src/popups/UserMentions.h10
6 files changed, 108 insertions, 50 deletions
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 &notif : 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 &notif : 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> &notifs); + void initializeMentions(const QMap<QString, mtx::responses::Notifications> &notifs); 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> &notifs) +UserMentions::initializeMentions(const QMap<QString, mtx::responses::Notifications> &notifs) { - 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> &notifs); + +private: void pushItem(const QString &event_id, const QString &user_id, const QString &body, const QString &room_id, const QString &current_room_id); - - void initializeMentions(const std::map<QString, mtx::responses::Notifications> &notifs); - -private: QTabWidget *tab_layout_; QVBoxLayout *top_layout_; QVBoxLayout *local_scroll_layout_;