diff options
Diffstat (limited to 'src/timeline/CommunitiesModel.cpp')
-rw-r--r-- | src/timeline/CommunitiesModel.cpp | 164 |
1 files changed, 163 insertions, 1 deletions
diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index 7b267bcb..6d60c2b9 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -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()); + } + }); + } + } +} |