File indexing completed on 2024-04-21 04:59:31

0001 
0002 // SPDX-FileCopyrightText: 2022 Snehit Sah <hi@snehit.dev>
0003 // SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0004 
0005 #pragma once
0006 
0007 #include <QHash>
0008 #include <QList>
0009 #include <QObject>
0010 #include <QQmlEngine>
0011 #include <QString>
0012 
0013 #include "neochatconnection.h"
0014 
0015 namespace Quotient
0016 {
0017 class Room;
0018 }
0019 
0020 /**
0021  * @class SpaceHierarchyCache
0022  *
0023  * A class to store the child spaces for each space.
0024  *
0025  * Spaces are cached on startup or when the user enters a new space.
0026  */
0027 class SpaceHierarchyCache : public QObject
0028 {
0029     Q_OBJECT
0030     QML_ELEMENT
0031     QML_SINGLETON
0032 
0033     Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
0034 
0035 public:
0036     static SpaceHierarchyCache &instance()
0037     {
0038         static SpaceHierarchyCache _instance;
0039         return _instance;
0040     }
0041     static SpaceHierarchyCache *create(QQmlEngine *engine, QJSEngine *)
0042     {
0043         engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership);
0044         return &instance();
0045     }
0046 
0047     /**
0048      * @brief Whether the given room is a member of the given space.
0049      */
0050     Q_INVOKABLE bool isSpaceChild(const QString &spaceId, const QString &roomId);
0051 
0052     /**
0053      * @brief Return the list of child rooms for the given space ID.
0054      */
0055     [[nodiscard]] QList<QString> &getRoomListForSpace(const QString &spaceId, bool updateCache);
0056 
0057     /**
0058      * @brief Returns whether the room is a child space of any space.
0059      *
0060      * @note We need to do this from the hierarchy as it is not guaranteed that the
0061      *       child knows it's in a space. See
0062      *       https://spec.matrix.org/v1.8/client-server-api/#managing-roomsspaces-included-in-a-space
0063      */
0064     [[nodiscard]] bool isChild(const QString &roomId) const;
0065 
0066     NeoChatConnection *connection() const;
0067     void setConnection(NeoChatConnection *connection);
0068 
0069 Q_SIGNALS:
0070     void spaceHierarchyChanged();
0071     void connectionChanged();
0072 
0073 private Q_SLOTS:
0074     void addSpaceToHierarchy(Quotient::Room *room);
0075     void removeSpaceFromHierarchy(Quotient::Room *room);
0076 
0077 private:
0078     explicit SpaceHierarchyCache(QObject *parent = nullptr);
0079 
0080     QList<QString> m_activeSpaceRooms;
0081     QHash<QString, QList<QString>> m_spaceHierarchy;
0082     void cacheSpaceHierarchy();
0083     void populateSpaceHierarchy(const QString &spaceId);
0084     NeoChatConnection *m_connection;
0085 };