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
|
# 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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
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);
|
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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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(); }
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -131,7 +132,8 @@ private:
|
||||||
bool isInitialSync_ = true;
|
bool isInitialSync_ = true;
|
||||||
bool isWindowFocused_ = false;
|
bool isWindowFocused_ = false;
|
||||||
|
|
||||||
RoomlistModel *rooms_ = nullptr;
|
RoomlistModel *rooms_ = nullptr;
|
||||||
|
CommunitiesModel *communities_ = nullptr;
|
||||||
|
|
||||||
QHash<QString, QColor> userColors;
|
QHash<QString, QColor> userColors;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue