summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--resources/qml/RoomMembers.qml111
-rw-r--r--resources/qml/TopBar.qml2
-rw-r--r--resources/res.qrc1
-rw-r--r--src/MainWindow.cpp10
-rw-r--r--src/MainWindow.h1
-rw-r--r--src/MemberList.cpp91
-rw-r--r--src/MemberList.h58
-rw-r--r--src/dialogs/MemberList.cpp146
-rw-r--r--src/dialogs/MemberList.h57
-rw-r--r--src/main.cpp3
-rw-r--r--src/timeline/TimelineModel.cpp12
-rw-r--r--src/timeline/TimelineModel.h5
-rw-r--r--src/timeline/TimelineViewManager.cpp7
-rw-r--r--src/timeline/TimelineViewManager.h1
15 files changed, 284 insertions, 225 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6b26b2e5..84f52766 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -285,7 +285,6 @@ set(SRC_FILES
 	src/dialogs/JoinRoom.cpp
 	src/dialogs/LeaveRoom.cpp
 	src/dialogs/Logout.cpp
-	src/dialogs/MemberList.cpp
 	src/dialogs/PreviewUploadOverlay.cpp
 	src/dialogs/ReCaptcha.cpp
 	src/dialogs/ReadReceipts.cpp
@@ -351,6 +350,7 @@ set(SRC_FILES
 	src/LoginPage.cpp
 	src/MainWindow.cpp
 	src/MatrixClient.cpp
+	src/MemberList.cpp
 	src/MxcImageProvider.cpp
 	src/Olm.cpp
 	src/RegisterPage.cpp
@@ -496,7 +496,6 @@ qt5_wrap_cpp(MOC_HEADERS
 	src/dialogs/JoinRoom.h
 	src/dialogs/LeaveRoom.h
 	src/dialogs/Logout.h
-	src/dialogs/MemberList.h
 	src/dialogs/PreviewUploadOverlay.h
 	src/dialogs/RawMessage.h
 	src/dialogs/ReCaptcha.h
@@ -557,6 +556,7 @@ qt5_wrap_cpp(MOC_HEADERS
 	src/InviteeItem.h
 	src/LoginPage.h
 	src/MainWindow.h
+	src/MemberList.h
 	src/MxcImageProvider.h
 	src/RegisterPage.h
 	src/SSOHandler.h
diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml
new file mode 100644
index 00000000..4406c1b0
--- /dev/null
+++ b/resources/qml/RoomMembers.qml
@@ -0,0 +1,111 @@
+import QtQuick 2.12
+import QtQuick.Controls 2.12
+import QtQuick.Layouts 1.12
+import QtQuick.Window 2.12
+import im.nheko 1.0
+
+ApplicationWindow {
+    id: roomMembersRoot
+
+    property string roomName: Rooms.currentRoom.roomName
+    property MemberList members
+
+    title: qsTr("Members of ") + roomName
+    x: MainWindow.x + (MainWindow.width / 2) - (width / 2)
+    y: MainWindow.y + (MainWindow.height / 2) - (height / 2)
+    height: 650
+    width: 420
+    minimumHeight: 420
+
+    Shortcut {
+        sequence: StandardKey.Cancel
+        onActivated: roomMembersRoot.close()
+    }
+
+    ColumnLayout {
+        anchors.fill: parent
+        anchors.margins: 10
+        spacing: 10
+
+        Avatar {
+            id: roomAvatar
+
+            width: 130
+            height: width
+            displayName: members.roomName
+            Layout.alignment: Qt.AlignHCenter
+            url: members.avatarUrl.replace("mxc://", "image://MxcImage/")
+            onClicked: TimelineManager.timeline.openRoomSettings(members.roomId)
+        }
+
+        Label {
+            font.pixelSize: 24
+            text: members.memberCount + (members.memberCount === 1 ? qsTr(" person in ") : qsTr(" people in ")) + roomName
+            Layout.alignment: Qt.AlignHCenter
+        }
+
+        ScrollView {
+            clip: false
+            palette: colors
+            padding: 10
+            ScrollBar.horizontal.visible: false
+            Layout.fillHeight: true
+            Layout.minimumHeight: 200
+            Layout.fillWidth: true
+
+            ListView {
+                id: memberList
+
+                clip: true
+                spacing: 8
+                boundsBehavior: Flickable.StopAtBounds
+                model: members
+
+                ScrollHelper {
+                    flickable: parent
+                    anchors.fill: parent
+                    enabled: !Settings.mobileMode
+                }
+
+                delegate: RowLayout {
+                    spacing: 10
+
+                    Avatar {
+                        width: avatarSize
+                        height: avatarSize
+                        userid: model.mxid
+                        url: model.avatarUrl.replace("mxc://", "image://MxcImage/")
+                        displayName: model.displayName
+                        onClicked: TimelineManager.timeline.openUserProfile(model.mxid)
+                    }
+
+                    ColumnLayout {
+                        spacing: 5
+
+                        Label {
+                            text: model.displayName
+                            color: TimelineManager.userColor(model ? model.mxid : "", colors.window)
+                            font.pointSize: 12
+                        }
+
+                        Label {
+                            text: model.mxid
+                            color: colors.buttonText
+                            font.pointSize: 10
+                        }
+
+                        Item {
+                            Layout.fillHeight: true
+                            Layout.fillWidth: true
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    footer: DialogButtonBox {
+        standardButtons: DialogButtonBox.Ok
+        onAccepted: roomMembersRoot.close()
+    }
+}
diff --git a/resources/qml/TopBar.qml b/resources/qml/TopBar.qml
index 58aba0c7..50c2447c 100644
--- a/resources/qml/TopBar.qml
+++ b/resources/qml/TopBar.qml
@@ -116,7 +116,7 @@ Rectangle {
 
                 Platform.MenuItem {
                     text: qsTr("Members")
-                    onTriggered: TimelineManager.openMemberListDialog(room.roomId())
+                    onTriggered: Rooms.currentRoom.openRoomMembers(room.roomId())
                 }
 
                 Platform.MenuItem {
diff --git a/resources/res.qrc b/resources/res.qrc
index e9479e57..da5288c8 100644
--- a/resources/res.qrc
+++ b/resources/res.qrc
@@ -185,6 +185,7 @@
         <file>qml/components/AdaptiveLayout.qml</file>
         <file>qml/components/AdaptiveLayoutElement.qml</file>
         <file>qml/components/FlatButton.qml</file>
+        <file>qml/RoomMembers.qml</file>
     </qresource>
     <qresource prefix="/media">
         <file>media/ring.ogg</file>
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index ed337ca4..36bada83 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -21,6 +21,7 @@
 #include "LoginPage.h"
 #include "MainWindow.h"
 #include "MatrixClient.h"
+#include "MemberList.h"
 #include "RegisterPage.h"
 #include "TrayIcon.h"
 #include "UserSettingsPage.h"
@@ -36,7 +37,6 @@
 #include "dialogs/JoinRoom.h"
 #include "dialogs/LeaveRoom.h"
 #include "dialogs/Logout.h"
-#include "dialogs/MemberList.h"
 #include "dialogs/ReadReceipts.h"
 
 MainWindow *MainWindow::instance_ = nullptr;
@@ -311,14 +311,6 @@ MainWindow::hasActiveUser()
 }
 
 void
-MainWindow::openMemberListDialog(const QString &room_id)
-{
-        auto dialog = new dialogs::MemberList(room_id, this);
-
-        showDialog(dialog);
-}
-
-void
 MainWindow::openLeaveRoomDialog(const QString &room_id)
 {
         auto dialog = new dialogs::LeaveRoom(this);
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 3571f079..6d62545c 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -65,7 +65,6 @@ public:
           std::function<void(const mtx::requests::CreateRoom &request)> callback);
         void openJoinRoomDialog(std::function<void(const QString &room_id)> callback);
         void openLogoutDialog();
-        void openMemberListDialog(const QString &room_id);
         void openReadReceiptsDialog(const QString &event_id);
 
         void hideOverlay();
diff --git a/src/MemberList.cpp b/src/MemberList.cpp
new file mode 100644
index 00000000..62488277
--- /dev/null
+++ b/src/MemberList.cpp
@@ -0,0 +1,91 @@
+// SPDX-FileCopyrightText: 2021 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include <QAbstractSlider>
+#include <QLabel>
+#include <QListWidgetItem>
+#include <QPainter>
+#include <QPushButton>
+#include <QScrollBar>
+#include <QShortcut>
+#include <QStyleOption>
+#include <QVBoxLayout>
+
+#include "MemberList.h"
+
+#include "Cache.h"
+#include "ChatPage.h"
+#include "Config.h"
+#include "Logging.h"
+#include "Utils.h"
+#include "timeline/TimelineViewManager.h"
+#include "ui/Avatar.h"
+
+MemberList::MemberList(const QString &room_id, QWidget *parent)
+  : QAbstractListModel{parent}
+  , room_id_{room_id}
+{
+        try {
+                info_ = cache::singleRoomInfo(room_id_.toStdString());
+        } catch (const lmdb::error &) {
+                nhlog::db()->warn("failed to retrieve room info from cache: {}",
+                                  room_id_.toStdString());
+        }
+
+        try {
+                addUsers(cache::getMembers(room_id_.toStdString()));
+        } catch (const lmdb::error &e) {
+                nhlog::db()->critical("Failed to retrieve members from cache: {}", e.what());
+        }
+}
+
+void
+MemberList::addUsers(const std::vector<RoomMember> &members)
+{
+        beginInsertRows(QModelIndex{}, m_memberList.count(), m_memberList.count() + members.size() - 1);
+
+        for (const auto &member : members)
+                m_memberList.push_back(
+                  {member,
+                   ChatPage::instance()->timelineManager()->rooms()->currentRoom()->avatarUrl(
+                     member.user_id)});
+
+        endInsertRows();
+}
+
+QHash<int, QByteArray>
+MemberList::roleNames() const
+{
+        return {{Mxid, "mxid"}, {DisplayName, "displayName"}, {AvatarUrl, "avatarUrl"}};
+}
+
+QVariant
+MemberList::data(const QModelIndex &index, int role) const
+{
+        if (!index.isValid() || index.row() >= (int)m_memberList.size() || index.row() < 0)
+                return {};
+
+        switch (role) {
+        case Mxid:
+                return m_memberList[index.row()].first.user_id;
+        case DisplayName:
+                return m_memberList[index.row()].first.display_name;
+        case AvatarUrl:
+                return m_memberList[index.row()].second;
+        default:
+                return {};
+        }
+}
+
+bool MemberList::canFetchMore(const QModelIndex &) const
+{
+    const size_t numMembers = rowCount();
+    return (numMembers > 1 && numMembers < info_.member_count);
+}
+
+void
+MemberList::fetchMore(const QModelIndex &)
+{
+        addUsers(cache::getMembers(room_id_.toStdString(), rowCount()));
+}
diff --git a/src/MemberList.h b/src/MemberList.h
new file mode 100644
index 00000000..dbe69f4b
--- /dev/null
+++ b/src/MemberList.h
@@ -0,0 +1,58 @@
+// SPDX-FileCopyrightText: 2021 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "CacheStructs.h"
+#include <QAbstractListModel>
+
+class MemberList : public QAbstractListModel
+{
+        Q_OBJECT
+
+        Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged)
+        Q_PROPERTY(size_t memberCount READ memberCount NOTIFY memberCountChanged)
+        Q_PROPERTY(QString avatarUrl READ avatarUrl NOTIFY avatarUrlChanged)
+        Q_PROPERTY(QString roomId READ roomId NOTIFY roomIdChanged)
+
+public:
+        enum Roles
+        {
+                Mxid,
+                DisplayName,
+                AvatarUrl,
+        };
+        MemberList(const QString &room_id, QWidget *parent = nullptr);
+
+        QHash<int, QByteArray> roleNames() const override;
+        int rowCount(const QModelIndex &parent = QModelIndex()) const override
+        {
+                Q_UNUSED(parent)
+                return static_cast<int>(m_memberList.size());
+        }
+        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+
+        QString roomName() const { return QString::fromStdString(info_.name); }
+        size_t memberCount() const { return info_.member_count; }
+        QString avatarUrl() const { return QString::fromStdString(info_.avatar_url); }
+        QString roomId() const { return room_id_; }
+
+signals:
+        void roomNameChanged();
+        void memberCountChanged();
+        void avatarUrlChanged();
+        void roomIdChanged();
+
+public slots:
+        void addUsers(const std::vector<RoomMember> &users);
+
+protected:
+        bool canFetchMore(const QModelIndex &) const;
+        void fetchMore(const QModelIndex &);
+
+private:
+        QVector<QPair<RoomMember, QString>> m_memberList;
+        QString room_id_;
+        RoomInfo info_;
+};
diff --git a/src/dialogs/MemberList.cpp b/src/dialogs/MemberList.cpp
deleted file mode 100644
index 21eb72b0..00000000
--- a/src/dialogs/MemberList.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-// SPDX-FileCopyrightText: 2021 Nheko Contributors
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include <QAbstractSlider>
-#include <QLabel>
-#include <QListWidgetItem>
-#include <QPainter>
-#include <QPushButton>
-#include <QScrollBar>
-#include <QShortcut>
-#include <QStyleOption>
-#include <QVBoxLayout>
-
-#include "dialogs/MemberList.h"
-
-#include "Cache.h"
-#include "ChatPage.h"
-#include "Config.h"
-#include "Logging.h"
-#include "Utils.h"
-#include "ui/Avatar.h"
-
-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, 44);
-        avatar_->setLetter(utils::firstChar(member.display_name));
-
-        avatar_->setImage(ChatPage::instance()->currentRoom(), member.user_id);
-
-        QFont nameFont;
-        nameFont.setPointSizeF(nameFont.pointSizeF() * 1.1);
-
-        userId_   = new QLabel(member.user_id, this);
-        userName_ = new QLabel(member.display_name, this);
-        userName_->setFont(nameFont);
-
-        textLayout_->addWidget(userName_);
-        textLayout_->addWidget(userId_);
-
-        topLayout_->addWidget(avatar_);
-        topLayout_->addLayout(textLayout_, 1);
-}
-
-void
-MemberItem::paintEvent(QPaintEvent *)
-{
-        QStyleOption opt;
-        opt.init(this);
-        QPainter p(this);
-        style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
-}
-
-MemberList::MemberList(const QString &room_id, QWidget *parent)
-  : QFrame(parent)
-  , room_id_{room_id}
-{
-        setAutoFillBackground(true);
-        setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
-        setWindowModality(Qt::WindowModal);
-        setAttribute(Qt::WA_DeleteOnClose, true);
-
-        auto layout = new QVBoxLayout(this);
-        layout->setSpacing(conf::modals::WIDGET_SPACING);
-        layout->setMargin(conf::modals::WIDGET_MARGIN);
-
-        list_ = new QListWidget;
-        list_->setFrameStyle(QFrame::NoFrame);
-        list_->setSelectionMode(QAbstractItemView::NoSelection);
-        list_->setSpacing(5);
-
-        QFont largeFont;
-        largeFont.setPointSizeF(largeFont.pointSizeF() * 1.5);
-
-        setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
-        setMinimumHeight(list_->sizeHint().height() * 2);
-        setMinimumWidth(std::max(list_->sizeHint().width() + 4 * conf::modals::WIDGET_MARGIN,
-                                 QFontMetrics(largeFont).averageCharWidth() * 30 -
-                                   2 * conf::modals::WIDGET_MARGIN));
-
-        QFont font;
-        font.setPointSizeF(font.pointSizeF() * conf::modals::LABEL_MEDIUM_SIZE_RATIO);
-
-        topLabel_ = new QLabel(tr("Room members"), this);
-        topLabel_->setAlignment(Qt::AlignCenter);
-        topLabel_->setFont(font);
-
-        auto okBtn = new QPushButton(tr("OK"), this);
-
-        auto buttonLayout = new QHBoxLayout();
-        buttonLayout->setSpacing(15);
-        buttonLayout->addStretch(1);
-        buttonLayout->addWidget(okBtn);
-
-        layout->addWidget(topLabel_);
-        layout->addWidget(list_);
-        layout->addLayout(buttonLayout);
-
-        list_->clear();
-
-        connect(list_->verticalScrollBar(), &QAbstractSlider::valueChanged, this, [this](int pos) {
-                if (pos != list_->verticalScrollBar()->maximum())
-                        return;
-
-                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) {
-                nhlog::db()->critical("Failed to retrieve members from cache: {}", e.what());
-        }
-
-        auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this);
-        connect(closeShortcut, &QShortcut::activated, this, &MemberList::close);
-        connect(okBtn, &QPushButton::clicked, this, &MemberList::close);
-}
-
-void
-MemberList::addUsers(const std::vector<RoomMember> &members)
-{
-        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);
-        }
-}
diff --git a/src/dialogs/MemberList.h b/src/dialogs/MemberList.h
deleted file mode 100644
index b822eec8..00000000
--- a/src/dialogs/MemberList.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-FileCopyrightText: 2021 Nheko Contributors
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include <QFrame>
-#include <QListWidget>
-
-class Avatar;
-class QPushButton;
-class QHBoxLayout;
-class QLabel;
-class QVBoxLayout;
-
-struct RoomMember;
-
-template<class T>
-class QSharedPointer;
-
-namespace dialogs {
-
-class MemberItem : public QWidget
-{
-        Q_OBJECT
-
-public:
-        MemberItem(const RoomMember &member, QWidget *parent);
-
-protected:
-        void paintEvent(QPaintEvent *) override;
-
-private:
-        QHBoxLayout *topLayout_;
-        QVBoxLayout *textLayout_;
-
-        Avatar *avatar_;
-
-        QLabel *userName_;
-        QLabel *userId_;
-};
-
-class MemberList : public QFrame
-{
-        Q_OBJECT
-public:
-        MemberList(const QString &room_id, QWidget *parent = nullptr);
-
-public slots:
-        void addUsers(const std::vector<RoomMember> &users);
-
-private:
-        QString room_id_;
-        QLabel *topLabel_;
-        QListWidget *list_;
-};
-} // dialogs
diff --git a/src/main.cpp b/src/main.cpp
index 29e93d49..376fc4f5 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -205,6 +205,9 @@ main(int argc, char *argv[])
 
         parser.process(app);
 
+        // make sure that size_t properties will work
+        qRegisterMetaType<size_t>("size_t");
+
         app.setWindowIcon(QIcon::fromTheme("nheko", QIcon{":/logos/nheko.png"}));
 
         http::init();
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 7b3f0729..48d69493 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -25,6 +25,7 @@
 #include "Logging.h"
 #include "MainWindow.h"
 #include "MatrixClient.h"
+#include "MemberList.h"
 #include "MxcImageProvider.h"
 #include "Olm.h"
 #include "TimelineViewManager.h"
@@ -1061,9 +1062,16 @@ TimelineModel::openUserProfile(QString userid)
 }
 
 void
-TimelineModel::openRoomSettings()
+TimelineModel::openRoomMembers()
 {
-        RoomSettings *settings = new RoomSettings(roomId(), this);
+        MemberList *memberList = new MemberList(roomId());
+        emit openRoomMembersDialog(memberList);
+}
+
+void
+TimelineModel::openRoomSettings(QString room_id)
+{
+        RoomSettings *settings = new RoomSettings(room_id == QString() ? roomId() : room_id, this);
         connect(this, &TimelineModel::roomAvatarUrlChanged, settings, &RoomSettings::avatarChanged);
         openRoomSettingsDialog(settings);
 }
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index 3c80ade8..feb7b5f5 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -17,6 +17,7 @@
 #include "CacheStructs.h"
 #include "EventStore.h"
 #include "InputBar.h"
+#include "MemberList.h"
 #include "Permissions.h"
 #include "ui/RoomSettings.h"
 #include "ui/UserProfile.h"
@@ -235,7 +236,8 @@ public:
         Q_INVOKABLE void forwardMessage(QString eventId, QString roomId);
         Q_INVOKABLE void viewDecryptedRawMessage(QString id) const;
         Q_INVOKABLE void openUserProfile(QString userid);
-        Q_INVOKABLE void openRoomSettings();
+        Q_INVOKABLE void openRoomMembers();
+        Q_INVOKABLE void openRoomSettings(QString room_id = QString());
         Q_INVOKABLE void editAction(QString id);
         Q_INVOKABLE void replyAction(QString id);
         Q_INVOKABLE void readReceiptsAction(QString id) const;
@@ -352,6 +354,7 @@ signals:
         void lastMessageChanged();
         void notificationsChanged();
 
+        void openRoomMembersDialog(MemberList *members);
         void openRoomSettingsDialog(RoomSettings *settings);
 
         void newMessageToSend(mtx::events::collections::TimelineEvents event);
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 3e69f92b..011ff61c 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -174,6 +174,8 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
           0,
           "UserProfileModel",
           "UserProfile needs to be instantiated on the C++ side");
+        qmlRegisterUncreatableType<MemberList>(
+          "im.nheko", 1, 0, "MemberList", "MemberList needs to be instantiated on the C++ side");
         qmlRegisterUncreatableType<RoomSettings>(
           "im.nheko",
           1,
@@ -428,11 +430,6 @@ TimelineViewManager::openInviteUsersDialog()
           [this](const QStringList &invitees) { emit inviteUsers(invitees); });
 }
 void
-TimelineViewManager::openMemberListDialog(QString roomid) const
-{
-        MainWindow::instance()->openMemberListDialog(roomid);
-}
-void
 TimelineViewManager::openLeaveRoomDialog(QString roomid) const
 {
         MainWindow::instance()->openLeaveRoomDialog(roomid);
diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index 15b4f523..39d0d31c 100644
--- a/src/timeline/TimelineViewManager.h
+++ b/src/timeline/TimelineViewManager.h
@@ -66,7 +66,6 @@ public:
 
         Q_INVOKABLE void focusMessageInput();
         Q_INVOKABLE void openInviteUsersDialog();
-        Q_INVOKABLE void openMemberListDialog(QString roomid) const;
         Q_INVOKABLE void openLeaveRoomDialog(QString roomid) const;
         Q_INVOKABLE void removeVerificationFlow(DeviceVerificationFlow *flow);