Remove Space Child

Add button to remove a child in a space if the user has the correct power levels
This commit is contained in:
James Graham
2023-09-29 20:15:17 +00:00
parent 925393deab
commit eba62103a4
7 changed files with 157 additions and 3 deletions

View File

@@ -280,6 +280,7 @@ qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
qml/ShareAction.qml
qml/SpaceHomePage.qml
qml/SpaceHierarchyDelegate.qml
qml/RemoveChildDialog.qml
RESOURCES
qml/confetti.png
qml/glowdot.png

View File

@@ -71,7 +71,7 @@ void SpaceChildrenModel::refreshModel()
delete m_rootItem;
m_loading = true;
Q_EMIT loadingChanged();
m_rootItem = new SpaceTreeItem();
m_rootItem = new SpaceTreeItem(nullptr, m_space->id(), m_space->displayName(), m_space->canonicalAlias());
endResetModel();
auto job = m_space->connection()->callApi<Quotient::GetSpaceHierarchyJob>(m_space->id(), Quotient::none, Quotient::none, 1);
m_currentJobs.append(job);
@@ -193,12 +193,50 @@ QVariant SpaceChildrenModel::data(const QModelIndex &index, int role) const
return child->isSpace();
}
if (role == CanAddChildrenRole) {
auto connection = Controller::instance().activeConnection();
if (const auto room = static_cast<NeoChatRoom *>(connection->room(child->id()))) {
if (const auto room = static_cast<NeoChatRoom *>(m_space->connection()->room(child->id()))) {
return room->canSendState(QLatin1String("m.space.child"));
}
return false;
}
if (role == ParentDisplayNameRole) {
const auto parent = child->parentItem();
auto displayName = parent->name();
if (!displayName.isEmpty()) {
return displayName;
}
displayName = parent->canonicalAlias();
if (!displayName.isEmpty()) {
return displayName;
}
return parent->id();
}
if (role == CanSetParentRole) {
if (const auto room = static_cast<NeoChatRoom *>(m_space->connection()->room(child->id()))) {
return room->canSendState(QLatin1String("m.space.parent"));
}
return false;
}
if (role == IsDeclaredParentRole) {
if (const auto room = static_cast<NeoChatRoom *>(m_space->connection()->room(child->id()))) {
return room->currentState().contains(QLatin1String("m.space.parent"), child->parentItem()->id());
}
return false;
}
if (role == CanRemove) {
const auto parent = child->parentItem();
if (const auto room = static_cast<NeoChatRoom *>(m_space->connection()->room(parent->id()))) {
return room->canSendState(QLatin1String("m.space.child"));
}
return false;
}
if (role == ParentRoomRole) {
if (const auto parentRoom = static_cast<NeoChatRoom *>(m_space->connection()->room(child->parentItem()->id()))) {
return QVariant::fromValue(parentRoom);
}
return QVariant::fromValue(nullptr);
}
return {};
}
@@ -274,6 +312,11 @@ QHash<int, QByteArray> SpaceChildrenModel::roleNames() const
roles[AliasRole] = "alias";
roles[IsSpaceRole] = "isSpace";
roles[CanAddChildrenRole] = "canAddChildren";
roles[ParentDisplayNameRole] = "parentDisplayName";
roles[CanSetParentRole] = "canSetParent";
roles[IsDeclaredParentRole] = "isDeclaredParent";
roles[CanRemove] = "canRemove";
roles[ParentRoomRole] = "parentRoom";
return roles;
}

View File

@@ -45,6 +45,11 @@ public:
IsJoinedRole,
IsSpaceRole,
CanAddChildrenRole,
ParentDisplayNameRole,
CanSetParentRole,
IsDeclaredParentRole,
CanRemove,
ParentRoomRole,
};
explicit SpaceChildrenModel(QObject *parent = nullptr);

View File

@@ -1128,6 +1128,25 @@ void NeoChatRoom::addChild(const QString &childId, bool setChildParent)
}
}
void NeoChatRoom::removeChild(const QString &childId, bool unsetChildParent)
{
if (!isSpace()) {
return;
}
if (!canSendEvent("m.space.child"_ls)) {
return;
}
setState("m.space.child"_ls, childId, {});
if (unsetChildParent) {
if (auto child = static_cast<NeoChatRoom *>(connection()->room(childId))) {
if (child->canSendState("m.space.parent"_ls) && child->currentState().contains("m.space.parent"_ls, id())) {
child->setState("m.space.parent"_ls, id(), {});
}
}
}
}
PushNotificationState::State NeoChatRoom::pushNotificationState() const
{
return m_currentPushNotificationState;

View File

@@ -591,6 +591,8 @@ public:
Q_INVOKABLE void addChild(const QString &childId, bool setChildParent = false);
Q_INVOKABLE void removeChild(const QString &childId, bool unsetChildParent = false);
bool isInvite() const;
Q_INVOKABLE void clearInvitationNotification();

View File

@@ -0,0 +1,53 @@
// 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.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
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: FormCard.FormCardPage {
FormCard.FormCard {
Layout.topMargin: Kirigami.Units.largeSpacing
FormCard.FormTextDelegate {
text: i18n("The child ") + root.displayName + i18n(" will be removed from the space ") + 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

@@ -26,6 +26,11 @@ Item {
required property string topic
required property bool isJoined
required property bool canAddChildren
required property string parentDisplayName
required property bool canSetParent
required property bool isDeclaredParent
required property bool canRemove
required property NeoChatRoom parentRoom
signal createRoom()
signal enterRoom()
@@ -95,8 +100,29 @@ Item {
visible: root.isSpace && root.canAddChildren
text: i18nc("@button", "Add new child")
icon.name: "list-add"
display: QQC2.AbstractButton.IconOnly
onClicked: root.createRoom()
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
}
QQC2.ToolButton {
visible: root.canRemove
text: i18nc("@button", "Remove")
icon.name: "list-remove"
display: QQC2.AbstractButton.IconOnly
onClicked: {
removeChildDialog.createObject(QQC2.ApplicationWindow.overlay, {
parentRoom: root.parentRoom,
roomId: root.roomId,
displayName: root.displayName,
parentDisplayName: root.parentDisplayName,
canSetParent: root.canSetParent,
isDeclaredParent: root.isDeclaredParent
}).open();
}
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
@@ -128,4 +154,9 @@ Item {
parentWidth: root.treeView ? root.treeView.width : 0
}
Component {
id: removeChildDialog
RemoveChildDialog {}
}
}