Remove NeoChatUser and just use Quotient::User this simplifies things and avoids casting from one to the other which address santizer didn't like

This commit is contained in:
James Graham
2023-07-30 15:34:12 +01:00
parent 403c1ed391
commit 25e0e3fa8e
19 changed files with 110 additions and 163 deletions

View File

@@ -71,6 +71,13 @@ private Q_SLOTS:
void linkPreviewsReject(); void linkPreviewsReject();
}; };
static QColor polishColor(qreal hueF)
{
const auto lightness = static_cast<QGuiApplication *>(QGuiApplication::instance())->palette().color(QPalette::Active, QPalette::Window).lightnessF();
// https://github.com/quotient-im/libQuotient/wiki/User-color-coding-standard-draft-proposal
return QColor::fromHslF(hueF, 1, -0.7 * lightness + 0.9, 1);
}
void TextHandlerTest::initTestCase() void TextHandlerTest::initTestCase()
{ {
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org")); connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
@@ -555,10 +562,10 @@ void TextHandlerTest::receiveRichPlainUrl()
void TextHandlerTest::receiveRichEmote() void TextHandlerTest::receiveRichEmote()
{ {
auto event = room->messageEvents().at(1).get(); auto event = room->messageEvents().at(1).get();
auto author = static_cast<NeoChatUser *>(room->user(event->senderId())); auto author = room->user(event->senderId());
const QString testInputString = QStringLiteral("This is an emote."); const QString testInputString = QStringLiteral("This is an emote.");
const QString testOutputString = QStringLiteral("* <a href=\"https://matrix.to/#/@example:example.org\" style=\"color:") + author->color().name() const QString testOutputString = QStringLiteral("* <a href=\"https://matrix.to/#/@example:example.org\" style=\"color:")
+ QStringLiteral("\">@example:example.org</a> This is an emote."); + polishColor(author->hueF()).name() + QStringLiteral("\">@example:example.org</a> This is an emote.");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -644,5 +651,5 @@ void TextHandlerTest::linkPreviewsReject()
QCOMPARE(testTextHandler.getLinkPreviews(), testOutputLinks); QCOMPARE(testTextHandler.getLinkPreviews(), testOutputLinks);
} }
QTEST_GUILESS_MAIN(TextHandlerTest) QTEST_MAIN(TextHandlerTest)
#include "texthandlertest.moc" #include "texthandlertest.moc"

View File

@@ -44,8 +44,6 @@ add_library(neochat STATIC
roommanager.h roommanager.h
neochatroom.cpp neochatroom.cpp
neochatroom.h neochatroom.h
neochatuser.cpp
neochatuser.h
models/userlistmodel.cpp models/userlistmodel.cpp
models/userlistmodel.h models/userlistmodel.h
models/userfiltermodel.cpp models/userfiltermodel.cpp

View File

@@ -35,15 +35,15 @@
#include <Quotient/connection.h> #include <Quotient/connection.h>
#include <Quotient/csapi/content-repo.h> #include <Quotient/csapi/content-repo.h>
#include <Quotient/csapi/logout.h> #include <Quotient/csapi/logout.h>
#include <Quotient/csapi/notifications.h>
#include <Quotient/csapi/profile.h> #include <Quotient/csapi/profile.h>
#include <Quotient/eventstats.h>
#include <Quotient/jobs/downloadfilejob.h> #include <Quotient/jobs/downloadfilejob.h>
#include <Quotient/qt_connection_util.h> #include <Quotient/qt_connection_util.h>
#include <Quotient/csapi/notifications.h> #include <Quotient/user.h>
#include <Quotient/eventstats.h>
#include "neochatconfig.h" #include "neochatconfig.h"
#include "neochatroom.h" #include "neochatroom.h"
#include "neochatuser.h"
#include "notificationsmanager.h" #include "notificationsmanager.h"
#include "roommanager.h" #include "roommanager.h"
#include "windowcontroller.h" #include "windowcontroller.h"
@@ -60,7 +60,7 @@ Controller::Controller(QObject *parent)
: QObject(parent) : QObject(parent)
{ {
Connection::setRoomType<NeoChatRoom>(); Connection::setRoomType<NeoChatRoom>();
Connection::setUserType<NeoChatUser>(); Connection::setUserType<User>();
setApplicationProxy(); setApplicationProxy();
@@ -532,7 +532,7 @@ void Controller::joinRoom(const QString &alias)
RoomManager::instance().joinRoom(m_connection, alias, QStringList{knownServer}); RoomManager::instance().joinRoom(m_connection, alias, QStringList{knownServer});
} }
void Controller::openOrCreateDirectChat(NeoChatUser *user) void Controller::openOrCreateDirectChat(User *user)
{ {
const auto existing = activeConnection()->directChats(); const auto existing = activeConnection()->directChats();

View File

@@ -12,9 +12,9 @@
#include <Quotient/accountregistry.h> #include <Quotient/accountregistry.h>
#include <Quotient/jobs/basejob.h> #include <Quotient/jobs/basejob.h>
#include <Quotient/settings.h> #include <Quotient/settings.h>
#include <Quotient/user.h>
class NeoChatRoom; class NeoChatRoom;
class NeoChatUser;
class TrayIcon; class TrayIcon;
class QWindow; class QWindow;
class QQuickTextDocument; class QQuickTextDocument;
@@ -23,6 +23,7 @@ namespace Quotient
{ {
class Connection; class Connection;
class Room; class Room;
class User;
} }
namespace QKeychain namespace QKeychain
@@ -183,7 +184,7 @@ public:
* *
* If a direct chat with the user doesn't exist one is created and then joined. * If a direct chat with the user doesn't exist one is created and then joined.
*/ */
Q_INVOKABLE void openOrCreateDirectChat(NeoChatUser *user); Q_INVOKABLE void openOrCreateDirectChat(Quotient::User *user);
[[nodiscard]] bool supportSystemTray() const; [[nodiscard]] bool supportSystemTray() const;

View File

@@ -29,10 +29,11 @@
#include "neochat-version.h" #include "neochat-version.h"
#include <Quotient/keyverificationsession.h>
#include <Quotient/accountregistry.h> #include <Quotient/accountregistry.h>
#include <Quotient/keyverificationsession.h>
#include <Quotient/networkaccessmanager.h> #include <Quotient/networkaccessmanager.h>
#include <Quotient/room.h> #include <Quotient/room.h>
#include <Quotient/user.h>
#include <Quotient/util.h> #include <Quotient/util.h>
#include "actionshandler.h" #include "actionshandler.h"
@@ -76,7 +77,6 @@
#include "models/webshortcutmodel.h" #include "models/webshortcutmodel.h"
#include "neochatconfig.h" #include "neochatconfig.h"
#include "neochatroom.h" #include "neochatroom.h"
#include "neochatuser.h"
#include "notificationsmanager.h" #include "notificationsmanager.h"
#include "pollhandler.h" #include "pollhandler.h"
#include "roommanager.h" #include "roommanager.h"
@@ -89,7 +89,6 @@
#endif #endif
#include "models/completionmodel.h" #include "models/completionmodel.h"
#include "models/statemodel.h" #include "models/statemodel.h"
#include "neochatuser.h"
#ifdef HAVE_RUNNER #ifdef HAVE_RUNNER
#include "runner.h" #include "runner.h"
@@ -260,7 +259,7 @@ int main(int argc, char *argv[])
qmlRegisterUncreatableType<PushNotificationState>("org.kde.neochat", 1, 0, "PushNotificationState", "ENUM"); qmlRegisterUncreatableType<PushNotificationState>("org.kde.neochat", 1, 0, "PushNotificationState", "ENUM");
qmlRegisterUncreatableType<PushNotificationAction>("org.kde.neochat", 1, 0, "PushNotificationAction", "ENUM"); qmlRegisterUncreatableType<PushNotificationAction>("org.kde.neochat", 1, 0, "PushNotificationAction", "ENUM");
qmlRegisterUncreatableType<NeoChatRoomType>("org.kde.neochat", 1, 0, "NeoChatRoomType", "ENUM"); qmlRegisterUncreatableType<NeoChatRoomType>("org.kde.neochat", 1, 0, "NeoChatRoomType", "ENUM");
qmlRegisterUncreatableType<NeoChatUser>("org.kde.neochat", 1, 0, "NeoChatUser", {}); qmlRegisterUncreatableType<User>("org.kde.neochat", 1, 0, "User", {});
qmlRegisterUncreatableType<NeoChatRoom>("org.kde.neochat", 1, 0, "NeoChatRoom", {}); qmlRegisterUncreatableType<NeoChatRoom>("org.kde.neochat", 1, 0, "NeoChatRoom", {});
qRegisterMetaType<User *>("User*"); qRegisterMetaType<User *>("User*");
@@ -270,7 +269,7 @@ int main(int argc, char *argv[])
qRegisterMetaType<Connection *>("Connection*"); qRegisterMetaType<Connection *>("Connection*");
qRegisterMetaType<MessageEventType>("MessageEventType"); qRegisterMetaType<MessageEventType>("MessageEventType");
qRegisterMetaType<NeoChatRoom *>("NeoChatRoom*"); qRegisterMetaType<NeoChatRoom *>("NeoChatRoom*");
qRegisterMetaType<NeoChatUser *>("NeoChatUser*"); qRegisterMetaType<User *>("User*");
qRegisterMetaType<GetRoomEventsJob *>("GetRoomEventsJob*"); qRegisterMetaType<GetRoomEventsJob *>("GetRoomEventsJob*");
qRegisterMetaType<QMimeType>("QMimeType"); qRegisterMetaType<QMimeType>("QMimeType");
#ifdef Quotient_E2EE_ENABLED #ifdef Quotient_E2EE_ENABLED

View File

@@ -61,7 +61,7 @@ void LocationsModel::addLocation(const RoomMessageEvent *event)
.latitude = latitude, .latitude = latitude,
.longitude = longitude, .longitude = longitude,
.content = event->contentJson(), .content = event->contentJson(),
.author = dynamic_cast<NeoChatUser *>(m_room->user(event->senderId())), .author = m_room->user(event->senderId()),
}; };
endInsertRows(); endInsertRows();
} }

View File

@@ -10,6 +10,7 @@
#include "neochatroom.h" #include "neochatroom.h"
#include <Quotient/events/roommessageevent.h> #include <Quotient/events/roommessageevent.h>
#include <Quotient/user.h>
class LocationsModel : public QAbstractListModel class LocationsModel : public QAbstractListModel
{ {
@@ -51,7 +52,7 @@ private:
float latitude; float latitude;
float longitude; float longitude;
QJsonObject content; QJsonObject content;
NeoChatUser *author; Quotient::User *author;
}; };
QList<LocationData> m_locations; QList<LocationData> m_locations;
void addLocation(const Quotient::RoomMessageEvent *event); void addLocation(const Quotient::RoomMessageEvent *event);

View File

@@ -25,7 +25,6 @@
#include <KLocalizedString> #include <KLocalizedString>
#include "models/reactionmodel.h" #include "models/reactionmodel.h"
#include "neochatuser.h"
#include "texthandler.h" #include "texthandler.h"
using namespace Quotient; using namespace Quotient;
@@ -531,7 +530,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
} }
if (role == AuthorRole) { if (role == AuthorRole) {
auto author = static_cast<NeoChatUser *>(isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId())); auto author = isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId());
return m_currentRoom->getUser(author); return m_currentRoom->getUser(author);
} }
@@ -679,7 +678,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
auto replyPtr = m_currentRoom->getReplyForEvent(evt); auto replyPtr = m_currentRoom->getReplyForEvent(evt);
if (replyPtr) { if (replyPtr) {
auto replyUser = static_cast<NeoChatUser *>(m_currentRoom->user(replyPtr->senderId())); auto replyUser = m_currentRoom->user(replyPtr->senderId());
return m_currentRoom->getUser(replyUser); return m_currentRoom->getUser(replyUser);
} else { } else {
return m_currentRoom->getUser(nullptr); return m_currentRoom->getUser(nullptr);
@@ -808,7 +807,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
QVariantList users; QVariantList users;
users.reserve(userIds.size()); users.reserve(userIds.size());
for (const auto &userId : userIds) { for (const auto &userId : userIds) {
auto user = static_cast<NeoChatUser *>(m_currentRoom->user(userId)); auto user = m_currentRoom->user(userId);
users += m_currentRoom->getUser(user); users += m_currentRoom->getUser(user);
} }
@@ -836,7 +835,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
*/ */
QString readMarkersString = i18np("1 user: ", "%1 users: ", userIds.size()); QString readMarkersString = i18np("1 user: ", "%1 users: ", userIds.size());
for (const auto &userId : userIds) { for (const auto &userId : userIds) {
auto user = static_cast<NeoChatUser *>(m_currentRoom->user(userId)); auto user = m_currentRoom->user(userId);
readMarkersString += user->displayname(m_currentRoom) + i18nc("list separator", ", "); readMarkersString += user->displayname(m_currentRoom) + i18nc("list separator", ", ");
} }
readMarkersString.chop(2); readMarkersString.chop(2);
@@ -877,7 +876,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
} }
if (role == DisplayNameForInitialsRole) { if (role == DisplayNameForInitialsRole) {
auto user = static_cast<NeoChatUser *>(isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId())); auto user = isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId());
return user->displayname(m_currentRoom).remove(QStringLiteral(" (%1)").arg(user->id())); return user->displayname(m_currentRoom).remove(QStringLiteral(" (%1)").arg(user->id()));
} }
@@ -889,7 +888,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
} }
return previousDisplayName; return previousDisplayName;
} else { } else {
auto author = static_cast<NeoChatUser *>(isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId())); auto author = isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId());
return m_currentRoom->htmlSafeMemberName(author->id()); return m_currentRoom->htmlSafeMemberName(author->id());
} }
} }
@@ -1062,13 +1061,13 @@ void MessageEventModel::createReactionModelForEvent(const Quotient::RoomMessageE
return; return;
}; };
QMap<QString, QList<NeoChatUser *>> reactions = {}; QMap<QString, QList<Quotient::User *>> reactions = {};
for (const auto &a : annotations) { for (const auto &a : annotations) {
if (a->isRedacted()) { // Just in case? if (a->isRedacted()) { // Just in case?
continue; continue;
} }
if (const auto &e = eventCast<const ReactionEvent>(a)) { if (const auto &e = eventCast<const ReactionEvent>(a)) {
reactions[e->key()].append(static_cast<NeoChatUser *>(m_currentRoom->user(e->senderId()))); reactions[e->key()].append(m_currentRoom->user(e->senderId()));
} }
} }
@@ -1095,7 +1094,7 @@ void MessageEventModel::createReactionModelForEvent(const Quotient::RoomMessageE
if (m_reactionModels.contains(eventId)) { if (m_reactionModels.contains(eventId)) {
m_reactionModels[eventId]->setReactions(res); m_reactionModels[eventId]->setReactions(res);
} else if (res.size() > 0) { } else if (res.size() > 0) {
m_reactionModels[eventId] = new ReactionModel(this, res, static_cast<NeoChatUser *>(m_currentRoom->localUser())); m_reactionModels[eventId] = new ReactionModel(this, res, m_currentRoom->localUser());
} else { } else {
if (m_reactionModels.contains(eventId)) { if (m_reactionModels.contains(eventId)) {
delete m_reactionModels[eventId]; delete m_reactionModels[eventId];

View File

@@ -7,9 +7,9 @@
#include <KLocalizedString> #include <KLocalizedString>
#include "neochatuser.h" #include <Quotient/user.h>
ReactionModel::ReactionModel(QObject *parent, QList<Reaction> reactions, NeoChatUser *localUser) ReactionModel::ReactionModel(QObject *parent, QList<Reaction> reactions, Quotient::User *localUser)
: QAbstractListModel(parent) : QAbstractListModel(parent)
, m_localUser(localUser) , m_localUser(localUser)
{ {

View File

@@ -5,7 +5,10 @@
#include <QAbstractListModel> #include <QAbstractListModel>
class NeoChatUser; namespace Quotient
{
class User;
}
/** /**
* @class ReactionModel * @class ReactionModel
@@ -36,7 +39,7 @@ public:
HasLocalUser, /**< Whether the local user is in the list of authors. */ HasLocalUser, /**< Whether the local user is in the list of authors. */
}; };
explicit ReactionModel(QObject *parent = nullptr, QList<Reaction> reactions = {}, NeoChatUser *localUser = nullptr); explicit ReactionModel(QObject *parent = nullptr, QList<Reaction> reactions = {}, Quotient::User *localUser = nullptr);
/** /**
* @brief Get the given role value at the given index. * @brief Get the given role value at the given index.
@@ -67,6 +70,6 @@ public:
private: private:
QList<Reaction> m_reactions; QList<Reaction> m_reactions;
NeoChatUser *m_localUser; Quotient::User *m_localUser;
}; };
Q_DECLARE_METATYPE(ReactionModel *) Q_DECLARE_METATYPE(ReactionModel *)

View File

@@ -5,7 +5,6 @@
#include "messageeventmodel.h" #include "messageeventmodel.h"
#include "neochatroom.h" #include "neochatroom.h"
#include "neochatuser.h"
#include <Quotient/events/stickerevent.h> #include <Quotient/events/stickerevent.h>
#include <KLocalizedString> #include <KLocalizedString>
@@ -109,7 +108,7 @@ QVariant SearchModel::data(const QModelIndex &index, int role) const
return false; return false;
case ReplyAuthorRole: case ReplyAuthorRole:
if (const auto &replyPtr = m_room->getReplyForEvent(event)) { if (const auto &replyPtr = m_room->getReplyForEvent(event)) {
return m_room->getUser(static_cast<NeoChatUser *>(m_room->user(replyPtr->senderId()))); return m_room->getUser(m_room->user(replyPtr->senderId()));
} else { } else {
return m_room->getUser(nullptr); return m_room->getUser(nullptr);
} }

View File

@@ -71,8 +71,7 @@ QVariant UserListModel::data(const QModelIndex &index, int role) const
return user->id(); return user->id();
} }
if (role == AvatarRole) { if (role == AvatarRole) {
auto neoChatUser = static_cast<NeoChatUser *>(user); return m_currentRoom->avatarForMember(user);
return m_currentRoom->avatarForMember(neoChatUser);
} }
if (role == ObjectRole) { if (role == ObjectRole) {
return QVariant::fromValue(user); return QVariant::fromValue(user);

View File

@@ -4,8 +4,10 @@
#include "neochatroom.h" #include "neochatroom.h"
#include <QFileInfo> #include <QFileInfo>
#include <QGuiApplication>
#include <QMetaObject> #include <QMetaObject>
#include <QMimeDatabase> #include <QMimeDatabase>
#include <QPalette>
#include <QTemporaryFile> #include <QTemporaryFile>
#include <QTextDocument> #include <QTextDocument>
@@ -13,6 +15,7 @@
#include <QMediaPlayer> #include <QMediaPlayer>
#include <Quotient/jobs/basejob.h> #include <Quotient/jobs/basejob.h>
#include <Quotient/user.h>
#include <qcoro/qcorosignal.h> #include <qcoro/qcorosignal.h>
#include <Quotient/connection.h> #include <Quotient/connection.h>
@@ -405,6 +408,13 @@ QDateTime NeoChatRoom::lastActiveTime()
return messageEvents().rbegin()->get()->originTimestamp(); return messageEvents().rbegin()->get()->originTimestamp();
} }
static QColor polishColor(qreal hueF)
{
const auto lightness = static_cast<QGuiApplication *>(QGuiApplication::instance())->palette().color(QPalette::Active, QPalette::Window).lightnessF();
// https://github.com/quotient-im/libQuotient/wiki/User-color-coding-standard-draft-proposal
return QColor::fromHslF(hueF, 1, -0.7 * lightness + 0.9, 1);
}
QVariantList NeoChatRoom::getUsers(const QString &keyword, int limit) const QVariantList NeoChatRoom::getUsers(const QString &keyword, int limit) const
{ {
const auto userList = users(); const auto userList = users();
@@ -412,11 +422,11 @@ QVariantList NeoChatRoom::getUsers(const QString &keyword, int limit) const
int count = 0; int count = 0;
for (const auto u : userList) { for (const auto u : userList) {
if (u->displayname(this).contains(keyword, Qt::CaseInsensitive)) { if (u->displayname(this).contains(keyword, Qt::CaseInsensitive)) {
NeoChatUser user(u->id(), u->connection()); Quotient::User user(u->id(), u->connection());
QVariantMap userVariant{{QStringLiteral("id"), user.id()}, QVariantMap userVariant{{QStringLiteral("id"), user.id()},
{QStringLiteral("displayName"), user.displayname(this)}, {QStringLiteral("displayName"), user.displayname(this)},
{QStringLiteral("avatarMediaId"), user.avatarMediaId(this)}, {QStringLiteral("avatarMediaId"), user.avatarMediaId(this)},
{QStringLiteral("color"), user.color()}}; {QStringLiteral("color"), polishColor(user.hueF())}};
matchedList.append(QVariant::fromValue(userVariant)); matchedList.append(QVariant::fromValue(userVariant));
count++; count++;
@@ -442,11 +452,10 @@ static const QVariantMap emptyUser = {
QVariantMap NeoChatRoom::getUser(const QString &userID) const QVariantMap NeoChatRoom::getUser(const QString &userID) const
{ {
NeoChatUser *userObject = static_cast<NeoChatUser *>(user(userID)); return getUser(user(userID));
return getUser(userObject);
} }
QVariantMap NeoChatRoom::getUser(NeoChatUser *user) const QVariantMap NeoChatRoom::getUser(User *user) const
{ {
if (user == nullptr) { if (user == nullptr) {
return emptyUser; return emptyUser;
@@ -458,7 +467,7 @@ QVariantMap NeoChatRoom::getUser(NeoChatUser *user) const
{QStringLiteral("displayName"), user->displayname(this)}, {QStringLiteral("displayName"), user->displayname(this)},
{QStringLiteral("avatarSource"), avatarForMember(user)}, {QStringLiteral("avatarSource"), avatarForMember(user)},
{QStringLiteral("avatarMediaId"), user->avatarMediaId(this)}, {QStringLiteral("avatarMediaId"), user->avatarMediaId(this)},
{QStringLiteral("color"), user->color()}, {QStringLiteral("color"), polishColor(user->hueF())},
{QStringLiteral("object"), QVariant::fromValue(user)}, {QStringLiteral("object"), QVariant::fromValue(user)},
}; };
} }
@@ -539,7 +548,7 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
if (prettyPrint) { if (prettyPrint) {
subjectName = QStringLiteral("<a href=\"https://matrix.to/#/%1\" style=\"color: %2\">%3</a>") subjectName = QStringLiteral("<a href=\"https://matrix.to/#/%1\" style=\"color: %2\">%3</a>")
.arg(e.userId(), static_cast<NeoChatUser *>(user(e.userId()))->color().name(), subjectName); .arg(e.userId(), polishColor(user(e.userId())->hueF()).name(), subjectName);
} }
// The below code assumes senderName output in AuthorRole // The below code assumes senderName output in AuthorRole
@@ -1682,7 +1691,7 @@ QVariantMap NeoChatRoom::chatBoxReplyUser() const
if (m_chatBoxReplyId.isEmpty()) { if (m_chatBoxReplyId.isEmpty()) {
return emptyUser; return emptyUser;
} }
return getUser(static_cast<NeoChatUser *>(user((*findInTimeline(m_chatBoxReplyId))->senderId()))); return getUser(user((*findInTimeline(m_chatBoxReplyId))->senderId()));
} }
QString NeoChatRoom::chatBoxReplyMessage() const QString NeoChatRoom::chatBoxReplyMessage() const
@@ -1698,7 +1707,7 @@ QVariantMap NeoChatRoom::chatBoxEditUser() const
if (m_chatBoxEditId.isEmpty()) { if (m_chatBoxEditId.isEmpty()) {
return emptyUser; return emptyUser;
} }
return getUser(static_cast<NeoChatUser *>(user((*findInTimeline(m_chatBoxEditId))->senderId()))); return getUser(user((*findInTimeline(m_chatBoxEditId))->senderId()));
} }
QString NeoChatRoom::chatBoxEditMessage() const QString NeoChatRoom::chatBoxEditMessage() const
@@ -1904,9 +1913,10 @@ int NeoChatRoom::maxRoomVersion() const
} }
return maxVersion; return maxVersion;
} }
NeoChatUser *NeoChatRoom::directChatRemoteUser() const
Quotient::User *NeoChatRoom::directChatRemoteUser() const
{ {
return dynamic_cast<NeoChatUser *>(connection()->directChatUsers(this)[0]); return connection()->directChatUsers(this)[0];
} }
void NeoChatRoom::sendLocation(float lat, float lon, const QString &description) void NeoChatRoom::sendLocation(float lat, float lon, const QString &description)
@@ -1938,7 +1948,7 @@ QByteArray NeoChatRoom::roomAcountDataJson(const QString &eventType)
return QJsonDocument(accountData(eventType)->fullJson()).toJson(); return QJsonDocument(accountData(eventType)->fullJson()).toJson();
} }
QUrl NeoChatRoom::avatarForMember(NeoChatUser *user) const QUrl NeoChatRoom::avatarForMember(Quotient::User *user) const
{ {
const auto &url = memberAvatarUrl(user->id()); const auto &url = memberAvatarUrl(user->id());
if (url.isEmpty() || url.scheme() != "mxc"_ls) { if (url.isEmpty() || url.scheme() != "mxc"_ls) {

View File

@@ -10,10 +10,15 @@
#include <QTextCursor> #include <QTextCursor>
#include <QCoroTask> #include <QCoroTask>
#include <Quotient/user.h>
#include "neochatuser.h"
#include "pollhandler.h" #include "pollhandler.h"
namespace Quotient
{
class User;
}
class PushNotificationState : public QObject class PushNotificationState : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -64,7 +69,7 @@ class NeoChatRoom : public Quotient::Room
* *
* The list does not include the local user. * The list does not include the local user.
* *
* This is different to getting a list of NeoChatUser objects or Quotient::User objects * This is different to getting a list of Quotient::User objects
* as neither of those can provide details like the displayName or avatarMediaId * as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room. This function * without the room context as these can vary from room to room. This function
* provides the room context and puts the result as a list of QVariantMap objects. * provides the room context and puts the result as a list of QVariantMap objects.
@@ -76,7 +81,7 @@ class NeoChatRoom : public Quotient::Room
* - displayName - Display name in the context of this room. * - displayName - Display name in the context of this room.
* - display - Name in the context of this room. * - display - Name in the context of this room.
* *
* @sa Quotient::User, NeoChatUser * @sa Quotient::User
*/ */
Q_PROPERTY(QVariantList usersTyping READ getUsersTyping NOTIFY typingChanged) Q_PROPERTY(QVariantList usersTyping READ getUsersTyping NOTIFY typingChanged)
@@ -119,7 +124,7 @@ class NeoChatRoom : public Quotient::Room
/** /**
* @brief Get a user object for the other person in a direct chat. * @brief Get a user object for the other person in a direct chat.
*/ */
Q_PROPERTY(NeoChatUser *directChatRemoteUser READ directChatRemoteUser CONSTANT) Q_PROPERTY(Quotient::User *directChatRemoteUser READ directChatRemoteUser CONSTANT)
/** /**
* @brief If the room is a space. * @brief If the room is a space.
@@ -316,7 +321,7 @@ class NeoChatRoom : public Quotient::Room
/** /**
* @brief Get the user for the message being replied to. * @brief Get the user for the message being replied to.
* *
* This is different to getting a NeoChatUser object or Quotient::User object * This is different to getting a Quotient::User object
* as neither of those can provide details like the displayName or avatarMediaId * as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room. * without the room context as these can vary from room to room.
* *
@@ -329,9 +334,9 @@ class NeoChatRoom : public Quotient::Room
* - avatarSource - The mxc URL for the user's avatar in the current room. * - avatarSource - The mxc URL for the user's avatar in the current room.
* - avatarMediaId - Avatar id in the context of this room. * - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user. * - color - Color for the user.
* - object - The NeoChatUser object for the user. * - object - The Quotient::User object for the user.
* *
* @sa getUser, Quotient::User, NeoChatUser * @sa getUser, Quotient::User
*/ */
Q_PROPERTY(QVariantMap chatBoxReplyUser READ chatBoxReplyUser NOTIFY chatBoxReplyIdChanged) Q_PROPERTY(QVariantMap chatBoxReplyUser READ chatBoxReplyUser NOTIFY chatBoxReplyIdChanged)
@@ -345,7 +350,7 @@ class NeoChatRoom : public Quotient::Room
/** /**
* @brief Get the user for the message being edited. * @brief Get the user for the message being edited.
* *
* This is different to getting a NeoChatUser object or Quotient::User object * This is different to getting a Quotient::User object
* as neither of those can provide details like the displayName or avatarMediaId * as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room. * without the room context as these can vary from room to room.
* *
@@ -358,9 +363,9 @@ class NeoChatRoom : public Quotient::Room
* - avatarSource - The mxc URL for the user's avatar in the current room. * - avatarSource - The mxc URL for the user's avatar in the current room.
* - avatarMediaId - Avatar id in the context of this room. * - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user. * - color - Color for the user.
* - object - The NeoChatUser object for the user. * - object - The Quotient::User object for the user.
* *
* @sa getUser, Quotient::User, NeoChatUser * @sa getUser, Quotient::User
*/ */
Q_PROPERTY(QVariantMap chatBoxEditUser READ chatBoxEditUser NOTIFY chatBoxEditIdChanged) Q_PROPERTY(QVariantMap chatBoxEditUser READ chatBoxEditUser NOTIFY chatBoxEditIdChanged)
@@ -392,7 +397,7 @@ public:
/** /**
* @brief Get a list of users in the context of this room. * @brief Get a list of users in the context of this room.
* *
* This is different to getting a list of NeoChatUser objects or Quotient::User objects * This is different to getting a list of Quotient::User objects
* as neither of those can provide details like the displayName or avatarMediaId * as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room. This function * without the room context as these can vary from room to room. This function
* provides the room context and returns the result as a list of QVariantMap objects. * provides the room context and returns the result as a list of QVariantMap objects.
@@ -407,14 +412,14 @@ public:
* - avatarMediaId - Avatar id in the context of this room. * - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user. * - color - Color for the user.
* *
* @sa Quotient::User, NeoChatUser * @sa Quotient::User
*/ */
Q_INVOKABLE [[nodiscard]] QVariantList getUsers(const QString &keyword, int limit = -1) const; Q_INVOKABLE [[nodiscard]] QVariantList getUsers(const QString &keyword, int limit = -1) const;
/** /**
* @brief Get a user in the context of this room. * @brief Get a user in the context of this room.
* *
* This is different to getting a NeoChatUser object or Quotient::User object * This is different to getting a Quotient::User object
* as neither of those can provide details like the displayName or avatarMediaId * as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room. This function * without the room context as these can vary from room to room. This function
* provides the room context and outputs the result as QVariantMap. * provides the room context and outputs the result as QVariantMap.
@@ -431,16 +436,16 @@ public:
* - avatarSource - The mxc URL for the user's avatar in the current room. * - avatarSource - The mxc URL for the user's avatar in the current room.
* - avatarMediaId - Avatar id in the context of this room. * - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user. * - color - Color for the user.
* - object - The NeoChatUser object for the user. * - object - The Quotient::User object for the user.
* *
* @sa Quotient::User, NeoChatUser * @sa Quotient::User
*/ */
Q_INVOKABLE [[nodiscard]] QVariantMap getUser(const QString &userID) const; Q_INVOKABLE [[nodiscard]] QVariantMap getUser(const QString &userID) const;
/** /**
* @brief Get a user in the context of this room. * @brief Get a user in the context of this room.
* *
* This is different to getting a NeoChatUser object or Quotient::User object * This is different to getting a Quotient::User object
* as neither of those can provide details like the displayName or avatarMediaId * as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room. This function * without the room context as these can vary from room to room. This function
* provides the room context and outputs the result as QVariantMap. * provides the room context and outputs the result as QVariantMap.
@@ -457,11 +462,11 @@ public:
* - avatarSource - The mxc URL for the user's avatar in the current room. * - avatarSource - The mxc URL for the user's avatar in the current room.
* - avatarMediaId - Avatar id in the context of this room. * - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user. * - color - Color for the user.
* - object - The NeoChatUser object for the user. * - object - The Quotient::User object for the user.
* *
* @sa Quotient::User, NeoChatUser * @sa Quotient::User
*/ */
Q_INVOKABLE [[nodiscard]] QVariantMap getUser(NeoChatUser *user) const; Q_INVOKABLE [[nodiscard]] QVariantMap getUser(Quotient::User *user) const;
[[nodiscard]] QVariantList getUsersTyping() const; [[nodiscard]] QVariantList getUsersTyping() const;
@@ -602,7 +607,7 @@ public:
[[nodiscard]] QString avatarMediaId() const; [[nodiscard]] QString avatarMediaId() const;
NeoChatUser *directChatRemoteUser() const; Quotient::User *directChatRemoteUser() const;
[[nodiscard]] bool isSpace(); [[nodiscard]] bool isSpace();
@@ -818,7 +823,7 @@ public:
*/ */
Q_INVOKABLE QByteArray roomAcountDataJson(const QString &eventType); Q_INVOKABLE QByteArray roomAcountDataJson(const QString &eventType);
Q_INVOKABLE [[nodiscard]] QUrl avatarForMember(NeoChatUser *user) const; Q_INVOKABLE [[nodiscard]] QUrl avatarForMember(Quotient::User *user) const;
/** /**
* @brief Returns the event that is being replied to. This includes events that were manually loaded using NeoChatRoom::loadReply. * @brief Returns the event that is being replied to. This includes events that were manually loaded using NeoChatRoom::loadReply.

View File

@@ -1,43 +0,0 @@
// SPDX-FileCopyrightText: 2019 Black Hat <bhat@encom.eu.org>
// SPDX-License-Identifier: GPL-3.0-only
#include "neochatuser.h"
#include <QGuiApplication>
#include <QJsonObject>
#include <QPalette>
#include <Quotient/connection.h>
using namespace Quotient;
NeoChatUser::NeoChatUser(QString userId, Connection *connection)
: User(std::move(userId), connection)
{
connect(static_cast<QGuiApplication *>(QGuiApplication::instance()), &QGuiApplication::paletteChanged, this, &NeoChatUser::polishColor);
polishColor();
}
QColor NeoChatUser::color()
{
return m_color;
}
void NeoChatUser::setColor(const QColor &color)
{
if (m_color == color) {
return;
}
m_color = color;
Q_EMIT colorChanged(m_color);
}
void NeoChatUser::polishColor()
{
const auto lightness = static_cast<QGuiApplication *>(QGuiApplication::instance())->palette().color(QPalette::Active, QPalette::Window).lightnessF();
// https://github.com/quotient-im/libQuotient/wiki/User-color-coding-standard-draft-proposal
setColor(QColor::fromHslF(hueF(), 1, -0.7 * lightness + 0.9, 1));
}
#include "moc_neochatuser.cpp"

View File

@@ -1,39 +0,0 @@
// SPDX-FileCopyrightText: 2018-2019 Black Hat <bhat@encom.eu.org>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <QObject>
#include <Quotient/user.h>
/**
* @class NeoChatUser
*
* A class inherited from Quotient::User to add a user color function.
*
* @sa Quotient::User
*/
class NeoChatUser : public Quotient::User
{
Q_OBJECT
/**
* @brief The color to use for the user.
*/
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
public:
explicit NeoChatUser(QString userId, Quotient::Connection *connection);
public Q_SLOTS:
QColor color();
void setColor(const QColor &color);
Q_SIGNALS:
void colorChanged(QColor _t1);
private:
QColor m_color;
void polishColor();
};

View File

@@ -34,9 +34,9 @@ Item {
* - displayName - The display name of the reply author. * - displayName - The display name of the reply author.
* - display - The name of the reply author. * - display - The name of the reply author.
* - color - The color for the reply author. * - color - The color for the reply author.
* - object - The NeoChatUser object for the reply author. * - object - The Quotient::User object for the reply author.
* *
* @sa NeoChatUser * @sa Quotient::User
*/ */
required property var author required property var author

View File

@@ -54,9 +54,9 @@ ColumnLayout {
* - displayName - The display name of the author. * - displayName - The display name of the author.
* - display - The name of the author. * - display - The name of the author.
* - color - The color for the author. * - color - The color for the author.
* - object - The NeoChatUser object for the author. * - object - The Quotient::User object for the author.
* *
* @sa NeoChatUser * @sa Quotient::User
*/ */
required property var author required property var author
@@ -137,9 +137,9 @@ ColumnLayout {
* - displayName - The display name of the reply author. * - displayName - The display name of the reply author.
* - display - The name of the reply author. * - display - The name of the reply author.
* - color - The color for the reply author. * - color - The color for the reply author.
* - object - The NeoChatUser object for the reply author. * - object - The Quotient::User object for the reply author.
* *
* @sa NeoChatUser * @sa Quotient::User
*/ */
required property var replyAuthor required property var replyAuthor

View File

@@ -4,8 +4,9 @@
#include "texthandler.h" #include "texthandler.h"
#include <QDebug> #include <QDebug>
#include <QUrl> #include <QGuiApplication>
#include <QStringLiteral> #include <QStringLiteral>
#include <QUrl>
#include <Quotient/events/roommessageevent.h> #include <Quotient/events/roommessageevent.h>
#include <Quotient/util.h> #include <Quotient/util.h>
@@ -76,6 +77,13 @@ QString TextHandler::handleSendText()
return outputString; return outputString;
} }
static QColor polishColor(qreal hueF)
{
const auto lightness = static_cast<QGuiApplication *>(QGuiApplication::instance())->palette().color(QPalette::Active, QPalette::Window).lightnessF();
// https://github.com/quotient-im/libQuotient/wiki/User-color-coding-standard-draft-proposal
return QColor::fromHslF(hueF, 1, -0.7 * lightness + 0.9, 1);
}
QString TextHandler::handleRecieveRichText(Qt::TextFormat inputFormat, const NeoChatRoom *room, const Quotient::RoomEvent *event, bool stripNewlines) QString TextHandler::handleRecieveRichText(Qt::TextFormat inputFormat, const NeoChatRoom *room, const Quotient::RoomEvent *event, bool stripNewlines)
{ {
m_pos = 0; m_pos = 0;
@@ -135,9 +143,9 @@ QString TextHandler::handleRecieveRichText(Qt::TextFormat inputFormat, const Neo
if (event != nullptr) { if (event != nullptr) {
auto e = eventCast<const Quotient::RoomMessageEvent>(event); auto e = eventCast<const Quotient::RoomMessageEvent>(event);
if (e->msgtype() == Quotient::MessageEventType::Emote) { if (e->msgtype() == Quotient::MessageEventType::Emote) {
auto author = static_cast<NeoChatUser *>(room->user(e->senderId())); auto author = room->user(e->senderId());
QString emoteString = QStringLiteral("* <a href=\"https://matrix.to/#/") + e->senderId() + QStringLiteral("\" style=\"color:") QString emoteString = QStringLiteral("* <a href=\"https://matrix.to/#/") + e->senderId() + QStringLiteral("\" style=\"color:")
+ author->color().name() + QStringLiteral("\">") + author->displayname(room) + QStringLiteral("</a> "); + polishColor(author->hueF()).name() + QStringLiteral("\">") + author->displayname(room) + QStringLiteral("</a> ");
if (outputString.startsWith(QStringLiteral("<p>"))) { if (outputString.startsWith(QStringLiteral("<p>"))) {
outputString.insert(3, emoteString); outputString.insert(3, emoteString);
} else { } else {