From 3f563e1e6e5e73b0eb50f53cc4568064a0f2f780 Mon Sep 17 00:00:00 2001 From: Joseph Donofry Date: Fri, 9 Aug 2019 23:34:44 -0400 Subject: [PATCH] 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. --- CMakeLists.txt | 6 +- src/Cache.cpp | 66 ++++- src/Cache.h | 20 +- src/ChatPage.cpp | 29 ++- src/ChatPage.h | 6 +- src/UserMentionsWidget.cpp | 309 ----------------------- src/UserMentionsWidget.h | 164 ------------ src/{dialogs => popups}/UserMentions.cpp | 9 +- src/{dialogs => popups}/UserMentions.h | 7 +- 9 files changed, 112 insertions(+), 504 deletions(-) delete mode 100644 src/UserMentionsWidget.cpp delete mode 100644 src/UserMentionsWidget.h rename src/{dialogs => popups}/UserMentions.cpp (95%) rename src/{dialogs => popups}/UserMentions.h (82%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 09eea071..4d5aff7a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,7 +179,6 @@ set(SRC_FILES src/dialogs/LeaveRoom.cpp src/dialogs/Logout.cpp src/dialogs/UserProfile.cpp - src/dialogs/UserMentions.cpp src/dialogs/ReadReceipts.cpp src/dialogs/ReCaptcha.cpp src/dialogs/RoomSettings.cpp @@ -241,13 +240,13 @@ set(SRC_FILES src/popups/SuggestionsPopup.cpp src/popups/PopupItem.cpp src/popups/ReplyPopup.cpp + src/popups/UserMentions.cpp src/TextInputWidget.cpp src/TopRoomBar.cpp src/TrayIcon.cpp src/TypingDisplay.cpp src/Utils.cpp src/UserInfoWidget.cpp - src/UserMentionsWidget.cpp src/UserSettingsPage.cpp src/WelcomePage.cpp src/main.cpp @@ -321,7 +320,6 @@ qt5_wrap_cpp(MOC_HEADERS src/dialogs/MemberList.h src/dialogs/LeaveRoom.h src/dialogs/Logout.h - src/dialogs/UserMentions.h src/dialogs/UserProfile.h src/dialogs/RawMessage.h src/dialogs/ReadReceipts.h @@ -383,12 +381,12 @@ qt5_wrap_cpp(MOC_HEADERS src/popups/SuggestionsPopup.h src/popups/ReplyPopup.h src/popups/PopupItem.h + src/popups/UserMentions.h src/TextInputWidget.h src/TopRoomBar.h src/TrayIcon.h src/TypingDisplay.h src/UserInfoWidget.h - src/UserMentionsWidget.h src/UserSettingsPage.h src/WelcomePage.h ) diff --git a/src/Cache.cpp b/src/Cache.cpp index 9bf3b5b0..5ccf9291 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -1232,6 +1232,28 @@ Cache::roomMessages() return msgs; } +std::map +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; + + 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); + } + + txn.commit(); + + return notifs; +} + + mtx::responses::Timeline Cache::getTimelineMessages(lmdb::txn &txn, const std::string &room_id) { @@ -1934,11 +1956,16 @@ Cache::saveTimelineMessages(lmdb::txn &txn, lmdb::val(obj.dump())); } } + mtx::responses::Notifications -Cache::getTimelineMentions(lmdb::txn &txn, const std::string &room_id) +Cache::getTimelineMentionsForRoom(lmdb::txn &txn, const std::string &room_id) { auto db = getMentionsDb(txn, room_id); + if (db.size(txn) == 0) { + return mtx::responses::Notifications{}; + } + mtx::responses::Notifications notif; std::string event_id, msg; @@ -1961,29 +1988,52 @@ Cache::getTimelineMentions(lmdb::txn &txn, const std::string &room_id) return notif; } + +//! Add all notifications containing a user mention to the db. +void +Cache::saveTimelineMentions(const mtx::responses::Notifications &res) +{ + QMap> notifsByRoom; + + // Sort into room-specific 'buckets' + for (const auto ¬if : res.notifications) { + 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]); + } + + txn.commit(); +} + void Cache::saveTimelineMentions(lmdb::txn &txn, const std::string &room_id, - const mtx::responses::Notifications &res) + const QList &res) { auto db = getMentionsDb(txn, room_id); using namespace mtx::events; using namespace mtx::events::state; - for (const auto &n : res.notifications) { - const auto event_id = utils::event_id(n.event); + 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... - if (room_id.compare(n.room_id) != 0) - continue; + if (room_id.compare(notif.room_id) != 0) { + return; + } json obj = json::object(); lmdb::dbi_put(txn, db, lmdb::val(event_id), lmdb::val(obj.dump())); } - - txn.commit(); } void diff --git a/src/Cache.h b/src/Cache.h index 5971df66..07ccf790 100644 --- a/src/Cache.h +++ b/src/Cache.h @@ -323,6 +323,8 @@ public: std::map roomMessages(); + std::map getTimelineMentions(); + //! Retrieve all the user ids from a room. std::vector roomMembers(const std::string &room_id); @@ -402,13 +404,8 @@ public: //! Check if we have sent a desktop notification for the given event id. bool isNotificationSent(const std::string &event_id); - //! Add a notification containing a user mention to the db. - void saveTimelineMentions(lmdb::txn &txn, - const std::string &room_id, - const mtx::responses::Notifications &res); - //! Get timeline items that a user was mentions in - mtx::responses::Notifications getTimelineMentions(lmdb::txn &txn, - const std::string &room_id); + //! Add all notifications containing a user mention to the db. + void saveTimelineMentions(const mtx::responses::Notifications &res); //! Remove old unused data. void deleteOldMessages(); @@ -478,6 +475,15 @@ private: lmdb::dbi &membersdb, const mtx::responses::InvitedRoom &room); + //! Add a notification containing a user mention to the db. + void saveTimelineMentions(lmdb::txn &txn, + const std::string &room_id, + const QList &res); + + //! Get timeline items that a user was mentions in for a given room + mtx::responses::Notifications getTimelineMentionsForRoom(lmdb::txn &txn, + const std::string &room_id); + QString getInviteRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); QString getInviteRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb); QString getInviteRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index ca18d810..2a02e740 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -35,7 +35,6 @@ #include "TopRoomBar.h" #include "TypingDisplay.h" #include "UserInfoWidget.h" -#include "UserMentionsWidget.h" #include "UserSettingsPage.h" #include "Utils.h" #include "ui/OverlayModal.h" @@ -44,7 +43,7 @@ #include "notifications/Manager.h" #include "dialogs/ReadReceipts.h" -#include "dialogs/UserMentions.h" +#include "popups/UserMentions.h" #include "timeline/TimelineViewManager.h" // TODO: Needs to be updated with an actual secret. @@ -91,7 +90,7 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(sidebarActions_, &SideBarActions::createRoom, this, &ChatPage::createRoom); user_info_widget_ = new UserInfoWidget(sideBar_); - // user_mentions_widget_ = new UserMentionsWidget(top_bar_); + user_mentions_popup_ = new popups::UserMentions(); room_list_ = new RoomList(sideBar_); connect(room_list_, &RoomList::joinRoom, this, &ChatPage::joinRoom); @@ -518,8 +517,17 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(this, &ChatPage::leftRoom, this, &ChatPage::removeRoom); connect(this, &ChatPage::notificationsRetrieved, this, &ChatPage::sendDesktopNotifications); - connect( - this, &ChatPage::highlightedNotifsRetrieved, this, &ChatPage::showNotificationsDialog); + connect(this, + &ChatPage::highlightedNotifsRetrieved, + this, + [this](const mtx::responses::Notifications ¬if, const QPoint &widgetPos) { + try { + cache::client()->saveTimelineMentions(notif); + } catch (const lmdb::error &e) { + nhlog::db()->error("failed to save mentions: {}", e.what()); + } + showNotificationsDialog(notif, widgetPos); + }); connect(communitiesList_, &CommunitiesList::communityChanged, @@ -558,6 +566,10 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) &ChatPage::initializeEmptyViews, view_manager_, &TimelineViewManager::initWithMessages); + connect(this, + &ChatPage::initializeMentions, + user_mentions_popup_, + &popups::UserMentions::initializeMentions); connect(this, &ChatPage::syncUI, this, [this](const mtx::responses::Rooms &rooms) { try { room_list_->cleanupInvites(cache::client()->invites()); @@ -830,6 +842,7 @@ ChatPage::loadStateFromCache() emit initializeEmptyViews(cache::client()->roomMessages()); emit initializeRoomList(cache::client()->roomInfo()); + emit initializeMentions(cache::client()->getTimelineMentions()); emit syncTags(cache::client()->roomInfo().toStdMap()); cache::client()->calculateRoomReadStatus(); @@ -988,9 +1001,7 @@ ChatPage::sendDesktopNotifications(const mtx::responses::Notifications &res) void ChatPage::showNotificationsDialog(const mtx::responses::Notifications &res, const QPoint &widgetPos) { - // TODO: This should NOT BE A DIALOG. Make the TimelineView support - // creating a timeline view from notifications (similarly to how it can show history views) - auto notifDialog = new dialogs::UserMentions(); + auto notifDialog = user_mentions_popup_; for (const auto &item : res.notifications) { const auto event_id = QString::fromStdString(utils::event_id(item.event)); @@ -1242,6 +1253,8 @@ ChatPage::sendTypingNotifications() void ChatPage::initialSyncHandler(const mtx::responses::Sync &res, mtx::http::RequestErr err) { + // TODO: Initial Sync should include mentions as well... + if (err) { const auto error = QString::fromStdString(err->matrix_error.error); const auto msg = tr("Please try to login again: %1").arg(error); 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_; diff --git a/src/UserMentionsWidget.cpp b/src/UserMentionsWidget.cpp deleted file mode 100644 index a28db930..00000000 --- a/src/UserMentionsWidget.cpp +++ /dev/null @@ -1,309 +0,0 @@ -#include -#include -#include -#include -#include - -#include "MainWindow.h" -#include "UserMentionsWidget.h" -#include "Utils.h" -#include "ui/Ripple.h" -#include "ui/RippleOverlay.h" - -constexpr int MaxUnreadCountDisplayed = 99; - -struct WMetrics -{ - int maxHeight; - int iconSize; - int padding; - int unit; - - int unreadLineWidth; - int unreadLineOffset; - - int inviteBtnX; - int inviteBtnY; -}; - -WMetrics -getWMetrics(const QFont &font) -{ - WMetrics m; - - const int height = QFontMetrics(font).lineSpacing(); - - m.unit = height; - m.maxHeight = std::ceil((double)height * 3.8); - m.iconSize = std::ceil((double)height * 2.8); - m.padding = std::ceil((double)height / 2.0); - m.unreadLineWidth = m.padding - m.padding / 3; - m.unreadLineOffset = m.padding - m.padding / 4; - - m.inviteBtnX = m.iconSize + 2 * m.padding; - m.inviteBtnX = m.iconSize / 2.0 + m.padding + m.padding / 3.0; - - return m; -} - -UserMentionsWidget::UserMentionsWidget(QWidget *parent) - : QWidget(parent) - , isPressed_(false) - , unreadMsgCount_(0) -{ - init(parent); - - QFont f; - f.setPointSizeF(f.pointSizeF()); - - const int fontHeight = QFontMetrics(f).height(); - const int widgetMargin = fontHeight / 3; - const int contentHeight = fontHeight * 3; - - setFixedHeight(contentHeight + widgetMargin); - - topLayout_ = new QHBoxLayout(this); - topLayout_->setSpacing(0); - topLayout_->setMargin(widgetMargin); -} - -void -UserMentionsWidget::init(QWidget *parent) -{ - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - setMouseTracking(true); - setAttribute(Qt::WA_Hover); - - setFixedHeight(getWMetrics(QFont{}).maxHeight); - - QPainterPath path; - path.addRect(0, 0, parent->width(), height()); - - ripple_overlay_ = new RippleOverlay(this); - ripple_overlay_->setClipPath(path); - ripple_overlay_->setClipping(true); - - unreadCountFont_.setPointSizeF(unreadCountFont_.pointSizeF() * 0.8); - unreadCountFont_.setBold(true); - - bubbleDiameter_ = QFontMetrics(unreadCountFont_).averageCharWidth() * 3; -} - -// void -// UserMentionsWidget::resizeEvent(QResizeEvent *event) -// { -// Q_UNUSED(event); - -// const auto sz = utils::calculateSidebarSizes(QFont{}); - -// if (width() <= sz.small) { -// topLayout_->setContentsMargins(0, 0, logoutButtonSize_, 0); - -// } else { -// topLayout_->setMargin(5); -// } - -// QWidget::resizeEvent(event); -// } - -void -UserMentionsWidget::setPressedState(bool state) -{ - if (isPressed_ != state) { - isPressed_ = state; - update(); - } -} - -void -UserMentionsWidget::resizeEvent(QResizeEvent *) -{ - // Update ripple's clipping path. - QPainterPath path; - path.addRect(0, 0, width(), height()); - - const auto sidebarSizes = utils::calculateSidebarSizes(QFont{}); - - if (width() > sidebarSizes.small) - setToolTip(""); - else - setToolTip(""); - - ripple_overlay_->setClipPath(path); - ripple_overlay_->setClipping(true); -} - -void -UserMentionsWidget::mousePressEvent(QMouseEvent *event) -{ - if (event->buttons() == Qt::RightButton) { - QWidget::mousePressEvent(event); - return; - } - - emit clicked(); - - setPressedState(true); - - // Ripple on mouse position by default. - QPoint pos = event->pos(); - qreal radiusEndValue = static_cast(width()) / 3; - - Ripple *ripple = new Ripple(pos); - - ripple->setRadiusEndValue(radiusEndValue); - ripple->setOpacityStartValue(0.15); - ripple->setColor(QColor("white")); - ripple->radiusAnimation()->setDuration(200); - ripple->opacityAnimation()->setDuration(400); - - ripple_overlay_->addRipple(ripple); -} - -void -UserMentionsWidget::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - - QPainter p(this); - p.setRenderHint(QPainter::TextAntialiasing); - p.setRenderHint(QPainter::SmoothPixmapTransform); - p.setRenderHint(QPainter::Antialiasing); - - auto wm = getWMetrics(QFont{}); - - QPen titlePen(titleColor_); - QPen subtitlePen(subtitleColor_); - - QFontMetrics metrics(QFont{}); - - if (isPressed_) { - p.fillRect(rect(), highlightedBackgroundColor_); - titlePen.setColor(highlightedTitleColor_); - subtitlePen.setColor(highlightedSubtitleColor_); - } else if (underMouse()) { - p.fillRect(rect(), hoverBackgroundColor_); - titlePen.setColor(hoverTitleColor_); - subtitlePen.setColor(hoverSubtitleColor_); - } else { - p.fillRect(rect(), backgroundColor_); - titlePen.setColor(titleColor_); - subtitlePen.setColor(subtitleColor_); - } - - // Description line with the default font. - int bottom_y = wm.maxHeight - wm.padding - metrics.ascent() / 2; - - const auto sidebarSizes = utils::calculateSidebarSizes(QFont{}); - - if (width() > sidebarSizes.small) { - QFont headingFont; - headingFont.setWeight(QFont::Medium); - p.setFont(headingFont); - p.setPen(titlePen); - - QFont tsFont; - tsFont.setPointSizeF(tsFont.pointSizeF() * 0.9); -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - const int msgStampWidth = QFontMetrics(tsFont).width("timestamp") + 4; -#else - const int msgStampWidth = QFontMetrics(tsFont).horizontalAdvance("timestamp") + 4; -#endif - // We use the full width of the widget if there is no unread msg bubble. - // const int bottomLineWidthLimit = (unreadMsgCount_ > 0) ? msgStampWidth : 0; - - // Name line. - QFontMetrics fontNameMetrics(headingFont); - int top_y = 2 * wm.padding + fontNameMetrics.ascent() / 2; - - const auto name = metrics.elidedText( - "Mentions", - Qt::ElideRight, - (width() - wm.iconSize - 2 * wm.padding - msgStampWidth) * 0.8); - p.drawText(QPoint(2 * wm.padding + wm.iconSize, top_y), name); - - p.setFont(QFont{}); - p.setPen(subtitlePen); - - // The limit is the space between the end of the avatar and the start of the - // timestamp. - int usernameLimit = - std::max(0, width() - 3 * wm.padding - msgStampWidth - wm.iconSize - 20); - auto userName = - metrics.elidedText("Show Mentioned Messages", Qt::ElideRight, usernameLimit); - - p.setFont(QFont{}); - p.drawText(QPoint(2 * wm.padding + wm.iconSize, bottom_y), userName); - - // We show the last message timestamp. - p.save(); - if (isPressed_) { - p.setPen(QPen(highlightedTimestampColor_)); - } else if (underMouse()) { - p.setPen(QPen(hoverTimestampColor_)); - } else { - p.setPen(QPen(timestampColor_)); - } - - // p.setFont(tsFont); - // p.drawText(QPoint(width() - wm.padding - msgStampWidth, top_y), "timestamp"); - p.restore(); - } - - p.setPen(Qt::NoPen); - - if (unreadMsgCount_ > 0) { - QBrush brush; - brush.setStyle(Qt::SolidPattern); - - brush.setColor(mentionedColor()); - - if (isPressed_) - brush.setColor(bubbleFgColor()); - - p.setBrush(brush); - p.setPen(Qt::NoPen); - p.setFont(unreadCountFont_); - - // Extra space on the x-axis to accomodate the extra character space - // inside the bubble. - const int x_width = unreadMsgCount_ > MaxUnreadCountDisplayed - ? QFontMetrics(p.font()).averageCharWidth() - : 0; - - QRectF r(width() - bubbleDiameter_ - wm.padding - x_width, - bottom_y - bubbleDiameter_ / 2 - 5, - bubbleDiameter_ + x_width, - bubbleDiameter_); - - if (width() == sidebarSizes.small) - r = QRectF(width() - bubbleDiameter_ - 5, - height() - bubbleDiameter_ - 5, - bubbleDiameter_ + x_width, - bubbleDiameter_); - - p.setPen(Qt::NoPen); - p.drawEllipse(r); - - p.setPen(QPen(bubbleFgColor())); - - if (isPressed_) - p.setPen(QPen(bubbleBgColor())); - - auto countTxt = unreadMsgCount_ > MaxUnreadCountDisplayed - ? QString("99+") - : QString::number(unreadMsgCount_); - - p.setBrush(Qt::NoBrush); - p.drawText(r.translated(0, -0.5), Qt::AlignCenter, countTxt); - } - - if (!isPressed_ && hasUnreadMessages_) { - QPen pen; - pen.setWidth(wm.unreadLineWidth); - pen.setColor(highlightedBackgroundColor_); - - p.setPen(pen); - p.drawLine(0, wm.unreadLineOffset, 0, height() - wm.unreadLineOffset); - } -} \ No newline at end of file diff --git a/src/UserMentionsWidget.h b/src/UserMentionsWidget.h deleted file mode 100644 index 179f0026..00000000 --- a/src/UserMentionsWidget.h +++ /dev/null @@ -1,164 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -class FlatButton; -class RippleOverlay; - -class UserMentionsWidget : public QWidget -{ - Q_OBJECT - - Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) - - Q_PROPERTY(QColor highlightedBackgroundColor READ highlightedBackgroundColor WRITE - setHighlightedBackgroundColor) - Q_PROPERTY( - QColor hoverBackgroundColor READ hoverBackgroundColor WRITE setHoverBackgroundColor) - Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) - - Q_PROPERTY(QColor avatarBgColor READ avatarBgColor WRITE setAvatarBgColor) - Q_PROPERTY(QColor avatarFgColor READ avatarFgColor WRITE setAvatarFgColor) - - Q_PROPERTY(QColor bubbleBgColor READ bubbleBgColor WRITE setBubbleBgColor) - Q_PROPERTY(QColor bubbleFgColor READ bubbleFgColor WRITE setBubbleFgColor) - - Q_PROPERTY(QColor titleColor READ titleColor WRITE setTitleColor) - Q_PROPERTY(QColor subtitleColor READ subtitleColor WRITE setSubtitleColor) - - Q_PROPERTY(QColor timestampColor READ timestampColor WRITE setTimestampColor) - Q_PROPERTY(QColor highlightedTimestampColor READ highlightedTimestampColor WRITE - setHighlightedTimestampColor) - Q_PROPERTY(QColor hoverTimestampColor READ hoverTimestampColor WRITE setHoverTimestampColor) - - Q_PROPERTY( - QColor highlightedTitleColor READ highlightedTitleColor WRITE setHighlightedTitleColor) - Q_PROPERTY(QColor highlightedSubtitleColor READ highlightedSubtitleColor WRITE - setHighlightedSubtitleColor) - - Q_PROPERTY(QColor hoverTitleColor READ hoverTitleColor WRITE setHoverTitleColor) - Q_PROPERTY(QColor hoverSubtitleColor READ hoverSubtitleColor WRITE setHoverSubtitleColor) - - Q_PROPERTY(QColor mentionedColor READ mentionedColor WRITE setMentionedColor) - Q_PROPERTY(QColor btnColor READ btnColor WRITE setBtnColor) - Q_PROPERTY(QColor btnTextColor READ btnTextColor WRITE setBtnTextColor) - -public: - UserMentionsWidget(QWidget *parent = 0); - - void updateUnreadMessageCount(int count); - void clearUnreadMessageCount() { updateUnreadMessageCount(0); }; - bool isPressed() const { return isPressed_; } - int unreadMessageCount() const { return unreadMsgCount_; } - QColor borderColor() const { return borderColor_; } - void setBorderColor(QColor &color) { borderColor_ = color; } - QColor highlightedBackgroundColor() const { return highlightedBackgroundColor_; } - QColor hoverBackgroundColor() const { return hoverBackgroundColor_; } - QColor hoverTitleColor() const { return hoverTitleColor_; } - QColor hoverSubtitleColor() const { return hoverSubtitleColor_; } - QColor hoverTimestampColor() const { return hoverTimestampColor_; } - QColor backgroundColor() const { return backgroundColor_; } - QColor avatarBgColor() const { return avatarBgColor_; } - QColor avatarFgColor() const { return avatarFgColor_; } - - QColor highlightedTitleColor() const { return highlightedTitleColor_; } - QColor highlightedSubtitleColor() const { return highlightedSubtitleColor_; } - QColor highlightedTimestampColor() const { return highlightedTimestampColor_; } - - QColor titleColor() const { return titleColor_; } - QColor subtitleColor() const { return subtitleColor_; } - QColor timestampColor() const { return timestampColor_; } - QColor btnColor() const { return btnColor_; } - QColor btnTextColor() const { return btnTextColor_; } - - QColor bubbleFgColor() const { return bubbleFgColor_; } - QColor bubbleBgColor() const { return bubbleBgColor_; } - QColor mentionedColor() const { return mentionedFontColor_; } - - void setHighlightedBackgroundColor(QColor &color) { highlightedBackgroundColor_ = color; } - void setHoverBackgroundColor(QColor &color) { hoverBackgroundColor_ = color; } - void setHoverSubtitleColor(QColor &color) { hoverSubtitleColor_ = color; } - void setHoverTitleColor(QColor &color) { hoverTitleColor_ = color; } - void setHoverTimestampColor(QColor &color) { hoverTimestampColor_ = color; } - void setBackgroundColor(QColor &color) { backgroundColor_ = color; } - void setTimestampColor(QColor &color) { timestampColor_ = color; } - void setAvatarFgColor(QColor &color) { avatarFgColor_ = color; } - void setAvatarBgColor(QColor &color) { avatarBgColor_ = color; } - - void setHighlightedTitleColor(QColor &color) { highlightedTitleColor_ = color; } - void setHighlightedSubtitleColor(QColor &color) { highlightedSubtitleColor_ = color; } - void setHighlightedTimestampColor(QColor &color) { highlightedTimestampColor_ = color; } - - void setTitleColor(QColor &color) { titleColor_ = color; } - void setSubtitleColor(QColor &color) { subtitleColor_ = color; } - - void setBtnColor(QColor &color) { btnColor_ = color; } - void setBtnTextColor(QColor &color) { btnTextColor_ = color; } - - void setBubbleFgColor(QColor &color) { bubbleFgColor_ = color; } - void setBubbleBgColor(QColor &color) { bubbleBgColor_ = color; } - void setMentionedColor(QColor &color) { mentionedFontColor_ = color; } - -signals: - void clicked(); - -public slots: - void setPressedState(bool state); - -protected: - void mousePressEvent(QMouseEvent *event) override; - void paintEvent(QPaintEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - -private: - void init(QWidget *parent); - - RippleOverlay *ripple_overlay_; - - bool isPressed_ = false; - - bool hasUnreadMessages_ = true; - - int unreadMsgCount_ = 0; - - QHBoxLayout *topLayout_; - - QColor borderColor_; - QColor highlightedBackgroundColor_; - QColor hoverBackgroundColor_; - QColor backgroundColor_; - - QColor highlightedTitleColor_; - QColor highlightedSubtitleColor_; - - QColor titleColor_; - QColor subtitleColor_; - - QColor hoverTitleColor_; - QColor hoverSubtitleColor_; - - QColor btnColor_; - QColor btnTextColor_; - - QRectF acceptBtnRegion_; - QRectF declineBtnRegion_; - - // Fonts - QColor mentionedFontColor_; - QFont unreadCountFont_; - int bubbleDiameter_; - - QColor timestampColor_; - QColor highlightedTimestampColor_; - QColor hoverTimestampColor_; - - QColor avatarBgColor_; - QColor avatarFgColor_; - - QColor bubbleBgColor_; - QColor bubbleFgColor_; -}; \ No newline at end of file diff --git a/src/dialogs/UserMentions.cpp b/src/popups/UserMentions.cpp similarity index 95% rename from src/dialogs/UserMentions.cpp rename to src/popups/UserMentions.cpp index f0874809..77e5260e 100644 --- a/src/dialogs/UserMentions.cpp +++ b/src/popups/UserMentions.cpp @@ -4,7 +4,7 @@ #include "UserMentions.h" #include "timeline/TimelineItem.h" -using namespace dialogs; +using namespace popups; UserMentions::UserMentions(QWidget *parent) : QWidget{parent} @@ -57,6 +57,13 @@ UserMentions::UserMentions(QWidget *parent) setLayout(top_layout_); } +void +UserMentions::initializeMentions(const std::map ¬ifs) +{ + Q_UNUSED(notifs); + // Very TODO: +} + void UserMentions::pushItem(const QString &event_id, const QString &user_id, diff --git a/src/dialogs/UserMentions.h b/src/popups/UserMentions.h similarity index 82% rename from src/dialogs/UserMentions.h rename to src/popups/UserMentions.h index 9b43dcfd..5dc475bf 100644 --- a/src/dialogs/UserMentions.h +++ b/src/popups/UserMentions.h @@ -1,12 +1,15 @@ #pragma once +#include + #include #include +#include #include #include #include -namespace dialogs { +namespace popups { class UserMentions : public QWidget { @@ -19,6 +22,8 @@ public: const QString &room_id, const QString ¤t_room_id); + void initializeMentions(const std::map ¬ifs); + private: QTabWidget *tab_layout_; QVBoxLayout *top_layout_;