From 208f9579118307d7749de9bf9be537bf1a1d2b27 Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris Date: Sat, 30 Dec 2017 17:29:57 +0200 Subject: [PATCH] Re-order room list based on activity fixes #2 --- include/ChatPage.h | 8 ++++- include/RoomInfoListItem.h | 1 + include/RoomList.h | 12 +++++++- include/UserSettingsPage.h | 16 +++++++++- src/ChatPage.cc | 8 +++-- src/MainWindow.cc | 2 +- src/RoomList.cc | 62 +++++++++++++++++++++++++++++++++++++- src/UserSettingsPage.cc | 32 ++++++++++++++------ 8 files changed, 125 insertions(+), 16 deletions(-) diff --git a/include/ChatPage.h b/include/ChatPage.h index 14d44ff3..24fc6a25 100644 --- a/include/ChatPage.h +++ b/include/ChatPage.h @@ -40,6 +40,7 @@ class TimelineViewManager; class TopRoomBar; class TypingDisplay; class UserInfoWidget; +class UserSettings; constexpr int CONSENSUS_TIMEOUT = 1000; constexpr int SHOW_CONTENT_TIMEOUT = 3000; @@ -50,7 +51,9 @@ class ChatPage : public QWidget Q_OBJECT public: - ChatPage(QSharedPointer client, QWidget *parent = 0); + ChatPage(QSharedPointer client, + QSharedPointer userSettings, + QWidget *parent = 0); ~ChatPage(); // Initialize all the components of the UI. @@ -150,6 +153,9 @@ private: // Matrix Client API provider. QSharedPointer client_; + // Global user settings. + QSharedPointer userSettings_; + // LMDB wrapper. QSharedPointer cache_; diff --git a/include/RoomInfoListItem.h b/include/RoomInfoListItem.h index bb8e0f1a..799e95bb 100644 --- a/include/RoomInfoListItem.h +++ b/include/RoomInfoListItem.h @@ -79,6 +79,7 @@ public: void setAvatar(const QImage &avatar_image); void setDescriptionMessage(const DescInfo &info); + DescInfo lastMessageInfo() const { return lastMsgInfo_; } QColor highlightedBackgroundColor() const { return highlightedBackgroundColor_; } QColor hoverBackgroundColor() const { return hoverBackgroundColor_; } diff --git a/include/RoomList.h b/include/RoomList.h index ed05e0be..6b2151a2 100644 --- a/include/RoomList.h +++ b/include/RoomList.h @@ -36,6 +36,7 @@ class RoomInfoListItem; class RoomSettings; class RoomState; class Sync; +class UserSettings; struct DescInfo; class RoomList : public QWidget @@ -43,7 +44,9 @@ class RoomList : public QWidget Q_OBJECT public: - RoomList(QSharedPointer client, QWidget *parent = 0); + RoomList(QSharedPointer client, + QSharedPointer userSettings, + QWidget *parent = 0); ~RoomList(); void setCache(QSharedPointer cache) { cache_ = cache; } @@ -81,6 +84,10 @@ public slots: protected: void paintEvent(QPaintEvent *event) override; + void leaveEvent(QEvent *event) override; + +private slots: + void sortRoomsByLastMessage(); private: void calculateUnreadMessageCount(); @@ -101,4 +108,7 @@ private: QSharedPointer client_; QSharedPointer cache_; + QSharedPointer userSettings_; + + bool isSortPending_ = false; }; diff --git a/include/UserSettingsPage.h b/include/UserSettingsPage.h index 99a149c6..adaa3956 100644 --- a/include/UserSettingsPage.h +++ b/include/UserSettingsPage.h @@ -38,14 +38,26 @@ public: void load(); void applyTheme(); void setTheme(QString theme); - void setTray(bool state); + void setTray(bool state) + { + isTrayEnabled_ = state; + save(); + }; + + void setRoomOrdering(bool state) + { + isOrderingEnabled_ = state; + save(); + }; QString theme() const { return !theme_.isEmpty() ? theme_ : "light"; } bool isTrayEnabled() const { return isTrayEnabled_; } + bool isOrderingEnabled() const { return isOrderingEnabled_; } private: QString theme_; bool isTrayEnabled_; + bool isOrderingEnabled_; }; class HorizontalLine : public QFrame @@ -84,6 +96,8 @@ private: QSharedPointer settings_; Toggle *trayToggle_; + Toggle *roomOrderToggle_; + QComboBox *themeCombo_; int sideMargin_ = 0; diff --git a/src/ChatPage.cc b/src/ChatPage.cc index 8abd651b..071fef71 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc @@ -37,15 +37,19 @@ #include "TopRoomBar.h" #include "TypingDisplay.h" #include "UserInfoWidget.h" +#include "UserSettingsPage.h" #include "timeline/TimelineViewManager.h" constexpr int MAX_INITIAL_SYNC_FAILURES = 5; constexpr int SYNC_RETRY_TIMEOUT = 10000; -ChatPage::ChatPage(QSharedPointer client, QWidget *parent) +ChatPage::ChatPage(QSharedPointer client, + QSharedPointer userSettings, + QWidget *parent) : QWidget(parent) , client_(client) + , userSettings_{userSettings} { setObjectName("chatPage"); @@ -74,7 +78,7 @@ ChatPage::ChatPage(QSharedPointer client, QWidget *parent) sidebarActions_, &SideBarActions::createRoom, client_.data(), &MatrixClient::createRoom); user_info_widget_ = new UserInfoWidget(sideBar_); - room_list_ = new RoomList(client, sideBar_); + room_list_ = new RoomList(client, userSettings_, sideBar_); sideBarLayout_->addWidget(user_info_widget_); sideBarLayout_->addWidget(room_list_); diff --git a/src/MainWindow.cc b/src/MainWindow.cc index 04b0e8e3..39f58dac 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -58,7 +58,7 @@ MainWindow::MainWindow(QWidget *parent) welcome_page_ = new WelcomePage(this); login_page_ = new LoginPage(client_, this); register_page_ = new RegisterPage(client_, this); - chat_page_ = new ChatPage(client_, this); + chat_page_ = new ChatPage(client_, userSettings_, this); userSettingsPage_ = new UserSettingsPage(userSettings_, this); // Initialize sliding widget manager. diff --git a/src/RoomList.cc b/src/RoomList.cc index ea13d700..a47c73a6 100644 --- a/src/RoomList.cc +++ b/src/RoomList.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include "Cache.h" #include "MainWindow.h" @@ -27,10 +28,14 @@ #include "RoomList.h" #include "RoomSettings.h" #include "RoomState.h" +#include "UserSettingsPage.h" -RoomList::RoomList(QSharedPointer client, QWidget *parent) +RoomList::RoomList(QSharedPointer client, + QSharedPointer userSettings, + QWidget *parent) : QWidget(parent) , client_(client) + , userSettings_{userSettings} { setStyleSheet("border: none;"); topLayout_ = new QVBoxLayout(this); @@ -291,6 +296,61 @@ RoomList::updateRoomDescription(const QString &roomid, const DescInfo &info) } rooms_.value(roomid)->setDescriptionMessage(info); + + if (underMouse()) { + // When the user hover out of the roomlist a sort will be triggered. + isSortPending_ = true; + return; + } + + isSortPending_ = false; + + emit sortRoomsByLastMessage(); +} + +void +RoomList::sortRoomsByLastMessage() +{ + if (!userSettings_->isOrderingEnabled()) + return; + + isSortPending_ = false; + + std::multimap> times; + + for (int ii = 0; ii < contentsLayout_->count(); ++ii) { + auto room = qobject_cast(contentsLayout_->itemAt(ii)->widget()); + + if (!room) + continue; + + // Not a room message. + if (room->lastMessageInfo().userid.isEmpty()) + times.emplace(0, room); + else + times.emplace(room->lastMessageInfo().datetime.toSecsSinceEpoch(), room); + } + + for (auto it = times.cbegin(); it != times.cend(); ++it) { + const auto roomWidget = it->second; + const auto currentIndex = contentsLayout_->indexOf(roomWidget); + const auto newIndex = std::distance(times.cbegin(), it); + + if (currentIndex == newIndex) + continue; + + contentsLayout_->removeWidget(roomWidget); + contentsLayout_->insertWidget(newIndex, roomWidget); + } +} + +void +RoomList::leaveEvent(QEvent *event) +{ + if (isSortPending_) + QTimer::singleShot(700, this, &RoomList::sortRoomsByLastMessage); + + QWidget::leaveEvent(event); } void diff --git a/src/UserSettingsPage.cc b/src/UserSettingsPage.cc index a5851c57..82cf23a7 100644 --- a/src/UserSettingsPage.cc +++ b/src/UserSettingsPage.cc @@ -33,8 +33,9 @@ void UserSettings::load() { QSettings settings; - isTrayEnabled_ = settings.value("user/window/tray", true).toBool(); - theme_ = settings.value("user/theme", "light").toString(); + isTrayEnabled_ = settings.value("user/window/tray", true).toBool(); + isOrderingEnabled_ = settings.value("user/room_ordering", true).toBool(); + theme_ = settings.value("user/theme", "light").toString(); applyTheme(); } @@ -47,12 +48,6 @@ UserSettings::setTheme(QString theme) applyTheme(); } -void -UserSettings::setTray(bool state) -{ - isTrayEnabled_ = state; - save(); -} void UserSettings::applyTheme() { @@ -86,6 +81,7 @@ UserSettings::save() settings.setValue("tray", isTrayEnabled_); settings.endGroup(); + settings.setValue("room_ordering", isOrderingEnabled_); settings.setValue("theme", theme()); settings.endGroup(); } @@ -132,6 +128,17 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge trayOptionLayout_->addWidget(trayLabel); trayOptionLayout_->addWidget(trayToggle_, 0, Qt::AlignBottom | Qt::AlignRight); + auto orderRoomLayout = new QHBoxLayout; + orderRoomLayout->setContentsMargins(0, OptionMargin, 0, OptionMargin); + auto orderLabel = new QLabel(tr("Re-order rooms based on activity"), this); + roomOrderToggle_ = new Toggle(this); + roomOrderToggle_->setActiveColor(QColor("#38A3D8")); + roomOrderToggle_->setInactiveColor(QColor("gray")); + orderLabel->setStyleSheet("font-size: 15px;"); + + orderRoomLayout->addWidget(orderLabel); + orderRoomLayout->addWidget(roomOrderToggle_, 0, Qt::AlignBottom | Qt::AlignRight); + auto themeOptionLayout_ = new QHBoxLayout; themeOptionLayout_->setContentsMargins(0, OptionMargin, 0, OptionMargin); auto themeLabel_ = new QLabel(tr("App theme"), this); @@ -155,6 +162,8 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge mainLayout_->addWidget(new HorizontalLine(this)); mainLayout_->addLayout(trayOptionLayout_); mainLayout_->addWidget(new HorizontalLine(this)); + mainLayout_->addLayout(orderRoomLayout); + mainLayout_->addWidget(new HorizontalLine(this)); mainLayout_->addLayout(themeOptionLayout_); mainLayout_->addWidget(new HorizontalLine(this)); @@ -171,6 +180,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer settings, QWidge emit trayOptionChanged(!isDisabled); }); + connect(roomOrderToggle_, &Toggle::toggled, this, [=](bool isDisabled) { + settings_->setRoomOrdering(!isDisabled); + }); + connect(backBtn_, &QPushButton::clicked, this, [=]() { settings_->save(); emit moveBack(); @@ -181,7 +194,8 @@ void UserSettingsPage::showEvent(QShowEvent *) { restoreThemeCombo(); - trayToggle_->setState(!settings_->isTrayEnabled()); // Treats true as "off" + trayToggle_->setState(!settings_->isTrayEnabled()); // Treats true as "off" + roomOrderToggle_->setState(!settings_->isOrderingEnabled()); // Treats true as "off" } void