diff --git a/src/Cache.cc b/src/Cache.cc
index 60181afc..92c86322 100644
--- a/src/Cache.cc
+++ b/src/Cache.cc
@@ -1045,6 +1045,48 @@ Cache::searchUsers(const std::string &room_id, const std::string &query, std::ui
return results;
}
+std::vector<RoomMember>
+Cache::getMembers(const std::string &room_id, std::size_t startIndex, std::size_t len)
+{
+ auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
+ auto db = getMembersDb(txn, room_id);
+ auto cursor = lmdb::cursor::open(txn, db);
+
+ std::size_t currentIndex = 0;
+
+ const auto endIndex = std::min(startIndex + len, db.size(txn));
+
+ std::vector<RoomMember> members;
+
+ std::string user_id, user_data;
+ while (cursor.get(user_id, user_data, MDB_NEXT)) {
+ if (currentIndex < startIndex) {
+ currentIndex += 1;
+ continue;
+ }
+
+ if (currentIndex >= endIndex)
+ break;
+
+ try {
+ MemberInfo tmp = json::parse(user_data);
+ members.emplace_back(
+ RoomMember{QString::fromStdString(user_id),
+ QString::fromStdString(tmp.name),
+ QImage::fromData(image(txn, tmp.avatar_url))});
+ } catch (const json::exception &e) {
+ qWarning() << e.what();
+ }
+
+ currentIndex += 1;
+ }
+
+ cursor.close();
+ txn.commit();
+
+ return members;
+}
+
QHash<QString, QString> Cache::DisplayNames;
QHash<QString, QString> Cache::AvatarUrls;
diff --git a/src/MainWindow.cc b/src/MainWindow.cc
index 66f956a5..c2353a11 100644
--- a/src/MainWindow.cc
+++ b/src/MainWindow.cc
@@ -41,6 +41,7 @@
#include "dialogs/JoinRoom.h"
#include "dialogs/LeaveRoom.h"
#include "dialogs/Logout.h"
+#include "dialogs/MemberList.hpp"
#include "dialogs/RoomSettings.hpp"
MainWindow *MainWindow::instance_ = nullptr;
@@ -268,8 +269,6 @@ MainWindow::openRoomSettings(const QString &room_id)
{
const auto roomToSearch = room_id.isEmpty() ? chat_page_->currentRoom() : "";
- qDebug() << "room settings" << roomToSearch;
-
roomSettingsDialog_ = QSharedPointer<dialogs::RoomSettings>(
new dialogs::RoomSettings(roomToSearch, chat_page_->cache(), this));
@@ -279,12 +278,25 @@ MainWindow::openRoomSettings(const QString &room_id)
roomSettingsModal_ =
QSharedPointer<OverlayModal>(new OverlayModal(this, roomSettingsDialog_.data()));
- roomSettingsModal_->setColor(QColor(30, 30, 30, 170));
roomSettingsModal_->show();
}
void
+MainWindow::openMemberListDialog(const QString &room_id)
+{
+ const auto roomToSearch = room_id.isEmpty() ? chat_page_->currentRoom() : "";
+
+ memberListDialog_ = QSharedPointer<dialogs::MemberList>(
+ new dialogs::MemberList(roomToSearch, chat_page_->cache(), this));
+
+ memberListModal_ =
+ QSharedPointer<OverlayModal>(new OverlayModal(this, memberListDialog_.data()));
+
+ memberListModal_->show();
+}
+
+void
MainWindow::openLeaveRoomDialog(const QString &room_id)
{
auto roomToLeave = room_id.isEmpty() ? chat_page_->currentRoom() : room_id;
@@ -325,6 +337,7 @@ MainWindow::showOverlayProgressBar()
progressModal_ =
QSharedPointer<OverlayModal>(new OverlayModal(this, spinner_.data()),
[](OverlayModal *modal) { modal->deleteLater(); });
+ progressModal_->setColor(QColor(30, 30, 30));
progressModal_->setDismissible(false);
progressModal_->show();
}
@@ -377,7 +390,6 @@ MainWindow::openJoinRoomDialog(std::function<void(const QString &room_id)> callb
if (joinRoomModal_.isNull()) {
joinRoomModal_ = QSharedPointer<OverlayModal>(
new OverlayModal(MainWindow::instance(), joinRoomDialog_.data()));
- joinRoomModal_->setColor(QColor(30, 30, 30, 170));
}
joinRoomModal_->show();
@@ -406,7 +418,6 @@ MainWindow::openCreateRoomDialog(
if (createRoomModal_.isNull()) {
createRoomModal_ = QSharedPointer<OverlayModal>(
new OverlayModal(MainWindow::instance(), createRoomDialog_.data()));
- createRoomModal_->setColor(QColor(30, 30, 30, 170));
}
createRoomModal_->show();
@@ -431,7 +442,6 @@ MainWindow::openLogoutDialog(std::function<void()> callback)
if (logoutModal_.isNull()) {
logoutModal_ = QSharedPointer<OverlayModal>(
new OverlayModal(MainWindow::instance(), logoutDialog_.data()));
- logoutModal_->setColor(QColor(30, 30, 30, 170));
}
logoutModal_->show();
diff --git a/src/TopRoomBar.cc b/src/TopRoomBar.cc
index beca1d51..7338cfb1 100644
--- a/src/TopRoomBar.cc
+++ b/src/TopRoomBar.cc
@@ -90,6 +90,11 @@ TopRoomBar::TopRoomBar(QWidget *parent)
[this](const QStringList &invitees) { emit inviteUsers(invitees); });
});
+ roomMembers_ = new QAction(tr("Members"), this);
+ connect(roomMembers_, &QAction::triggered, this, []() {
+ MainWindow::instance()->openMemberListDialog();
+ });
+
leaveRoom_ = new QAction(tr("Leave room"), this);
connect(leaveRoom_, &QAction::triggered, this, []() {
MainWindow::instance()->openLeaveRoomDialog();
@@ -101,6 +106,7 @@ TopRoomBar::TopRoomBar(QWidget *parent)
});
menu_->addAction(inviteUsers_);
+ menu_->addAction(roomMembers_);
menu_->addAction(leaveRoom_);
menu_->addAction(roomSettings_);
diff --git a/src/dialogs/MemberList.cpp b/src/dialogs/MemberList.cpp
new file mode 100644
index 00000000..26f526dd
--- /dev/null
+++ b/src/dialogs/MemberList.cpp
@@ -0,0 +1,145 @@
+#include <QListWidgetItem>
+#include <QPainter>
+#include <QStyleOption>
+#include <QVBoxLayout>
+
+#include "Config.h"
+#include "FlatButton.h"
+#include "Utils.h"
+
+#include "Avatar.h"
+#include "Cache.h"
+#include "dialogs/MemberList.hpp"
+
+using namespace dialogs;
+
+MemberItem::MemberItem(const RoomMember &member, QWidget *parent)
+ : QWidget(parent)
+{
+ topLayout_ = new QHBoxLayout(this);
+ topLayout_->setMargin(0);
+
+ textLayout_ = new QVBoxLayout;
+ textLayout_->setMargin(0);
+ textLayout_->setSpacing(0);
+
+ avatar_ = new Avatar(this);
+ avatar_->setSize(44);
+ avatar_->setLetter(utils::firstChar(member.display_name));
+
+ if (!member.avatar.isNull())
+ avatar_->setImage(member.avatar);
+
+ QFont nameFont, idFont;
+ nameFont.setWeight(65);
+ nameFont.setPixelSize(conf::receipts::font + 1);
+ idFont.setWeight(50);
+ idFont.setPixelSize(conf::receipts::font);
+
+ userName_ = new QLabel(member.display_name, this);
+ userName_->setFont(nameFont);
+
+ userId_ = new QLabel(member.user_id, this);
+ userId_->setFont(idFont);
+
+ textLayout_->addWidget(userName_);
+ textLayout_->addWidget(userId_);
+
+ topLayout_->addWidget(avatar_);
+ topLayout_->addLayout(textLayout_, 1);
+}
+
+MemberList::MemberList(const QString &room_id, QSharedPointer<Cache> cache, QWidget *parent)
+ : QFrame(parent)
+ , room_id_{room_id}
+ , cache_{cache}
+{
+ setMaximumSize(420, 380);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ auto layout = new QVBoxLayout(this);
+ layout->setSpacing(30);
+ layout->setMargin(20);
+
+ list_ = new QListWidget;
+ list_->setFrameStyle(QFrame::NoFrame);
+ list_->setSelectionMode(QAbstractItemView::NoSelection);
+ list_->setAttribute(Qt::WA_MacShowFocusRect, 0);
+ list_->setSpacing(5);
+
+ QFont font;
+ font.setPixelSize(conf::headerFontSize);
+
+ topLabel_ = new QLabel(tr("Room members"), this);
+ topLabel_->setAlignment(Qt::AlignCenter);
+ topLabel_->setFont(font);
+
+ layout->addWidget(topLabel_);
+ layout->addWidget(list_);
+
+ list_->clear();
+
+ // Add button at the bottom.
+ moreBtn_ = new FlatButton(tr("SHOW MORE"), this);
+ auto item = new QListWidgetItem;
+ item->setSizeHint(moreBtn_->minimumSizeHint());
+ item->setFlags(Qt::NoItemFlags);
+ item->setTextAlignment(Qt::AlignCenter);
+ list_->insertItem(0, item);
+ list_->setItemWidget(item, moreBtn_);
+
+ connect(moreBtn_, &FlatButton::clicked, this, [this]() {
+ const size_t numMembers = list_->count() - 1;
+
+ if (numMembers > 0)
+ addUsers(cache_->getMembers(room_id_.toStdString(), numMembers));
+ });
+
+ try {
+ addUsers(cache_->getMembers(room_id_.toStdString()));
+ } catch (const lmdb::error &e) {
+ qCritical() << e.what();
+ }
+}
+
+void
+MemberList::moveButtonToBottom()
+{
+ auto item = new QListWidgetItem(list_);
+ item->setSizeHint(moreBtn_->minimumSizeHint());
+ item->setFlags(Qt::NoItemFlags);
+ item->setTextAlignment(Qt::AlignCenter);
+ list_->setItemWidget(item, moreBtn_);
+ list_->addItem(item);
+}
+
+void
+MemberList::addUsers(const std::vector<RoomMember> &members)
+{
+ if (members.size() == 0) {
+ moreBtn_->hide();
+ } else {
+ moreBtn_->show();
+ }
+
+ for (const auto &member : members) {
+ auto user = new MemberItem(member, this);
+ auto item = new QListWidgetItem;
+
+ item->setSizeHint(user->minimumSizeHint());
+ item->setFlags(Qt::NoItemFlags);
+ item->setTextAlignment(Qt::AlignCenter);
+
+ list_->insertItem(list_->count() - 1, item);
+ list_->setItemWidget(item, user);
+ }
+}
+
+void
+MemberList::paintEvent(QPaintEvent *)
+{
+ QStyleOption opt;
+ opt.init(this);
+ QPainter p(this);
+ style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
+}
diff --git a/src/dialogs/RoomSettings.cpp b/src/dialogs/RoomSettings.cpp
index 8fcbc82f..b2c87c94 100644
--- a/src/dialogs/RoomSettings.cpp
+++ b/src/dialogs/RoomSettings.cpp
@@ -49,18 +49,20 @@ RoomSettings::RoomSettings(const QString &room_id, QSharedPointer<Cache> cache,
auto notifOptionLayout_ = new QHBoxLayout;
notifOptionLayout_->setMargin(5);
- auto themeLabel_ = new QLabel(tr("Notifications"), this);
- auto notifCombo = new QComboBox(this);
- notifCombo->addItem("Nothing");
- notifCombo->addItem("Mentions only");
- notifCombo->addItem("All messages");
- themeLabel_->setStyleSheet("font-size: 15px;");
+ auto notifLabel = new QLabel(tr("Notifications"), this);
+ auto notifCombo = new QComboBox(this);
+ notifCombo->setDisabled(true);
+ notifCombo->addItem(tr("Muted"));
+ notifCombo->addItem(tr("Mentions only"));
+ notifCombo->addItem(tr("All messages"));
+ notifLabel->setStyleSheet("font-size: 15px;");
- notifOptionLayout_->addWidget(themeLabel_);
+ notifOptionLayout_->addWidget(notifLabel);
notifOptionLayout_->addWidget(notifCombo, 0, Qt::AlignBottom | Qt::AlignRight);
layout->addWidget(new TopSection(info_, avatarImg_, this));
layout->addLayout(notifOptionLayout_);
+ layout->addLayout(notifOptionLayout_);
layout->addLayout(btnLayout);
connect(cancelBtn_, &FlatButton::clicked, this, &RoomSettings::closing);
diff --git a/src/ui/OverlayModal.cc b/src/ui/OverlayModal.cc
index 4b0747a1..6aa16b07 100644
--- a/src/ui/OverlayModal.cc
+++ b/src/ui/OverlayModal.cc
@@ -23,7 +23,7 @@
OverlayModal::OverlayModal(QWidget *parent, QWidget *content)
: OverlayWidget(parent)
, content_{content}
- , color_{QColor(55, 55, 55)}
+ , color_{QColor(30, 30, 30, 170)}
{
auto layout = new QVBoxLayout();
layout->addWidget(content);
|