Support editing space children

This commit is contained in:
Nicolas Werner 2022-08-10 00:20:44 +02:00
parent 68c02da6c8
commit 376612e4eb
No known key found for this signature in database
GPG key ID: C8D75E610773F2D9
9 changed files with 362 additions and 45 deletions

View file

@ -5,20 +5,29 @@
#include "CommunitiesModel.h"
#include <mtx/responses/common.hpp>
#include <set>
#include "Cache.h"
#include "Cache_p.h"
#include "ChatPage.h"
#include "Logging.h"
#include "MatrixClient.h"
#include "Permissions.h"
#include "UserSettingsPage.h"
#include "Utils.h"
#include "timeline/TimelineModel.h"
Q_DECLARE_METATYPE(SpaceItem)
CommunitiesModel::CommunitiesModel(QObject *parent)
: QAbstractListModel(parent)
, hiddenTagIds_{UserSettings::instance()->hiddenTags()}
, mutedTagIds_{UserSettings::instance()->mutedTags()}
{}
{
static auto ignore = qRegisterMetaType<SpaceItem>();
(void)ignore;
}
QHash<int, QByteArray>
CommunitiesModel::roleNames() const
@ -723,3 +732,156 @@ FilteredCommunitiesModel::filterAcceptsRow(int sourceRow, const QModelIndex &) c
return true;
}
QVariantList
CommunitiesModel::spaceChildrenListFromIndex(QString room, int idx) const
{
if (idx < -1)
return {};
auto room_ = room.toStdString();
int begin = idx + 1;
int end = idx >= 0 ? this->spaceOrder_.lastChild(idx) + 1 : this->spaceOrder_.size();
QVariantList ret;
bool canSendParent = Permissions(room).canChange(qml_mtx_events::SpaceParent);
for (int i = begin; i < end; i++) {
const auto &e = spaceOrder_.tree[i];
if (e.depth == spaceOrder_.tree[begin].depth && spaces_.count(e.id)) {
bool canSendChild = Permissions(e.id).canChange(qml_mtx_events::SpaceChild);
auto spaceId = e.id.toStdString();
auto child =
cache::client()->getStateEvent<mtx::events::state::space::Child>(spaceId, room_);
auto parent =
cache::client()->getStateEvent<mtx::events::state::space::Parent>(room_, spaceId);
bool childValid =
child && !child->content.via.value_or(std::vector<std::string>{}).empty();
bool parentValid =
parent && !parent->content.via.value_or(std::vector<std::string>{}).empty();
bool canonical = parent && parent->content.canonical;
if (e.id == room) {
canonical = parentValid = childValid = canSendChild = canSendParent = false;
}
ret.push_back(
QVariant::fromValue(SpaceItem(e.id,
QString::fromStdString(spaces_.at(e.id).name),
i,
childValid,
parentValid,
canonical,
canSendChild,
canSendParent)));
}
}
nhlog::ui()->critical("Returning {} spaces", ret.size());
return ret;
}
void
CommunitiesModel::updateSpaceStatus(QString space,
QString room,
bool setParent,
bool setChild,
bool canonical) const
{
nhlog::ui()->critical("Setting space {} children {}: {} {} {}",
space.toStdString(),
room.toStdString(),
setParent,
setChild,
canonical);
auto child =
cache::client()
->getStateEvent<mtx::events::state::space::Child>(space.toStdString(), room.toStdString())
.value_or(mtx::events::StateEvent<mtx::events::state::space::Child>{})
.content;
auto parent =
cache::client()
->getStateEvent<mtx::events::state::space::Parent>(room.toStdString(), space.toStdString())
.value_or(mtx::events::StateEvent<mtx::events::state::space::Parent>{})
.content;
if (setChild) {
if (!child.via || child.via->empty()) {
child.via = utils::roomVias(room.toStdString());
child.suggested = true;
http::client()->send_state_event(
space.toStdString(),
room.toStdString(),
child,
[space, room](mtx::responses::EventId, mtx::http::RequestErr err) {
if (err) {
ChatPage::instance()->showNotification(
tr("Failed to update space child: %1")
.arg(QString::fromStdString(err->matrix_error.error)));
nhlog::net()->error("Failed to update child {} of {}: {}",
room.toStdString(),
space.toStdString());
}
});
}
} else {
if (child.via && !child.via->empty()) {
http::client()->send_state_event(
space.toStdString(),
room.toStdString(),
mtx::events::state::space::Child{},
[space, room](mtx::responses::EventId, mtx::http::RequestErr err) {
if (err) {
ChatPage::instance()->showNotification(
tr("Failed to delete space child: %1")
.arg(QString::fromStdString(err->matrix_error.error)));
nhlog::net()->error("Failed to delete child {} of {}: {}",
room.toStdString(),
space.toStdString());
}
});
}
}
if (setParent) {
if (!parent.via || parent.via->empty() || canonical != parent.canonical) {
parent.via = utils::roomVias(room.toStdString());
parent.canonical = canonical;
http::client()->send_state_event(
room.toStdString(),
space.toStdString(),
parent,
[space, room](mtx::responses::EventId, mtx::http::RequestErr err) {
if (err) {
ChatPage::instance()->showNotification(
tr("Failed to update space parent: %1")
.arg(QString::fromStdString(err->matrix_error.error)));
nhlog::net()->error("Failed to update parent {} of {}: {}",
space.toStdString(),
room.toStdString());
}
});
}
} else {
if (parent.via && !parent.via->empty()) {
http::client()->send_state_event(
room.toStdString(),
space.toStdString(),
mtx::events::state::space::Parent{},
[space, room](mtx::responses::EventId, mtx::http::RequestErr err) {
if (err) {
ChatPage::instance()->showNotification(
tr("Failed to delete space parent: %1")
.arg(QString::fromStdString(err->matrix_error.error)));
nhlog::net()->error("Failed to delete parent {} of {}: {}",
space.toStdString(),
room.toStdString());
}
});
}
}
}