diff --git a/resources/qml/RoomMembers.qml b/resources/qml/RoomMembers.qml
index d31fe3199c0f2ca2e79850a433913201ba469c0a..8060a6ccb3109f3e03cbfe325a39b547ba567c48 100644
--- a/resources/qml/RoomMembers.qml
+++ b/resources/qml/RoomMembers.qml
@@ -109,6 +109,13 @@ ApplicationWindow {
                         }
                     }
                 }
+
+                footer: BusyIndicator {
+                    // This is not a wonderful solution, but it is the best way to calculate whether
+                    // all users are loaded while keeping canFetchMore() const
+                    running: members.numUsersLoaded < members.memberCount
+                    anchors.centerIn: parent
+                }
             }
         }
     }
diff --git a/src/MemberList.cpp b/src/MemberList.cpp
index 2a9c3fbc8ef2eb8103cf68255a4f70473eff07aa..da4412d2321f066c4d4a4bdfd071b33953db8064 100644
--- a/src/MemberList.cpp
+++ b/src/MemberList.cpp
@@ -34,7 +34,10 @@ MemberList::MemberList(const QString &room_id, QWidget *parent)
         }
 
         try {
-                addUsers(cache::getMembers(room_id_.toStdString()));
+                auto members = cache::getMembers(room_id_.toStdString());
+                addUsers(members);
+                numUsersLoaded_ = members.size();
+                emit numUsersLoadedChanged();
         } catch (const lmdb::error &e) {
                 nhlog::db()->critical("Failed to retrieve members from cache: {}", e.what());
         }
@@ -83,11 +86,17 @@ bool
 MemberList::canFetchMore(const QModelIndex &) const
 {
         const size_t numMembers = rowCount();
-        return (numMembers > 1 && numMembers < info_.member_count);
+        if (numMembers > 1 && numMembers < info_.member_count)
+                return true;
+        else
+                return false;
 }
 
 void
 MemberList::fetchMore(const QModelIndex &)
 {
-        addUsers(cache::getMembers(room_id_.toStdString(), rowCount()));
+        auto members = cache::getMembers(room_id_.toStdString(), rowCount());
+        addUsers(members);
+        numUsersLoaded_ = members.size();
+        emit numUsersLoadedChanged();
 }
diff --git a/src/MemberList.h b/src/MemberList.h
index dbe69f4bf9049e458a63794928f6d6bcae8d1206..afc1a6e5ecc8466be39c191fe2eaab62427c212e 100644
--- a/src/MemberList.h
+++ b/src/MemberList.h
@@ -15,6 +15,7 @@ class MemberList : public QAbstractListModel
         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)
+        Q_PROPERTY(int numUsersLoaded READ numUsersLoaded NOTIFY numUsersLoadedChanged)
 
 public:
         enum Roles
@@ -37,12 +38,14 @@ public:
         size_t memberCount() const { return info_.member_count; }
         QString avatarUrl() const { return QString::fromStdString(info_.avatar_url); }
         QString roomId() const { return room_id_; }
+        int numUsersLoaded() const { return numUsersLoaded_; }
 
 signals:
         void roomNameChanged();
         void memberCountChanged();
         void avatarUrlChanged();
         void roomIdChanged();
+        void numUsersLoadedChanged();
 
 public slots:
         void addUsers(const std::vector<RoomMember> &users);
@@ -55,4 +58,5 @@ private:
         QVector<QPair<RoomMember, QString>> m_memberList;
         QString room_id_;
         RoomInfo info_;
+        int numUsersLoaded_;
 };