File indexing completed on 2024-04-28 16:10:26

0001 // SPDX-FileCopyrightText: 2022 Snehit Sah <hi@snehit.dev>
0002 // SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0003 
0004 #include "spacehierarchycache.h"
0005 
0006 #include <Quotient/csapi/space_hierarchy.h>
0007 #include <Quotient/qt_connection_util.h>
0008 
0009 #include "controller.h"
0010 #include "neochatroom.h"
0011 
0012 using namespace Quotient;
0013 
0014 SpaceHierarchyCache::SpaceHierarchyCache(QObject *parent)
0015     : QObject{parent}
0016 {
0017     cacheSpaceHierarchy();
0018     connect(&Controller::instance(), &Controller::activeConnectionChanged, this, [this]() {
0019         cacheSpaceHierarchy();
0020         connect(Controller::instance().activeConnection(), &Connection::joinedRoom, this, &SpaceHierarchyCache::addSpaceToHierarchy);
0021         connect(Controller::instance().activeConnection(), &Connection::aboutToDeleteRoom, this, &SpaceHierarchyCache::removeSpaceFromHierarchy);
0022     });
0023 }
0024 
0025 void SpaceHierarchyCache::cacheSpaceHierarchy()
0026 {
0027     auto connection = Controller::instance().activeConnection();
0028     if (!connection) {
0029         return;
0030     }
0031 
0032     const auto &roomList = connection->allRooms();
0033     for (const auto &room : roomList) {
0034         const auto neoChatRoom = static_cast<NeoChatRoom *>(room);
0035         if (neoChatRoom->isSpace()) {
0036             populateSpaceHierarchy(neoChatRoom->id());
0037         } else {
0038             connectSingleShot(neoChatRoom, &Room::baseStateLoaded, neoChatRoom, [this, neoChatRoom]() {
0039                 if (neoChatRoom->isSpace()) {
0040                     populateSpaceHierarchy(neoChatRoom->id());
0041                 }
0042             });
0043         }
0044     }
0045 }
0046 
0047 void SpaceHierarchyCache::populateSpaceHierarchy(const QString &spaceId)
0048 {
0049     auto connection = Controller::instance().activeConnection();
0050     if (!connection) {
0051         return;
0052     }
0053     auto job = connection->callApi<GetSpaceHierarchyJob>(spaceId);
0054 
0055     connect(job, &BaseJob::success, this, [this, job, spaceId]() {
0056         const auto rooms = job->rooms();
0057         QVector<QString> roomList;
0058         for (unsigned long i = 0; i < rooms.size(); ++i) {
0059             for (const auto &state : rooms[i].childrenState) {
0060                 roomList.push_back(state->stateKey());
0061             }
0062         }
0063         m_spaceHierarchy.insert(spaceId, roomList);
0064         Q_EMIT spaceHierarchyChanged();
0065     });
0066 }
0067 
0068 void SpaceHierarchyCache::addSpaceToHierarchy(Quotient::Room *room)
0069 {
0070     connectSingleShot(room, &Quotient::Room::baseStateLoaded, this, [this, room]() {
0071         const auto neoChatRoom = static_cast<NeoChatRoom *>(room);
0072         if (neoChatRoom->isSpace()) {
0073             populateSpaceHierarchy(neoChatRoom->id());
0074         }
0075     });
0076 }
0077 
0078 void SpaceHierarchyCache::removeSpaceFromHierarchy(Quotient::Room *room)
0079 {
0080     const auto neoChatRoom = static_cast<NeoChatRoom *>(room);
0081     if (neoChatRoom->isSpace()) {
0082         m_spaceHierarchy.remove(neoChatRoom->id());
0083     }
0084 }
0085 
0086 QVector<QString> &SpaceHierarchyCache::getRoomListForSpace(const QString &spaceId, bool updateCache)
0087 {
0088     if (updateCache) {
0089         populateSpaceHierarchy(spaceId);
0090     }
0091     return m_spaceHierarchy[spaceId];
0092 }
0093 
0094 bool SpaceHierarchyCache::isChildSpace(const QString &spaceId) const
0095 {
0096     const auto childrens = m_spaceHierarchy.values();
0097     for (const auto &children : childrens) {
0098         if (children.contains(spaceId)) {
0099             return true;
0100         }
0101     }
0102     return false;
0103 }
0104 
0105 #include "moc_spacehierarchycache.cpp"