diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml
new file mode 100644
index 00000000..e6fc2b84
--- /dev/null
+++ b/resources/qml/RoomDirectory.qml
@@ -0,0 +1,155 @@
+// SPDX-FileCopyrightText: 2021 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+import QtQuick 2.9
+import QtQuick.Controls 2.3
+import QtQuick.Layouts 1.3
+import im.nheko 1.0
+import im.nheko.RoomDirectoryModel 1.0
+
+ApplicationWindow {
+ id: roomDirectoryWindow
+ visible: true
+
+ x: MainWindow.x + (MainWindow.width / 2) - (width / 2)
+ y: MainWindow.y + (MainWindow.height / 2) - (height / 2)
+ minimumWidth: 650
+ minimumHeight: 420
+ palette: Nheko.colors
+ color: Nheko.colors.window
+ modality: Qt.WindowModal
+ flags: Qt.Dialog
+ title: qsTr("Explore Public Rooms")
+
+ header: RowLayout {
+ id: searchBarLayout
+ spacing: Nheko.paddingMedium
+ width: parent.width
+
+ implicitHeight: roomTextInput.height
+
+ MatrixTextField {
+ id: roomSearch
+
+ Layout.fillWidth: true
+
+ font.pixelSize: fontMetrics.font.pixelSize
+ padding: Nheko.paddingSmall
+ color: Nheko.colors.text
+ placeholderText: qsTr("Search for public rooms")
+ onTextChanged: searchTimer.restart()
+ }
+
+ Timer {
+ id: searchTimer
+
+ interval: 350
+ onTriggered: roomDirView.model.setSearchTerm(roomSearch.text)
+ }
+ }
+
+ ListView {
+ id: roomDirView
+ anchors.fill: parent
+ height: parent.height - searchBarLayout.height
+ model: RoomDirectoryModel {
+ id: roomDir
+ }
+ delegate: Rectangle {
+ id: roomDirDelegate
+
+ property color background: Nheko.colors.window
+ property color importantText: Nheko.colors.text
+ property color unimportantText: Nheko.colors.buttonText
+ property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 2.5)
+
+ color: background
+
+ height: avatarSize + 2.5 * Nheko.paddingMedium
+ width: ListView.view.width
+
+ RowLayout {
+
+ spacing: Nheko.paddingMedium
+ anchors.fill: parent
+ anchors.margins: Nheko.paddingMedium
+ implicitHeight: textContent.height
+
+ Avatar {
+ id: roomAvatar
+
+ Layout.alignment: Qt.AlignVCenter
+ width: avatarSize
+ height: avatarSize
+ url: model.avatarUrl.replace("mxc://", "image://MxcImage/")
+ displayName: model.name
+ }
+
+ ColumnLayout {
+ id: textContent
+
+ Layout.alignment: Qt.AlignLeft
+ Layout.fillWidth: true
+ width: parent.width - avatar.width
+ Layout.preferredWidth: parent.width - avatar.width
+ Layout.preferredHeight: roomNameRow.height + roomDescriptionRow.height
+ spacing: Nheko.paddingSmall
+
+ RowLayout {
+ id: roomNameRow
+ Layout.fillWidth: true
+ spacing: 0
+
+ ElidedLabel {
+ Layout.alignment: Qt.AlignBottom
+ color: roomDirDelegate.importantText
+ elideWidth: textContent.width * 0.5 - Nheko.paddingMedium
+ font.pixelSize: fontMetrics.font.pixelSize * 1.1
+ fullText: model.name
+ }
+ }
+
+ RowLayout {
+ id: roomDescriptionRow
+ Layout.fillWidth: true
+ Layout.preferredWidth: parent.width
+ spacing: Nheko.paddingSmall
+ Layout.alignment: Qt.AlignLeft
+ Layout.preferredHeight: Math.max(roomTopic.height, roomCount.height, joinRoomButton.height)
+
+ Label {
+ id: roomTopic
+ color: roomDirDelegate.unimportantText
+ font.weight: Font.Thin
+ font.pixelSize: fontMetrics.font.pixelSize
+ elide: Text.ElideRight
+ maximumLineCount: 2
+ Layout.fillWidth: true
+ text: model.topic
+ verticalAlignment: Text.AlignVCenter
+ wrapMode: Text.WordWrap
+ }
+
+ Label {
+ id: roomCount
+ color: roomDirDelegate.unimportantText
+ Layout.fillWidth: false
+ font.weight: Font.Thin
+ font.pixelSize: fontMetrics.font.pixelSize
+ text: model.numMembers.toString()
+ }
+
+ Button {
+ id: joinRoomButton
+ Layout.fillWidth: false
+ text: "Join"
+ Layout.margins: Nheko.paddingSmall
+ onClicked: roomDir.joinRoom(model.index)
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml
index a2e50fab..31c9d3cf 100644
--- a/resources/qml/RoomList.qml
+++ b/resources/qml/RoomList.qml
@@ -16,6 +16,13 @@ Page {
property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 2.3)
property bool collapsed: false
+Component {
+ id: roomDirectoryComponent
+
+ RoomDirectory {
+ }
+ }
+
ListView {
id: roomlist
@@ -549,6 +556,11 @@ Page {
ToolTip.visible: hovered
ToolTip.text: qsTr("Room directory")
Layout.margins: Nheko.paddingMedium
+ onClicked: {
+ console.debug("Roomdir clicked");
+ var win = roomDirectoryComponent.createObject(timelineRoot);
+ win.show();
+ }
}
ImageButton {
diff --git a/resources/res.qrc b/resources/res.qrc
index 5d37c397..407a0a98 100644
--- a/resources/res.qrc
+++ b/resources/res.qrc
@@ -143,7 +143,8 @@
qml/emoji/EmojiPicker.qml
qml/emoji/StickerPicker.qml
qml/UserProfile.qml
- qml/delegates/MessageDelegate.qml
+ qml/RoomDirectory.qml
+ qml/delegates/MessageDelegate.qml
qml/delegates/TextMessage.qml
qml/delegates/NoticeMessage.qml
qml/delegates/ImageMessage.qml