diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml
index 4db24f01cc8d16ad9217c8294df4112421a5aa30..cc36f00867e61291efb0127ae0af0e88ce7694da 100644
--- a/resources/qml/RoomDirectory.qml
+++ b/resources/qml/RoomDirectory.qml
@@ -132,9 +132,8 @@ ApplicationWindow {
                             Button {
                                 id: joinRoomButton
 
-                                visible: publicRooms.canJoinRoom(model.roomid)
+                                visible: model.canJoin
                                 anchors.centerIn: parent
-                                width: Math.ceil(0.1 * roomDirectoryWindow.width)
                                 text: "Join"
                                 onClicked: publicRooms.joinRoom(model.index)
                             }
diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp
index 61c3eb72b29e9dfb5002452052caa04ae4cbbb5d..14e0fe84c18281ec2cfa32db11714f825fb3d665 100644
--- a/src/RoomDirectoryModel.cpp
+++ b/src/RoomDirectoryModel.cpp
@@ -8,10 +8,23 @@
 
 #include <algorithm>
 
-RoomDirectoryModel::RoomDirectoryModel(QObject *parent, const std::string &s)
+RoomDirectoryModel::RoomDirectoryModel(QObject *parent, const std::string &server)
   : QAbstractListModel(parent)
-  , server_(s)
+  , server_(server)
 {
+        connect(ChatPage::instance(), &ChatPage::newRoom, this, [this](const QString &roomid) {
+                auto roomid_ = roomid.toStdString();
+
+                int i = 0;
+                for (const auto &room : publicRoomsData_) {
+                        if (room.room_id == roomid_) {
+                                emit dataChanged(index(i), index(i), {Roles::CanJoin});
+                                break;
+                        }
+                        i++;
+                }
+        });
+
         connect(this,
                 &RoomDirectoryModel::fetchedRoomsBatch,
                 this,
@@ -29,6 +42,7 @@ RoomDirectoryModel::roleNames() const
           {Roles::Topic, "topic"},
           {Roles::MemberCount, "numMembers"},
           {Roles::Previewable, "canPreview"},
+          {Roles::CanJoin, "canJoin"},
         };
 }
 
@@ -67,10 +81,9 @@ RoomDirectoryModel::setSearchTerm(const QString &f)
 }
 
 bool
-RoomDirectoryModel::canJoinRoom(const QByteArray &room)
+RoomDirectoryModel::canJoinRoom(const QString &room) const
 {
-        const QString room_id(room);
-        return !room_id.isEmpty() && !cache::getRoomInfo({room_id.toStdString()}).count(room_id);
+        return !room.isEmpty() && cache::getRoomInfo({room.toStdString()}).empty();
 }
 
 std::vector<std::string>
@@ -116,6 +129,8 @@ RoomDirectoryModel::data(const QModelIndex &index, int role) const
                         return QVariant::fromValue(room_chunk.num_joined_members);
                 case Roles::Previewable:
                         return QVariant::fromValue(room_chunk.world_readable);
+                case Roles::CanJoin:
+                        return canJoinRoom(QString::fromStdString(room_chunk.room_id));
                 }
         }
         return {};
diff --git a/src/RoomDirectoryModel.h b/src/RoomDirectoryModel.h
index 791384fabc4d3776d1d71f55351976eec7004cf8..0bec39434f08744ffe8f07c9c6c2189e4db23d88 100644
--- a/src/RoomDirectoryModel.h
+++ b/src/RoomDirectoryModel.h
@@ -32,7 +32,7 @@ class RoomDirectoryModel : public QAbstractListModel
                      reachedEndOfPaginationChanged)
 
 public:
-        explicit RoomDirectoryModel(QObject *parent = nullptr, const std::string &s = "");
+        explicit RoomDirectoryModel(QObject *parent = nullptr, const std::string &server = "");
 
         enum Roles
         {
@@ -41,7 +41,8 @@ public:
                 AvatarUrl,
                 Topic,
                 MemberCount,
-                Previewable
+                Previewable,
+                CanJoin,
         };
         QHash<int, QByteArray> roleNames() const override;
 
@@ -61,7 +62,6 @@ public:
 
         void fetchMore(const QModelIndex &) override;
 
-        Q_INVOKABLE bool canJoinRoom(const QByteArray &room);
         Q_INVOKABLE void joinRoom(const int &index = -1);
 
 signals:
@@ -80,6 +80,8 @@ private slots:
                           const std::string &next_batch);
 
 private:
+        bool canJoinRoom(const QString &room) const;
+
         static constexpr size_t limit_ = 50;
 
         std::string server_;
diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp
index f4c927acefc4f26bbc638781f7df5ee82bd075f8..942a4b05c61fa3aa6002fe4df436d5af8daa925c 100644
--- a/src/timeline/RoomlistModel.cpp
+++ b/src/timeline/RoomlistModel.cpp
@@ -379,6 +379,8 @@ RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification)
                 if (!suppressInsertNotification &&
                     ((!wasInvite && !wasPreview) || !previewedRooms.empty()))
                         endInsertRows();
+
+                emit ChatPage::instance()->newRoom(room_id);
         }
 }