Basic community list model

This commit is contained in:
Nicolas Werner 2021-06-09 23:52:28 +02:00
parent d364c29c43
commit 2cd1a931c2
No known key found for this signature in database
GPG key ID: C8D75E610773F2D9
8 changed files with 234 additions and 29 deletions

View file

@ -265,6 +265,7 @@ set(SRC_FILES
# Timeline # Timeline
src/timeline/CommunitiesModel.cpp
src/timeline/EventStore.cpp src/timeline/EventStore.cpp
src/timeline/InputBar.cpp src/timeline/InputBar.cpp
src/timeline/Reaction.cpp src/timeline/Reaction.cpp
@ -481,6 +482,7 @@ qt5_wrap_cpp(MOC_HEADERS
src/emoji/Provider.h src/emoji/Provider.h
# Timeline # Timeline
src/timeline/CommunitiesModel.h
src/timeline/EventStore.h src/timeline/EventStore.h
src/timeline/InputBar.h src/timeline/InputBar.h
src/timeline/Reaction.h src/timeline/Reaction.h

View file

@ -43,12 +43,10 @@ Page {
property string roomid property string roomid
property var tags property var tags
property var allTags
function show(roomid_, tags_) { function show(roomid_, tags_) {
roomid = roomid_; roomid = roomid_;
tags = tags_; tags = tags_;
allTags = Rooms.tags();
open(); open();
} }
@ -72,7 +70,7 @@ Page {
} }
Instantiator { Instantiator {
model: roomContextMenu.allTags model: Communities.tags
onObjectAdded: roomContextMenu.insertItem(index + 2, object) onObjectAdded: roomContextMenu.insertItem(index + 2, object)
onObjectRemoved: roomContextMenu.removeItem(object) onObjectRemoved: roomContextMenu.removeItem(object)
@ -92,7 +90,7 @@ Page {
} }
} }
checkable: true checkable: true
checked: roomContextMenu.tags.includes(t) checked: roomContextMenu.tags !== undefined && roomContextMenu.tags.includes(t)
onTriggered: Rooms.toggleTag(roomContextMenu.roomid, t, checked) onTriggered: Rooms.toggleTag(roomContextMenu.roomid, t, checked)
} }

View 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();
}

View 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_;
};

View file

@ -485,29 +485,6 @@ FilteredRoomlistModel::FilteredRoomlistModel(RoomlistModel *model, QObject *pare
sort(0); 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 void
FilteredRoomlistModel::toggleTag(QString roomid, QString tag, bool on) FilteredRoomlistModel::toggleTag(QString roomid, QString tag, bool on)
{ {

View file

@ -119,7 +119,6 @@ public slots:
void acceptInvite(QString roomid) { roomlistmodel->acceptInvite(roomid); } void acceptInvite(QString roomid) { roomlistmodel->acceptInvite(roomid); }
void declineInvite(QString roomid) { roomlistmodel->declineInvite(roomid); } void declineInvite(QString roomid) { roomlistmodel->declineInvite(roomid); }
void leave(QString roomid) { roomlistmodel->leave(roomid); } void leave(QString roomid) { roomlistmodel->leave(roomid); }
QStringList tags();
void toggleTag(QString roomid, QString tag, bool on); void toggleTag(QString roomid, QString tag, bool on);
TimelineModel *currentRoom() const { return roomlistmodel->currentRoom(); } TimelineModel *currentRoom() const { return roomlistmodel->currentRoom(); }

View file

@ -135,6 +135,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
, blurhashProvider(new BlurhashProvider()) , blurhashProvider(new BlurhashProvider())
, callManager_(callManager) , callManager_(callManager)
, rooms_(new RoomlistModel(this)) , rooms_(new RoomlistModel(this))
, communities_(new CommunitiesModel(this))
{ {
qRegisterMetaType<mtx::events::msg::KeyVerificationAccept>(); qRegisterMetaType<mtx::events::msg::KeyVerificationAccept>();
qRegisterMetaType<mtx::events::msg::KeyVerificationCancel>(); qRegisterMetaType<mtx::events::msg::KeyVerificationCancel>();
@ -196,6 +197,12 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
"im.nheko", 1, 0, "Rooms", [](QQmlEngine *, QJSEngine *) -> QObject * { "im.nheko", 1, 0, "Rooms", [](QQmlEngine *, QJSEngine *) -> QObject * {
return new FilteredRoomlistModel(self->rooms_); 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>( qmlRegisterSingletonType<UserSettings>(
"im.nheko", 1, 0, "Settings", [](QQmlEngine *, QJSEngine *) -> QObject * { "im.nheko", 1, 0, "Settings", [](QQmlEngine *, QJSEngine *) -> QObject * {
auto ptr = ChatPage::instance()->userSettings().data(); auto ptr = ChatPage::instance()->userSettings().data();
@ -324,6 +331,7 @@ void
TimelineViewManager::sync(const mtx::responses::Rooms &rooms_res) TimelineViewManager::sync(const mtx::responses::Rooms &rooms_res)
{ {
this->rooms_->sync(rooms_res); this->rooms_->sync(rooms_res);
this->communities_->sync(rooms_res);
if (isInitialSync_) { if (isInitialSync_) {
this->isInitialSync_ = false; this->isInitialSync_ = false;
@ -486,6 +494,7 @@ void
TimelineViewManager::initializeRoomlist() TimelineViewManager::initializeRoomlist()
{ {
rooms_->initializeRooms(); rooms_->initializeRooms();
communities_->initializeSidebar();
} }
void void

View file

@ -22,6 +22,7 @@
#include "WebRTCSession.h" #include "WebRTCSession.h"
#include "emoji/EmojiModel.h" #include "emoji/EmojiModel.h"
#include "emoji/Provider.h" #include "emoji/Provider.h"
#include "timeline/CommunitiesModel.h"
#include "timeline/RoomlistModel.h" #include "timeline/RoomlistModel.h"
class MxcImageProvider; class MxcImageProvider;
@ -132,6 +133,7 @@ private:
bool isWindowFocused_ = false; bool isWindowFocused_ = false;
RoomlistModel *rooms_ = nullptr; RoomlistModel *rooms_ = nullptr;
CommunitiesModel *communities_ = nullptr;
QHash<QString, QColor> userColors; QHash<QString, QColor> userColors;