diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7594d22b39a4df685abb27f6d3a228de6bbc190e..5f822ac1f58732d7a27e5d29a14667521564c400 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -309,7 +309,6 @@ configure_file(cmake/nheko.h config/nheko.h)
 #
 set(SRC_FILES
 	# Dialogs
-	src/dialogs/CreateRoom.cpp
 	src/dialogs/FallbackAuth.cpp
 	src/dialogs/ReCaptcha.cpp
 
@@ -404,7 +403,7 @@ if(USE_BUNDLED_MTXCLIENT)
 	FetchContent_Declare(
 		MatrixClient
 		GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
-		GIT_TAG        v0.7.0
+		GIT_TAG        817ae6e110829cfec39cd367a133a628ab923bb4
 		)
 	set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
 	set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")
@@ -506,7 +505,6 @@ feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAG
 
 qt5_wrap_cpp(MOC_HEADERS
 	# Dialogs
-	src/dialogs/CreateRoom.h
 	src/dialogs/FallbackAuth.h
 	src/dialogs/ReCaptcha.h
 
diff --git a/io.github.NhekoReborn.Nheko.yaml b/io.github.NhekoReborn.Nheko.yaml
index 9aefc04cb44fa2b1b5b5f27328d3424060ac7061..4832ea5327af9d10b384355938b5fa31650bca7d 100644
--- a/io.github.NhekoReborn.Nheko.yaml
+++ b/io.github.NhekoReborn.Nheko.yaml
@@ -176,8 +176,8 @@ modules:
     buildsystem: cmake-ninja
     name: mtxclient
     sources:
-      - commit: 9eb9c152faf3461237d4b97ffe12503e367c8809
-        tag: v0.7.0
+      - commit: 817ae6e110829cfec39cd367a133a628ab923bb4
+        #tag: v0.7.0
         type: git
         url: https://github.com/Nheko-Reborn/mtxclient.git
   - config-opts:
diff --git a/resources/qml/dialogs/CreateDirect.qml b/resources/qml/dialogs/CreateDirect.qml
index 3ae0b72dcc0f97d85ccda7b645ed9002f61e388e..85768cadf2a265904712bd37b77f058e54aa3dd8 100644
--- a/resources/qml/dialogs/CreateDirect.qml
+++ b/resources/qml/dialogs/CreateDirect.qml
@@ -15,36 +15,26 @@ ApplicationWindow {
     id: createDirectRoot
     title: qsTr("Create Direct Chat")
     property var profile
-    property bool otherUserHasE2ee: profile? dMod.count > 0 : true
-    minimumHeight: layout.implicitHeight+2*layout.anchors.margins+footer.height
-    minimumWidth: footer.width
+    property bool otherUserHasE2ee: profile? profile.deviceList.rowCount() > 0 : true
+    minimumHeight: layout.implicitHeight + footer.implicitHeight + Nheko.paddingLarge*2
+    minimumWidth: Math.max(footer.implicitWidth, layout.implicitWidth)
+    modality: Qt.NonModal
+    flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
+
+    onVisibilityChanged: {
+        userID.forceActiveFocus();
+    }
 
     Shortcut {
         sequence: StandardKey.Cancel
-        onActivated: roomDirectoryWindow.close()
-    }
-    DelegateModel {
-        id: dMod
-        model: profile? profile.deviceList : undefined
+        onActivated: createDirectRoot.close()
     }
 
     ColumnLayout {
         id: layout
         anchors.fill: parent
-        anchors.margins: Nheko.paddingSmall
-        MatrixTextField {
-            id: userID
-            property bool isValidMxid: text.match("@.+?:.{3,}")
-            Layout.fillWidth: true
-            focus: true
-            placeholderText: qsTr("Name")
-            onTextChanged: {
-                if(isValidMxid) {
-                    profile = TimelineManager.getGlobalUserProfile(text);
-                } else
-                    profile = null;
-            }
-        }
+        anchors.margins: Nheko.paddingLarge
+        spacing: userID.height/4
 
         GridLayout {
             Layout.fillWidth: true
@@ -58,7 +48,7 @@ ApplicationWindow {
                 Layout.preferredWidth: Nheko.avatarSize
                 Layout.preferredHeight: Nheko.avatarSize
                 Layout.alignment: Qt.AlignLeft
-                userid: profile? profile.mxid : ""
+                userid: profile? profile.userid : ""
                 url: profile? profile.avatarUrl.replace("mxc://", "image://MxcImage/") : null
                 displayName: profile? profile.displayName : ""
                 enabled: false
@@ -77,6 +67,22 @@ ApplicationWindow {
                 font.pointSize: fontMetrics.font.pointSize * 0.9
             }
         }
+
+        MatrixTextField {
+            id: userID
+            property bool isValidMxid: text.match("@.+?:.{3,}")
+            Layout.fillWidth: true
+            focus: true
+            label: qsTr("User to invite")
+            placeholderText: qsTr("@user:server.tld")
+            onTextChanged: {
+                if(isValidMxid) {
+                    profile = TimelineManager.getGlobalUserProfile(text);
+                } else
+                    profile = null;
+            }
+        }
+
         RowLayout {
             Layout.fillWidth: true
             Label {
@@ -91,6 +97,8 @@ ApplicationWindow {
                 checked: otherUserHasE2ee
             }
         }
+
+        Item {Layout.fillHeight: true}
     }
     footer: DialogButtonBox {
         standardButtons: DialogButtonBox.Cancel
@@ -101,7 +109,7 @@ ApplicationWindow {
         }
         onRejected: createDirectRoot.close();
         onAccepted: {
-            profile.startChat()
+            profile.startChat(encryption.checked)
             createDirectRoot.close()
         }
     }
diff --git a/resources/qml/dialogs/CreateRoom.qml b/resources/qml/dialogs/CreateRoom.qml
index c000642d6d2a5c66e21a63900186a6792ad912f9..5d2248850fb9043906732b0c0e0d39ceba48e78e 100644
--- a/resources/qml/dialogs/CreateRoom.qml
+++ b/resources/qml/dialogs/CreateRoom.qml
@@ -13,8 +13,15 @@ import im.nheko 1.0
 ApplicationWindow {
     id: createRoomRoot
     title: qsTr("Create Room")
-    minimumWidth: rootLayout.implicitWidth+2*rootLayout.anchors.margins
+    minimumWidth: Math.max(rootLayout.implicitWidth+2*rootLayout.anchors.margins, footer.implicitWidth + Nheko.paddingLarge)
     minimumHeight: rootLayout.implicitHeight+footer.implicitHeight+2*rootLayout.anchors.margins
+    modality: Qt.NonModal
+    flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
+
+    onVisibilityChanged: {
+        newRoomName.forceActiveFocus();
+    }
+
     Shortcut {
         sequence: StandardKey.Cancel
         onActivated: createRoomRoot.close()
@@ -22,15 +29,18 @@ ApplicationWindow {
     GridLayout {
         id: rootLayout
         anchors.fill: parent
-        anchors.margins: Nheko.paddingSmall
+        anchors.margins: Nheko.paddingLarge
         columns: 2
+        rowSpacing: Nheko.paddingMedium
+
         MatrixTextField {
             id: newRoomName
             Layout.columnSpan: 2
             Layout.fillWidth: true
 
             focus: true
-            placeholderText: qsTr("Name")
+            label: qsTr("Name")
+            placeholderText: qsTr("No name")
         }
         MatrixTextField {
             id: newRoomTopic
@@ -38,8 +48,14 @@ ApplicationWindow {
             Layout.fillWidth: true
 
             focus: true
-            placeholderText: qsTr("Topic")
+            label: qsTr("Topic")
+            placeholderText: qsTr("No topic")
         }
+
+        Item {
+            Layout.preferredHeight: newRoomName.height / 2
+        }
+
         RowLayout {
             Layout.columnSpan: 2
             Layout.fillWidth: true
@@ -63,20 +79,20 @@ ApplicationWindow {
         Label {
             Layout.preferredWidth: implicitWidth
             Layout.alignment: Qt.AlignLeft
-            text: qsTr("Private")
+            text: qsTr("Public")
             color: Nheko.colors.text
             HoverHandler {
                 id: privateHover
             }
             ToolTip.visible: privateHover.hovered
-            ToolTip.text: qsTr("Only invited users can join the room")
+            ToolTip.text: qsTr("Public rooms can be joined by anyone, private rooms need explicit invites.")
             ToolTip.delay: Nheko.tooltipDelay
         }
         ToggleButton {
             Layout.alignment: Qt.AlignRight
             Layout.preferredWidth: implicitWidth
-            id: isPrivate
-            checked: true
+            id: isPublic
+            checked: false
         }
         Label {
             Layout.preferredWidth: implicitWidth
@@ -95,7 +111,7 @@ ApplicationWindow {
             Layout.preferredWidth: implicitWidth
             id: isTrusted
             checked: false
-            enabled: isPrivate.checked
+            enabled: !isPublic.checked
         }
         Label {
             Layout.preferredWidth: implicitWidth
@@ -115,6 +131,8 @@ ApplicationWindow {
             id: isEncrypted
             checked: false
         }
+
+        Item {Layout.fillHeight: true}
     }
     footer: DialogButtonBox {
         standardButtons: DialogButtonBox.Cancel
@@ -123,6 +141,17 @@ ApplicationWindow {
             DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
         }
         onRejected: createRoomRoot.close();
-        //onAccepted: createRoom(newRoomName.text, newRoomTopic.text, newRoomAlias.text, newRoomVisibility.index, newRoomPreset.index)
+        onAccepted: {
+            var preset = 0;
+
+            if (isPublic.checked) {
+                preset = 1;
+            }
+            else {
+                preset = isTrusted.checked ? 2 : 0;
+            }
+            Nheko.createRoom(newRoomName.text, newRoomTopic.text, newRoomAlias.text, isEncrypted.checked, preset)
+            createRoomRoot.close();
+        }
     }
 }
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 3743eae08144249d274026d98d3f6a8bb9f12066..a355a5b21c90c43c0906aa4ea414b9c6112c79b1 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -1187,7 +1187,7 @@ ChatPage::decryptDownloadedSecrets(mtx::secret_storage::AesHmacSha2KeyDescriptio
 }
 
 void
-ChatPage::startChat(QString userid)
+ChatPage::startChat(QString userid, std::optional<bool> encryptionEnabled)
 {
     auto joined_rooms = cache::joinedRooms();
     auto room_infos   = cache::getRoomInfo(joined_rooms);
@@ -1213,6 +1213,14 @@ ChatPage::startChat(QString userid)
     mtx::requests::CreateRoom req;
     req.preset     = mtx::requests::Preset::PrivateChat;
     req.visibility = mtx::common::RoomVisibility::Private;
+
+    if (encryptionEnabled.value_or(false)) {
+        mtx::events::StrippedEvent<mtx::events::state::Encryption> enc;
+        enc.type              = mtx::events::EventType::RoomEncryption;
+        enc.content.algorithm = mtx::crypto::MEGOLM_ALGO;
+        req.initial_state.emplace_back(std::move(enc));
+    }
+
     if (utils::localUser() != userid) {
         req.invite    = {userid.toStdString()};
         req.is_direct = true;
diff --git a/src/ChatPage.h b/src/ChatPage.h
index e4b9e4e85634a49cbe3abee8ba975e799b21307a..f43a008de8dc6ecb11bd5a64b62bc4b0db5199a0 100644
--- a/src/ChatPage.h
+++ b/src/ChatPage.h
@@ -74,12 +74,13 @@ public:
 
     // TODO(Nico): Get rid of this!
     QString currentRoom() const;
+    void startChat(QString userid, std::optional<bool> encryptionEnabled);
 
 public slots:
     bool handleMatrixUri(QString uri);
     bool handleMatrixUri(const QUrl &uri);
 
-    void startChat(QString userid);
+    void startChat(QString userid) { startChat(userid, std::nullopt); }
     void leaveRoom(const QString &room_id);
     void createRoom(const mtx::requests::CreateRoom &req);
     void joinRoom(const QString &room);
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index c4af7f0cea277f78c2539947d84d9d987505f3e3..7235f93d258e0fc4319d68a6fc457788e8e43fa5 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -54,8 +54,6 @@
 #include "ui/UIA.h"
 #include "voip/WebRTCSession.h"
 
-#include "dialogs/CreateRoom.h"
-
 Q_DECLARE_METATYPE(mtx::events::collections::TimelineEvents)
 Q_DECLARE_METATYPE(std::vector<DeviceInfo>)
 Q_DECLARE_METATYPE(std::vector<mtx::responses::PublicRoomsChunk>)
@@ -404,19 +402,6 @@ MainWindow::hasActiveUser()
            settings->contains(prefix + "auth/user_id");
 }
 
-void
-MainWindow::openCreateRoomDialog(
-  std::function<void(const mtx::requests::CreateRoom &request)> callback)
-{
-    auto dialog = new dialogs::CreateRoom(nullptr);
-    connect(dialog,
-            &dialogs::CreateRoom::createRoom,
-            this,
-            [callback](const mtx::requests::CreateRoom &request) { callback(request); });
-
-    showDialog(dialog);
-}
-
 bool
 MainWindow::pageSupportsTray() const
 {
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 7bc94328bc535aaaeb655ef2b298eb2cd8a134fa..e8c6fafd91da0120fe96464ce37d196af8f30832 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -47,8 +47,6 @@ public:
     static MainWindow *instance() { return instance_; }
     void saveCurrentWindowSize();
 
-    void
-    openCreateRoomDialog(std::function<void(const mtx::requests::CreateRoom &request)> callback);
     void openJoinRoomDialog(std::function<void(const QString &room_id)> callback);
 
     MxcImageProvider *imageProvider() { return imgProvider; }
diff --git a/src/dialogs/CreateRoom.cpp b/src/dialogs/CreateRoom.cpp
deleted file mode 100644
index e828ae7c1bce5a18e93587a82b6461d7beb48e40..0000000000000000000000000000000000000000
--- a/src/dialogs/CreateRoom.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-// SPDX-FileCopyrightText: 2021 Nheko Contributors
-// SPDX-FileCopyrightText: 2022 Nheko Contributors
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include <QComboBox>
-#include <QLabel>
-#include <QPushButton>
-#include <QVBoxLayout>
-
-#include "dialogs/CreateRoom.h"
-
-#include "Config.h"
-#include "ui/TextField.h"
-#include "ui/ToggleButton.h"
-
-using namespace dialogs;
-
-CreateRoom::CreateRoom(QWidget *parent)
-  : QFrame(parent)
-{
-    setAutoFillBackground(true);
-    setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
-    setWindowModality(Qt::WindowModal);
-    setAttribute(Qt::WA_DeleteOnClose, true);
-
-    QFont largeFont;
-    largeFont.setPointSizeF(largeFont.pointSizeF() * 1.5);
-
-    setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
-    setMinimumHeight(conf::window::minHeight);
-    setMinimumWidth(conf::window::minModalWidth);
-
-    auto layout = new QVBoxLayout(this);
-    layout->setSpacing(conf::modals::WIDGET_SPACING);
-    layout->setContentsMargins(conf::modals::WIDGET_MARGIN,
-                               conf::modals::WIDGET_MARGIN,
-                               conf::modals::WIDGET_MARGIN,
-                               conf::modals::WIDGET_MARGIN);
-
-    buttonBox_  = new QDialogButtonBox(QDialogButtonBox::Cancel);
-    confirmBtn_ = new QPushButton(tr("Create room"), this);
-    confirmBtn_->setDefault(true);
-    buttonBox_->addButton(confirmBtn_, QDialogButtonBox::AcceptRole);
-
-    QFont font;
-    font.setPointSizeF(font.pointSizeF() * 1.3);
-
-    nameInput_ = new TextField(this);
-    nameInput_->setLabel(tr("Name"));
-
-    topicInput_ = new TextField(this);
-    topicInput_->setLabel(tr("Topic"));
-
-    aliasInput_ = new TextField(this);
-    aliasInput_->setLabel(tr("Alias"));
-
-    auto visibilityLayout = new QHBoxLayout;
-    visibilityLayout->setContentsMargins(0, 10, 0, 10);
-
-    auto presetLayout = new QHBoxLayout;
-    presetLayout->setContentsMargins(0, 10, 0, 10);
-
-    auto visibilityLabel = new QLabel(tr("Room Visibility"), this);
-    visibilityCombo_     = new QComboBox(this);
-    visibilityCombo_->addItem(tr("Private"));
-    visibilityCombo_->addItem(tr("Public"));
-
-    visibilityLayout->addWidget(visibilityLabel);
-    visibilityLayout->addWidget(visibilityCombo_, 0, Qt::AlignBottom | Qt::AlignRight);
-
-    auto presetLabel = new QLabel(tr("Room Preset"), this);
-    presetCombo_     = new QComboBox(this);
-    presetCombo_->addItem(tr("Private Chat"));
-    presetCombo_->addItem(tr("Public Chat"));
-    presetCombo_->addItem(tr("Trusted Private Chat"));
-
-    presetLayout->addWidget(presetLabel);
-    presetLayout->addWidget(presetCombo_, 0, Qt::AlignBottom | Qt::AlignRight);
-
-    auto directLabel_ = new QLabel(tr("Direct Chat"), this);
-    directToggle_     = new Toggle(this);
-    directToggle_->setActiveColor(QColor(0x38, 0xA3, 0xD8));
-    directToggle_->setInactiveColor(QColor("gray"));
-    directToggle_->setState(false);
-
-    auto directLayout = new QHBoxLayout;
-    directLayout->setContentsMargins(0, 10, 0, 10);
-    directLayout->addWidget(directLabel_);
-    directLayout->addWidget(directToggle_, 0, Qt::AlignBottom | Qt::AlignRight);
-
-    layout->addWidget(nameInput_);
-    layout->addWidget(topicInput_);
-    layout->addWidget(aliasInput_);
-    layout->addLayout(visibilityLayout);
-    layout->addLayout(presetLayout);
-    layout->addLayout(directLayout);
-    layout->addWidget(buttonBox_);
-
-    connect(buttonBox_, &QDialogButtonBox::accepted, this, [this]() {
-        request_.name            = nameInput_->text().toStdString();
-        request_.topic           = topicInput_->text().toStdString();
-        request_.room_alias_name = aliasInput_->text().toStdString();
-
-        emit createRoom(request_);
-
-        clearFields();
-        emit close();
-    });
-
-    connect(buttonBox_, &QDialogButtonBox::rejected, this, [this]() {
-        clearFields();
-        emit close();
-    });
-
-    connect(visibilityCombo_,
-            static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
-            this,
-            [this](int idx) {
-                if (idx == 0) {
-                    request_.visibility = mtx::common::RoomVisibility::Private;
-                } else {
-                    request_.visibility = mtx::common::RoomVisibility::Public;
-                }
-            });
-
-    connect(presetCombo_,
-            static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
-            this,
-            [this](int idx) {
-                if (idx == 0) {
-                    request_.preset = mtx::requests::Preset::PrivateChat;
-                } else if (idx == 1) {
-                    request_.preset = mtx::requests::Preset::PublicChat;
-                } else {
-                    request_.preset = mtx::requests::Preset::TrustedPrivateChat;
-                }
-            });
-
-    connect(directToggle_, &Toggle::toggled, this, [this](bool isEnabled) {
-        request_.is_direct = isEnabled;
-    });
-}
-
-void
-CreateRoom::clearFields()
-{
-    nameInput_->clear();
-    topicInput_->clear();
-    aliasInput_->clear();
-}
-
-void
-CreateRoom::showEvent(QShowEvent *event)
-{
-    nameInput_->setFocus();
-
-    QFrame::showEvent(event);
-}
diff --git a/src/dialogs/CreateRoom.h b/src/dialogs/CreateRoom.h
deleted file mode 100644
index c395941dedde2b6f77ce65c2a7295feb1aeaf7fa..0000000000000000000000000000000000000000
--- a/src/dialogs/CreateRoom.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// SPDX-FileCopyrightText: 2021 Nheko Contributors
-// SPDX-FileCopyrightText: 2022 Nheko Contributors
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include <QDialogButtonBox>
-#include <QFrame>
-
-#include <mtx/requests.hpp>
-
-class QPushButton;
-class TextField;
-class QComboBox;
-class Toggle;
-
-namespace dialogs {
-
-class CreateRoom : public QFrame
-{
-    Q_OBJECT
-public:
-    CreateRoom(QWidget *parent = nullptr);
-
-signals:
-    void createRoom(const mtx::requests::CreateRoom &request);
-
-protected:
-    void showEvent(QShowEvent *event) override;
-
-private:
-    void clearFields();
-
-    QComboBox *visibilityCombo_;
-    QComboBox *presetCombo_;
-
-    Toggle *directToggle_;
-
-    QPushButton *confirmBtn_;
-    QDialogButtonBox *buttonBox_;
-
-    TextField *nameInput_;
-    TextField *topicInput_;
-    TextField *aliasInput_;
-
-    mtx::requests::CreateRoom request_;
-};
-
-} // dialogs
diff --git a/src/ui/NhekoGlobalObject.cpp b/src/ui/NhekoGlobalObject.cpp
index 3abcdf08d465f26e05cfbebf0596e44e6a56325e..2e1aadf0b586036beb58089ffe98e5d87360f5b5 100644
--- a/src/ui/NhekoGlobalObject.cpp
+++ b/src/ui/NhekoGlobalObject.cpp
@@ -13,7 +13,6 @@
 #include "Cache_p.h"
 #include "ChatPage.h"
 #include "Logging.h"
-#include "MainWindow.h"
 #include "UserSettingsPage.h"
 #include "Utils.h"
 #include "voip/WebRTCSession.h"
@@ -129,8 +128,32 @@ Nheko::logout() const
 }
 
 void
-Nheko::openCreateRoomDialog() const
+Nheko::createRoom(QString name, QString topic, QString aliasLocalpart, bool isEncrypted, int preset)
 {
-    MainWindow::instance()->openCreateRoomDialog(
-      [](const mtx::requests::CreateRoom &req) { ChatPage::instance()->createRoom(req); });
+    mtx::requests::CreateRoom req;
+
+    switch (preset) {
+    case 1:
+        req.preset = mtx::requests::Preset::PublicChat;
+        break;
+    case 2:
+        req.preset = mtx::requests::Preset::TrustedPrivateChat;
+        break;
+    case 0:
+    default:
+        req.preset = mtx::requests::Preset::PrivateChat;
+    }
+
+    req.name            = name.toStdString();
+    req.topic           = topic.toStdString();
+    req.room_alias_name = aliasLocalpart.toStdString();
+
+    if (isEncrypted) {
+        mtx::events::StrippedEvent<mtx::events::state::Encryption> enc;
+        enc.type              = mtx::events::EventType::RoomEncryption;
+        enc.content.algorithm = mtx::crypto::MEGOLM_ALGO;
+        req.initial_state.emplace_back(std::move(enc));
+    }
+
+    emit ChatPage::instance()->createRoom(req);
 }
diff --git a/src/ui/NhekoGlobalObject.h b/src/ui/NhekoGlobalObject.h
index 2449387397e9305619e6c663f949d19c5b126dbe..1139cf31c5dd50c5627c6525c948bdf62d21a772 100644
--- a/src/ui/NhekoGlobalObject.h
+++ b/src/ui/NhekoGlobalObject.h
@@ -52,7 +52,8 @@ public:
     Q_INVOKABLE void setStatusMessage(QString msg) const;
     Q_INVOKABLE void showUserSettingsPage() const;
     Q_INVOKABLE void logout() const;
-    Q_INVOKABLE void openCreateRoomDialog() const;
+    Q_INVOKABLE void
+    createRoom(QString name, QString topic, QString aliasLocalpart, bool isEncrypted, int preset);
 
 public slots:
     void updateUserProfile();
diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp
index 898b56fdbd03b7ea02ff49d791d4bc2fd96df818..db50b050788e9a000768928018d537390dc54c47 100644
--- a/src/ui/UserProfile.cpp
+++ b/src/ui/UserProfile.cpp
@@ -53,6 +53,9 @@ UserProfile::UserProfile(QString roomid,
 
           emit verificationStatiChanged();
       });
+    connect(this, &UserProfile::devicesChanged, [this]() {
+        nhlog::net()->critical("Device list: {}", deviceList_.rowCount());
+    });
     fetchDeviceList(this->userid_);
 }
 
@@ -187,7 +190,6 @@ UserProfile::fetchDeviceList(const QString &userID)
               nhlog::net()->warn("failed to query device keys: {},{}",
                                  mtx::errors::to_string(err->matrix_error.errcode),
                                  static_cast<int>(err->status_code));
-              return;
           }
 
           // Ensure local key cache is up to date
@@ -201,7 +203,6 @@ UserProfile::fetchDeviceList(const QString &userID)
                     nhlog::net()->warn("failed to query device keys: {},{}",
                                        mtx::errors::to_string(err->matrix_error.errcode),
                                        static_cast<int>(err->status_code));
-                    return;
                 }
 
                 emit verificationStatiChanged();
@@ -312,10 +313,16 @@ UserProfile::kickUser()
     ChatPage::instance()->kickUser(this->userid_, QLatin1String(""));
 }
 
+void
+UserProfile::startChat(bool encryption)
+{
+    ChatPage::instance()->startChat(this->userid_, encryption);
+}
+
 void
 UserProfile::startChat()
 {
-    ChatPage::instance()->startChat(this->userid_);
+    ChatPage::instance()->startChat(this->userid_, std::nullopt);
 }
 
 void
diff --git a/src/ui/UserProfile.h b/src/ui/UserProfile.h
index 0f03e537168432b4ac11387a832d04aeb3a888d3..4652a72e8a3e7baf49383dfd9b0996f14b8c5cb1 100644
--- a/src/ui/UserProfile.h
+++ b/src/ui/UserProfile.h
@@ -143,6 +143,7 @@ public:
     // Q_INVOKABLE void ignoreUser();
     Q_INVOKABLE void kickUser();
     Q_INVOKABLE void startChat();
+    Q_INVOKABLE void startChat(bool encryptionEnabled);
     Q_INVOKABLE void changeUsername(QString username);
     Q_INVOKABLE void changeDeviceName(QString deviceID, QString deviceName);
     Q_INVOKABLE void changeAvatar();