Show spaces horizontal bar
### Summary This merge request adds a horizontal bar at top of room list, which shows spaces. By clicking on a space, user can filter out rooms belonging only to that specific space. ### Pending/ Help needed #### Segfault when loading active connection on startup Refer `void SortFilterRoomListModel::cacheSpaceHierarchy()` ([link](8c372800d7 (b969e462c30df43ef3714ea441948d8d8027f6a0_117_126))) in `src/sortfilterroomlistmodel.cpp`. On [line 129](8c372800d7 (b969e462c30df43ef3714ea441948d8d8027f6a0_117_129)), I have called `connection->allRooms()`, which segfaults if the active connection hasn't been loaded yet. Is there a way to ensure that `Controller::instance().activeConnection()` on line 128 waits till connection is loaded? #### Avatars Avatars on space horizontal bar aren't aligned to vertical middle. I'll need help with that. Using the code below doesn't help with padding ```qml delegate: QQC2.Control { topPadding: 10 contentItem: Kirigami.Avatar { ..... } } ``` This complains about uninitialized properties in `Kirigami.Avatar`. (`id`, `currentRoom`, `avatar`, `index` are properties utilized during run time) After we get around these two issue, this MR will be ready from my side.
This commit is contained in:
@@ -15,6 +15,95 @@ import NeoChat.Component 1.0
|
|||||||
import NeoChat.Menu 1.0
|
import NeoChat.Menu 1.0
|
||||||
|
|
||||||
Kirigami.ScrollablePage {
|
Kirigami.ScrollablePage {
|
||||||
|
|
||||||
|
header: ColumnLayout {
|
||||||
|
visible: !page.collapsedMode
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: spaceList
|
||||||
|
property string activeSpaceId: ''
|
||||||
|
|
||||||
|
orientation: Qt.Horizontal
|
||||||
|
spacing: Kirigami.Units.largeSpacing
|
||||||
|
clip:true
|
||||||
|
visible: spaceList.count > 0
|
||||||
|
|
||||||
|
Layout.preferredHeight: Kirigami.Units.gridUnit * 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
model: SortFilterSpaceListModel {
|
||||||
|
id: sortFilterSpaceListModel
|
||||||
|
sourceModel: RoomListModel {
|
||||||
|
id: spaceListModel
|
||||||
|
connection: Controller.activeConnection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: SpaceHierarchyCache
|
||||||
|
function onSpaceHierarchyChanged() {
|
||||||
|
if (spaceList.activeSpaceId !== '') {
|
||||||
|
sortFilterRoomListModel.activeSpaceRooms = SpaceHierarchyCache.getRoomListForSpace(spaceList.activeSpaceId, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header: QQC2.Control {
|
||||||
|
contentItem: QQC2.RoundButton {
|
||||||
|
id: homeButton
|
||||||
|
flat: true
|
||||||
|
padding: Kirigami.Units.gridUnit / 2
|
||||||
|
icon.name: "home"
|
||||||
|
text: i18nc('@action:button', 'Show All Rooms')
|
||||||
|
display: QQC2.AbstractButton.IconOnly
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
sortFilterRoomListModel.activeSpaceRooms = [];
|
||||||
|
spaceList.activeSpaceId = '';
|
||||||
|
listView.positionViewAtIndex(0, ListView.Beginning);
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.ToolTip {
|
||||||
|
text: homeButton.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: QQC2.Control {
|
||||||
|
required property string avatar
|
||||||
|
required property var currentRoom
|
||||||
|
required property int index
|
||||||
|
required property string id
|
||||||
|
implicitWidth: ListView.view.headerItem.implicitWidth
|
||||||
|
implicitHeight: ListView.view.headerItem.implicitHeight
|
||||||
|
|
||||||
|
contentItem: Kirigami.Avatar {
|
||||||
|
id: del
|
||||||
|
|
||||||
|
actions.main: Kirigami.Action {
|
||||||
|
id: enterSpaceAction
|
||||||
|
onTriggered: {
|
||||||
|
spaceList.activeSpaceId = id;
|
||||||
|
sortFilterRoomListModel.activeSpaceRooms = SpaceHierarchyCache.getRoomListForSpace(id, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.ToolTip {
|
||||||
|
text: currentRoom.displayName
|
||||||
|
}
|
||||||
|
|
||||||
|
source: avatar !== "" ? "image://mxc/" + avatar : ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Kirigami.Separator {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
id: page
|
id: page
|
||||||
|
|
||||||
title: i18n("Rooms")
|
title: i18n("Rooms")
|
||||||
@@ -68,7 +157,6 @@ Kirigami.ScrollablePage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: listView
|
id: listView
|
||||||
|
|
||||||
@@ -100,6 +188,8 @@ Kirigami.ScrollablePage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
Kirigami.PlaceholderMessage {
|
Kirigami.PlaceholderMessage {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: parent.width - (Kirigami.Units.largeSpacing * 4)
|
width: parent.width - (Kirigami.Units.largeSpacing * 4)
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ add_library(neochat STATIC
|
|||||||
messageeventmodel.cpp
|
messageeventmodel.cpp
|
||||||
messagefiltermodel.cpp
|
messagefiltermodel.cpp
|
||||||
roomlistmodel.cpp
|
roomlistmodel.cpp
|
||||||
|
sortfilterspacelistmodel.cpp
|
||||||
|
spacehierarchycache.cpp
|
||||||
roommanager.cpp
|
roommanager.cpp
|
||||||
neochatroom.cpp
|
neochatroom.cpp
|
||||||
neochatuser.cpp
|
neochatuser.cpp
|
||||||
|
|||||||
@@ -69,6 +69,8 @@
|
|||||||
#include "roomlistmodel.h"
|
#include "roomlistmodel.h"
|
||||||
#include "roommanager.h"
|
#include "roommanager.h"
|
||||||
#include "sortfilterroomlistmodel.h"
|
#include "sortfilterroomlistmodel.h"
|
||||||
|
#include "sortfilterspacelistmodel.h"
|
||||||
|
#include "spacehierarchycache.h"
|
||||||
#include "urlhelper.h"
|
#include "urlhelper.h"
|
||||||
#include "userdirectorylistmodel.h"
|
#include "userdirectorylistmodel.h"
|
||||||
#include "userlistmodel.h"
|
#include "userlistmodel.h"
|
||||||
@@ -177,6 +179,7 @@ int main(int argc, char *argv[])
|
|||||||
Login *login = new Login();
|
Login *login = new Login();
|
||||||
ChatBoxHelper chatBoxHelper;
|
ChatBoxHelper chatBoxHelper;
|
||||||
UrlHelper urlHelper;
|
UrlHelper urlHelper;
|
||||||
|
SpaceHierarchyCache spaceHierarchyCache;
|
||||||
|
|
||||||
#ifdef HAVE_COLORSCHEME
|
#ifdef HAVE_COLORSCHEME
|
||||||
ColorSchemer colorScheme;
|
ColorSchemer colorScheme;
|
||||||
@@ -197,6 +200,7 @@ int main(int argc, char *argv[])
|
|||||||
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "EmojiModel", new EmojiModel(&app));
|
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "EmojiModel", new EmojiModel(&app));
|
||||||
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "CommandModel", new CommandModel(&app));
|
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "CommandModel", new CommandModel(&app));
|
||||||
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "AccountRegistry", &Quotient::AccountRegistry::instance());
|
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "AccountRegistry", &Quotient::AccountRegistry::instance());
|
||||||
|
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "SpaceHierarchyCache", &spaceHierarchyCache);
|
||||||
qmlRegisterType<ActionsHandler>("org.kde.neochat", 1, 0, "ActionsHandler");
|
qmlRegisterType<ActionsHandler>("org.kde.neochat", 1, 0, "ActionsHandler");
|
||||||
qmlRegisterType<ChatDocumentHandler>("org.kde.neochat", 1, 0, "ChatDocumentHandler");
|
qmlRegisterType<ChatDocumentHandler>("org.kde.neochat", 1, 0, "ChatDocumentHandler");
|
||||||
qmlRegisterType<RoomListModel>("org.kde.neochat", 1, 0, "RoomListModel");
|
qmlRegisterType<RoomListModel>("org.kde.neochat", 1, 0, "RoomListModel");
|
||||||
@@ -209,6 +213,7 @@ int main(int argc, char *argv[])
|
|||||||
qmlRegisterType<PublicRoomListModel>("org.kde.neochat", 1, 0, "PublicRoomListModel");
|
qmlRegisterType<PublicRoomListModel>("org.kde.neochat", 1, 0, "PublicRoomListModel");
|
||||||
qmlRegisterType<UserDirectoryListModel>("org.kde.neochat", 1, 0, "UserDirectoryListModel");
|
qmlRegisterType<UserDirectoryListModel>("org.kde.neochat", 1, 0, "UserDirectoryListModel");
|
||||||
qmlRegisterType<SortFilterRoomListModel>("org.kde.neochat", 1, 0, "SortFilterRoomListModel");
|
qmlRegisterType<SortFilterRoomListModel>("org.kde.neochat", 1, 0, "SortFilterRoomListModel");
|
||||||
|
qmlRegisterType<SortFilterSpaceListModel>("org.kde.neochat", 1, 0, "SortFilterSpaceListModel");
|
||||||
qmlRegisterType<DevicesModel>("org.kde.neochat", 1, 0, "DevicesModel");
|
qmlRegisterType<DevicesModel>("org.kde.neochat", 1, 0, "DevicesModel");
|
||||||
qmlRegisterUncreatableType<RoomMessageEvent>("org.kde.neochat", 1, 0, "RoomMessageEvent", "ENUM");
|
qmlRegisterUncreatableType<RoomMessageEvent>("org.kde.neochat", 1, 0, "RoomMessageEvent", "ENUM");
|
||||||
qmlRegisterUncreatableType<NeoChatRoomType>("org.kde.neochat", 1, 0, "NeoChatRoomType", "ENUM");
|
qmlRegisterUncreatableType<NeoChatRoomType>("org.kde.neochat", 1, 0, "NeoChatRoomType", "ENUM");
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "events/accountdataevents.h"
|
#include "events/accountdataevents.h"
|
||||||
#include "events/reactionevent.h"
|
#include "events/reactionevent.h"
|
||||||
#include "events/roomcanonicalaliasevent.h"
|
#include "events/roomcanonicalaliasevent.h"
|
||||||
|
#include "events/roomcreateevent.h"
|
||||||
#include "events/roommessageevent.h"
|
#include "events/roommessageevent.h"
|
||||||
#include "events/roompowerlevelsevent.h"
|
#include "events/roompowerlevelsevent.h"
|
||||||
#include "events/typingevent.h"
|
#include "events/typingevent.h"
|
||||||
@@ -869,3 +870,17 @@ void NeoChatRoom::clearInvitationNotification()
|
|||||||
{
|
{
|
||||||
NotificationsManager::instance().clearInvitationNotification(id());
|
NotificationsManager::instance().clearInvitationNotification(id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NeoChatRoom::isSpace()
|
||||||
|
{
|
||||||
|
const auto creationEvent = this->creation();
|
||||||
|
if (!creationEvent) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef QUOTIENT_07
|
||||||
|
return creationEvent->roomType() == RoomType::Space;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ public:
|
|||||||
/// \see lastEventToString
|
/// \see lastEventToString
|
||||||
[[nodiscard]] QString subtitleText();
|
[[nodiscard]] QString subtitleText();
|
||||||
|
|
||||||
|
[[nodiscard]] bool isSpace();
|
||||||
|
|
||||||
bool isEventHighlighted(const Quotient::RoomEvent *e) const;
|
bool isEventHighlighted(const Quotient::RoomEvent *e) const;
|
||||||
|
|
||||||
[[nodiscard]] QString joinRule() const;
|
[[nodiscard]] QString joinRule() const;
|
||||||
|
|||||||
@@ -408,6 +408,10 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
|
|||||||
if (role == IdRole) {
|
if (role == IdRole) {
|
||||||
return room->id();
|
return room->id();
|
||||||
}
|
}
|
||||||
|
if (role == IsSpaceRole) {
|
||||||
|
return room->isSpace();
|
||||||
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,6 +443,8 @@ QHash<int, QByteArray> RoomListModel::roleNames() const
|
|||||||
roles[CurrentRoomRole] = "currentRoom";
|
roles[CurrentRoomRole] = "currentRoom";
|
||||||
roles[CategoryVisibleRole] = "categoryVisible";
|
roles[CategoryVisibleRole] = "categoryVisible";
|
||||||
roles[SubtitleTextRole] = "subtitleText";
|
roles[SubtitleTextRole] = "subtitleText";
|
||||||
|
roles[IsSpaceRole] = "isSpace";
|
||||||
|
roles[IdRole] = "id";
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public:
|
|||||||
SubtitleTextRole,
|
SubtitleTextRole,
|
||||||
AvatarImageRole,
|
AvatarImageRole,
|
||||||
IdRole,
|
IdRole,
|
||||||
|
IsSpaceRole,
|
||||||
};
|
};
|
||||||
Q_ENUM(EventRoles)
|
Q_ENUM(EventRoles)
|
||||||
|
|
||||||
@@ -99,6 +100,7 @@ private:
|
|||||||
QMap<int, bool> m_categoryVisibility;
|
QMap<int, bool> m_categoryVisibility;
|
||||||
|
|
||||||
int m_notificationCount = 0;
|
int m_notificationCount = 0;
|
||||||
|
QString m_activeSpaceId = "";
|
||||||
|
|
||||||
void connectRoomSignals(NeoChatRoom *room);
|
void connectRoomSignals(NeoChatRoom *room);
|
||||||
void handleNotifications();
|
void handleNotifications();
|
||||||
|
|||||||
@@ -76,6 +76,23 @@ QString SortFilterRoomListModel::filterText() const
|
|||||||
bool SortFilterRoomListModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
bool SortFilterRoomListModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(source_parent);
|
Q_UNUSED(source_parent);
|
||||||
return sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::NameRole).toString().contains(m_filterText, Qt::CaseInsensitive)
|
|
||||||
&& sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::JoinStateRole).toString() != "upgraded";
|
bool acceptRoom = sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::NameRole).toString().contains(m_filterText, Qt::CaseInsensitive)
|
||||||
|
&& sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::JoinStateRole).toString() != "upgraded"
|
||||||
|
&& sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::IsSpaceRole).toBool() == false;
|
||||||
|
|
||||||
|
if (m_activeSpaceRooms.empty())
|
||||||
|
return acceptRoom;
|
||||||
|
else
|
||||||
|
return std::find(m_activeSpaceRooms.begin(),
|
||||||
|
m_activeSpaceRooms.end(),
|
||||||
|
sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::IdRole).toString())
|
||||||
|
!= m_activeSpaceRooms.end()
|
||||||
|
&& acceptRoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SortFilterRoomListModel::setActiveSpaceRooms(QVector<QString> activeSpaceRooms)
|
||||||
|
{
|
||||||
|
this->m_activeSpaceRooms = activeSpaceRooms;
|
||||||
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class SortFilterRoomListModel : public QSortFilterProxyModel
|
|||||||
|
|
||||||
Q_PROPERTY(RoomSortOrder roomSortOrder READ roomSortOrder WRITE setRoomSortOrder NOTIFY roomSortOrderChanged)
|
Q_PROPERTY(RoomSortOrder roomSortOrder READ roomSortOrder WRITE setRoomSortOrder NOTIFY roomSortOrderChanged)
|
||||||
Q_PROPERTY(QString filterText READ filterText READ filterText WRITE setFilterText NOTIFY filterTextChanged)
|
Q_PROPERTY(QString filterText READ filterText READ filterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||||
|
Q_PROPERTY(QVector<QString> activeSpaceRooms WRITE setActiveSpaceRooms)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum RoomSortOrder {
|
enum RoomSortOrder {
|
||||||
@@ -30,6 +31,8 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
[[nodiscard]] bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
||||||
|
|
||||||
|
Q_INVOKABLE void setActiveSpaceRooms(QVector<QString> activeSpaceRooms);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
[[nodiscard]] bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
[[nodiscard]] bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||||
|
|
||||||
@@ -40,4 +43,5 @@ Q_SIGNALS:
|
|||||||
private:
|
private:
|
||||||
RoomSortOrder m_sortOrder = Categories;
|
RoomSortOrder m_sortOrder = Categories;
|
||||||
QString m_filterText;
|
QString m_filterText;
|
||||||
|
QVector<QString> m_activeSpaceRooms;
|
||||||
};
|
};
|
||||||
|
|||||||
28
src/sortfilterspacelistmodel.cpp
Normal file
28
src/sortfilterspacelistmodel.cpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2022 Snehit Sah <hi@snehit.dev>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
|
||||||
|
#include "sortfilterspacelistmodel.h"
|
||||||
|
|
||||||
|
#include "roomlistmodel.h"
|
||||||
|
|
||||||
|
SortFilterSpaceListModel::SortFilterSpaceListModel(QObject *parent)
|
||||||
|
: QSortFilterProxyModel{parent}
|
||||||
|
{
|
||||||
|
setSortRole(RoomListModel::IdRole);
|
||||||
|
sort(0);
|
||||||
|
invalidateFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SortFilterSpaceListModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(source_parent);
|
||||||
|
return sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::IsSpaceRole).toBool()
|
||||||
|
&& sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::JoinStateRole).toString() != "upgraded";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SortFilterSpaceListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
||||||
|
{
|
||||||
|
const auto idLeft = sourceModel()->data(source_left, RoomListModel::IdRole).toString();
|
||||||
|
const auto idRight = sourceModel()->data(source_right, RoomListModel::IdRole).toString();
|
||||||
|
return idLeft < idRight;
|
||||||
|
}
|
||||||
24
src/sortfilterspacelistmodel.h
Normal file
24
src/sortfilterspacelistmodel.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2022 Snehit Sah <hi@snehit.dev>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
class SortFilterSpaceListModel : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SortFilterSpaceListModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
[[nodiscard]] QString activeSpaceId() const;
|
||||||
|
|
||||||
|
[[nodiscard]] bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void activeSpaceIdChanged(QString &activeSpaceId);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
[[nodiscard]] bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||||
|
};
|
||||||
72
src/spacehierarchycache.cpp
Normal file
72
src/spacehierarchycache.cpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2022 Snehit Sah <hi@snehit.dev>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
|
||||||
|
#include "spacehierarchycache.h"
|
||||||
|
|
||||||
|
#include "controller.h"
|
||||||
|
#ifdef QUOTIENT_07
|
||||||
|
#include "csapi/space_hierarchy.h"
|
||||||
|
#endif
|
||||||
|
#include "neochatroom.h"
|
||||||
|
|
||||||
|
SpaceHierarchyCache::SpaceHierarchyCache(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
cacheSpaceHierarchy();
|
||||||
|
connect(&Controller::instance(), &Controller::activeConnectionChanged, this, [this]() {
|
||||||
|
cacheSpaceHierarchy();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpaceHierarchyCache::cacheSpaceHierarchy()
|
||||||
|
{
|
||||||
|
#ifdef QUOTIENT_07
|
||||||
|
auto connection = Controller::instance().activeConnection();
|
||||||
|
if (!connection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto roomList = connection->allRooms();
|
||||||
|
for (const auto &room : roomList) {
|
||||||
|
const auto neoChatRoom = static_cast<NeoChatRoom *>(room);
|
||||||
|
if (neoChatRoom->isSpace()) {
|
||||||
|
populateSpaceHierarchy(neoChatRoom->id());
|
||||||
|
} else {
|
||||||
|
connect(neoChatRoom, &Room::baseStateLoaded, neoChatRoom, [this, neoChatRoom]() {
|
||||||
|
if (neoChatRoom->isSpace()) {
|
||||||
|
populateSpaceHierarchy(neoChatRoom->id());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpaceHierarchyCache::populateSpaceHierarchy(const QString &spaceId)
|
||||||
|
{
|
||||||
|
auto connection = Controller::instance().activeConnection();
|
||||||
|
if (!connection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef QUOTIENT_07
|
||||||
|
GetSpaceHierarchyJob *job = connection->callApi<GetSpaceHierarchyJob>(spaceId);
|
||||||
|
|
||||||
|
connect(job, &BaseJob::success, this, [this, job, spaceId]() {
|
||||||
|
const auto rooms = job->rooms();
|
||||||
|
QVector<QString> roomList;
|
||||||
|
for (unsigned long i = 0; i < rooms.size(); ++i) {
|
||||||
|
roomList.push_back(rooms.at(i).roomId);
|
||||||
|
}
|
||||||
|
m_spaceHierarchy.insert(spaceId, roomList);
|
||||||
|
Q_EMIT spaceHierarchyChanged();
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QString> SpaceHierarchyCache::getRoomListForSpace(const QString &spaceId, bool updateCache)
|
||||||
|
{
|
||||||
|
if (updateCache) {
|
||||||
|
populateSpaceHierarchy(spaceId);
|
||||||
|
}
|
||||||
|
return m_spaceHierarchy[spaceId];
|
||||||
|
}
|
||||||
28
src/spacehierarchycache.h
Normal file
28
src/spacehierarchycache.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2022 Snehit Sah <hi@snehit.dev>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QHash>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
class SpaceHierarchyCache : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SpaceHierarchyCache(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
[[nodiscard]] Q_INVOKABLE QVector<QString> getRoomListForSpace(const QString &spaceId, bool updateCache);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void spaceHierarchyChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<QString> m_activeSpaceRooms;
|
||||||
|
QHash<QString, QVector<QString>> m_spaceHierarchy;
|
||||||
|
void cacheSpaceHierarchy();
|
||||||
|
void populateSpaceHierarchy(const QString &spaceId);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user