ShowMessage

Move showMessage to RoomManager and merge warning in. A new Message type enum is created aligned with the Kirgami.MessageType used by Kirigami.Banner to avoid needing to translate from 2 enums. 

showMessage is also sent as a signal from NeoChatRoom (and via the room from ActionsModel), this removes the need for them to have a dependency on Controller (and RoomManager). While not necessarily the cause of Windows crashes the spaghetti dependencies of RoomManager and Controller throughout the code base has made debugging that harder so this aims to simplify that as well.
This commit is contained in:
James Graham
2024-10-03 18:42:29 +00:00
parent 777ea9fbe0
commit 153cbeae8a
10 changed files with 112 additions and 102 deletions

View File

@@ -194,6 +194,7 @@ add_library(neochat STATIC
neochatroommember.h neochatroommember.h
models/threadmodel.cpp models/threadmodel.cpp
models/threadmodel.h models/threadmodel.h
enums/messagetype.h
) )
set_source_files_properties(qml/OsmLocationPlugin.qml PROPERTIES set_source_files_properties(qml/OsmLocationPlugin.qml PROPERTIES

View File

@@ -53,16 +53,6 @@ class Controller : public QObject
Q_PROPERTY(bool csSupported READ csSupported CONSTANT) Q_PROPERTY(bool csSupported READ csSupported CONSTANT)
public: public:
/**
* @brief Define the types on inline messages that can be shown.
*/
enum MessageType {
Positive, /**< Positive message, typically green. */
Info, /**< Info message, typically highlight color. */
Error, /**< Error message, typically red. */
};
Q_ENUM(MessageType)
static Controller &instance(); static Controller &instance();
static Controller *create(QQmlEngine *engine, QJSEngine *) static Controller *create(QQmlEngine *engine, QJSEngine *)
{ {
@@ -144,5 +134,4 @@ Q_SIGNALS:
void connectionDropped(NeoChatConnection *connection); void connectionDropped(NeoChatConnection *connection);
void activeConnectionChanged(NeoChatConnection *connection); void activeConnectionChanged(NeoChatConnection *connection);
void accountsLoadingChanged(); void accountsLoadingChanged();
void showMessage(MessageType messageType, const QString &message);
}; };

31
src/enums/messagetype.h Normal file
View File

@@ -0,0 +1,31 @@
// 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
#pragma once
#include <QObject>
#include <QQmlEngine>
/**
* @class MessageType
*
* This class is designed to define the MessageType enumeration.
*/
class MessageType : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
public:
/**
* @brief The types of messages that can be shown.
*/
enum Type {
Information = 0, /**< Info message, typically highlight color. */
Positive, /**< Positive message, typically green. */
Warning, /**< Warning message, typically amber. */
Error, /**< Error message, typically red. */
};
Q_ENUM(Type);
};

View File

@@ -4,7 +4,7 @@
#include "actionsmodel.h" #include "actionsmodel.h"
#include "chatbarcache.h" #include "chatbarcache.h"
#include "controller.h" #include "enums/messagetype.h"
#include "neochatconnection.h" #include "neochatconnection.h"
#include "neochatroom.h" #include "neochatroom.h"
#include "roommanager.h" #include "roommanager.h"
@@ -24,15 +24,14 @@ QStringList rainbowColors{"#ff2b00"_ls, "#ff5500"_ls, "#ff8000"_ls, "#ffaa00"_ls
auto leaveRoomLambda = [](const QString &text, NeoChatRoom *room, ChatBarCache *) { auto leaveRoomLambda = [](const QString &text, NeoChatRoom *room, ChatBarCache *) {
if (text.isEmpty()) { if (text.isEmpty()) {
Q_EMIT Controller::instance().showMessage(Controller::Info, i18n("Leaving this room.")); Q_EMIT room->showMessage(MessageType::Information, i18n("Leaving this room."));
room->connection()->leaveRoom(room); room->connection()->leaveRoom(room);
} else { } else {
QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)")); QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"));
auto regexMatch = roomRegex.match(text); auto regexMatch = roomRegex.match(text);
if (!regexMatch.hasMatch()) { if (!regexMatch.hasMatch()) {
Q_EMIT Controller::instance().showMessage( Q_EMIT room->showMessage(MessageType::Error,
Controller::Error, i18nc("'<text>' does not look like a room id or alias.", "'%1' does not look like a room id or alias.", text));
i18nc("'<text>' does not look like a room id or alias.", "'%1' does not look like a room id or alias.", text));
return QString(); return QString();
} }
auto leaving = room->connection()->room(text); auto leaving = room->connection()->room(text);
@@ -40,10 +39,10 @@ auto leaveRoomLambda = [](const QString &text, NeoChatRoom *room, ChatBarCache *
leaving = room->connection()->roomByAlias(text); leaving = room->connection()->roomByAlias(text);
} }
if (leaving) { if (leaving) {
Q_EMIT Controller::instance().showMessage(Controller::Info, i18nc("Leaving room <roomname>.", "Leaving room %1.", text)); Q_EMIT room->showMessage(MessageType::Information, i18nc("Leaving room <roomname>.", "Leaving room %1.", text));
room->connection()->leaveRoom(leaving); room->connection()->leaveRoom(leaving);
} else { } else {
Q_EMIT Controller::instance().showMessage(Controller::Info, i18nc("Room <roomname> not found", "Room %1 not found.", text)); Q_EMIT room->showMessage(MessageType::Information, i18nc("Room <roomname> not found", "Room %1 not found.", text));
} }
} }
return QString(); return QString();
@@ -51,7 +50,7 @@ auto leaveRoomLambda = [](const QString &text, NeoChatRoom *room, ChatBarCache *
auto roomNickLambda = [](const QString &text, NeoChatRoom *room, ChatBarCache *) { auto roomNickLambda = [](const QString &text, NeoChatRoom *room, ChatBarCache *) {
if (text.isEmpty()) { if (text.isEmpty()) {
Q_EMIT Controller::instance().showMessage(Controller::Error, i18n("No new nickname provided, no changes will happen.")); Q_EMIT room->showMessage(MessageType::Error, i18n("No new nickname provided, no changes will happen."));
} else { } else {
room->connection()->user()->rename(text, room); room->connection()->user()->rename(text, room);
} }
@@ -193,31 +192,29 @@ QList<ActionsModel::Action> actions{
QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))")); QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"));
auto regexMatch = mxidRegex.match(text); auto regexMatch = mxidRegex.match(text);
if (!regexMatch.hasMatch()) { if (!regexMatch.hasMatch()) {
Q_EMIT Controller::instance().showMessage(Controller::Error, Q_EMIT room->showMessage(MessageType::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
return QString(); return QString();
} }
const RoomMemberEvent *roomMemberEvent = room->currentState().get<RoomMemberEvent>(text); const RoomMemberEvent *roomMemberEvent = room->currentState().get<RoomMemberEvent>(text);
if (roomMemberEvent && roomMemberEvent->membership() == Membership::Invite) { if (roomMemberEvent && roomMemberEvent->membership() == Membership::Invite) {
Q_EMIT Controller::instance().showMessage(Controller::Info, Q_EMIT room->showMessage(MessageType::Information,
i18nc("<user> is already invited to this room.", "%1 is already invited to this room.", text)); i18nc("<user> is already invited to this room.", "%1 is already invited to this room.", text));
return QString(); return QString();
} }
if (roomMemberEvent && roomMemberEvent->membership() == Membership::Ban) { if (roomMemberEvent && roomMemberEvent->membership() == Membership::Ban) {
Q_EMIT Controller::instance().showMessage(Controller::Info, i18nc("<user> is banned from this room.", "%1 is banned from this room.", text)); Q_EMIT room->showMessage(MessageType::Information, i18nc("<user> is banned from this room.", "%1 is banned from this room.", text));
return QString(); return QString();
} }
if (room->localMember().id() == text) { if (room->localMember().id() == text) {
Q_EMIT Controller::instance().showMessage(Controller::Positive, i18n("You are already in this room.")); Q_EMIT room->showMessage(MessageType::Positive, i18n("You are already in this room."));
return QString(); return QString();
} }
if (room->joinedMemberIds().contains(text)) { if (room->joinedMemberIds().contains(text)) {
Q_EMIT Controller::instance().showMessage(Controller::Info, i18nc("<user> is already in this room.", "%1 is already in this room.", text)); Q_EMIT room->showMessage(MessageType::Information, i18nc("<user> is already in this room.", "%1 is already in this room.", text));
return QString(); return QString();
} }
room->inviteToRoom(text); room->inviteToRoom(text);
Q_EMIT Controller::instance().showMessage(Controller::Positive, Q_EMIT room->showMessage(MessageType::Positive, i18nc("<username> was invited into this room", "%1 was invited into this room", text));
i18nc("<username> was invited into this room", "%1 was invited into this room", text));
return QString(); return QString();
}, },
false, false,
@@ -231,9 +228,8 @@ QList<ActionsModel::Action> actions{
QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)")); QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"));
auto regexMatch = roomRegex.match(text); auto regexMatch = roomRegex.match(text);
if (!regexMatch.hasMatch()) { if (!regexMatch.hasMatch()) {
Q_EMIT Controller::instance().showMessage( Q_EMIT room->showMessage(MessageType::Error,
Controller::Error, i18nc("'<text>' does not look like a room id or alias.", "'%1' does not look like a room id or alias.", text));
i18nc("'<text>' does not look like a room id or alias.", "'%1' does not look like a room id or alias.", text));
return QString(); return QString();
} }
auto targetRoom = text.startsWith(QLatin1Char('!')) ? room->connection()->room(text) : room->connection()->roomByAlias(text); auto targetRoom = text.startsWith(QLatin1Char('!')) ? room->connection()->room(text) : room->connection()->roomByAlias(text);
@@ -241,7 +237,7 @@ QList<ActionsModel::Action> actions{
RoomManager::instance().resolveResource(targetRoom->id()); RoomManager::instance().resolveResource(targetRoom->id());
return QString(); return QString();
} }
Q_EMIT Controller::instance().showMessage(Controller::Info, i18nc("Joining room <roomname>.", "Joining room %1.", text)); Q_EMIT room->showMessage(MessageType::Information, i18nc("Joining room <roomname>.", "Joining room %1.", text));
RoomManager::instance().resolveResource(text, "join"_ls); RoomManager::instance().resolveResource(text, "join"_ls);
return QString(); return QString();
}, },
@@ -258,9 +254,8 @@ QList<ActionsModel::Action> actions{
QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)")); QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"));
auto regexMatch = roomRegex.match(roomName); auto regexMatch = roomRegex.match(roomName);
if (!regexMatch.hasMatch()) { if (!regexMatch.hasMatch()) {
Q_EMIT Controller::instance().showMessage( Q_EMIT room->showMessage(MessageType::Error,
Controller::Error, i18nc("'<text>' does not look like a room id or alias.", "'%1' does not look like a room id or alias.", text));
i18nc("'<text>' does not look like a room id or alias.", "'%1' does not look like a room id or alias.", text));
return QString(); return QString();
} }
auto targetRoom = text.startsWith(QLatin1Char('!')) ? room->connection()->room(text) : room->connection()->roomByAlias(text); auto targetRoom = text.startsWith(QLatin1Char('!')) ? room->connection()->room(text) : room->connection()->roomByAlias(text);
@@ -268,7 +263,7 @@ QList<ActionsModel::Action> actions{
RoomManager::instance().resolveResource(targetRoom->id()); RoomManager::instance().resolveResource(targetRoom->id());
return QString(); return QString();
} }
Q_EMIT Controller::instance().showMessage(Controller::Info, i18nc("Knocking room <roomname>.", "Knocking room %1.", text)); Q_EMIT room->showMessage(MessageType::Information, i18nc("Knocking room <roomname>.", "Knocking room %1.", text));
auto connection = dynamic_cast<NeoChatConnection *>(room->connection()); auto connection = dynamic_cast<NeoChatConnection *>(room->connection());
const auto knownServer = roomName.mid(roomName.indexOf(":"_ls) + 1); const auto knownServer = roomName.mid(roomName.indexOf(":"_ls) + 1);
if (parts.length() >= 2) { if (parts.length() >= 2) {
@@ -289,16 +284,15 @@ QList<ActionsModel::Action> actions{
QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)")); QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"));
auto regexMatch = roomRegex.match(text); auto regexMatch = roomRegex.match(text);
if (!regexMatch.hasMatch()) { if (!regexMatch.hasMatch()) {
Q_EMIT Controller::instance().showMessage( Q_EMIT room->showMessage(MessageType::Error,
Controller::Error, i18nc("'<text>' does not look like a room id or alias.", "'%1' does not look like a room id or alias.", text));
i18nc("'<text>' does not look like a room id or alias.", "'%1' does not look like a room id or alias.", text));
return QString(); return QString();
} }
if (room->connection()->room(text) || room->connection()->roomByAlias(text)) { if (room->connection()->room(text) || room->connection()->roomByAlias(text)) {
Q_EMIT Controller::instance().showMessage(Controller::Info, i18nc("You are already in room <roomname>.", "You are already in room %1.", text)); Q_EMIT room->showMessage(MessageType::Information, i18nc("You are already in room <roomname>.", "You are already in room %1.", text));
return QString(); return QString();
} }
Q_EMIT Controller::instance().showMessage(Controller::Info, i18nc("Joining room <roomname>.", "Joining room %1.", text)); Q_EMIT room->showMessage(MessageType::Information, i18nc("Joining room <roomname>.", "Joining room %1.", text));
RoomManager::instance().resolveResource(text, "join"_ls); RoomManager::instance().resolveResource(text, "join"_ls);
return QString(); return QString();
}, },
@@ -327,7 +321,7 @@ QList<ActionsModel::Action> actions{
QStringLiteral("nick"), QStringLiteral("nick"),
[](const QString &text, NeoChatRoom *room, ChatBarCache *) { [](const QString &text, NeoChatRoom *room, ChatBarCache *) {
if (text.isEmpty()) { if (text.isEmpty()) {
Q_EMIT Controller::instance().showMessage(Controller::Error, i18n("No new nickname provided, no changes will happen.")); Q_EMIT room->showMessage(MessageType::Error, i18n("No new nickname provided, no changes will happen."));
} else { } else {
room->connection()->user()->rename(text); room->connection()->user()->rename(text);
} }
@@ -361,16 +355,15 @@ QList<ActionsModel::Action> actions{
QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))")); QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"));
auto regexMatch = mxidRegex.match(text); auto regexMatch = mxidRegex.match(text);
if (!regexMatch.hasMatch()) { if (!regexMatch.hasMatch()) {
Q_EMIT Controller::instance().showMessage(Controller::Error, Q_EMIT room->showMessage(MessageType::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
return QString(); return QString();
} }
if (room->connection()->ignoredUsers().contains(text)) { if (room->connection()->ignoredUsers().contains(text)) {
Q_EMIT Controller::instance().showMessage(Controller::Info, i18nc("<username> is already ignored.", "%1 is already ignored.", text)); Q_EMIT room->showMessage(MessageType::Information, i18nc("<username> is already ignored.", "%1 is already ignored.", text));
return QString(); return QString();
} }
room->connection()->addToIgnoredUsers(text); room->connection()->addToIgnoredUsers(text);
Q_EMIT Controller::instance().showMessage(Controller::Positive, i18nc("<username> is now ignored", "%1 is now ignored.", text)); Q_EMIT room->showMessage(MessageType::Positive, i18nc("<username> is now ignored", "%1 is now ignored.", text));
return QString(); return QString();
}, },
@@ -386,16 +379,15 @@ QList<ActionsModel::Action> actions{
QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))")); QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"));
auto regexMatch = mxidRegex.match(text); auto regexMatch = mxidRegex.match(text);
if (!regexMatch.hasMatch()) { if (!regexMatch.hasMatch()) {
Q_EMIT Controller::instance().showMessage(Controller::Error, Q_EMIT room->showMessage(MessageType::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
return QString(); return QString();
} }
if (!room->connection()->ignoredUsers().contains(text)) { if (!room->connection()->ignoredUsers().contains(text)) {
Q_EMIT Controller::instance().showMessage(Controller::Info, i18nc("<username> is not ignored.", "%1 is not ignored.", text)); Q_EMIT room->showMessage(MessageType::Information, i18nc("<username> is not ignored.", "%1 is not ignored.", text));
return QString(); return QString();
} }
room->connection()->removeFromIgnoredUsers(text); room->connection()->removeFromIgnoredUsers(text);
Q_EMIT Controller::instance().showMessage(Controller::Positive, i18nc("<username> is no longer ignored.", "%1 is no longer ignored.", text)); Q_EMIT room->showMessage(MessageType::Positive, i18nc("<username> is no longer ignored.", "%1 is no longer ignored.", text));
return QString(); return QString();
}, },
false, false,
@@ -431,14 +423,13 @@ QList<ActionsModel::Action> actions{
QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))")); QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"));
auto regexMatch = mxidRegex.match(parts[0]); auto regexMatch = mxidRegex.match(parts[0]);
if (!regexMatch.hasMatch()) { if (!regexMatch.hasMatch()) {
Q_EMIT Controller::instance().showMessage(Controller::Error, Q_EMIT room->showMessage(MessageType::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
return QString(); return QString();
} }
auto state = room->currentState().get<RoomMemberEvent>(parts[0]); auto state = room->currentState().get<RoomMemberEvent>(parts[0]);
if (state && state->membership() == Membership::Ban) { if (state && state->membership() == Membership::Ban) {
Q_EMIT Controller::instance().showMessage(Controller::Info, Q_EMIT room->showMessage(MessageType::Information,
i18nc("<user> is already banned from this room.", "%1 is already banned from this room.", text)); i18nc("<user> is already banned from this room.", "%1 is already banned from this room.", text));
return QString(); return QString();
} }
auto plEvent = room->currentState().get<RoomPowerLevelsEvent>(); auto plEvent = room->currentState().get<RoomPowerLevelsEvent>();
@@ -446,18 +437,17 @@ QList<ActionsModel::Action> actions{
return QString(); return QString();
} }
if (plEvent->ban() > plEvent->powerLevelForUser(room->localMember().id())) { if (plEvent->ban() > plEvent->powerLevelForUser(room->localMember().id())) {
Q_EMIT Controller::instance().showMessage(Controller::Error, i18n("You are not allowed to ban users from this room.")); Q_EMIT room->showMessage(MessageType::Error, i18n("You are not allowed to ban users from this room."));
return QString(); return QString();
} }
if (plEvent->powerLevelForUser(room->localMember().id()) <= plEvent->powerLevelForUser(parts[0])) { if (plEvent->powerLevelForUser(room->localMember().id()) <= plEvent->powerLevelForUser(parts[0])) {
Q_EMIT Controller::instance().showMessage( Q_EMIT room->showMessage(
Controller::Error, MessageType::Error,
i18nc("You are not allowed to ban <username> from this room.", "You are not allowed to ban %1 from this room.", parts[0])); i18nc("You are not allowed to ban <username> from this room.", "You are not allowed to ban %1 from this room.", parts[0]));
return QString(); return QString();
} }
room->ban(parts[0], parts.size() > 1 ? parts.mid(1).join(QLatin1Char(' ')) : QString()); room->ban(parts[0], parts.size() > 1 ? parts.mid(1).join(QLatin1Char(' ')) : QString());
Q_EMIT Controller::instance().showMessage(Controller::Positive, Q_EMIT room->showMessage(MessageType::Positive, i18nc("<username> was banned from this room.", "%1 was banned from this room.", parts[0]));
i18nc("<username> was banned from this room.", "%1 was banned from this room.", parts[0]));
return QString(); return QString();
}, },
false, false,
@@ -472,8 +462,7 @@ QList<ActionsModel::Action> actions{
QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))")); QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"));
auto regexMatch = mxidRegex.match(text); auto regexMatch = mxidRegex.match(text);
if (!regexMatch.hasMatch()) { if (!regexMatch.hasMatch()) {
Q_EMIT Controller::instance().showMessage(Controller::Error, Q_EMIT room->showMessage(MessageType::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
return QString(); return QString();
} }
auto plEvent = room->currentState().get<RoomPowerLevelsEvent>(); auto plEvent = room->currentState().get<RoomPowerLevelsEvent>();
@@ -481,18 +470,16 @@ QList<ActionsModel::Action> actions{
return QString(); return QString();
} }
if (plEvent->ban() > plEvent->powerLevelForUser(room->localMember().id())) { if (plEvent->ban() > plEvent->powerLevelForUser(room->localMember().id())) {
Q_EMIT Controller::instance().showMessage(Controller::Error, i18n("You are not allowed to unban users from this room.")); Q_EMIT room->showMessage(MessageType::Error, i18n("You are not allowed to unban users from this room."));
return QString(); return QString();
} }
auto state = room->currentState().get<RoomMemberEvent>(text); auto state = room->currentState().get<RoomMemberEvent>(text);
if (state && state->membership() != Membership::Ban) { if (state && state->membership() != Membership::Ban) {
Q_EMIT Controller::instance().showMessage(Controller::Info, Q_EMIT room->showMessage(MessageType::Information, i18nc("<user> is not banned from this room.", "%1 is not banned from this room.", text));
i18nc("<user> is not banned from this room.", "%1 is not banned from this room.", text));
return QString(); return QString();
} }
room->unban(text); room->unban(text);
Q_EMIT Controller::instance().showMessage(Controller::Positive, Q_EMIT room->showMessage(MessageType::Positive, i18nc("<username> was unbanned from this room.", "%1 was unbanned from this room.", text));
i18nc("<username> was unbanned from this room.", "%1 was unbanned from this room.", text));
return QString(); return QString();
}, },
@@ -509,16 +496,16 @@ QList<ActionsModel::Action> actions{
QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))")); QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"));
auto regexMatch = mxidRegex.match(parts[0]); auto regexMatch = mxidRegex.match(parts[0]);
if (!regexMatch.hasMatch()) { if (!regexMatch.hasMatch()) {
Q_EMIT Controller::instance().showMessage(Controller::Error, Q_EMIT room->showMessage(MessageType::Error,
i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", parts[0])); i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", parts[0]));
return QString(); return QString();
} }
if (parts[0] == room->localMember().id()) { if (parts[0] == room->localMember().id()) {
Q_EMIT Controller::instance().showMessage(Controller::Error, i18n("You cannot kick yourself from the room.")); Q_EMIT room->showMessage(MessageType::Error, i18n("You cannot kick yourself from the room."));
return QString(); return QString();
} }
if (!room->isMember(parts[0])) { if (!room->isMember(parts[0])) {
Q_EMIT Controller::instance().showMessage(Controller::Error, i18nc("<username> is not in this room", "%1 is not in this room.", parts[0])); Q_EMIT room->showMessage(MessageType::Error, i18nc("<username> is not in this room", "%1 is not in this room.", parts[0]));
return QString(); return QString();
} }
auto plEvent = room->currentState().get<RoomPowerLevelsEvent>(); auto plEvent = room->currentState().get<RoomPowerLevelsEvent>();
@@ -527,18 +514,17 @@ QList<ActionsModel::Action> actions{
} }
auto kick = plEvent->kick(); auto kick = plEvent->kick();
if (plEvent->powerLevelForUser(room->localMember().id()) < kick) { if (plEvent->powerLevelForUser(room->localMember().id()) < kick) {
Q_EMIT Controller::instance().showMessage(Controller::Error, i18n("You are not allowed to kick users from this room.")); Q_EMIT room->showMessage(MessageType::Error, i18n("You are not allowed to kick users from this room."));
return QString(); return QString();
} }
if (plEvent->powerLevelForUser(room->localMember().id()) <= plEvent->powerLevelForUser(parts[0])) { if (plEvent->powerLevelForUser(room->localMember().id()) <= plEvent->powerLevelForUser(parts[0])) {
Q_EMIT Controller::instance().showMessage( Q_EMIT room->showMessage(
Controller::Error, MessageType::Error,
i18nc("You are not allowed to kick <username> from this room", "You are not allowed to kick %1 from this room.", parts[0])); i18nc("You are not allowed to kick <username> from this room", "You are not allowed to kick %1 from this room.", parts[0]));
return QString(); return QString();
} }
room->kickMember(parts[0], parts.size() > 1 ? parts.mid(1).join(QLatin1Char(' ')) : QString()); room->kickMember(parts[0], parts.size() > 1 ? parts.mid(1).join(QLatin1Char(' ')) : QString());
Q_EMIT Controller::instance().showMessage(Controller::Positive, Q_EMIT room->showMessage(MessageType::Positive, i18nc("<username> was kicked from this room.", "%1 was kicked from this room.", parts[0]));
i18nc("<username> was kicked from this room.", "%1 was kicked from this room.", parts[0]));
return QString(); return QString();
}, },
false, false,

View File

@@ -83,7 +83,8 @@ void NeoChatConnection::connectSignals()
}); });
connect(this, &NeoChatConnection::requestFailed, this, [](BaseJob *job) { connect(this, &NeoChatConnection::requestFailed, this, [](BaseJob *job) {
if (dynamic_cast<DownloadFileJob *>(job) && job->jsonData()["errcode"_ls].toString() == "M_TOO_LARGE"_ls) { if (dynamic_cast<DownloadFileJob *>(job) && job->jsonData()["errcode"_ls].toString() == "M_TOO_LARGE"_ls) {
RoomManager::instance().warning(i18n("File too large to download."), i18n("Contact your matrix server administrator for support.")); RoomManager::instance().showMessage(MessageType::Warning,
i18n("File too large to download.<br />Contact your matrix server administrator for support."));
} }
}); });
connect(this, &NeoChatConnection::directChatsListChanged, this, [this](DirectChatsMap additions, DirectChatsMap removals) { connect(this, &NeoChatConnection::directChatsListChanged, this, [this](DirectChatsMap additions, DirectChatsMap removals) {

View File

@@ -36,7 +36,6 @@
#include "chatbarcache.h" #include "chatbarcache.h"
#include "clipboard.h" #include "clipboard.h"
#include "controller.h"
#include "eventhandler.h" #include "eventhandler.h"
#include "events/joinrulesevent.h" #include "events/joinrulesevent.h"
#include "events/pollevent.h" #include "events/pollevent.h"
@@ -1450,9 +1449,9 @@ void NeoChatRoom::updatePushNotificationState(QString type)
void NeoChatRoom::reportEvent(const QString &eventId, const QString &reason) void NeoChatRoom::reportEvent(const QString &eventId, const QString &reason)
{ {
auto job = connection()->callApi<ReportContentJob>(id(), eventId, -50, reason); auto job = connection()->callApi<ReportContentJob>(id(), eventId, -50, reason);
connect(job, &BaseJob::finished, this, [job]() { connect(job, &BaseJob::finished, this, [this, job]() {
if (job->error() == BaseJob::Success) { if (job->error() == BaseJob::Success) {
Q_EMIT Controller::instance().showMessage(Controller::Positive, i18n("Report sent successfully.")); Q_EMIT showMessage(MessageType::Positive, i18n("Report sent successfully."));
} }
}); });
} }

View File

@@ -12,6 +12,7 @@
#include <QCoroTask> #include <QCoroTask>
#include <Quotient/roommember.h> #include <Quotient/roommember.h>
#include "enums/messagetype.h"
#include "enums/pushrule.h" #include "enums/pushrule.h"
#include "neochatroommember.h" #include "neochatroommember.h"
#include "pollhandler.h" #include "pollhandler.h"
@@ -658,6 +659,11 @@ Q_SIGNALS:
void extraEventLoaded(const QString &eventId); void extraEventLoaded(const QString &eventId);
void extraEventNotFound(const QString &eventId); void extraEventNotFound(const QString &eventId);
/**
* @brief Request a message be shown to the user of the given type.
*/
void showMessage(MessageType::Type messageType, const QString &message);
public Q_SLOTS: public Q_SLOTS:
/** /**
* @brief Upload a file to the matrix server and post the file to the room. * @brief Upload a file to the matrix server and post the file to the room.

View File

@@ -199,10 +199,6 @@ Kirigami.Page {
} }
} }
function onWarning(title, message) {
root.warning(title, message);
}
function onGoToEvent(eventId) { function onGoToEvent(eventId) {
(timelineViewLoader.item as TimelineView).goToEvent(eventId); (timelineViewLoader.item as TimelineView).goToEvent(eventId);
} }
@@ -241,22 +237,13 @@ Kirigami.Page {
} }
Connections { Connections {
target: Controller target: RoomManager
function onShowMessage(messageType, message) { function onShowMessage(messageType, message) {
banner.text = message; banner.text = message;
banner.type = messageType === ActionsHandler.Error ? Kirigami.MessageType.Error : messageType === ActionsHandler.Positive ? Kirigami.MessageType.Positive : Kirigami.MessageType.Information; banner.type = messageType;
banner.visible = true; banner.visible = true;
} }
}
function warning(title, message) {
banner.text = `${title}<br />${message}`;
banner.type = Kirigami.MessageType.Warning;
banner.visible = true;
}
Connections {
target: RoomManager
function onShowEventSource(eventId) { function onShowEventSource(eventId) {
applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), { applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), {

View File

@@ -134,7 +134,7 @@ void RoomManager::resolveResource(const QString &idOrUri, const QString &action)
{ {
Uri uri{idOrUri}; Uri uri{idOrUri};
if (!uri.isValid()) { if (!uri.isValid()) {
Q_EMIT warning(i18n("Malformed or empty Matrix id"), i18n("%1 is not a correct Matrix identifier", idOrUri)); Q_EMIT showMessage(MessageType::Warning, i18n("Malformed or empty Matrix id<br />%1 is not a correct Matrix identifier", idOrUri));
return; return;
} }
@@ -351,7 +351,7 @@ void RoomManager::joinRoom(Quotient::Connection *account, const QString &roomAli
}, },
Qt::SingleShotConnection); Qt::SingleShotConnection);
} else { } else {
Q_EMIT warning(i18n("Failed to join room"), finish->errorString()); Q_EMIT showMessage(MessageType::Warning, i18n("Failed to join room<br />%1", finish->errorString()));
} }
}, },
Qt::SingleShotConnection); Qt::SingleShotConnection);
@@ -386,12 +386,12 @@ void RoomManager::knockRoom(NeoChatConnection *account, const QString &roomAlias
account, account,
&NeoChatConnection::newRoom, &NeoChatConnection::newRoom,
this, this,
[](Quotient::Room *room) { [this](Quotient::Room *room) {
Q_EMIT Controller::instance().showMessage(Controller::Info, i18n("You requested to join '%1'", room -> name())); Q_EMIT showMessage(MessageType::Information, i18n("You requested to join '%1'", room->name()));
}, },
Qt::SingleShotConnection); Qt::SingleShotConnection);
} else { } else {
Q_EMIT warning(i18n("Failed to request joining room"), job->errorString()); Q_EMIT showMessage(MessageType::Warning, i18n("Failed to request joining room<br />%1", job->errorString()));
} }
}, },
Qt::SingleShotConnection); Qt::SingleShotConnection);
@@ -466,11 +466,20 @@ void RoomManager::setCurrentSpace(const QString &spaceId, bool setRoom)
void RoomManager::setCurrentRoom(const QString &roomId) void RoomManager::setCurrentRoom(const QString &roomId)
{ {
if (m_currentRoom != nullptr) {
m_currentRoom->disconnect(this);
}
if (roomId.isEmpty()) { if (roomId.isEmpty()) {
m_currentRoom = nullptr; m_currentRoom = nullptr;
} else { } else {
m_currentRoom = dynamic_cast<NeoChatRoom *>(m_connection->room(roomId)); m_currentRoom = dynamic_cast<NeoChatRoom *>(m_connection->room(roomId));
} }
if (m_currentRoom != nullptr) {
connect(m_currentRoom, &NeoChatRoom::showMessage, this, &RoomManager::showMessage);
}
Q_EMIT currentRoomChanged(); Q_EMIT currentRoomChanged();
if (m_connection) { if (m_connection) {
m_lastRoomConfig.writeEntry(m_connection->userId(), roomId); m_lastRoomConfig.writeEntry(m_connection->userId(), roomId);

View File

@@ -13,6 +13,7 @@
#include "chatdocumenthandler.h" #include "chatdocumenthandler.h"
#include "enums/messagecomponenttype.h" #include "enums/messagecomponenttype.h"
#include "enums/messagetype.h"
#include "models/mediamessagefiltermodel.h" #include "models/mediamessagefiltermodel.h"
#include "models/messagefiltermodel.h" #include "models/messagefiltermodel.h"
#include "models/roomlistmodel.h" #include "models/roomlistmodel.h"
@@ -328,9 +329,9 @@ Q_SIGNALS:
void askDirectChatConfirmation(const Quotient::User *user); void askDirectChatConfirmation(const Quotient::User *user);
/** /**
* @brief Displays warning to the user. * @brief Request a message be shown to the user of the given type.
*/ */
void warning(const QString &title, const QString &message); void showMessage(MessageType::Type messageType, const QString &message);
void chatDocumentHandlerChanged(); void chatDocumentHandlerChanged();