diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2021-06-09 23:52:28 +0200 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2021-06-09 23:52:28 +0200 |
commit | 2cd1a931c28d0fd8e8755e9622a7d8f56d1a24a0 (patch) | |
tree | afb784e8479553904b64fe49abea031c6ff09879 /src/timeline | |
parent | Implement switching in narrow mode (diff) | |
download | nheko-2cd1a931c28d0fd8e8755e9622a7d8f56d1a24a0.tar.xz |
Basic community list model
Diffstat (limited to 'src/timeline')
-rw-r--r-- | src/timeline/CommunitiesModel.cpp | 158 | ||||
-rw-r--r-- | src/timeline/CommunitiesModel.h | 60 | ||||
-rw-r--r-- | src/timeline/RoomlistModel.cpp | 23 | ||||
-rw-r--r-- | src/timeline/RoomlistModel.h | 1 | ||||
-rw-r--r-- | src/timeline/TimelineViewManager.cpp | 9 | ||||
-rw-r--r-- | src/timeline/TimelineViewManager.h | 4 |
6 files changed, 230 insertions, 25 deletions
diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp new file mode 100644 index 00000000..cedaacce --- /dev/null +++ b/src/timeline/CommunitiesModel.cpp @@ -0,0 +1,158 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "CommunitiesModel.h" + +#include <set> + +#include "Cache.h" +#include "UserSettingsPage.h" + +CommunitiesModel::CommunitiesModel(QObject *parent) + : QAbstractListModel(parent) +{} + +QHash<int, QByteArray> +CommunitiesModel::roleNames() const +{ + return { + {AvatarUrl, "avatarUrl"}, + {DisplayName, "displayName"}, + {Tooltip, "tooltip"}, + {ChildrenHidden, "childrenHidden"}, + }; +} + +QVariant +CommunitiesModel::data(const QModelIndex &index, int role) const +{ + if (index.row() == 0) { + switch (role) { + case CommunitiesModel::Roles::AvatarUrl: + return QString(":/icons/icons/ui/world.png"); + case CommunitiesModel::Roles::DisplayName: + return tr("All rooms"); + case CommunitiesModel::Roles::Tooltip: + return tr("Shows all rooms without filtering."); + case CommunitiesModel::Roles::ChildrenHidden: + return false; + case CommunitiesModel::Roles::Id: + return ""; + } + } else if (index.row() - 1 < tags_.size()) { + auto tag = tags_.at(index.row() - 1); + if (tag == "m.favourite") { + switch (role) { + case CommunitiesModel::Roles::AvatarUrl: + return QString(":/icons/icons/ui/star.png"); + case CommunitiesModel::Roles::DisplayName: + return tr("Favourites"); + case CommunitiesModel::Roles::Tooltip: + return tr("Rooms you have favourited."); + } + } else if (tag == "m.lowpriority") { + switch (role) { + case CommunitiesModel::Roles::AvatarUrl: + return QString(":/icons/icons/ui/star.png"); + case CommunitiesModel::Roles::DisplayName: + return tr("Low Priority"); + case CommunitiesModel::Roles::Tooltip: + return tr("Rooms with low priority."); + } + } else if (tag == "m.server_notice") { + switch (role) { + case CommunitiesModel::Roles::AvatarUrl: + return QString(":/icons/icons/ui/tag.png"); + case CommunitiesModel::Roles::DisplayName: + return tr("Server Notices"); + case CommunitiesModel::Roles::Tooltip: + return tr("Messages from your server or administrator."); + } + } else { + switch (role) { + case CommunitiesModel::Roles::AvatarUrl: + return QString(":/icons/icons/ui/tag.png"); + case CommunitiesModel::Roles::DisplayName: + return tag.right(2); + case CommunitiesModel::Roles::Tooltip: + return tag.right(2); + } + } + + switch (role) { + case CommunitiesModel::Roles::ChildrenHidden: + return UserSettings::instance()->hiddenTags().contains("tag:" + tag); + case CommunitiesModel::Roles::Id: + return "tag:" + tag; + } + } + return QVariant(); +} + +void +CommunitiesModel::initializeSidebar() +{ + std::set<std::string> ts; + for (const auto &e : cache::roomInfo()) { + for (const auto &t : e.tags) { + if (t.find("u.") == 0 || t.find("m." == 0)) { + ts.insert(t); + } + } + } + + beginResetModel(); + tags_.clear(); + for (const auto &t : ts) + tags_.push_back(QString::fromStdString(t)); + endResetModel(); + + emit tagsChanged(); +} + +void +CommunitiesModel::clear() +{ + beginResetModel(); + tags_.clear(); + endResetModel(); + + emit tagsChanged(); +} + +void +CommunitiesModel::sync(const mtx::responses::Rooms &rooms) +{ + bool tagsUpdated = false; + + for (const auto &[roomid, room] : rooms.join) { + (void)roomid; + for (const auto &e : room.account_data.events) + if (std::holds_alternative< + mtx::events::AccountDataEvent<mtx::events::account_data::Tags>>(e)) { + tagsUpdated = true; + } + } + + if (tagsUpdated) + initializeSidebar(); +} + +void +CommunitiesModel::setCurrentTagId(QString tagId) +{ + if (tagId.startsWith("tag:")) { + auto tag = tagId.remove(0, 4); + for (const auto &t : tags_) { + if (t == tag) { + this->currentTagId_ = tagId; + emit currentTagIdChanged(); + return; + } + } + } + + this->currentTagId_ = ""; + emit currentTagIdChanged(); +} diff --git a/src/timeline/CommunitiesModel.h b/src/timeline/CommunitiesModel.h new file mode 100644 index 00000000..3f6a2a4c --- /dev/null +++ b/src/timeline/CommunitiesModel.h @@ -0,0 +1,60 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <QAbstractListModel> +#include <QHash> +#include <QString> +#include <QStringList> + +#include <mtx/responses/sync.hpp> + +class CommunitiesModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(QString currentTagId READ currentTagId WRITE setCurrentTagId NOTIFY + currentTagIdChanged RESET resetCurrentTagId) + Q_PROPERTY(QStringList tags READ tags NOTIFY tagsChanged) + +public: + enum Roles + { + AvatarUrl = Qt::UserRole, + DisplayName, + Tooltip, + ChildrenHidden, + Id, + }; + + CommunitiesModel(QObject *parent = nullptr); + QHash<int, QByteArray> roleNames() const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override + { + (void)parent; + return 1 + tags_.size(); + } + QVariant data(const QModelIndex &index, int role) const override; + +public slots: + void initializeSidebar(); + void sync(const mtx::responses::Rooms &rooms); + void clear(); + QString currentTagId() const { return currentTagId_; } + void setCurrentTagId(QString tagId); + void resetCurrentTagId() + { + currentTagId_.clear(); + emit currentTagIdChanged(); + } + QStringList tags() const { return tags_; } + +signals: + void currentTagIdChanged(); + void tagsChanged(); + +private: + QStringList tags_; + QString currentTagId_; +}; diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index 283224f1..4dd44b30 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -485,29 +485,6 @@ FilteredRoomlistModel::FilteredRoomlistModel(RoomlistModel *model, QObject *pare sort(0); } -QStringList -FilteredRoomlistModel::tags() -{ - std::set<std::string> ts; - for (const auto &e : cache::roomInfo()) { - for (const auto &t : e.tags) { - if (t.find("u.") == 0) { - ts.insert(t); - } - } - } - - QStringList ret{{ - "m.favourite", - "m.lowpriority", - }}; - - for (const auto &t : ts) - ret.push_back(QString::fromStdString(t)); - - return ret; -} - void FilteredRoomlistModel::toggleTag(QString roomid, QString tag, bool on) { diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h index fa991f6b..7ee0419f 100644 --- a/src/timeline/RoomlistModel.h +++ b/src/timeline/RoomlistModel.h @@ -119,7 +119,6 @@ public slots: void acceptInvite(QString roomid) { roomlistmodel->acceptInvite(roomid); } void declineInvite(QString roomid) { roomlistmodel->declineInvite(roomid); } void leave(QString roomid) { roomlistmodel->leave(roomid); } - QStringList tags(); void toggleTag(QString roomid, QString tag, bool on); TimelineModel *currentRoom() const { return roomlistmodel->currentRoom(); } diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index dd623f2f..faf56b85 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -135,6 +135,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par , blurhashProvider(new BlurhashProvider()) , callManager_(callManager) , rooms_(new RoomlistModel(this)) + , communities_(new CommunitiesModel(this)) { qRegisterMetaType<mtx::events::msg::KeyVerificationAccept>(); qRegisterMetaType<mtx::events::msg::KeyVerificationCancel>(); @@ -196,6 +197,12 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par "im.nheko", 1, 0, "Rooms", [](QQmlEngine *, QJSEngine *) -> QObject * { return new FilteredRoomlistModel(self->rooms_); }); + qmlRegisterSingletonType<RoomlistModel>( + "im.nheko", 1, 0, "Communities", [](QQmlEngine *, QJSEngine *) -> QObject * { + auto ptr = self->communities_; + QQmlEngine::setObjectOwnership(ptr, QQmlEngine::CppOwnership); + return ptr; + }); qmlRegisterSingletonType<UserSettings>( "im.nheko", 1, 0, "Settings", [](QQmlEngine *, QJSEngine *) -> QObject * { auto ptr = ChatPage::instance()->userSettings().data(); @@ -324,6 +331,7 @@ void TimelineViewManager::sync(const mtx::responses::Rooms &rooms_res) { this->rooms_->sync(rooms_res); + this->communities_->sync(rooms_res); if (isInitialSync_) { this->isInitialSync_ = false; @@ -486,6 +494,7 @@ void TimelineViewManager::initializeRoomlist() { rooms_->initializeRooms(); + communities_->initializeSidebar(); } void diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 68d9cd1b..556bcf4c 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -22,6 +22,7 @@ #include "WebRTCSession.h" #include "emoji/EmojiModel.h" #include "emoji/Provider.h" +#include "timeline/CommunitiesModel.h" #include "timeline/RoomlistModel.h" class MxcImageProvider; @@ -131,7 +132,8 @@ private: bool isInitialSync_ = true; bool isWindowFocused_ = false; - RoomlistModel *rooms_ = nullptr; + RoomlistModel *rooms_ = nullptr; + CommunitiesModel *communities_ = nullptr; QHash<QString, QColor> userColors; |