Remove any dependencies on App from the spaces module.

Remove any dependencies on App from the spaces module. This requires moving some dialogs either to spaces, or libneochat if they're used more generically.
This commit is contained in:
James Graham
2025-05-18 14:38:57 +01:00
parent 2cb89807ef
commit 6ef7acc8e5
12 changed files with 46 additions and 36 deletions

View File

@@ -56,10 +56,8 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
qml/AccountMenu.qml
qml/CollapsedRoomDelegate.qml
qml/RoomPage.qml
qml/ExploreRoomsPage.qml
qml/ManualRoomDialog.qml
qml/ExplorerDelegate.qml
qml/InviteUserPage.qml
qml/ImageEditorPage.qml
qml/NeochatMaximizeComponent.qml
qml/TypingPane.qml
@@ -67,7 +65,6 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
qml/AttachmentPane.qml
qml/QuickFormatBar.qml
qml/UserDetailDialog.qml
qml/CreateRoomDialog.qml
qml/OpenFileDialog.qml
qml/KeyVerificationDialog.qml
qml/ConfirmLogoutDialog.qml
@@ -83,7 +80,6 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
qml/OsmLocationPlugin.qml
qml/FullScreenMap.qml
qml/ChooseRoomDialog.qml
qml/RemoveChildDialog.qml
qml/QrCodeMaximizeComponent.qml
qml/NotificationsView.qml
qml/ServerComboBox.qml
@@ -105,8 +101,6 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
qml/AvatarNotification.qml
qml/ReasonDialog.qml
qml/NewPollDialog.qml
qml/CreateSpaceDialog.qml
qml/SelectExistingRoomDialog.qml
DEPENDENCIES
QtCore
QtQuick

View File

@@ -1,73 +0,0 @@
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-or-later 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
Kirigami.Dialog {
id: root
property string parentId
required property NeoChatConnection connection
signal newChild(string childName)
title: i18nc("@title", "Create Room")
implicitWidth: Kirigami.Units.gridUnit * 20
standardButtons: Kirigami.Dialog.Cancel
customFooterActions: [
Kirigami.Action {
icon.name: "list-add-symbolic"
text: i18nc("@action:button Create new room", "Create")
enabled: roomNameField.text.length > 0
onTriggered: {
root.connection.createRoom(roomNameField.text, "", root.parentId, false);
root.newChild(roomNameField.text);
root.close();
}
}
]
Component.onCompleted: roomNameField.forceActiveFocus()
ColumnLayout {
spacing: Kirigami.Units.largeSpacing
FormCard.FormRadioDelegate {
id: privateTypeDelegate
text: i18nc("@info:label", "Private")
description: i18nc("@info:description", "This room can only be joined with an invite.")
checked: true
}
FormCard.FormRadioDelegate {
id: publicTypeDelegate
text: i18nc("@info:label", "Public")
description: i18nc("@info:description", "This room can be found and joined by anyone.")
}
FormCard.FormDelegateSeparator {}
FormCard.FormTextFieldDelegate {
id: roomNameField
label: i18nc("@info:label Name of the room", "Name:")
placeholderText: i18nc("@info:placeholder Placeholder for room name", "New Room")
}
FormCard.FormTextFieldDelegate {
id: roomAddressField
label: i18nc("@info:label Address or alias to refer to the room by", "Address:")
placeholderText: i18nc("@info:placeholder Placeholder address for the room", "new-room")
visible: publicTypeDelegate.checked
}
}
}

View File

@@ -1,64 +0,0 @@
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-or-later 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
Kirigami.Dialog {
id: root
property string parentId
required property NeoChatConnection connection
signal newChild(string childName)
title: i18nc("@title", "Create a Space")
implicitWidth: Kirigami.Units.gridUnit * 20
standardButtons: Kirigami.Dialog.Cancel
Component.onCompleted: roomNameField.forceActiveFocus()
customFooterActions: [
Kirigami.Action {
icon.name: "list-add-symbolic"
text: i18nc("@action:button Create new space", "Create")
enabled: roomNameField.text.length > 0
onTriggered: {
root.connection.createSpace(roomNameField.text, "", root.parentId, newOfficialCheck.checked);
root.newChild(roomNameField.text);
root.close();
}
}
]
ColumnLayout {
spacing: Kirigami.Units.largeSpacing
FormCard.FormTextFieldDelegate {
id: roomNameField
label: i18nc("@info:label Name of the space", "Name:")
placeholderText: i18nc("@info:placeholder", "New Space")
}
FormCard.FormDelegateSeparator {
above: roomNameField
below: newOfficialCheck
visible: newOfficialCheck.visible
}
FormCard.FormCheckDelegate {
id: newOfficialCheck
visible: root.parentId.length > 0
text: i18nc("@option:check As in make the space from which this dialog was created an official parent.", "Make this parent official")
checked: true
}
}
}

View File

@@ -1,140 +0,0 @@
// SPDX-FileCopyrightText: 2019 Black Hat <bhat@encom.eu.org>
// SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
// SPDX-License-Identifier: GPL-3.0-only
import QtQuick
import QtQuick.Controls as QQC2
import QtQuick.Layouts
import Qt.labs.qmlmodels
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.delegates as Delegates
import org.kde.neochat
/**
* @brief Component for finding rooms for the public list.
*
* This component is based on a SearchPage, adding the functionality to select or
* enter a server in the header, as well as the ability to manually type a room in
* if the public room search cannot find it.
*
* @sa SearchPage
*/
SearchPage {
id: root
/**
* @brief The connection for the current local user.
*/
required property NeoChatConnection connection
/**
* @brief Whether results should only includes spaces.
*/
property bool showOnlySpaces: spacesOnlyButton.checked
onShowOnlySpacesChanged: updateSearch()
/**
* @brief Whetherthe button to toggle the showOnlySpaces state should be shown.
*/
property bool showOnlySpacesButton: true
/**
* @brief Signal emitted when a room is selected.
*
* The signal contains all the room's info so that it can be acted
* upon as required, e.g. joining or entering the room or adding the room as
* the child of a space.
*/
signal roomSelected(string roomId, string displayName, url avatarUrl, string alias, string topic, int memberCount, bool isJoined)
title: i18nc("@action:title", "Explore Rooms")
customPlaceholderText: publicRoomListModel.redirectedText
customPlaceholderIcon: "data-warning"
Component.onCompleted: focusSearch()
headerTrailing: RowLayout {
QQC2.Button {
id: spacesOnlyButton
icon.name: "globe"
display: QQC2.Button.IconOnly
checkable: true
text: i18nc("@action:button", "Only show spaces")
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.text: text
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
}
ServerComboBox {
id: serverComboBox
connection: root.connection
}
}
model: PublicRoomListModel {
id: publicRoomListModel
connection: root.connection
server: serverComboBox.server
showOnlySpaces: root.showOnlySpaces
}
modelDelegate: ExplorerDelegate {
onRoomSelected: (roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined) => {
root.roomSelected(roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined);
root.closeDialog();
}
}
listHeaderDelegate: Delegates.RoundedItemDelegate {
id: delegate
onClicked: _private.openManualRoomDialog()
activeFocusOnTab: false // We handle moving to this item via up/down arrows, otherwise the tab order is wacky
text: i18n("Enter a Room Manually")
visible: publicRoomListModel.redirectedText.length === 0
icon.name: "compass"
icon.width: Kirigami.Units.gridUnit * 2
icon.height: Kirigami.Units.gridUnit * 2
contentItem: Kirigami.IconTitleSubtitle {
icon: icon.fromControlsIcon(delegate.icon)
title: delegate.text
subtitle: i18n("If you already know a room's address or alias, and it isn't shown here.")
}
}
listFooterDelegate: QQC2.ProgressBar {
width: ListView.view.width
leftInset: Kirigami.Units.largeSpacing
rightInset: Kirigami.Units.largeSpacing
visible: root.count !== 0 && publicRoomListModel.searching
indeterminate: true
}
searchFieldPlaceholder: i18n("Find a room…")
noResultPlaceholderMessage: i18nc("@info:label", "No public rooms found")
Component {
id: manualRoomDialog
ManualRoomDialog {}
}
QtObject {
id: _private
function openManualRoomDialog() {
let dialog = manualRoomDialog.createObject(root.QQC2.Overlay.overlay, {
connection: root.connection
});
dialog.parent = root.Window.window.overlay;
dialog.roomSelected.connect((roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined) => {
root.roomSelected(roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined);
root.closeDialog();
});
dialog.open();
}
}
}

View File

@@ -1,90 +0,0 @@
// SPDX-FileCopyrightText: 2019 Black Hat <bhat@encom.eu.org>
// SPDX-License-Identifier: GPL-3.0-only
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Controls as QQC2
import QtQuick.Layouts
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.delegates as Delegates
import org.kde.kirigamiaddons.labs.components as KirigamiComponents
import org.kde.neochat
SearchPage {
id: root
property NeoChatRoom room
title: i18nc("@title:dialog", "Invite a User")
searchFieldPlaceholder: i18nc("@info:placeholder", "Find a user…")
noResultPlaceholderMessage: i18nc("@info:placeholder", "No users found")
headerTrailing: QQC2.Button {
icon.name: "list-add"
display: QQC2.Button.IconOnly
enabled: root.model.searchText.match(/@(.+):(.+)/g) && !root.room.containsUser(root.model.searchText)
text: i18nc("@action:button", "Invite this User")
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.text: root.room.containsUser(root.model.searchText) ? i18nc("@info:tooltip", "User is either already a member or has been invited") : text
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
onClicked: root.room.inviteToRoom(root.model.searchText);
}
model: UserDirectoryListModel {
id: userDictListModel
connection: root.room.connection
}
modelDelegate: Delegates.RoundedItemDelegate {
id: delegate
required property string userId
required property string displayName
required property url avatarUrl
text: displayName
contentItem: RowLayout {
KirigamiComponents.Avatar {
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
source: delegate.avatarUrl
name: delegate.displayName
}
Delegates.SubtitleContentItem {
itemDelegate: delegate
subtitle: delegate.userId
labelItem.textFormat: Text.PlainText
}
QQC2.ToolButton {
id: inviteButton
readonly property bool inRoom: root.room && root.room.containsUser(delegate.userId)
icon.name: "document-send"
text: i18nc("@action:button", "Send invitation")
opacity: inRoom ? 0.5 : 1
enabled: !inRoom
onClicked: {
inviteButton.enabled = false;
root.room.inviteToRoom(delegate.userId);
}
QQC2.ToolTip.text: !inRoom ? text : i18nc("@info:tooltip", "User is either already a member or has been invited")
QQC2.ToolTip.visible: inviteButton.hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
}
}
}
}

View File

@@ -1,49 +0,0 @@
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
import QtQuick
import QtQuick.Layouts
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard
import org.kde.neochat
Kirigami.Dialog {
id: root
required property NeoChatRoom parentRoom
required property string roomId
required property string displayName
required property string parentDisplayName
required property bool canSetParent
required property bool isDeclaredParent
title: i18nc("@title", "Remove Child")
width: Math.min(applicationWindow().width, Kirigami.Units.gridUnit * 24)
standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel
onAccepted: parentRoom.removeChild(root.roomId, removeOfficalCheck.checked)
contentItem: ColumnLayout {
spacing: 0
FormCard.FormTextDelegate {
text: i18n("The child %1 will be removed from the space %2", root.displayName, root.parentDisplayName)
textItem.wrapMode: Text.Wrap
}
FormCard.FormCheckDelegate {
id: removeOfficalCheck
visible: root.isDeclaredParent
enabled: root.canSetParent
text: i18n("The current space is the official parent of this room, should this be cleared?")
checked: root.canSetParent
}
}
}

View File

@@ -137,7 +137,11 @@ Kirigami.Page {
id: spaceLoader
active: root.currentRoom && root.currentRoom.isSpace
anchors.fill: parent
sourceComponent: SpaceHomePage {}
sourceComponent: SpaceHomePage {
room: root.currentRoom
onRequestLeaveRoom: room => RoomManager.leaveRoom(room);
}
}
Loader {

View File

@@ -1,180 +0,0 @@
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-or-later 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
Kirigami.Dialog {
id: root
property string parentId
required property NeoChatConnection connection
signal addChild(string childId, bool setChildParent, bool canonical)
signal newChild(string childName)
title: i18nc("@title", "Select Existing Room")
implicitWidth: Kirigami.Units.gridUnit * 20
standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel
onAccepted: root.addChild(chosenRoomDelegate.roomId, existingOfficialCheck.checked, makeCanonicalCheck.checked);
Component.onCompleted: pickRoomDelegate.forceActiveFocus()
ColumnLayout {
spacing: Kirigami.Units.largeSpacing
FormCard.FormButtonDelegate {
id: pickRoomDelegate
visible: !chosenRoomDelegate.visible
text: i18nc("@action:button", "Pick Room")
onClicked: {
let dialog = pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'ExploreRoomsPage'), {
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: 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(Qt.createComponent('org.kde.neochat', 'ExploreRoomsPage'), {
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.FormDelegateSeparator {
below: existingOfficialCheck
}
FormCard.FormCheckDelegate {
id: existingOfficialCheck
visible: root.parentId.length > 0
text: i18nc("@option:check As in make the space from which this dialog was created an official parent.", "Make this parent official")
description: enabled ? i18nc("@info:description", "You have the required privilege level in the child to set this state") : i18n("You do not have a high enough privilege level in the child to set this state")
checked: enabled
enabled: {
if (chosenRoomDelegate.visible) {
let room = root.connection.room(chosenRoomDelegate.roomId);
if (room) {
if (room.canSendState("m.space.parent")) {
return true;
}
}
}
return false;
}
}
FormCard.FormDelegateSeparator {
above: existingOfficialCheck
below: makeCanonicalCheck
}
FormCard.FormCheckDelegate {
id: makeCanonicalCheck
text: i18nc("@option:check The canonical parent is the default one if a room has multiple parent spaces.", "Make this space the canonical parent")
description: i18nc("@info:description", "The canonical parent is the default one if a room has multiple parent spaces.")
checked: enabled
enabled: existingOfficialCheck.enabled
}
}
}