From f5417a622790de719f4e764d7c7dbc5e1f4790ab Mon Sep 17 00:00:00 2001 From: James Graham Date: Sun, 15 Oct 2023 11:28:17 +0000 Subject: [PATCH] New parent dialog Move the add new offical parent to a dialog and make sure that the join room dialog only shows spaces. --- src/CMakeLists.txt | 1 + src/models/publicroomlistmodel.cpp | 20 +++- src/models/publicroomlistmodel.h | 10 ++ src/qml/General.qml | 133 ++--------------------- src/qml/JoinRoomPage.qml | 3 + src/qml/SelectParentDialog.qml | 165 +++++++++++++++++++++++++++++ 6 files changed, 205 insertions(+), 127 deletions(-) create mode 100644 src/qml/SelectParentDialog.qml diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8f14ec952..3fd29355e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -282,6 +282,7 @@ qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN qml/SpaceHomePage.qml qml/SpaceHierarchyDelegate.qml qml/RemoveChildDialog.qml + qml/SelectParentDialog.qml RESOURCES qml/confetti.png qml/glowdot.png diff --git a/src/models/publicroomlistmodel.cpp b/src/models/publicroomlistmodel.cpp index f8a015f57..3084c11a6 100644 --- a/src/models/publicroomlistmodel.cpp +++ b/src/models/publicroomlistmodel.cpp @@ -124,6 +124,20 @@ void PublicRoomListModel::setKeyword(const QString &value) Q_EMIT hasMoreChanged(); } +bool PublicRoomListModel::showOnlySpaces() const +{ + return m_showOnlySpaces; +} + +void PublicRoomListModel::setShowOnlySpaces(bool showOnlySpaces) +{ + if (showOnlySpaces == m_showOnlySpaces) { + return; + } + m_showOnlySpaces = showOnlySpaces; + Q_EMIT showOnlySpacesChanged(); +} + void PublicRoomListModel::next(int count) { if (count < 1) { @@ -136,7 +150,11 @@ void PublicRoomListModel::next(int count) return; } - job = m_connection->callApi(m_server, count, nextBatch, QueryPublicRoomsJob::Filter{m_keyword, {}}); + QStringList roomTypes; + if (m_showOnlySpaces) { + roomTypes += QLatin1String("m.space"); + } + job = m_connection->callApi(m_server, count, nextBatch, QueryPublicRoomsJob::Filter{m_keyword, roomTypes}); Q_EMIT loadingChanged(); connect(job, &BaseJob::finished, this, [this] { diff --git a/src/models/publicroomlistmodel.h b/src/models/publicroomlistmodel.h index 56daae969..33588c7a4 100644 --- a/src/models/publicroomlistmodel.h +++ b/src/models/publicroomlistmodel.h @@ -45,6 +45,11 @@ class PublicRoomListModel : public QAbstractListModel */ Q_PROPERTY(QString keyword READ keyword WRITE setKeyword NOTIFY keywordChanged) + /** + * @brief Whether only space rooms should be shown. + */ + Q_PROPERTY(bool showOnlySpaces READ showOnlySpaces WRITE setShowOnlySpaces NOTIFY showOnlySpacesChanged) + /** * @brief Whether the model has more items to load. */ @@ -103,6 +108,9 @@ public: [[nodiscard]] QString keyword() const; void setKeyword(const QString &value); + [[nodiscard]] bool showOnlySpaces() const; + void setShowOnlySpaces(bool showOnlySpaces); + [[nodiscard]] bool hasMore() const; [[nodiscard]] bool loading() const; @@ -118,6 +126,7 @@ private: Quotient::Connection *m_connection = nullptr; QString m_server; QString m_keyword; + bool m_showOnlySpaces; bool attempted = false; bool m_loading = false; @@ -131,6 +140,7 @@ Q_SIGNALS: void connectionChanged(); void serverChanged(); void keywordChanged(); + void showOnlySpacesChanged(); void hasMoreChanged(); void loadingChanged(); }; diff --git a/src/qml/General.qml b/src/qml/General.qml index d8453dc55..ca783c5c1 100644 --- a/src/qml/General.qml +++ b/src/qml/General.qml @@ -349,134 +349,16 @@ FormCard.FormCardPage { visible: officalParentRepeater.count <= 0 text: i18n("This room has no official parent spaces.") } - } - FormCard.FormHeader { - visible: root.room.canSendState("m.space.parent") - title: i18n("Add Official Parent Space") - } - FormCard.FormCard { - visible: root.room.canSendState("m.space.parent") FormCard.FormButtonDelegate { - visible: !chosenRoomDelegate.visible - text: i18nc("@action:button", "Pick room") - onClicked: { - let dialog = pageStack.pushDialogLayer("qrc:/org/kde/neochat/qml/JoinRoomPage.qml", {connection: root.connection}, {title: i18nc("@title", "Explore Rooms")}) - dialog.roomSelected.connect((roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined) => { - chosenRoomDelegate.roomId = roomId; - chosenRoomDelegate.displayName = displayName; - chosenRoomDelegate.avatarUrl = avatarUrl; - chosenRoomDelegate.alias = alias; - chosenRoomDelegate.topic = topic; - chosenRoomDelegate.memberCount = memberCount; - chosenRoomDelegate.isJoined = isJoined; - chosenRoomDelegate.visible = true; - }) - } - } - FormCard.AbstractFormDelegate { - id: chosenRoomDelegate - property string roomId - property string displayName - property url avatarUrl - property string alias - property string topic - property int memberCount - property bool isJoined + visible: root.room.canSendState("m.space.parent") + text: i18nc("@action:button", "Add new official parent") + onClicked: selectParentDialog.createObject(applicationWindow().overlay).open(); - visible: false - - contentItem: RowLayout { - KirigamiComponents.Avatar { - Layout.preferredWidth: Kirigami.Units.gridUnit * 2 - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - - source: chosenRoomDelegate.avatarUrl - name: chosenRoomDelegate.displayName + Component { + id: selectParentDialog + SelectParentDialog { + room: root.room } - ColumnLayout { - Layout.fillWidth: true - RowLayout { - Layout.fillWidth: true - Kirigami.Heading { - Layout.fillWidth: true - level: 4 - text: chosenRoomDelegate.displayName - font.bold: true - textFormat: Text.PlainText - elide: Text.ElideRight - wrapMode: Text.NoWrap - } - QQC2.Label { - visible: chosenRoomDelegate.isJoined - text: i18n("Joined") - color: Kirigami.Theme.linkColor - } - } - QQC2.Label { - Layout.fillWidth: true - visible: text - text: chosenRoomDelegate.topic ? chosenRoomDelegate.topic.replace(/(\r\n\t|\n|\r\t)/gm," ") : "" - textFormat: Text.PlainText - elide: Text.ElideRight - wrapMode: Text.NoWrap - } - RowLayout { - Layout.fillWidth: true - Kirigami.Icon { - source: "user" - color: Kirigami.Theme.disabledTextColor - implicitHeight: Kirigami.Units.iconSizes.small - implicitWidth: Kirigami.Units.iconSizes.small - } - QQC2.Label { - text: chosenRoomDelegate.memberCount + " " + (chosenRoomDelegate.alias ?? chosenRoomDelegate.roomId) - color: Kirigami.Theme.disabledTextColor - elide: Text.ElideRight - Layout.fillWidth: true - } - } - } - } - - onClicked: { - let dialog = pageStack.pushDialogLayer("qrc:/org/kde/neochat/qml/JoinRoomPage.qml", {connection: root.connection}, {title: i18nc("@title", "Explore Rooms")}) - dialog.roomSelected.connect((roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined) => { - chosenRoomDelegate.roomId = roomId; - chosenRoomDelegate.displayName = displayName; - chosenRoomDelegate.avatarUrl = avatarUrl; - chosenRoomDelegate.alias = alias; - chosenRoomDelegate.topic = topic; - chosenRoomDelegate.memberCount = memberCount; - chosenRoomDelegate.isJoined = isJoined; - chosenRoomDelegate.visible = true; - }) - } - } - FormCard.FormCheckDelegate { - id: existingOfficialCheck - property NeoChatRoom space: root.connection.room(chosenRoomDelegate.roomId) - text: i18n("Set this room as a child of the space %1", space?.displayName ?? "") - checked: enabled - - enabled: chosenRoomDelegate.visible && space && space.canSendState("m.space.child") - } - FormCard.FormTextDelegate { - visible: chosenRoomDelegate.visible && !root.room.canModifyParent(chosenRoomDelegate.roomId) - text: existingOfficialCheck.space ? (existingOfficialCheck.space.isSpace ? i18n("You do not have a high enough privilege level in the parent to set this state") : i18n("The selected room is not a space")) : i18n("You do not have the privileges to complete this action") - textItem.color: Kirigami.Theme.negativeTextColor - } - FormCard.FormCheckDelegate { - id: makeCanonicalCheck - text: i18n("Make this space the canonical parent") - checked: enabled - - enabled: chosenRoomDelegate.visible - } - FormCard.FormButtonDelegate { - text: i18nc("@action:button", "Ok") - enabled: chosenRoomDelegate.visible && root.room.canModifyParent(chosenRoomDelegate.roomId) - onClicked: { - root.room.addParent(chosenRoomDelegate.roomId, makeCanonicalCheck.checked, existingOfficialCheck.checked) } } } @@ -541,6 +423,5 @@ FormCard.FormCardPage { } } } - } diff --git a/src/qml/JoinRoomPage.qml b/src/qml/JoinRoomPage.qml index e85a07e27..b41d4617d 100644 --- a/src/qml/JoinRoomPage.qml +++ b/src/qml/JoinRoomPage.qml @@ -17,6 +17,8 @@ Kirigami.ScrollablePage { required property NeoChatConnection connection + property bool showOnlySpaces: false + property alias keyword: identifierField.text property string server @@ -216,6 +218,7 @@ Kirigami.ScrollablePage { connection: root.connection server: root.server keyword: root.keyword + showOnlySpaces: root.showOnlySpaces } onContentYChanged: { diff --git a/src/qml/SelectParentDialog.qml b/src/qml/SelectParentDialog.qml new file mode 100644 index 000000000..1b2fff119 --- /dev/null +++ b/src/qml/SelectParentDialog.qml @@ -0,0 +1,165 @@ +// SPDX-FileCopyrightText: 2023 James Graham +// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + +import QtQuick +import QtQuick.Controls as QQC2 +import QtQuick.Layouts + +import org.kde.kirigami as Kirigami +import org.kde.kirigamiaddons.formcard as FormCard +import org.kde.kirigamiaddons.labs.components as Components + +import org.kde.neochat + +/** + * @brief A dialog to select a parent space to add to a given room. + */ +Kirigami.Dialog { + id: root + + /** + * @brief The current room that a parent is being selected for. + */ + required property NeoChatRoom room + + title: i18nc("@title", "Select new offical parent") + + width: Math.min(applicationWindow().width, Kirigami.Units.gridUnit * 24) + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + standardButtons: Kirigami.Dialog.Cancel + customFooterActions: [ + Kirigami.Action { + enabled: chosenRoomDelegate.visible && root.room.canModifyParent(chosenRoomDelegate.roomId) + text: i18n("OK") + icon.name: "dialog-ok" + onTriggered: { + root.room.addParent(chosenRoomDelegate.roomId, makeCanonicalCheck.checked, existingOfficialCheck.checked) + root.close(); + } + } + ] + + contentItem: ColumnLayout { + spacing: 0 + FormCard.FormButtonDelegate { + visible: !chosenRoomDelegate.visible + text: i18nc("@action:button", "Pick room") + onClicked: { + let dialog = pageStack.pushDialogLayer("qrc:/org/kde/neochat/qml/JoinRoomPage.qml", {connection: root.room.connection, showOnlySpaces: true}, {title: i18nc("@title", "Choose Parent Space")}) + dialog.roomSelected.connect((roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined) => { + chosenRoomDelegate.roomId = roomId; + chosenRoomDelegate.displayName = displayName; + chosenRoomDelegate.avatarUrl = avatarUrl; + chosenRoomDelegate.alias = alias; + chosenRoomDelegate.topic = topic; + chosenRoomDelegate.memberCount = memberCount; + chosenRoomDelegate.isJoined = isJoined; + chosenRoomDelegate.visible = true; + }) + } + } + FormCard.AbstractFormDelegate { + id: chosenRoomDelegate + property string roomId + property string displayName + property url avatarUrl + property string alias + property string topic + property int memberCount + property bool isJoined + + visible: false + + contentItem: RowLayout { + Components.Avatar { + Layout.preferredWidth: Kirigami.Units.gridUnit * 2 + Layout.preferredHeight: Kirigami.Units.gridUnit * 2 + + source: chosenRoomDelegate.avatarUrl + name: chosenRoomDelegate.displayName + } + ColumnLayout { + Layout.fillWidth: true + RowLayout { + Layout.fillWidth: true + Kirigami.Heading { + Layout.fillWidth: true + level: 4 + text: chosenRoomDelegate.displayName + font.bold: true + textFormat: Text.PlainText + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + QQC2.Label { + visible: chosenRoomDelegate.isJoined + text: i18n("Joined") + color: Kirigami.Theme.linkColor + } + } + QQC2.Label { + Layout.fillWidth: true + visible: text + text: chosenRoomDelegate.topic ? chosenRoomDelegate.topic.replace(/(\r\n\t|\n|\r\t)/gm," ") : "" + textFormat: Text.PlainText + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + RowLayout { + Layout.fillWidth: true + Kirigami.Icon { + source: "user" + color: Kirigami.Theme.disabledTextColor + implicitHeight: Kirigami.Units.iconSizes.small + implicitWidth: Kirigami.Units.iconSizes.small + } + QQC2.Label { + text: chosenRoomDelegate.memberCount + " " + (chosenRoomDelegate.alias ?? chosenRoomDelegate.roomId) + color: Kirigami.Theme.disabledTextColor + elide: Text.ElideRight + Layout.fillWidth: true + } + } + } + } + + onClicked: { + let dialog = pageStack.pushDialogLayer("qrc:/org/kde/neochat/qml/JoinRoomPage.qml", {connection: root.room.connection, showOnlySpaces: true}, {title: i18nc("@title", "Explore Rooms")}) + dialog.roomSelected.connect((roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined) => { + chosenRoomDelegate.roomId = roomId; + chosenRoomDelegate.displayName = displayName; + chosenRoomDelegate.avatarUrl = avatarUrl; + chosenRoomDelegate.alias = alias; + chosenRoomDelegate.topic = topic; + chosenRoomDelegate.memberCount = memberCount; + chosenRoomDelegate.isJoined = isJoined; + chosenRoomDelegate.visible = true; + }) + } + } + FormCard.FormCheckDelegate { + id: existingOfficialCheck + property NeoChatRoom space: root.room.connection.room(chosenRoomDelegate.roomId) + text: i18n("Set this room as a child of the space %1", space?.displayName ?? "") + checked: enabled + + enabled: chosenRoomDelegate.visible && space && space.canSendState("m.space.child") + } + FormCard.FormTextDelegate { + visible: chosenRoomDelegate.visible && !root.room.canModifyParent(chosenRoomDelegate.roomId) + text: existingOfficialCheck.space ? (existingOfficialCheck.space.isSpace ? i18n("You do not have a high enough privilege level in the parent to set this state") : i18n("The selected room is not a space")) : i18n("You do not have the privileges to complete this action") + textItem.color: Kirigami.Theme.negativeTextColor + } + FormCard.FormCheckDelegate { + id: makeCanonicalCheck + text: i18n("Make this space the canonical parent") + checked: enabled + + enabled: chosenRoomDelegate.visible + } + } +}