mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Basic community list model
This commit is contained in:
parent
d364c29c43
commit
2cd1a931c2
8 changed files with 234 additions and 29 deletions
|
@ -265,6 +265,7 @@ set(SRC_FILES
|
|||
|
||||
|
||||
# Timeline
|
||||
src/timeline/CommunitiesModel.cpp
|
||||
src/timeline/EventStore.cpp
|
||||
src/timeline/InputBar.cpp
|
||||
src/timeline/Reaction.cpp
|
||||
|
@ -481,6 +482,7 @@ qt5_wrap_cpp(MOC_HEADERS
|
|||
src/emoji/Provider.h
|
||||
|
||||
# Timeline
|
||||
src/timeline/CommunitiesModel.h
|
||||
src/timeline/EventStore.h
|
||||
src/timeline/InputBar.h
|
||||
src/timeline/Reaction.h
|
||||
|
|
|
@ -43,12 +43,10 @@ Page {
|
|||
|
||||
property string roomid
|
||||
property var tags
|
||||
property var allTags
|
||||
|
||||
function show(roomid_, tags_) {
|
||||
roomid = roomid_;
|
||||
tags = tags_;
|
||||
allTags = Rooms.tags();
|
||||
open();
|
||||
}
|
||||
|
||||
|
@ -72,7 +70,7 @@ Page {
|
|||
}
|
||||
|
||||
Instantiator {
|
||||
model: roomContextMenu.allTags
|
||||
model: Communities.tags
|
||||
onObjectAdded: roomContextMenu.insertItem(index + 2, object)
|
||||
onObjectRemoved: roomContextMenu.removeItem(object)
|
||||
|
||||
|
@ -92,7 +90,7 @@ Page {
|
|||
}
|
||||
}
|
||||
checkable: true
|
||||
checked: roomContextMenu.tags.includes(t)
|
||||
checked: roomContextMenu.tags !== undefined && roomContextMenu.tags.includes(t)
|
||||
onTriggered: Rooms.toggleTag(roomContextMenu.roomid, t, checked)
|
||||
}
|
||||
|
||||
|
|
158
src/timeline/CommunitiesModel.cpp
Normal file
158
src/timeline/CommunitiesModel.cpp
Normal file
|
@ -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();
|
||||
}
|
60
src/timeline/CommunitiesModel.h
Normal file
60
src/timeline/CommunitiesModel.h
Normal file
|
@ -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_;
|
||||
};
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue