Port to Integral
This commit is contained in:
@@ -4,23 +4,23 @@
|
||||
#include "completionmodel.h"
|
||||
#include <QDebug>
|
||||
|
||||
#include "actionsmodel.h"
|
||||
#include "completionproxymodel.h"
|
||||
#include "customemojimodel.h"
|
||||
#include "emojimodel.h"
|
||||
// #include "actionsmodel.h"
|
||||
// #include "completionproxymodel.h"
|
||||
// #include "customemojimodel.h"
|
||||
// #include "emojimodel.h"
|
||||
#include "neochatroom.h"
|
||||
#include "roommanager.h"
|
||||
#include "userlistmodel.h"
|
||||
// #include "roommanager.h"
|
||||
// #include "userlistmodel.h"
|
||||
|
||||
CompletionModel::CompletionModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_filterModel(new CompletionProxyModel())
|
||||
, m_userListModel(RoomManager::instance().userListModel())
|
||||
// , m_filterModel(new CompletionProxyModel())
|
||||
// , m_userListModel(RoomManager::instance().userListModel())
|
||||
, m_emojiModel(new QConcatenateTablesProxyModel(this))
|
||||
{
|
||||
connect(this, &CompletionModel::textChanged, this, &CompletionModel::updateCompletion);
|
||||
m_emojiModel->addSourceModel(&CustomEmojiModel::instance());
|
||||
m_emojiModel->addSourceModel(&EmojiModel::instance());
|
||||
// m_emojiModel->addSourceModel(&CustomEmojiModel::instance());
|
||||
// m_emojiModel->addSourceModel(&EmojiModel::instance());
|
||||
}
|
||||
|
||||
QString CompletionModel::text() const
|
||||
@@ -41,67 +41,68 @@ int CompletionModel::rowCount(const QModelIndex &parent) const
|
||||
if (m_autoCompletionType == None) {
|
||||
return 0;
|
||||
}
|
||||
return m_filterModel->rowCount();
|
||||
// return m_filterModel->rowCount();
|
||||
return {};
|
||||
}
|
||||
|
||||
QVariant CompletionModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (index.row() < 0 || index.row() >= m_filterModel->rowCount()) {
|
||||
return {};
|
||||
}
|
||||
auto filterIndex = m_filterModel->index(index.row(), 0);
|
||||
if (m_autoCompletionType == User) {
|
||||
if (role == DisplayNameRole) {
|
||||
return m_filterModel->data(filterIndex, UserListModel::DisplayNameRole);
|
||||
}
|
||||
if (role == SubtitleRole) {
|
||||
return m_filterModel->data(filterIndex, UserListModel::UserIdRole);
|
||||
}
|
||||
if (role == IconNameRole) {
|
||||
return m_filterModel->data(filterIndex, UserListModel::AvatarRole);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_autoCompletionType == Command) {
|
||||
if (role == DisplayNameRole) {
|
||||
return u"%1 %2"_s.arg(m_filterModel->data(filterIndex, ActionsModel::Prefix).toString(),
|
||||
m_filterModel->data(filterIndex, ActionsModel::Parameters).toString());
|
||||
}
|
||||
if (role == SubtitleRole) {
|
||||
return m_filterModel->data(filterIndex, ActionsModel::Description);
|
||||
}
|
||||
if (role == IconNameRole) {
|
||||
return u"invalid"_s;
|
||||
}
|
||||
if (role == ReplacedTextRole) {
|
||||
return m_filterModel->data(filterIndex, ActionsModel::Prefix);
|
||||
}
|
||||
}
|
||||
if (m_autoCompletionType == Room) {
|
||||
if (role == DisplayNameRole) {
|
||||
return m_filterModel->data(filterIndex, RoomListModel::DisplayNameRole);
|
||||
}
|
||||
if (role == SubtitleRole) {
|
||||
return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole);
|
||||
}
|
||||
if (role == IconNameRole) {
|
||||
return m_filterModel->data(filterIndex, RoomListModel::AvatarRole).toString();
|
||||
}
|
||||
}
|
||||
if (m_autoCompletionType == Emoji) {
|
||||
if (role == DisplayNameRole) {
|
||||
return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole);
|
||||
}
|
||||
if (role == IconNameRole) {
|
||||
return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl);
|
||||
}
|
||||
if (role == ReplacedTextRole) {
|
||||
return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole);
|
||||
}
|
||||
if (role == SubtitleRole) {
|
||||
return m_filterModel->data(filterIndex, EmojiModel::DescriptionRole);
|
||||
}
|
||||
}
|
||||
// if (index.row() < 0 || index.row() >= m_filterModel->rowCount()) {
|
||||
// return {};
|
||||
// }
|
||||
// auto filterIndex = m_filterModel->index(index.row(), 0);
|
||||
// if (m_autoCompletionType == User) {
|
||||
// if (role == DisplayNameRole) {
|
||||
// return m_filterModel->data(filterIndex, UserListModel::DisplayNameRole);
|
||||
// }
|
||||
// if (role == SubtitleRole) {
|
||||
// return m_filterModel->data(filterIndex, UserListModel::UserIdRole);
|
||||
// }
|
||||
// if (role == IconNameRole) {
|
||||
// return m_filterModel->data(filterIndex, UserListModel::AvatarRole);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (m_autoCompletionType == Command) {
|
||||
// if (role == DisplayNameRole) {
|
||||
// return u"%1 %2"_s.arg(m_filterModel->data(filterIndex, ActionsModel::Prefix).toString(),
|
||||
// m_filterModel->data(filterIndex, ActionsModel::Parameters).toString());
|
||||
// }
|
||||
// if (role == SubtitleRole) {
|
||||
// return m_filterModel->data(filterIndex, ActionsModel::Description);
|
||||
// }
|
||||
// if (role == IconNameRole) {
|
||||
// return u"invalid"_s;
|
||||
// }
|
||||
// if (role == ReplacedTextRole) {
|
||||
// return m_filterModel->data(filterIndex, ActionsModel::Prefix);
|
||||
// }
|
||||
// }
|
||||
// if (m_autoCompletionType == Room) {
|
||||
// if (role == DisplayNameRole) {
|
||||
// return m_filterModel->data(filterIndex, RoomListModel::DisplayNameRole);
|
||||
// }
|
||||
// if (role == SubtitleRole) {
|
||||
// return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole);
|
||||
// }
|
||||
// if (role == IconNameRole) {
|
||||
// return m_filterModel->data(filterIndex, RoomListModel::AvatarRole).toString();
|
||||
// }
|
||||
// }
|
||||
// if (m_autoCompletionType == Emoji) {
|
||||
// if (role == DisplayNameRole) {
|
||||
// return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole);
|
||||
// }
|
||||
// if (role == IconNameRole) {
|
||||
// return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl);
|
||||
// }
|
||||
// if (role == ReplacedTextRole) {
|
||||
// return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole);
|
||||
// }
|
||||
// if (role == SubtitleRole) {
|
||||
// return m_filterModel->data(filterIndex, EmojiModel::DescriptionRole);
|
||||
// }
|
||||
// }
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -118,50 +119,50 @@ QHash<int, QByteArray> CompletionModel::roleNames() const
|
||||
|
||||
void CompletionModel::updateCompletion()
|
||||
{
|
||||
if (text().startsWith(QLatin1Char('@'))) {
|
||||
m_filterModel->setSourceModel(m_userListModel);
|
||||
m_filterModel->setFilterRole(UserListModel::UserIdRole);
|
||||
m_filterModel->setSecondaryFilterRole(UserListModel::DisplayNameRole);
|
||||
m_filterModel->setFullText(m_fullText);
|
||||
m_filterModel->setFilterText(m_text);
|
||||
m_autoCompletionType = User;
|
||||
m_filterModel->invalidate();
|
||||
} else if (text().startsWith(QLatin1Char('/'))) {
|
||||
m_filterModel->setSourceModel(&ActionsModel::instance());
|
||||
m_filterModel->setFilterRole(ActionsModel::Prefix);
|
||||
m_filterModel->setSecondaryFilterRole(-1);
|
||||
m_filterModel->setFullText(m_fullText);
|
||||
m_filterModel->setFilterText(m_text.mid(1));
|
||||
m_autoCompletionType = Command;
|
||||
m_filterModel->invalidate();
|
||||
} else if (text().startsWith(QLatin1Char('#'))) {
|
||||
m_autoCompletionType = Room;
|
||||
m_filterModel->setSourceModel(m_roomListModel);
|
||||
m_filterModel->setFilterRole(RoomListModel::CanonicalAliasRole);
|
||||
m_filterModel->setSecondaryFilterRole(RoomListModel::DisplayNameRole);
|
||||
m_filterModel->setFullText(m_fullText);
|
||||
m_filterModel->setFilterText(m_text);
|
||||
m_filterModel->invalidate();
|
||||
} else if (text().startsWith(QLatin1Char(':')) && text().size() > 1 && !text()[1].isUpper()
|
||||
&& (m_fullText.indexOf(QLatin1Char(':'), 1) == -1
|
||||
|| (m_fullText.indexOf(QLatin1Char(' ')) != -1 && m_fullText.indexOf(QLatin1Char(':'), 1) > m_fullText.indexOf(QLatin1Char(' '), 1)))) {
|
||||
m_filterModel->setSourceModel(m_emojiModel);
|
||||
m_autoCompletionType = Emoji;
|
||||
m_filterModel->setFilterRole(CustomEmojiModel::Name);
|
||||
m_filterModel->setSecondaryFilterRole(EmojiModel::DescriptionRole);
|
||||
m_filterModel->setFullText(m_fullText);
|
||||
m_filterModel->setFilterText(m_text);
|
||||
m_filterModel->invalidate();
|
||||
} else {
|
||||
m_autoCompletionType = None;
|
||||
}
|
||||
// if (text().startsWith(QLatin1Char('@'))) {
|
||||
// m_filterModel->setSourceModel(m_userListModel);
|
||||
// m_filterModel->setFilterRole(UserListModel::UserIdRole);
|
||||
// m_filterModel->setSecondaryFilterRole(UserListModel::DisplayNameRole);
|
||||
// m_filterModel->setFullText(m_fullText);
|
||||
// m_filterModel->setFilterText(m_text);
|
||||
// m_autoCompletionType = User;
|
||||
// m_filterModel->invalidate();
|
||||
// } else if (text().startsWith(QLatin1Char('/'))) {
|
||||
// m_filterModel->setSourceModel(&ActionsModel::instance());
|
||||
// m_filterModel->setFilterRole(ActionsModel::Prefix);
|
||||
// m_filterModel->setSecondaryFilterRole(-1);
|
||||
// m_filterModel->setFullText(m_fullText);
|
||||
// m_filterModel->setFilterText(m_text.mid(1));
|
||||
// m_autoCompletionType = Command;
|
||||
// m_filterModel->invalidate();
|
||||
// } else if (text().startsWith(QLatin1Char('#'))) {
|
||||
// m_autoCompletionType = Room;
|
||||
// m_filterModel->setSourceModel(m_roomListModel);
|
||||
// m_filterModel->setFilterRole(RoomListModel::CanonicalAliasRole);
|
||||
// m_filterModel->setSecondaryFilterRole(RoomListModel::DisplayNameRole);
|
||||
// m_filterModel->setFullText(m_fullText);
|
||||
// m_filterModel->setFilterText(m_text);
|
||||
// m_filterModel->invalidate();
|
||||
// } else if (text().startsWith(QLatin1Char(':')) && text().size() > 1 && !text()[1].isUpper()
|
||||
// && (m_fullText.indexOf(QLatin1Char(':'), 1) == -1
|
||||
// || (m_fullText.indexOf(QLatin1Char(' ')) != -1 && m_fullText.indexOf(QLatin1Char(':'), 1) > m_fullText.indexOf(QLatin1Char(' '), 1)))) {
|
||||
// m_filterModel->setSourceModel(m_emojiModel);
|
||||
// m_autoCompletionType = Emoji;
|
||||
// m_filterModel->setFilterRole(CustomEmojiModel::Name);
|
||||
// m_filterModel->setSecondaryFilterRole(EmojiModel::DescriptionRole);
|
||||
// m_filterModel->setFullText(m_fullText);
|
||||
// m_filterModel->setFilterText(m_text);
|
||||
// m_filterModel->invalidate();
|
||||
// } else {
|
||||
// m_autoCompletionType = None;
|
||||
// }
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
NeoChatRoom *CompletionModel::room() const
|
||||
{
|
||||
return m_room;
|
||||
return m_room.get();
|
||||
}
|
||||
|
||||
void CompletionModel::setRoom(NeoChatRoom *room)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <QQmlEngine>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "roomlistmodel.h"
|
||||
// #include "roomlistmodel.h"
|
||||
|
||||
class CompletionProxyModel;
|
||||
class UserListModel;
|
||||
@@ -47,7 +47,7 @@ class CompletionModel : public QAbstractListModel
|
||||
/**
|
||||
* @brief The RoomListModel to be used for room completions.
|
||||
*/
|
||||
Q_PROPERTY(RoomListModel *roomListModel READ roomListModel WRITE setRoomListModel NOTIFY roomListModelChanged)
|
||||
// Q_PROPERTY(RoomListModel *roomListModel READ roomListModel WRITE setRoomListModel NOTIFY roomListModelChanged)
|
||||
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <Quotient/converters.h>
|
||||
#include <Quotient/csapi/definitions/push_ruleset.h>
|
||||
#include <Quotient/csapi/pushrules.h>
|
||||
#include <Quotient/jobs/basejob.h>
|
||||
// #include <Quotient/converters.h>
|
||||
// #include <Quotient/csapi/definitions/push_ruleset.h>
|
||||
// #include <Quotient/csapi/pushrules.h>
|
||||
// #include <Quotient/jobs/basejob.h>
|
||||
|
||||
#include "neochatconfig.h"
|
||||
|
||||
@@ -74,18 +74,18 @@ void PushRuleModel::updateNotificationRules(const QString &type)
|
||||
return;
|
||||
}
|
||||
|
||||
const QJsonObject ruleDataJson = m_connection->accountDataJson(u"m.push_rules"_s);
|
||||
const Quotient::PushRuleset ruleData = Quotient::fromJson<Quotient::PushRuleset>(ruleDataJson["global"_L1].toObject());
|
||||
// const QJsonObject ruleDataJson = m_connection->accountDataJson(u"m.push_rules"_s);
|
||||
// const Quotient::PushRuleset ruleData = Quotient::fromJson<Quotient::PushRuleset>(ruleDataJson["global"_L1].toObject());
|
||||
|
||||
beginResetModel();
|
||||
m_rules.clear();
|
||||
|
||||
// Doing this 5 times because PushRuleset is a struct.
|
||||
setRules(ruleData.override, PushRuleKind::Override);
|
||||
setRules(ruleData.content, PushRuleKind::Content);
|
||||
setRules(ruleData.room, PushRuleKind::Room);
|
||||
setRules(ruleData.sender, PushRuleKind::Sender);
|
||||
setRules(ruleData.underride, PushRuleKind::Underride);
|
||||
// setRules(ruleData.override, PushRuleKind::Override);
|
||||
// setRules(ruleData.content, PushRuleKind::Content);
|
||||
// setRules(ruleData.room, PushRuleKind::Room);
|
||||
// setRules(ruleData.sender, PushRuleKind::Sender);
|
||||
// setRules(ruleData.underride, PushRuleKind::Underride);
|
||||
|
||||
Q_EMIT globalNotificationsEnabledChanged();
|
||||
Q_EMIT globalNotificationsSetChanged();
|
||||
@@ -93,28 +93,28 @@ void PushRuleModel::updateNotificationRules(const QString &type)
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void PushRuleModel::setRules(QList<Quotient::PushRule> rules, PushRuleKind::Kind kind)
|
||||
{
|
||||
for (const auto &rule : rules) {
|
||||
QString roomId;
|
||||
if (rule.conditions.size() > 0) {
|
||||
for (const auto &condition : std::as_const(rule.conditions)) {
|
||||
if (condition.key == u"room_id"_s) {
|
||||
roomId = condition.pattern;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_rules.append(Rule{
|
||||
rule.ruleId,
|
||||
kind,
|
||||
variantToAction(rule.actions, rule.enabled),
|
||||
getSection(rule),
|
||||
rule.enabled,
|
||||
roomId,
|
||||
});
|
||||
}
|
||||
}
|
||||
// void PushRuleModel::setRules(QList<Quotient::PushRule> rules, PushRuleKind::Kind kind)
|
||||
// {
|
||||
// for (const auto &rule : rules) {
|
||||
// QString roomId;
|
||||
// if (rule.conditions.size() > 0) {
|
||||
// for (const auto &condition : std::as_const(rule.conditions)) {
|
||||
// if (condition.key == u"room_id"_s) {
|
||||
// roomId = condition.pattern;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// m_rules.append(Rule{
|
||||
// rule.ruleId,
|
||||
// kind,
|
||||
// variantToAction(rule.actions, rule.enabled),
|
||||
// getSection(rule),
|
||||
// rule.enabled,
|
||||
// roomId,
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
int PushRuleModel::getRuleIndex(const QString &ruleId) const
|
||||
{
|
||||
@@ -126,51 +126,51 @@ int PushRuleModel::getRuleIndex(const QString &ruleId) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
PushRuleSection::Section PushRuleModel::getSection(Quotient::PushRule rule)
|
||||
{
|
||||
auto ruleId = rule.ruleId;
|
||||
|
||||
if (defaultSections.contains(ruleId)) {
|
||||
return defaultSections.value(ruleId);
|
||||
} else {
|
||||
if (rule.ruleId.startsWith(u'.')) {
|
||||
return PushRuleSection::Unknown;
|
||||
}
|
||||
/**
|
||||
* If the rule name resolves to a matrix id for a room that the user is part
|
||||
* of it shouldn't appear in the global list as it's overriding the global
|
||||
* state for that room.
|
||||
*
|
||||
* Rooms that the user hasn't joined shouldn't have a rule.
|
||||
*/
|
||||
if (m_connection->room(ruleId) != nullptr) {
|
||||
return PushRuleSection::Undefined;
|
||||
}
|
||||
/**
|
||||
* If the rule name resolves to a matrix id for a user it shouldn't appear
|
||||
* in the global list as it's a rule to block notifications from a user and
|
||||
* is handled elsewhere.
|
||||
*/
|
||||
auto testUserId = ruleId;
|
||||
// Rules for user matrix IDs often don't have the @ on the beginning so add
|
||||
// if not there to avoid malformed ID.
|
||||
if (!testUserId.startsWith(u'@')) {
|
||||
testUserId.prepend(u'@');
|
||||
}
|
||||
if (testUserId.startsWith(u'@') && !Quotient::serverPart(testUserId).isEmpty() && m_connection->user(testUserId) != nullptr) {
|
||||
return PushRuleSection::Undefined;
|
||||
}
|
||||
// If the rule has push conditions and one is a room ID it is a room only keyword.
|
||||
if (!rule.conditions.isEmpty()) {
|
||||
for (const auto &condition : std::as_const(rule.conditions)) {
|
||||
if (condition.key == u"room_id"_s) {
|
||||
return PushRuleSection::RoomKeywords;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PushRuleSection::Keywords;
|
||||
}
|
||||
}
|
||||
// PushRuleSection::Section PushRuleModel::getSection(Quotient::PushRule rule)
|
||||
// {
|
||||
// auto ruleId = rule.ruleId;
|
||||
//
|
||||
// if (defaultSections.contains(ruleId)) {
|
||||
// return defaultSections.value(ruleId);
|
||||
// } else {
|
||||
// if (rule.ruleId.startsWith(u'.')) {
|
||||
// return PushRuleSection::Unknown;
|
||||
// }
|
||||
// /**
|
||||
// * If the rule name resolves to a matrix id for a room that the user is part
|
||||
// * of it shouldn't appear in the global list as it's overriding the global
|
||||
// * state for that room.
|
||||
// *
|
||||
// * Rooms that the user hasn't joined shouldn't have a rule.
|
||||
// */
|
||||
// if (m_connection->room(ruleId) != nullptr) {
|
||||
// return PushRuleSection::Undefined;
|
||||
// }
|
||||
// /**
|
||||
// * If the rule name resolves to a matrix id for a user it shouldn't appear
|
||||
// * in the global list as it's a rule to block notifications from a user and
|
||||
// * is handled elsewhere.
|
||||
// */
|
||||
// auto testUserId = ruleId;
|
||||
// // Rules for user matrix IDs often don't have the @ on the beginning so add
|
||||
// // if not there to avoid malformed ID.
|
||||
// if (!testUserId.startsWith(u'@')) {
|
||||
// testUserId.prepend(u'@');
|
||||
// }
|
||||
// if (testUserId.startsWith(u'@') && !Quotient::serverPart(testUserId).isEmpty() && m_connection->user(testUserId) != nullptr) {
|
||||
// return PushRuleSection::Undefined;
|
||||
// }
|
||||
// // If the rule has push conditions and one is a room ID it is a room only keyword.
|
||||
// if (!rule.conditions.isEmpty()) {
|
||||
// for (const auto &condition : std::as_const(rule.conditions)) {
|
||||
// if (condition.key == u"room_id"_s) {
|
||||
// return PushRuleSection::RoomKeywords;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return PushRuleSection::Keywords;
|
||||
// }
|
||||
// }
|
||||
|
||||
PushRuleAction::Action PushRuleModel::defaultState() const
|
||||
{
|
||||
@@ -294,33 +294,33 @@ void PushRuleModel::addKeyword(const QString &keyword, const QString &roomId)
|
||||
{
|
||||
PushRuleKind::Kind kind = PushRuleKind::Content;
|
||||
const QList<QVariant> actions = actionToVariant(m_defaultKeywordAction);
|
||||
QList<Quotient::PushCondition> pushConditions;
|
||||
if (!roomId.isEmpty()) {
|
||||
kind = PushRuleKind::Override;
|
||||
|
||||
Quotient::PushCondition roomCondition;
|
||||
roomCondition.kind = u"event_match"_s;
|
||||
roomCondition.key = u"room_id"_s;
|
||||
roomCondition.pattern = roomId;
|
||||
pushConditions.append(roomCondition);
|
||||
|
||||
Quotient::PushCondition keywordCondition;
|
||||
keywordCondition.kind = u"event_match"_s;
|
||||
keywordCondition.key = u"content.body"_s;
|
||||
keywordCondition.pattern = keyword;
|
||||
pushConditions.append(keywordCondition);
|
||||
}
|
||||
|
||||
auto job = m_connection->callApi<Quotient::SetPushRuleJob>(PushRuleKind::kindString(kind),
|
||||
keyword,
|
||||
actions,
|
||||
QString(),
|
||||
QString(),
|
||||
pushConditions,
|
||||
roomId.isEmpty() ? keyword : QString());
|
||||
connect(job, &Quotient::BaseJob::failure, this, [job, keyword]() {
|
||||
qWarning() << "Unable to set push rule for keyword %1: "_L1.arg(keyword) << job->errorString();
|
||||
});
|
||||
// QList<Quotient::PushCondition> pushConditions;
|
||||
// if (!roomId.isEmpty()) {
|
||||
// kind = PushRuleKind::Override;
|
||||
//
|
||||
// Quotient::PushCondition roomCondition;
|
||||
// roomCondition.kind = u"event_match"_s;
|
||||
// roomCondition.key = u"room_id"_s;
|
||||
// roomCondition.pattern = roomId;
|
||||
// pushConditions.append(roomCondition);
|
||||
//
|
||||
// Quotient::PushCondition keywordCondition;
|
||||
// keywordCondition.kind = u"event_match"_s;
|
||||
// keywordCondition.key = u"content.body"_s;
|
||||
// keywordCondition.pattern = keyword;
|
||||
// pushConditions.append(keywordCondition);
|
||||
// }
|
||||
//
|
||||
// auto job = m_connection->callApi<Quotient::SetPushRuleJob>(PushRuleKind::kindString(kind),
|
||||
// keyword,
|
||||
// actions,
|
||||
// QString(),
|
||||
// QString(),
|
||||
// pushConditions,
|
||||
// roomId.isEmpty() ? keyword : QString());
|
||||
// connect(job, &Quotient::BaseJob::failure, this, [job, keyword]() {
|
||||
// qWarning() << "Unable to set push rule for keyword %1: "_L1.arg(keyword) << job->errorString();
|
||||
// });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -336,20 +336,20 @@ void PushRuleModel::removeKeyword(const QString &keyword)
|
||||
}
|
||||
|
||||
auto kind = PushRuleKind::kindString(m_rules[index].kind);
|
||||
auto job = m_connection->callApi<Quotient::DeletePushRuleJob>(kind, m_rules[index].id);
|
||||
connect(job, &Quotient::BaseJob::failure, this, [this, job, index]() {
|
||||
qWarning() << "Unable to remove push rule for keyword %1: "_L1.arg(m_rules[index].id) << job->errorString();
|
||||
});
|
||||
// auto job = m_connection->callApi<Quotient::DeletePushRuleJob>(kind, m_rules[index].id);
|
||||
// connect(job, &Quotient::BaseJob::failure, this, [this, job, index]() {
|
||||
// qWarning() << "Unable to remove push rule for keyword %1: "_L1.arg(m_rules[index].id) << job->errorString();
|
||||
// });
|
||||
}
|
||||
|
||||
void PushRuleModel::setNotificationRuleEnabled(const QString &kind, const QString &ruleId, bool enabled)
|
||||
{
|
||||
auto job = m_connection->callApi<Quotient::IsPushRuleEnabledJob>(kind, ruleId);
|
||||
connect(job, &Quotient::BaseJob::success, this, [job, kind, ruleId, enabled, this]() {
|
||||
if (job->enabled() != enabled) {
|
||||
m_connection->callApi<Quotient::SetPushRuleEnabledJob>(kind, ruleId, enabled);
|
||||
}
|
||||
});
|
||||
// auto job = m_connection->callApi<Quotient::IsPushRuleEnabledJob>(kind, ruleId);
|
||||
// connect(job, &Quotient::BaseJob::success, this, [job, kind, ruleId, enabled, this]() {
|
||||
// if (job->enabled() != enabled) {
|
||||
// m_connection->callApi<Quotient::SetPushRuleEnabledJob>(kind, ruleId, enabled);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
void PushRuleModel::setNotificationRuleActions(const QString &kind, const QString &ruleId, PushRuleAction::Action action)
|
||||
@@ -361,7 +361,7 @@ void PushRuleModel::setNotificationRuleActions(const QString &kind, const QStrin
|
||||
actions = actionToVariant(action);
|
||||
}
|
||||
|
||||
m_connection->callApi<Quotient::SetPushRuleActionsJob>(kind, ruleId, actions);
|
||||
// m_connection->callApi<Quotient::SetPushRuleActionsJob>(kind, ruleId, actions);
|
||||
}
|
||||
|
||||
PushRuleAction::Action PushRuleModel::variantToAction(const QList<QVariant> &actions, bool enabled)
|
||||
@@ -378,14 +378,14 @@ PushRuleAction::Action PushRuleModel::variantToAction(const QList<QVariant> &act
|
||||
continue;
|
||||
}
|
||||
|
||||
QJsonObject action = i.toJsonObject();
|
||||
if (action["set_tweak"_L1].toString() == u"sound"_s) {
|
||||
isNoisy = true;
|
||||
} else if (action["set_tweak"_L1].toString() == u"highlight"_s) {
|
||||
if (action["value"_L1].toString() != u"false"_s) {
|
||||
highlightEnabled = true;
|
||||
}
|
||||
}
|
||||
// QJsonObject action = i.toJsonObject();
|
||||
// if (action["set_tweak"_L1].toString() == u"sound"_s) {
|
||||
// isNoisy = true;
|
||||
// } else if (action["set_tweak"_L1].toString() == u"highlight"_s) {
|
||||
// if (action["value"_L1].toString() != u"false"_s) {
|
||||
// highlightEnabled = true;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
@@ -424,15 +424,15 @@ QList<QVariant> PushRuleModel::actionToVariant(PushRuleAction::Action action, co
|
||||
actions.append(u"dont_notify"_s);
|
||||
}
|
||||
if (action == PushRuleAction::Noisy || action == PushRuleAction::NoisyHighlight) {
|
||||
QJsonObject soundTweak;
|
||||
soundTweak.insert("set_tweak"_L1, u"sound"_s);
|
||||
soundTweak.insert("value"_L1, sound);
|
||||
actions.append(soundTweak);
|
||||
// QJsonObject soundTweak;
|
||||
// soundTweak.insert("set_tweak"_L1, u"sound"_s);
|
||||
// soundTweak.insert("value"_L1, sound);
|
||||
// actions.append(soundTweak);
|
||||
}
|
||||
if (action == PushRuleAction::Highlight || action == PushRuleAction::NoisyHighlight) {
|
||||
QJsonObject highlightTweak;
|
||||
highlightTweak.insert("set_tweak"_L1, u"highlight"_s);
|
||||
actions.append(highlightTweak);
|
||||
// QJsonObject highlightTweak;
|
||||
// highlightTweak.insert("set_tweak"_L1, u"highlight"_s);
|
||||
// actions.append(highlightTweak);
|
||||
}
|
||||
|
||||
return actions;
|
||||
@@ -452,7 +452,7 @@ void PushRuleModel::setConnection(NeoChatConnection *connection)
|
||||
Q_EMIT connectionChanged();
|
||||
|
||||
if (m_connection) {
|
||||
connect(m_connection, &NeoChatConnection::accountDataChanged, this, &PushRuleModel::updateNotificationRules);
|
||||
// connect(m_connection, &NeoChatConnection::accountDataChanged, this, &PushRuleModel::updateNotificationRules);
|
||||
updateNotificationRules(u"m.push_rules"_s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <QAbstractListModel>
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include <Quotient/csapi/definitions/push_rule.h>
|
||||
// #include <Quotient/csapi/definitions/push_rule.h>
|
||||
|
||||
#include "enums/pushrule.h"
|
||||
#include "neochatconnection.h"
|
||||
@@ -130,10 +130,10 @@ private:
|
||||
QList<Rule> m_rules;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
|
||||
void setRules(QList<Quotient::PushRule> rules, PushRuleKind::Kind kind);
|
||||
// void setRules(QList<Quotient::PushRule> rules, PushRuleKind::Kind kind);
|
||||
|
||||
int getRuleIndex(const QString &ruleId) const;
|
||||
PushRuleSection::Section getSection(Quotient::PushRule rule);
|
||||
// PushRuleSection::Section getSection(Quotient::PushRule rule);
|
||||
|
||||
void setNotificationRuleEnabled(const QString &kind, const QString &ruleId, bool enabled);
|
||||
void setNotificationRuleActions(const QString &kind, const QString &ruleId, PushRuleAction::Action action);
|
||||
|
||||
@@ -12,11 +12,11 @@ RoomTreeItem::RoomTreeItem(TreeData data, RoomTreeItem *parent)
|
||||
|
||||
bool RoomTreeItem::operator==(const RoomTreeItem &other) const
|
||||
{
|
||||
if (std::holds_alternative<NeoChatRoomType::Types>(m_data) && std::holds_alternative<NeoChatRoomType::Types>(other.data())) {
|
||||
return std::get<NeoChatRoomType::Types>(m_data) == std::get<NeoChatRoomType::Types>(m_data);
|
||||
if (std::holds_alternative<NeoChatRoomType::Type>(m_data) && std::holds_alternative<NeoChatRoomType::Type>(other.data())) {
|
||||
return std::get<NeoChatRoomType::Type>(m_data) == std::get<NeoChatRoomType::Type>(m_data);
|
||||
}
|
||||
if (std::holds_alternative<NeoChatRoom *>(m_data) && std::holds_alternative<NeoChatRoom *>(other.data())) {
|
||||
return std::get<NeoChatRoom *>(m_data)->id() == std::get<NeoChatRoom *>(m_data)->id();
|
||||
if (std::holds_alternative<RoomWrapper *>(m_data) && std::holds_alternative<RoomWrapper *>(other.data())) {
|
||||
return (*std::get<RoomWrapper *>(m_data)->item)->id() == (*std::get<RoomWrapper *>(other.data())->item)->id();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -84,13 +84,13 @@ RoomTreeItem::TreeData RoomTreeItem::data() const
|
||||
return m_data;
|
||||
}
|
||||
|
||||
std::optional<int> RoomTreeItem::rowForRoom(Quotient::Room *room) const
|
||||
std::optional<int> RoomTreeItem::rowForRoom(rust::Box<sdk::RoomListRoom> room) const
|
||||
{
|
||||
Q_ASSERT_X(std::holds_alternative<NeoChatRoomType::Types>(m_data), __FUNCTION__, "rowForRoom only works items for rooms not categories");
|
||||
Q_ASSERT_X(std::holds_alternative<NeoChatRoomType::Type>(m_data), __FUNCTION__, "rowForRoom only works items for rooms not categories");
|
||||
|
||||
int i = 0;
|
||||
for (const auto &child : m_children) {
|
||||
if (std::get<NeoChatRoom *>(child->data()) == room) {
|
||||
if ((*std::get<RoomWrapper *>(child->data())->item)->id() == room->id()) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
|
||||
// SPDX-FileCopyrightText: 2024 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include "enums/neochatroomtype.h"
|
||||
#include "neochatroomtype.h"
|
||||
|
||||
class NeoChatRoom;
|
||||
namespace sdk
|
||||
{
|
||||
struct RoomListRoom;
|
||||
}
|
||||
|
||||
struct RoomWrapper {
|
||||
std::optional<rust::Box<sdk::RoomListRoom>> item;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class RoomTreeItem
|
||||
*
|
||||
* This class defines an item in the space tree hierarchy model.
|
||||
*
|
||||
* @note This is separate from Quotient::Room and NeoChatRoom because we don't have
|
||||
* full room information for any room/space the user hasn't joined and we
|
||||
* don't want to create one for ever possible child in a space as that would
|
||||
* be expensive.
|
||||
*
|
||||
* @sa Quotient::Room, NeoChatRoom
|
||||
* This class defines an item in a room tree.
|
||||
*/
|
||||
class RoomTreeItem
|
||||
{
|
||||
public:
|
||||
using TreeData = std::variant<NeoChatRoom *, NeoChatRoomType::Types>;
|
||||
using TreeData = std::variant<RoomWrapper *, NeoChatRoomType::Type>;
|
||||
|
||||
explicit RoomTreeItem(TreeData data, RoomTreeItem *parent = nullptr);
|
||||
|
||||
@@ -68,7 +69,7 @@ public:
|
||||
*/
|
||||
TreeData data() const;
|
||||
|
||||
std::optional<int> rowForRoom(Quotient::Room *room) const;
|
||||
std::optional<int> rowForRoom(rust::Box<sdk::RoomListRoom> room) const;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<RoomTreeItem>> m_children;
|
||||
|
||||
@@ -1,23 +1,45 @@
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#include "roomtreemodel.h"
|
||||
|
||||
#include <Quotient/room.h>
|
||||
|
||||
#include "eventhandler.h"
|
||||
#include "neochatconnection.h"
|
||||
// #include "eventhandler.h"
|
||||
#include "neochatroomtype.h"
|
||||
#include "spacehierarchycache.h"
|
||||
#include "rust/cxx.h"
|
||||
#include <Integral/lib.rs.h>
|
||||
// #include "spacehierarchycache.h"
|
||||
#include <Integral/RoomStream>
|
||||
#include <Integral/Utils>
|
||||
|
||||
using namespace Quotient;
|
||||
using namespace Integral;
|
||||
|
||||
class RoomTreeModel::Private
|
||||
{
|
||||
public:
|
||||
QPointer<Integral::Connection> connection;
|
||||
std::unique_ptr<RoomStream> roomStream = nullptr;
|
||||
std::unique_ptr<RoomTreeItem> rootItem;
|
||||
// Since the rooms are streamed as vector diffs we need to keep track of them
|
||||
// for things like the index value of insert to make sense.
|
||||
QList<QPersistentModelIndex> roomIndexes;
|
||||
|
||||
void roomsUpdate();
|
||||
void resetTree();
|
||||
|
||||
RoomTreeModel *q = nullptr;
|
||||
};
|
||||
|
||||
RoomTreeModel::RoomTreeModel(QObject *parent)
|
||||
: QAbstractItemModel(parent)
|
||||
, m_rootItem(new RoomTreeItem(nullptr))
|
||||
, d(std::make_unique<Private>())
|
||||
{
|
||||
d->q = this;
|
||||
}
|
||||
|
||||
RoomTreeModel::~RoomTreeModel() = default;
|
||||
|
||||
RoomTreeItem *RoomTreeModel::getItem(const QModelIndex &index) const
|
||||
{
|
||||
if (index.isValid()) {
|
||||
@@ -26,179 +48,226 @@ RoomTreeItem *RoomTreeModel::getItem(const QModelIndex &index) const
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return m_rootItem.get();
|
||||
return d->rootItem.get();
|
||||
}
|
||||
|
||||
void RoomTreeModel::resetModel()
|
||||
{
|
||||
if (m_connection == nullptr) {
|
||||
if (d->connection == nullptr) {
|
||||
beginResetModel();
|
||||
m_rootItem.reset();
|
||||
d->rootItem.reset();
|
||||
d->roomStream.reset();
|
||||
endResetModel();
|
||||
return;
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
m_rootItem.reset(new RoomTreeItem(nullptr));
|
||||
d->resetTree();
|
||||
|
||||
for (int i = 0; i < NeoChatRoomType::TypesCount; i++) {
|
||||
m_rootItem->insertChild(std::make_unique<RoomTreeItem>(NeoChatRoomType::Types(i), m_rootItem.get()));
|
||||
}
|
||||
d->roomStream = d->connection->roomStream();
|
||||
connect(d->roomStream.get(), &RoomStream::roomsUpdate, this, [this]() {
|
||||
d->roomsUpdate();
|
||||
});
|
||||
|
||||
for (const auto &r : m_connection->allRooms()) {
|
||||
const auto room = dynamic_cast<NeoChatRoom *>(r);
|
||||
const auto type = NeoChatRoomType::typeForRoom(room);
|
||||
const auto categoryItem = m_rootItem->child(type);
|
||||
if (categoryItem->insertChild(std::make_unique<RoomTreeItem>(room, categoryItem))) {
|
||||
connectRoomSignals(room);
|
||||
}
|
||||
}
|
||||
d->roomStream->startStream();
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void RoomTreeModel::setConnection(NeoChatConnection *connection)
|
||||
void RoomTreeModel::Private::resetTree()
|
||||
{
|
||||
if (m_connection == connection) {
|
||||
rootItem.reset(new RoomTreeItem(nullptr));
|
||||
for (int i = 0; i < NeoChatRoomType::TypesCount; i++) {
|
||||
rootItem->insertChild(std::make_unique<RoomTreeItem>(NeoChatRoomType::Type(i), rootItem.get()));
|
||||
}
|
||||
}
|
||||
|
||||
void RoomTreeModel::setConnection(Connection *connection)
|
||||
{
|
||||
if (d->connection == connection) {
|
||||
return;
|
||||
}
|
||||
if (m_connection) {
|
||||
disconnect(m_connection.get(), nullptr, this, nullptr);
|
||||
if (d->connection) {
|
||||
d->connection->disconnect(this);
|
||||
}
|
||||
m_connection = connection;
|
||||
d->connection = connection;
|
||||
|
||||
resetModel();
|
||||
|
||||
connect(connection, &Connection::newRoom, this, &RoomTreeModel::newRoom);
|
||||
connect(connection, &Connection::leftRoom, this, &RoomTreeModel::leftRoom);
|
||||
connect(connection, &Connection::aboutToDeleteRoom, this, &RoomTreeModel::leftRoom);
|
||||
|
||||
Q_EMIT connectionChanged();
|
||||
}
|
||||
|
||||
void RoomTreeModel::newRoom(Room *r)
|
||||
void RoomTreeModel::Private::roomsUpdate()
|
||||
{
|
||||
const auto room = dynamic_cast<NeoChatRoom *>(r);
|
||||
const auto type = NeoChatRoomType::typeForRoom(room);
|
||||
// Check if the room is already in the model.
|
||||
const auto checkRoomIndex = indexForRoom(room);
|
||||
if (checkRoomIndex.isValid()) {
|
||||
// If the room is in the wrong type category for whatever reason, move it.
|
||||
if (checkRoomIndex.parent().row() != type) {
|
||||
moveRoom(room);
|
||||
const auto diff = roomStream->next();
|
||||
|
||||
switch (diff->op()) {
|
||||
case 0: { // Append
|
||||
for (const auto &it : diff->items_vec()) {
|
||||
const auto type = NeoChatRoomType::typeForRoom(it.box_me());
|
||||
const auto parentItem = rootItem->child(type);
|
||||
q->beginInsertRows(q->index(parentItem->row(), 0), parentItem->childCount(), parentItem->childCount());
|
||||
if (parentItem->insertChild(std::make_unique<RoomTreeItem>(new RoomWrapper{it.box_me()}, parentItem))) {
|
||||
// connectRoomSignals(room);
|
||||
}
|
||||
q->endInsertRows();
|
||||
roomIndexes.append(q->indexForRoom(it.box_me()));
|
||||
}
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
const auto parentItem = m_rootItem->child(type);
|
||||
beginInsertRows(index(parentItem->row(), 0), parentItem->childCount(), parentItem->childCount());
|
||||
parentItem->insertChild(std::make_unique<RoomTreeItem>(room, parentItem));
|
||||
connectRoomSignals(room);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void RoomTreeModel::leftRoom(Room *r)
|
||||
{
|
||||
const auto room = dynamic_cast<NeoChatRoom *>(r);
|
||||
auto index = indexForRoom(room);
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
case 1: { // Clear
|
||||
q->beginResetModel();
|
||||
resetTree();
|
||||
roomIndexes.clear();
|
||||
q->endResetModel();
|
||||
break;
|
||||
}
|
||||
|
||||
const auto parentItem = getItem(index.parent());
|
||||
Q_ASSERT(parentItem);
|
||||
|
||||
beginRemoveRows(index.parent(), index.row(), index.row());
|
||||
parentItem->removeChild(index.row());
|
||||
room->disconnect(this);
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
void RoomTreeModel::moveRoom(Quotient::Room *room)
|
||||
{
|
||||
// We can't assume the type as it has changed so currently the return of
|
||||
// NeoChatRoomType::typeForRoom doesn't match it's current location. So find the room.
|
||||
NeoChatRoomType::Types oldType;
|
||||
int oldRow = -1;
|
||||
for (int i = 0; i < NeoChatRoomType::TypesCount; i++) {
|
||||
const auto categoryItem = m_rootItem->child(i);
|
||||
const auto row = categoryItem->rowForRoom(room);
|
||||
if (row) {
|
||||
oldType = static_cast<NeoChatRoomType::Types>(i);
|
||||
oldRow = *row;
|
||||
case 2: { // Push Front
|
||||
const auto type = NeoChatRoomType::typeForRoom(diff->item());
|
||||
const auto parentItem = rootItem->child(type);
|
||||
q->beginInsertRows(q->index(parentItem->row(), 0), 0, 0);
|
||||
if (parentItem->insertChild(std::make_unique<RoomTreeItem>(new RoomWrapper{diff->item()}, parentItem))) {
|
||||
// connectRoomSignals(room);
|
||||
}
|
||||
q->endInsertRows();
|
||||
roomIndexes.prepend(q->indexForRoom(diff->item()));
|
||||
break;
|
||||
}
|
||||
|
||||
if (oldRow == -1) {
|
||||
return;
|
||||
case 3: { // Push Back
|
||||
const auto type = NeoChatRoomType::typeForRoom(diff->item());
|
||||
const auto parentItem = rootItem->child(type);
|
||||
q->beginInsertRows(q->index(parentItem->row(), 0), parentItem->childCount(), parentItem->childCount());
|
||||
if (parentItem->insertChild(std::make_unique<RoomTreeItem>(new RoomWrapper{diff->item()}, parentItem))) {
|
||||
// connectRoomSignals(room);
|
||||
}
|
||||
q->endInsertRows();
|
||||
roomIndexes.append(q->indexForRoom(diff->item()));
|
||||
break;
|
||||
}
|
||||
auto neochatRoom = dynamic_cast<NeoChatRoom *>(room);
|
||||
const auto newType = NeoChatRoomType::typeForRoom(neochatRoom);
|
||||
if (newType == oldType) {
|
||||
return;
|
||||
case 4: { // Pop Front
|
||||
const auto index = roomIndexes.front();
|
||||
q->beginRemoveRows(index.parent(), index.row(), index.row());
|
||||
const auto parentItem = q->getItem(index.parent());
|
||||
parentItem->removeChild(index.row());
|
||||
roomIndexes.removeFirst();
|
||||
q->endRemoveRows();
|
||||
break;
|
||||
}
|
||||
case 5: { // Pop Back
|
||||
const auto index = roomIndexes.back();
|
||||
q->beginRemoveRows(index.parent(), index.row(), index.row());
|
||||
const auto parentItem = q->getItem(index.parent());
|
||||
parentItem->removeChild(index.row());
|
||||
roomIndexes.removeLast();
|
||||
q->endRemoveRows();
|
||||
break;
|
||||
}
|
||||
case 6: { // Insert
|
||||
const auto type = NeoChatRoomType::typeForRoom(diff->item());
|
||||
const auto parentItem = rootItem->child(type);
|
||||
q->beginInsertRows(q->index(parentItem->row(), 0), parentItem->childCount(), parentItem->childCount());
|
||||
if (parentItem->insertChild(std::make_unique<RoomTreeItem>(new RoomWrapper{diff->item()}, parentItem))) {
|
||||
// connectRoomSignals(room);
|
||||
}
|
||||
q->endInsertRows();
|
||||
roomIndexes.insert(diff->index(), q->indexForRoom(diff->item()));
|
||||
break;
|
||||
}
|
||||
case 7: { // Set
|
||||
const auto index = roomIndexes.at(diff->index());
|
||||
q->beginRemoveRows(index.parent(), index.row(), index.row());
|
||||
q->getItem(index.parent())->removeChild(index.row());
|
||||
q->endRemoveRows();
|
||||
|
||||
const auto oldParent = index(oldType, 0, {});
|
||||
auto oldParentItem = getItem(oldParent);
|
||||
Q_ASSERT(oldParentItem);
|
||||
const auto type = NeoChatRoomType::typeForRoom(diff->item());
|
||||
const auto parentItem = rootItem->child(type);
|
||||
q->beginInsertRows(q->index(parentItem->row(), 0), parentItem->childCount(), parentItem->childCount());
|
||||
if (parentItem->insertChild(std::make_unique<RoomTreeItem>(new RoomWrapper{diff->item()}, parentItem))) {
|
||||
// connectRoomSignals(room);
|
||||
}
|
||||
q->endInsertRows();
|
||||
roomIndexes[diff->index()] = q->indexForRoom(diff->item());
|
||||
break;
|
||||
}
|
||||
case 8: { // Remove
|
||||
const auto index = roomIndexes.at(diff->index());
|
||||
q->beginRemoveRows(index.parent(), index.row(), index.row());
|
||||
q->getItem(index.parent())->removeChild(index.row());
|
||||
q->endRemoveRows();
|
||||
roomIndexes.removeAt(diff->index());
|
||||
break;
|
||||
}
|
||||
case 9: { // Truncate
|
||||
for (int i = q->rowCount({}) - 1; i >= int(diff->index()); i--) {
|
||||
const auto index = roomIndexes.at(i);
|
||||
q->beginRemoveRows(index.parent(), index.row(), index.row());
|
||||
q->getItem(index.parent())->removeChild(index.row());
|
||||
q->endRemoveRows();
|
||||
roomIndexes.removeAt(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 10: { // Reset
|
||||
q->beginResetModel();
|
||||
resetTree();
|
||||
roomIndexes.clear();
|
||||
q->endResetModel();
|
||||
|
||||
const auto newParent = index(newType, 0, {});
|
||||
auto newParentItem = getItem(newParent);
|
||||
Q_ASSERT(newParentItem);
|
||||
|
||||
// HACK: We're doing this as a remove then insert because moving doesn't work
|
||||
// properly with DelegateChooser for whatever reason.
|
||||
Q_ASSERT(checkIndex(index(oldRow, 0, oldParent), QAbstractItemModel::CheckIndexOption::IndexIsValid));
|
||||
beginRemoveRows(oldParent, oldRow, oldRow);
|
||||
const bool success = oldParentItem->removeChild(oldRow);
|
||||
Q_ASSERT(success);
|
||||
endRemoveRows();
|
||||
beginInsertRows(newParent, newParentItem->childCount(), newParentItem->childCount());
|
||||
newParentItem->insertChild(std::make_unique<RoomTreeItem>(neochatRoom, newParentItem));
|
||||
endInsertRows();
|
||||
for (const auto &it : diff->items_vec()) {
|
||||
const auto type = NeoChatRoomType::typeForRoom(it.box_me());
|
||||
const auto parentItem = rootItem->child(type);
|
||||
q->beginInsertRows(q->index(parentItem->row(), 0), parentItem->childCount(), parentItem->childCount());
|
||||
if (parentItem->insertChild(std::make_unique<RoomTreeItem>(new RoomWrapper{it.box_me()}, parentItem))) {
|
||||
// connectRoomSignals(room);
|
||||
}
|
||||
q->endInsertRows();
|
||||
roomIndexes.append(q->indexForRoom(it.box_me()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RoomTreeModel::connectRoomSignals(NeoChatRoom *room)
|
||||
{
|
||||
connect(room, &Room::displaynameChanged, this, [this, room] {
|
||||
refreshRoomRoles(room, {DisplayNameRole});
|
||||
});
|
||||
connect(room, &Room::unreadStatsChanged, this, [this, room] {
|
||||
refreshRoomRoles(room, {ContextNotificationCountRole, HasHighlightNotificationsRole});
|
||||
});
|
||||
connect(room, &Room::avatarChanged, this, [this, room] {
|
||||
refreshRoomRoles(room, {AvatarRole});
|
||||
});
|
||||
connect(room, &Room::tagsChanged, this, [this, room] {
|
||||
moveRoom(room);
|
||||
});
|
||||
connect(room, &Room::joinStateChanged, this, [this, room] {
|
||||
refreshRoomRoles(room);
|
||||
});
|
||||
connect(room, &Room::addedMessages, this, [this, room] {
|
||||
refreshRoomRoles(room, {SubtitleTextRole});
|
||||
});
|
||||
connect(room, &Room::pendingEventMerged, this, [this, room] {
|
||||
refreshRoomRoles(room, {SubtitleTextRole});
|
||||
});
|
||||
connect(room, &NeoChatRoom::pushNotificationStateChanged, this, [this, room] {
|
||||
refreshRoomRoles(room, {ContextNotificationCountRole, HasHighlightNotificationsRole});
|
||||
});
|
||||
}
|
||||
// void RoomTreeModel::connectRoomSignals(NeoChatRoom *room)
|
||||
// {
|
||||
// connect(room, &Room::displaynameChanged, this, [this, room] {
|
||||
// refreshRoomRoles(room, {DisplayNameRole});
|
||||
// });
|
||||
// connect(room, &Room::unreadStatsChanged, this, [this, room] {
|
||||
// refreshRoomRoles(room, {ContextNotificationCountRole, HasHighlightNotificationsRole});
|
||||
// });
|
||||
// connect(room, &Room::avatarChanged, this, [this, room] {
|
||||
// refreshRoomRoles(room, {AvatarRole});
|
||||
// });
|
||||
// connect(room, &Room::tagsChanged, this, [this, room] {
|
||||
// moveRoom(room);
|
||||
// });
|
||||
// connect(room, &Room::joinStateChanged, this, [this, room] {
|
||||
// refreshRoomRoles(room);
|
||||
// });
|
||||
// connect(room, &Room::addedMessages, this, [this, room] {
|
||||
// refreshRoomRoles(room, {SubtitleTextRole});
|
||||
// });
|
||||
// connect(room, &Room::pendingEventMerged, this, [this, room] {
|
||||
// refreshRoomRoles(room, {SubtitleTextRole});
|
||||
// });
|
||||
// connect(room, &NeoChatRoom::pushNotificationStateChanged, this, [this, room] {
|
||||
// refreshRoomRoles(room, {ContextNotificationCountRole, HasHighlightNotificationsRole});
|
||||
// });
|
||||
// }
|
||||
|
||||
void RoomTreeModel::refreshRoomRoles(NeoChatRoom *room, const QList<int> &roles)
|
||||
{
|
||||
const auto index = indexForRoom(room);
|
||||
if (!index.isValid()) {
|
||||
qCritical() << "Room" << room->id() << "not found in the room list";
|
||||
return;
|
||||
}
|
||||
Q_EMIT dataChanged(index, index, roles);
|
||||
}
|
||||
// void RoomTreeModel::refreshRoomRoles(NeoChatRoom *room, const QList<int> &roles)
|
||||
// {
|
||||
// const auto index = indexForRoom(room);
|
||||
// if (!index.isValid()) {
|
||||
// qCritical() << "Room" << room->id() << "not found in the room list";
|
||||
// return;
|
||||
// }
|
||||
// Q_EMIT dataChanged(index, index, roles);
|
||||
// }
|
||||
|
||||
NeoChatConnection *RoomTreeModel::connection() const
|
||||
Connection *RoomTreeModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
return d->connection;
|
||||
}
|
||||
|
||||
int RoomTreeModel::columnCount(const QModelIndex &parent) const
|
||||
@@ -215,7 +284,7 @@ int RoomTreeModel::rowCount(const QModelIndex &parent) const
|
||||
}
|
||||
|
||||
if (!parent.isValid()) {
|
||||
parentItem = m_rootItem.get();
|
||||
parentItem = d->rootItem.get();
|
||||
} else {
|
||||
parentItem = static_cast<RoomTreeItem *>(parent.internalPointer());
|
||||
}
|
||||
@@ -239,7 +308,7 @@ QModelIndex RoomTreeModel::parent(const QModelIndex &index) const
|
||||
}
|
||||
RoomTreeItem *parentItem = childItem->parentItem();
|
||||
|
||||
if (parentItem == m_rootItem.get()) {
|
||||
if (parentItem == d->rootItem.get()) {
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
@@ -295,7 +364,7 @@ QVariant RoomTreeModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
|
||||
RoomTreeItem *child = getItem(index);
|
||||
if (std::holds_alternative<NeoChatRoomType::Types>(child->data())) {
|
||||
if (std::holds_alternative<NeoChatRoomType::Type>(child->data())) {
|
||||
if (role == DisplayNameRole) {
|
||||
return NeoChatRoomType::typeName(index.row());
|
||||
}
|
||||
@@ -314,98 +383,91 @@ QVariant RoomTreeModel::data(const QModelIndex &index, int role) const
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto room = std::get<NeoChatRoom *>(child->data());
|
||||
const auto room = std::get<RoomWrapper *>(child->data());
|
||||
Q_ASSERT(room);
|
||||
|
||||
if (role == DisplayNameRole) {
|
||||
return room->displayName();
|
||||
return stringFromRust((*room->item)->display_name()).toHtmlEscaped();
|
||||
}
|
||||
if (role == AvatarRole) {
|
||||
return room->avatarMediaUrl();
|
||||
return u"%1?user_id=%2"_s.arg(stringFromRust((*room->item)->avatar_url()), d->connection->matrixId());
|
||||
}
|
||||
if (role == CanonicalAliasRole) {
|
||||
return room->canonicalAlias();
|
||||
return stringFromRust((*room->item)->canonical_alias()).toHtmlEscaped();
|
||||
}
|
||||
if (role == TopicRole) {
|
||||
return room->topic();
|
||||
return stringFromRust((*room->item)->topic()).toHtmlEscaped();
|
||||
}
|
||||
if (role == CategoryRole) {
|
||||
return NeoChatRoomType::typeForRoom(room);
|
||||
return NeoChatRoomType::typeForRoom((*room->item)->box_me());
|
||||
}
|
||||
if (role == ContextNotificationCountRole) {
|
||||
return int(room->contextAwareNotificationCount());
|
||||
return int((*room->item)->num_unread_messages());
|
||||
}
|
||||
if (role == HasHighlightNotificationsRole) {
|
||||
return room->highlightCount() > 0 && room->contextAwareNotificationCount() > 0;
|
||||
return (*room->item)->num_unread_mentions() > 0 && (*room->item)->num_unread_messages() > 0;
|
||||
}
|
||||
if (role == JoinStateRole) {
|
||||
if (!room->successorId().isEmpty()) {
|
||||
if (!(*room->item)->tombstone()->replacement_room().empty()) {
|
||||
return u"upgraded"_s;
|
||||
}
|
||||
return QVariant::fromValue(room->joinState());
|
||||
return QVariant::fromValue((*room->item)->state());
|
||||
}
|
||||
if (role == CurrentRoomRole) {
|
||||
return QVariant::fromValue(room);
|
||||
return {};
|
||||
// return QVariant::fromValue(room);
|
||||
}
|
||||
if (role == SubtitleTextRole) {
|
||||
if (room->isInvite()) {
|
||||
if (room->isDirectChat()) {
|
||||
return i18nc("@info:label", "Invited you to chat");
|
||||
}
|
||||
return i18nc("@info:label", "%1 invited you", room->member(room->invitingUserId()).displayName());
|
||||
}
|
||||
if (room->lastEvent() == nullptr || room->lastEventIsSpoiler()) {
|
||||
return QString();
|
||||
}
|
||||
return EventHandler::subtitleText(room, room->lastEvent());
|
||||
return {};
|
||||
// if (room->lastEvent() == nullptr || room->lastEventIsSpoiler()) {
|
||||
// return QString();
|
||||
// }
|
||||
// return EventHandler::subtitleText(room, room->lastEvent());
|
||||
}
|
||||
if (role == AvatarImageRole) {
|
||||
return room->avatar(128);
|
||||
return {};
|
||||
// return room->avatar(128);
|
||||
}
|
||||
if (role == RoomIdRole) {
|
||||
return room->id();
|
||||
return stringFromRust((*room->item)->id()).toHtmlEscaped();
|
||||
}
|
||||
if (role == IsSpaceRole) {
|
||||
return room->isSpace();
|
||||
return (*room->item)->is_space();
|
||||
}
|
||||
if (role == IsChildSpaceRole) {
|
||||
return SpaceHierarchyCache::instance().isChild(room->id());
|
||||
return false;
|
||||
// return SpaceHierarchyCache::instance().isChild(room->id());
|
||||
}
|
||||
if (role == ReplacementIdRole) {
|
||||
return room->successorId();
|
||||
return stringFromRust((*room->item)->tombstone()->replacement_room()).toHtmlEscaped();
|
||||
}
|
||||
if (role == IsDirectChat) {
|
||||
return room->isDirectChat();
|
||||
return false;
|
||||
// return room->isDirectChat();
|
||||
}
|
||||
if (role == DelegateTypeRole) {
|
||||
return u"normal"_s;
|
||||
}
|
||||
if (role == RoomTypeRole) {
|
||||
if (room->creation()) {
|
||||
return room->creation()->contentPart<QString>("type"_L1);
|
||||
}
|
||||
return stringFromRust((*room->item)->room_type()).toHtmlEscaped();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QModelIndex RoomTreeModel::indexForRoom(NeoChatRoom *room) const
|
||||
QModelIndex RoomTreeModel::indexForRoom(rust::Box<sdk::RoomListRoom> room) const
|
||||
{
|
||||
if (room == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// Try and find by checking type.
|
||||
const auto type = NeoChatRoomType::typeForRoom(room);
|
||||
const auto parentItem = m_rootItem->child(type);
|
||||
const auto row = parentItem->rowForRoom(room);
|
||||
const auto type = NeoChatRoomType::typeForRoom(room->box_me());
|
||||
const auto parentItem = d->rootItem->child(type);
|
||||
const auto row = parentItem->rowForRoom(room->box_me());
|
||||
if (row) {
|
||||
return index(*row, 0, index(type, 0));
|
||||
}
|
||||
// Double check that the room isn't in the wrong category.
|
||||
for (int i = 0; i < NeoChatRoomType::TypesCount; i++) {
|
||||
const auto parentItem = m_rootItem->child(i);
|
||||
const auto row = parentItem->rowForRoom(room);
|
||||
const auto parentItem = d->rootItem->child(i);
|
||||
const auto row = parentItem->rowForRoom(room->box_me());
|
||||
if (row) {
|
||||
return index(*row, 0, index(i, 0));
|
||||
}
|
||||
@@ -414,4 +476,13 @@ QModelIndex RoomTreeModel::indexForRoom(NeoChatRoom *room) const
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<rust::Box<sdk::RoomListRoom>> RoomTreeModel::roomForIndex(QModelIndex index) const
|
||||
{
|
||||
RoomTreeItem *child = getItem(index);
|
||||
if (std::holds_alternative<NeoChatRoomType::Type>(child->data())) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return (*std::get<RoomWrapper *>(child->data())->item)->box_me();
|
||||
}
|
||||
|
||||
#include "moc_roomtreemodel.cpp"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
@@ -6,23 +7,20 @@
|
||||
#include <QAbstractItemModel>
|
||||
#include <QPointer>
|
||||
|
||||
#include "enums/neochatroomtype.h"
|
||||
#include "roomtreeitem.h"
|
||||
|
||||
namespace Quotient
|
||||
namespace Integral
|
||||
{
|
||||
class Connection;
|
||||
class Room;
|
||||
}
|
||||
|
||||
class NeoChatConnection;
|
||||
class NeoChatRoom;
|
||||
|
||||
class RoomTreeModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
Q_PROPERTY(Integral::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -51,9 +49,10 @@ public:
|
||||
};
|
||||
Q_ENUM(EventRoles)
|
||||
explicit RoomTreeModel(QObject *parent = nullptr);
|
||||
~RoomTreeModel();
|
||||
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
NeoChatConnection *connection() const;
|
||||
void setConnection(Integral::Connection *connection);
|
||||
Integral::Connection *connection() const;
|
||||
|
||||
/**
|
||||
* @brief Get the given role value at the given index.
|
||||
@@ -75,23 +74,21 @@ public:
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
Q_INVOKABLE QModelIndex indexForRoom(NeoChatRoom *room) const;
|
||||
QModelIndex indexForRoom(rust::Box<sdk::RoomListRoom> room) const;
|
||||
std::optional<rust::Box<sdk::RoomListRoom>> roomForIndex(QModelIndex index) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void connectionChanged();
|
||||
|
||||
private:
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
std::unique_ptr<RoomTreeItem> m_rootItem;
|
||||
class Private;
|
||||
std::unique_ptr<Private> d;
|
||||
|
||||
RoomTreeItem *getItem(const QModelIndex &index) const;
|
||||
|
||||
void resetModel();
|
||||
void connectRoomSignals(NeoChatRoom *room);
|
||||
|
||||
void newRoom(Quotient::Room *room);
|
||||
void leftRoom(Quotient::Room *room);
|
||||
void moveRoom(Quotient::Room *room);
|
||||
// void connectRoomSignals(NeoChatRoom *room);
|
||||
|
||||
void refreshRoomRoles(NeoChatRoom *room, const QList<int> &roles = {});
|
||||
// void refreshRoomRoles(NeoChatRoom *room, const QList<int> &roles = {});
|
||||
};
|
||||
|
||||
@@ -4,26 +4,26 @@
|
||||
|
||||
#include "sortfilterroomtreemodel.h"
|
||||
|
||||
#include "enums/roomsortparameter.h"
|
||||
#include "neochatconfig.h"
|
||||
#include "roomsortparameter.h"
|
||||
// #include "neochatconfig.h"
|
||||
#include "neochatconnection.h"
|
||||
#include "neochatroom.h"
|
||||
#include "neochatroomtype.h"
|
||||
#include "roommanager.h"
|
||||
#include <Integral/Room>
|
||||
// #include "roommanager.h"
|
||||
#include "roomtreemodel.h"
|
||||
#include "spacehierarchycache.h"
|
||||
// #include "spacehierarchycache.h"
|
||||
|
||||
SortFilterRoomTreeModel::SortFilterRoomTreeModel(RoomTreeModel *sourceModel, QObject *parent)
|
||||
SortFilterRoomTreeModel::SortFilterRoomTreeModel(QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
Q_ASSERT(sourceModel);
|
||||
setSourceModel(sourceModel);
|
||||
// Q_ASSERT(sourceModel);
|
||||
// setSourceModel(sourceModel);
|
||||
|
||||
setRoomSortOrder(static_cast<RoomSortOrder>(NeoChatConfig::sortOrder()));
|
||||
connect(NeoChatConfig::self(), &NeoChatConfig::SortOrderChanged, this, [this]() {
|
||||
setRoomSortOrder(static_cast<RoomSortOrder>(NeoChatConfig::sortOrder()));
|
||||
invalidateFilter();
|
||||
});
|
||||
// setRoomSortOrder(static_cast<RoomSortOrder>(NeoChatConfig::sortOrder()));
|
||||
// connect(NeoChatConfig::self(), &NeoChatConfig::SortOrderChanged, this, [this]() {
|
||||
// setRoomSortOrder(static_cast<RoomSortOrder>(NeoChatConfig::sortOrder()));
|
||||
// invalidateFilter();
|
||||
// });
|
||||
|
||||
setRecursiveFilteringEnabled(true);
|
||||
sort(0);
|
||||
@@ -34,13 +34,13 @@ SortFilterRoomTreeModel::SortFilterRoomTreeModel(RoomTreeModel *sourceModel, QOb
|
||||
connect(this->sourceModel(), &QAbstractItemModel::rowsRemoved, this, &SortFilterRoomTreeModel::invalidateFilter);
|
||||
});
|
||||
|
||||
connect(NeoChatConfig::self(), &NeoChatConfig::CollapsedChanged, this, &SortFilterRoomTreeModel::invalidateFilter);
|
||||
connect(NeoChatConfig::self(), &NeoChatConfig::AllRoomsInHomeChanged, this, [this]() {
|
||||
invalidateFilter();
|
||||
if (NeoChatConfig::self()->allRoomsInHome()) {
|
||||
RoomManager::instance().resetState();
|
||||
}
|
||||
});
|
||||
// connect(NeoChatConfig::self(), &NeoChatConfig::CollapsedChanged, this, &SortFilterRoomTreeModel::invalidateFilter);
|
||||
// connect(NeoChatConfig::self(), &NeoChatConfig::AllRoomsInHomeChanged, this, [this]() {
|
||||
// invalidateFilter();
|
||||
// if (NeoChatConfig::self()->allRoomsInHome()) {
|
||||
// RoomManager::instance().resetState();
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
void SortFilterRoomTreeModel::setRoomSortOrder(SortFilterRoomTreeModel::RoomSortOrder sortOrder)
|
||||
@@ -78,14 +78,14 @@ bool SortFilterRoomTreeModel::lessThan(const QModelIndex &source_left, const QMo
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto leftRoom = dynamic_cast<NeoChatRoom *>(treeModel->connection()->room(source_left.data(RoomTreeModel::RoomIdRole).toString()));
|
||||
const auto rightRoom = dynamic_cast<NeoChatRoom *>(treeModel->connection()->room(source_right.data(RoomTreeModel::RoomIdRole).toString()));
|
||||
if (leftRoom == nullptr || rightRoom == nullptr) {
|
||||
const auto leftRoom = treeModel->roomForIndex(source_left);
|
||||
const auto rightRoom = treeModel->roomForIndex(source_right);
|
||||
if (!leftRoom.has_value() || !rightRoom.has_value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto sortRole : RoomSortParameter::currentParameterList()) {
|
||||
auto result = RoomSortParameter::compareParameter(sortRole, leftRoom, rightRoom);
|
||||
auto result = RoomSortParameter::compareParameter(sortRole, leftRoom.value()->box_me(), rightRoom.value()->box_me());
|
||||
|
||||
if (result != 0) {
|
||||
return result > 0;
|
||||
@@ -141,20 +141,22 @@ bool SortFilterRoomTreeModel::filterAcceptsRow(int source_row, const QModelIndex
|
||||
return false;
|
||||
}
|
||||
|
||||
static auto config = NeoChatConfig::self();
|
||||
if (config->allRoomsInHome() && RoomManager::instance().currentSpace().isEmpty()) {
|
||||
return acceptRoom;
|
||||
}
|
||||
return acceptRoom;
|
||||
|
||||
if (m_activeSpaceId.isEmpty()) {
|
||||
if (!SpaceHierarchyCache::instance().isChild(sourceModel()->data(index, RoomTreeModel::RoomIdRole).toString())) {
|
||||
return acceptRoom;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
const auto &rooms = SpaceHierarchyCache::instance().getRoomListForSpace(m_activeSpaceId, false);
|
||||
return std::find(rooms.begin(), rooms.end(), sourceModel()->data(index, RoomTreeModel::RoomIdRole).toString()) != rooms.end() && acceptRoom;
|
||||
}
|
||||
// static auto config = NeoChatConfig::self();
|
||||
// if (config->allRoomsInHome() && RoomManager::instance().currentSpace().isEmpty()) {
|
||||
// return acceptRoom;
|
||||
// }
|
||||
//
|
||||
// if (m_activeSpaceId.isEmpty()) {
|
||||
// if (!SpaceHierarchyCache::instance().isChild(sourceModel()->data(index, RoomTreeModel::RoomIdRole).toString())) {
|
||||
// return acceptRoom;
|
||||
// }
|
||||
// return false;
|
||||
// } else {
|
||||
// const auto &rooms = SpaceHierarchyCache::instance().getRoomListForSpace(m_activeSpaceId, false);
|
||||
// return std::find(rooms.begin(), rooms.end(), sourceModel()->data(index, RoomTreeModel::RoomIdRole).toString()) != rooms.end() && acceptRoom;
|
||||
// }
|
||||
}
|
||||
|
||||
QString SortFilterRoomTreeModel::activeSpaceId() const
|
||||
@@ -192,7 +194,7 @@ QModelIndex SortFilterRoomTreeModel::currentRoomIndex() const
|
||||
return {};
|
||||
}
|
||||
|
||||
return mapFromSource(roomModel->indexForRoom(RoomManager::instance().currentRoom()));
|
||||
return {}; // mapFromSource(roomModel->indexForRoom(RoomManager::instance().currentRoom()));
|
||||
}
|
||||
|
||||
#include "moc_sortfilterroomtreemodel.cpp"
|
||||
|
||||
@@ -32,7 +32,7 @@ class SortFilterRoomTreeModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("")
|
||||
// QML_UNCREATABLE("")
|
||||
|
||||
/**
|
||||
* @brief The text to use to filter room names.
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
};
|
||||
Q_ENUM(Mode)
|
||||
|
||||
explicit SortFilterRoomTreeModel(RoomTreeModel *sourceModel, QObject *parent = nullptr);
|
||||
explicit SortFilterRoomTreeModel(QObject *parent = nullptr);
|
||||
|
||||
void setRoomSortOrder(RoomSortOrder sortOrder);
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <Quotient/avatar.h>
|
||||
#include <Quotient/events/roompowerlevelsevent.h>
|
||||
// #include <Quotient/avatar.h>
|
||||
// #include <Quotient/events/roompowerlevelsevent.h>
|
||||
|
||||
#include "enums/powerlevel.h"
|
||||
#include "neochatroom.h"
|
||||
@@ -30,7 +30,7 @@ void UserListModel::setRoom(NeoChatRoom *room)
|
||||
// last room's objects before the room is actually changed
|
||||
beginResetModel();
|
||||
m_currentRoom->disconnect(this);
|
||||
m_currentRoom->connection()->disconnect(this);
|
||||
// m_currentRoom->connection()->disconnect(this);
|
||||
m_currentRoom = nullptr;
|
||||
m_members.clear();
|
||||
endResetModel();
|
||||
@@ -39,21 +39,21 @@ void UserListModel::setRoom(NeoChatRoom *room)
|
||||
m_currentRoom = room;
|
||||
|
||||
if (m_currentRoom) {
|
||||
connect(m_currentRoom, &Room::memberJoined, this, &UserListModel::memberJoined);
|
||||
connect(m_currentRoom, &Room::memberLeft, this, &UserListModel::memberLeft);
|
||||
connect(m_currentRoom, &Room::memberNameUpdated, this, [this](RoomMember member) {
|
||||
refreshMember(member, {DisplayNameRole});
|
||||
});
|
||||
connect(m_currentRoom, &Room::memberAvatarUpdated, this, [this](RoomMember member) {
|
||||
refreshMember(member, {AvatarRole});
|
||||
});
|
||||
connect(m_currentRoom, &Room::memberListChanged, this, [this]() {
|
||||
// this is slow
|
||||
UserListModel::refreshAllMembers();
|
||||
});
|
||||
connect(m_currentRoom->connection(), &Connection::loggedOut, this, [this]() {
|
||||
setRoom(nullptr);
|
||||
});
|
||||
// connect(m_currentRoom, &Room::memberJoined, this, &UserListModel::memberJoined);
|
||||
// connect(m_currentRoom, &Room::memberLeft, this, &UserListModel::memberLeft);
|
||||
// connect(m_currentRoom, &Room::memberNameUpdated, this, [this](RoomMember member) {
|
||||
// refreshMember(member, {DisplayNameRole});
|
||||
// });
|
||||
// connect(m_currentRoom, &Room::memberAvatarUpdated, this, [this](RoomMember member) {
|
||||
// refreshMember(member, {AvatarRole});
|
||||
// });
|
||||
// connect(m_currentRoom, &Room::memberListChanged, this, [this]() {
|
||||
// // this is slow
|
||||
// UserListModel::refreshAllMembers();
|
||||
// });
|
||||
// connect(m_currentRoom->connection(), &Connection::loggedOut, this, [this]() {
|
||||
// setRoom(nullptr);
|
||||
// });
|
||||
}
|
||||
|
||||
m_active = false;
|
||||
@@ -80,40 +80,40 @@ QVariant UserListModel::data(const QModelIndex &index, int role) const
|
||||
return {};
|
||||
}
|
||||
auto memberId = m_members.at(index.row());
|
||||
if (role == DisplayNameRole) {
|
||||
return m_currentRoom->member(memberId).disambiguatedName();
|
||||
}
|
||||
if (role == UserIdRole) {
|
||||
return memberId;
|
||||
}
|
||||
if (role == AvatarRole) {
|
||||
return m_currentRoom->member(memberId).avatarUrl();
|
||||
}
|
||||
if (role == ObjectRole) {
|
||||
return QVariant::fromValue(memberId);
|
||||
}
|
||||
if (role == PowerLevelRole) {
|
||||
auto plEvent = m_currentRoom->currentState().get<RoomPowerLevelsEvent>();
|
||||
if (!plEvent) {
|
||||
return 0;
|
||||
}
|
||||
return plEvent->powerLevelForUser(memberId);
|
||||
}
|
||||
if (role == PowerLevelStringRole) {
|
||||
auto pl = m_currentRoom->currentState().get<RoomPowerLevelsEvent>();
|
||||
// User might not in the room yet, in this case pl can be nullptr.
|
||||
// e.g. When invited but user not accepted or denied the invitation.
|
||||
if (!pl) {
|
||||
return u"Not Available"_s;
|
||||
}
|
||||
|
||||
auto userPl = pl->powerLevelForUser(memberId);
|
||||
|
||||
return i18nc("%1 is the name of the power level, e.g. admin and %2 is the value that represents.",
|
||||
"%1 (%2)",
|
||||
PowerLevel::nameForLevel(PowerLevel::levelForValue(userPl)),
|
||||
userPl);
|
||||
}
|
||||
// if (role == DisplayNameRole) {
|
||||
// return m_currentRoom->member(memberId).disambiguatedName();
|
||||
// }
|
||||
// if (role == UserIdRole) {
|
||||
// return memberId;
|
||||
// }
|
||||
// if (role == AvatarRole) {
|
||||
// return m_currentRoom->member(memberId).avatarUrl();
|
||||
// }
|
||||
// if (role == ObjectRole) {
|
||||
// return QVariant::fromValue(memberId);
|
||||
// }
|
||||
// if (role == PowerLevelRole) {
|
||||
// auto plEvent = m_currentRoom->currentState().get<RoomPowerLevelsEvent>();
|
||||
// if (!plEvent) {
|
||||
// return 0;
|
||||
// }
|
||||
// return plEvent->powerLevelForUser(memberId);
|
||||
// }
|
||||
// if (role == PowerLevelStringRole) {
|
||||
// auto pl = m_currentRoom->currentState().get<RoomPowerLevelsEvent>();
|
||||
// // User might not in the room yet, in this case pl can be nullptr.
|
||||
// // e.g. When invited but user not accepted or denied the invitation.
|
||||
// if (!pl) {
|
||||
// return u"Not Available"_s;
|
||||
// }
|
||||
//
|
||||
// auto userPl = pl->powerLevelForUser(memberId);
|
||||
//
|
||||
// return i18nc("%1 is the name of the power level, e.g. admin and %2 is the value that represents.",
|
||||
// "%1 (%2)",
|
||||
// PowerLevel::nameForLevel(PowerLevel::levelForValue(userPl)),
|
||||
// userPl);
|
||||
// }
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -134,65 +134,65 @@ bool UserListModel::event(QEvent *event)
|
||||
return QObject::event(event);
|
||||
}
|
||||
|
||||
void UserListModel::memberJoined(const Quotient::RoomMember &member)
|
||||
{
|
||||
auto pos = findUserPos(member);
|
||||
beginInsertRows(QModelIndex(), pos, pos);
|
||||
m_members.insert(pos, member.id());
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void UserListModel::memberLeft(const Quotient::RoomMember &member)
|
||||
{
|
||||
auto pos = findUserPos(member);
|
||||
if (pos != m_members.size()) {
|
||||
beginRemoveRows(QModelIndex(), pos, pos);
|
||||
m_members.removeAt(pos);
|
||||
endRemoveRows();
|
||||
} else {
|
||||
qWarning() << "Trying to remove a room member not in the user list";
|
||||
}
|
||||
}
|
||||
|
||||
void UserListModel::refreshMember(const Quotient::RoomMember &member, const QList<int> &roles)
|
||||
{
|
||||
auto pos = findUserPos(member);
|
||||
if (pos != m_members.size()) {
|
||||
// The update will have changed the state event so we need to insert the updated member object.
|
||||
m_members.insert(pos, member.id());
|
||||
Q_EMIT dataChanged(index(pos), index(pos), roles);
|
||||
} else {
|
||||
qWarning() << "Trying to access a room member not in the user list";
|
||||
}
|
||||
}
|
||||
// void UserListModel::memberJoined(const Quotient::RoomMember &member)
|
||||
// {
|
||||
// auto pos = findUserPos(member);
|
||||
// beginInsertRows(QModelIndex(), pos, pos);
|
||||
// m_members.insert(pos, member.id());
|
||||
// endInsertRows();
|
||||
// }
|
||||
//
|
||||
// void UserListModel::memberLeft(const Quotient::RoomMember &member)
|
||||
// {
|
||||
// auto pos = findUserPos(member);
|
||||
// if (pos != m_members.size()) {
|
||||
// beginRemoveRows(QModelIndex(), pos, pos);
|
||||
// m_members.removeAt(pos);
|
||||
// endRemoveRows();
|
||||
// } else {
|
||||
// qWarning() << "Trying to remove a room member not in the user list";
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// void UserListModel::refreshMember(const Quotient::RoomMember &member, const QList<int> &roles)
|
||||
// {
|
||||
// auto pos = findUserPos(member);
|
||||
// if (pos != m_members.size()) {
|
||||
// // The update will have changed the state event so we need to insert the updated member object.
|
||||
// m_members.insert(pos, member.id());
|
||||
// Q_EMIT dataChanged(index(pos), index(pos), roles);
|
||||
// } else {
|
||||
// qWarning() << "Trying to access a room member not in the user list";
|
||||
// }
|
||||
// }
|
||||
|
||||
void UserListModel::refreshAllMembers()
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
if (m_currentRoom != nullptr) {
|
||||
m_members = m_currentRoom->joinedMemberIds();
|
||||
MemberSorter sorter;
|
||||
std::sort(m_members.begin(), m_members.end(), [&sorter, this](const auto &left, const auto &right) {
|
||||
const auto leftPl = m_currentRoom->memberEffectivePowerLevel(left);
|
||||
const auto rightPl = m_currentRoom->memberEffectivePowerLevel(right);
|
||||
if (leftPl > rightPl) {
|
||||
return true;
|
||||
} else if (rightPl > leftPl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return sorter(m_currentRoom->member(left), m_currentRoom->member(right));
|
||||
});
|
||||
// m_members = m_currentRoom->joinedMemberIds();
|
||||
// MemberSorter sorter;
|
||||
// std::sort(m_members.begin(), m_members.end(), [&sorter, this](const auto &left, const auto &right) {
|
||||
// const auto leftPl = m_currentRoom->memberEffectivePowerLevel(left);
|
||||
// const auto rightPl = m_currentRoom->memberEffectivePowerLevel(right);
|
||||
// if (leftPl > rightPl) {
|
||||
// return true;
|
||||
// } else if (rightPl > leftPl) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// return sorter(m_currentRoom->member(left), m_currentRoom->member(right));
|
||||
// });
|
||||
}
|
||||
endResetModel();
|
||||
Q_EMIT usersRefreshed();
|
||||
}
|
||||
|
||||
int UserListModel::findUserPos(const RoomMember &member) const
|
||||
{
|
||||
return findUserPos(member.id());
|
||||
}
|
||||
// int UserListModel::findUserPos(const RoomMember &member) const
|
||||
// {
|
||||
// return findUserPos(member.id());
|
||||
// }
|
||||
|
||||
int UserListModel::findUserPos(const QString &userId) const
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Quotient/room.h>
|
||||
#include <Integral/Room>
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QObject>
|
||||
@@ -87,9 +87,9 @@ protected:
|
||||
bool event(QEvent *event) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void memberJoined(const Quotient::RoomMember &member);
|
||||
void memberLeft(const Quotient::RoomMember &member);
|
||||
void refreshMember(const Quotient::RoomMember &member, const QList<int> &roles = {});
|
||||
// void memberJoined(const Quotient::RoomMember &member);
|
||||
// void memberLeft(const Quotient::RoomMember &member);
|
||||
// void refreshMember(const Quotient::RoomMember &member, const QList<int> &roles = {});
|
||||
void refreshAllMembers();
|
||||
|
||||
private:
|
||||
@@ -98,6 +98,6 @@ private:
|
||||
|
||||
bool m_active = false;
|
||||
|
||||
int findUserPos(const Quotient::RoomMember &member) const;
|
||||
// int findUserPos(const Quotient::RoomMember &member) const;
|
||||
[[nodiscard]] int findUserPos(const QString &username) const;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user