Merge pull request #659 from kamathmanu/nhekoRoomDirectory
Nheko room directory
3 files changed, 216 insertions, 0 deletions
diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml
new file mode 100644
index 00000000..4db24f01
--- /dev/null
+++ b/resources/qml/RoomDirectory.qml
@@ -0,0 +1,204 @@
+// SPDX-FileCopyrightText: 2021 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+import "./ui"
+import QtQuick 2.9
+import QtQuick.Controls 2.3
+import QtQuick.Layouts 1.3
+import im.nheko 1.0
+
+ApplicationWindow {
+ id: roomDirectoryWindow
+
+ property RoomDirectoryModel publicRooms
+
+ visible: true
+ minimumWidth: 650
+ minimumHeight: 420
+ palette: Nheko.colors
+ color: Nheko.colors.window
+ modality: Qt.WindowModal
+ flags: Qt.Dialog | Qt.WindowCloseButtonHint
+ Component.onCompleted: Nheko.reparent(roomDirectoryWindow)
+ title: qsTr("Explore Public Rooms")
+
+ Shortcut {
+ sequence: StandardKey.Cancel
+ onActivated: roomDirectoryWindow.close()
+ }
+
+ ListView {
+ id: roomDirView
+
+ anchors.fill: parent
+ model: publicRooms
+
+ ScrollHelper {
+ flickable: parent
+ anchors.fill: parent
+ enabled: !Settings.mobileMode
+ }
+
+ 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: fontMetrics.lineSpacing * 4
+
+ color: background
+ height: avatarSize + Nheko.paddingLarge
+ width: ListView.view.width
+
+ RowLayout {
+ spacing: Nheko.paddingMedium
+ anchors.fill: parent
+ anchors.margins: Nheko.paddingLarge
+ 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
+ width: parent.width - avatar.width
+ Layout.preferredWidth: parent.width - avatar.width
+ spacing: Nheko.paddingSmall
+
+ ElidedLabel {
+ Layout.alignment: Qt.AlignBottom
+ color: roomDirDelegate.importantText
+ elideWidth: textContent.width - numMembersRectangle.width - buttonRectangle.width
+ font.pixelSize: fontMetrics.font.pixelSize * 1.1
+ fullText: model.name
+ }
+
+ RowLayout {
+ id: roomDescriptionRow
+
+ Layout.preferredWidth: parent.width
+ spacing: Nheko.paddingSmall
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
+ Layout.preferredHeight: fontMetrics.lineSpacing * 4
+
+ Label {
+ id: roomTopic
+
+ color: roomDirDelegate.unimportantText
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
+ font.pixelSize: fontMetrics.font.pixelSize
+ elide: Text.ElideRight
+ maximumLineCount: 2
+ Layout.fillWidth: true
+ text: model.topic
+ verticalAlignment: Text.AlignVCenter
+ wrapMode: Text.WordWrap
+ }
+
+ Item {
+ id: numMembersRectangle
+
+ Layout.margins: Nheko.paddingSmall
+ width: roomCount.width
+
+ Label {
+ id: roomCount
+
+ color: roomDirDelegate.unimportantText
+ anchors.centerIn: parent
+ font.pixelSize: fontMetrics.font.pixelSize
+ text: model.numMembers.toString()
+ }
+
+ }
+
+ Item {
+ id: buttonRectangle
+
+ Layout.margins: Nheko.paddingSmall
+ width: joinRoomButton.width
+
+ Button {
+ id: joinRoomButton
+
+ visible: publicRooms.canJoinRoom(model.roomid)
+ anchors.centerIn: parent
+ width: Math.ceil(0.1 * roomDirectoryWindow.width)
+ text: "Join"
+ onClicked: publicRooms.joinRoom(model.index)
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ footer: Item {
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: parent.width
+ visible: !publicRooms.reachedEndOfPagination && publicRooms.loadingMoreRooms
+ // hacky but works
+ height: loadingSpinner.height + 2 * Nheko.paddingLarge
+ anchors.margins: Nheko.paddingLarge
+
+ Spinner {
+ id: loadingSpinner
+
+ anchors.centerIn: parent
+ anchors.margins: Nheko.paddingLarge
+ running: visible
+ foreground: Nheko.colors.mid
+ }
+
+ }
+
+ }
+
+ publicRooms: RoomDirectoryModel {
+ }
+
+ header: RowLayout {
+ id: searchBarLayout
+
+ spacing: Nheko.paddingMedium
+ width: parent.width
+ implicitHeight: roomSearch.height
+
+ MatrixTextField {
+ id: roomSearch
+
+ Layout.fillWidth: true
+ selectByMouse: true
+ font.pixelSize: fontMetrics.font.pixelSize
+ padding: Nheko.paddingMedium
+ color: Nheko.colors.text
+ placeholderText: qsTr("Search for public rooms")
+ onTextChanged: searchTimer.restart()
+ }
+
+ Timer {
+ id: searchTimer
+
+ interval: 350
+ onTriggered: roomDirView.model.setSearchTerm(roomSearch.text)
+ }
+
+ }
+
+}
diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml
index 8fbfce91..b84b4c36 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
@@ -563,6 +570,10 @@ Page {
ToolTip.visible: hovered
ToolTip.text: qsTr("Room directory")
Layout.margins: Nheko.paddingMedium
+ onClicked: {
+ var win = roomDirectoryComponent.createObject(timelineRoot);
+ win.show();
+ }
}
ImageButton {
diff --git a/resources/res.qrc b/resources/res.qrc
index f50265ca..b46b726c 100644
--- a/resources/res.qrc
+++ b/resources/res.qrc
@@ -142,6 +142,7 @@
<file>qml/emoji/EmojiPicker.qml</file>
<file>qml/emoji/StickerPicker.qml</file>
<file>qml/UserProfile.qml</file>
+ <file>qml/RoomDirectory.qml</file>
<file>qml/delegates/MessageDelegate.qml</file>
<file>qml/delegates/Encrypted.qml</file>
<file>qml/delegates/FileMessage.qml</file>
|