// SPDX-FileCopyrightText: 2021 Nheko Contributors // // SPDX-License-Identifier: GPL-3.0-or-later #include "CommunitiesModel.h" #include #include "Cache.h" #include "UserSettingsPage.h" CommunitiesModel::CommunitiesModel(QObject *parent) : QAbstractListModel(parent) {} QHash CommunitiesModel::roleNames() const { return { {AvatarUrl, "avatarUrl"}, {DisplayName, "displayName"}, {Tooltip, "tooltip"}, {ChildrenHidden, "childrenHidden"}, {Hidden, "hidden"}, {Id, "id"}, }; } 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.svg"); 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::Hidden: return false; case CommunitiesModel::Roles::Id: return ""; } } else if (index.row() == 1) { switch (role) { case CommunitiesModel::Roles::AvatarUrl: return QString(":/icons/icons/ui/people.svg"); case CommunitiesModel::Roles::DisplayName: return tr("Direct Chats"); case CommunitiesModel::Roles::Tooltip: return tr("Show direct chats."); case CommunitiesModel::Roles::ChildrenHidden: return false; case CommunitiesModel::Roles::Hidden: return hiddentTagIds_.contains("dm"); case CommunitiesModel::Roles::Id: return "dm"; } } else if (index.row() - 2 < spaceOrder_.size()) { auto id = spaceOrder_.at(index.row() - 2); switch (role) { case CommunitiesModel::Roles::AvatarUrl: return QString::fromStdString(spaces_.at(id).avatar_url); case CommunitiesModel::Roles::DisplayName: case CommunitiesModel::Roles::Tooltip: return QString::fromStdString(spaces_.at(id).name); case CommunitiesModel::Roles::ChildrenHidden: return true; case CommunitiesModel::Roles::Hidden: return hiddentTagIds_.contains("space:" + id); case CommunitiesModel::Roles::Id: return "space:" + id; } } else if (index.row() - 2 < tags_.size() + spaceOrder_.size()) { auto tag = tags_.at(index.row() - 2 - spaceOrder_.size()); if (tag == "m.favourite") { switch (role) { case CommunitiesModel::Roles::AvatarUrl: return QString(":/icons/icons/ui/star.svg"); 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/lowprio.svg"); 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.svg"); 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.svg"); case CommunitiesModel::Roles::DisplayName: case CommunitiesModel::Roles::Tooltip: return tag.mid(2); } } switch (role) { case CommunitiesModel::Roles::Hidden: return hiddentTagIds_.contains("tag:" + tag); case CommunitiesModel::Roles::ChildrenHidden: return true; case CommunitiesModel::Roles::Id: return "tag:" + tag; } } return QVariant(); } void CommunitiesModel::initializeSidebar() { beginResetModel(); tags_.clear(); spaceOrder_.clear(); spaces_.clear(); std::set ts; std::vector tempSpaces; auto infos = cache::roomInfo(); for (auto it = infos.begin(); it != infos.end(); it++) { if (it.value().is_space) { spaceOrder_.push_back(it.key()); spaces_[it.key()] = it.value(); } else { for (const auto &t : it.value().tags) { if (t.find("u.") == 0 || t.find("m." == 0)) { ts.insert(t); } } } } for (const auto &t : ts) tags_.push_back(QString::fromStdString(t)); hiddentTagIds_ = UserSettings::instance()->hiddenTags(); endResetModel(); emit tagsChanged(); emit hiddenTagsChanged(); } void CommunitiesModel::clear() { beginResetModel(); tags_.clear(); endResetModel(); resetCurrentTagId(); emit tagsChanged(); } void CommunitiesModel::sync(const mtx::responses::Sync &sync_) { bool tagsUpdated = false; for (const auto &[roomid, room] : sync_.rooms.join) { (void)roomid; for (const auto &e : room.account_data.events) if (std::holds_alternative< mtx::events::AccountDataEvent>(e)) { tagsUpdated = true; } for (const auto &e : room.state.events) if (std::holds_alternative>( e) || std::holds_alternative>( e)) { tagsUpdated = true; } for (const auto &e : room.timeline.events) if (std::holds_alternative>( e) || std::holds_alternative>( e)) { tagsUpdated = true; } } for (const auto &[roomid, room] : sync_.rooms.leave) { (void)room; if (spaceOrder_.contains(QString::fromStdString(roomid))) tagsUpdated = true; } for (const auto &e : sync_.account_data.events) { if (std::holds_alternative< mtx::events::AccountDataEvent>(e)) { tagsUpdated = true; break; } } if (tagsUpdated) initializeSidebar(); } void CommunitiesModel::setCurrentTagId(QString tagId) { if (tagId.startsWith("tag:")) { auto tag = tagId.mid(4); for (const auto &t : tags_) { if (t == tag) { this->currentTagId_ = tagId; emit currentTagIdChanged(currentTagId_); return; } } } else if (tagId.startsWith("space:")) { auto tag = tagId.mid(6); for (const auto &t : spaceOrder_) { if (t == tag) { this->currentTagId_ = tagId; emit currentTagIdChanged(currentTagId_); return; } } } else if (tagId == "dm") { this->currentTagId_ = tagId; emit currentTagIdChanged(currentTagId_); return; } this->currentTagId_ = ""; emit currentTagIdChanged(currentTagId_); } void CommunitiesModel::toggleTagId(QString tagId) { if (hiddentTagIds_.contains(tagId)) { hiddentTagIds_.removeOne(tagId); UserSettings::instance()->setHiddenTags(hiddentTagIds_); } else { hiddentTagIds_.push_back(tagId); UserSettings::instance()->setHiddenTags(hiddentTagIds_); } if (tagId.startsWith("tag:")) { auto idx = tags_.indexOf(tagId.mid(4)); if (idx != -1) emit dataChanged( index(idx + 1 + spaceOrder_.size()), index(idx + 1 + spaceOrder_.size()), {Hidden}); } else if (tagId.startsWith("space:")) { auto idx = spaceOrder_.indexOf(tagId.mid(6)); if (idx != -1) emit dataChanged(index(idx + 1), index(idx + 1), {Hidden}); } else if (tagId == "dm") { emit dataChanged(index(1), index(1), {Hidden}); } emit hiddenTagsChanged(); }