diff --git a/imports/NeoChat/Component/ChatTextInput.qml b/imports/NeoChat/Component/ChatTextInput.qml index 312027409..658c60f48 100644 --- a/imports/NeoChat/Component/ChatTextInput.qml +++ b/imports/NeoChat/Component/ChatTextInput.qml @@ -326,7 +326,6 @@ ToolBar { room: currentRoom ?? null } - property int lineHeight: contentHeight / lineCount wrapMode: Text.Wrap @@ -470,12 +469,8 @@ ToolBar { } function postMessage() { - // Qt wraps lines so we need to use a small hack - // to remove the wrapped lines but not break the empty - // lines. - const updatedText = inputField.text.trim() - .replace(/@([^: ]*):([^ ]*\.[^ ]*)/, "[@$1:$2](https://matrix.to/#/@$1:$2)"); - documentHandler.postMessage(updatedText, attachmentPath, replyEventID, editEventId); + roomManager.actionsHandler.postMessage(inputField.text.trim(), attachmentPath, + replyEventID, editEventId); clearAttachment(); currentRoom.markAllMessagesAsRead(); clear(); diff --git a/imports/NeoChat/Dialog/CreateRoomDialog.qml b/imports/NeoChat/Dialog/CreateRoomDialog.qml index ff9b0c6a6..ad0015f6d 100644 --- a/imports/NeoChat/Dialog/CreateRoomDialog.qml +++ b/imports/NeoChat/Dialog/CreateRoomDialog.qml @@ -36,11 +36,11 @@ Kirigami.OverlaySheet { Button { id: okButton + text: i18nc("@action:button", "Ok") onClicked: { - Controller.createRoom(Controller.activeConnection, roomNameField.text, roomTopicField.text) + roomManager.actionsHandler.createRoom(roomNameField.text, roomTopicField.text); root.close(); - // TODO investigate how to join the new room automatically root.destroy(); } } diff --git a/imports/NeoChat/Page/JoinRoomPage.qml b/imports/NeoChat/Page/JoinRoomPage.qml index 484174f51..4b32ea323 100644 --- a/imports/NeoChat/Page/JoinRoomPage.qml +++ b/imports/NeoChat/Page/JoinRoomPage.qml @@ -22,8 +22,6 @@ Kirigami.ScrollablePage { property alias keyword: identifierField.text property string server - signal joinRoom(string room) - title: i18n("Explore Rooms") header: Control { @@ -51,9 +49,9 @@ Kirigami.ScrollablePage { onClicked: { if (!identifierField.isJoined) { - Controller.joinRoom(connection, identifierField.text); + roomManager.actionsHandler.joinRoom(identifierField.text); + // When joining the room, the room will be opened } - roomManager.enterRoom(connection.room(identifierField.room)); applicationWindow().pageStack.layers.pop(); } } @@ -104,12 +102,12 @@ Kirigami.ScrollablePage { width: publicRoomsListView.width onClicked: { if (!isJoined) { - Controller.joinRoom(connection, roomID) + roomManager.actionsHandler.joinRoom(connection, roomID) justJoined = true; } else { roomManager.enterRoom(connection.room(roomID)) - applicationWindow().pageStack.layers.pop(); } + applicationWindow().pageStack.layers.pop(); } contentItem: RowLayout { Kirigami.Avatar { diff --git a/imports/NeoChat/Page/RoomListPage.qml b/imports/NeoChat/Page/RoomListPage.qml index c13c53df4..e952653bf 100644 --- a/imports/NeoChat/Page/RoomListPage.qml +++ b/imports/NeoChat/Page/RoomListPage.qml @@ -22,9 +22,6 @@ Kirigami.ScrollablePage { property var enteredRoom required property var activeConnection - signal enterRoom(var room) - signal leaveRoom(var room) - function goToNextRoom() { do { listView.incrementCurrentIndex(); diff --git a/imports/NeoChat/Page/RoomPage.qml b/imports/NeoChat/Page/RoomPage.qml index 4df6a177a..8261706a9 100644 --- a/imports/NeoChat/Page/RoomPage.qml +++ b/imports/NeoChat/Page/RoomPage.qml @@ -28,7 +28,27 @@ Kirigami.ScrollablePage { signal switchRoomUp() signal switchRoomDown() - title: currentRoom.name + Connections { + target: roomManager.actionsHandler + onShowMessage: { + page.header.contentItem.text = message; + page.header.contentItem.type = messageType === ActionsHandler.Error ? Kirigami.MessageType.Error : Kirigami.MessageType.Information; + page.header.contentItem.visible = true; + } + + onHideMessage: page.header.contentItem.visible = false + } + + header: QQC2.Control { + visible: contentItem.visible + padding: Kirigami.Units.smallSpacing + contentItem: Kirigami.InlineMessage { + showCloseButton: true + visible: false + } + } + + title: currentRoom.displayName titleDelegate: Component { RowLayout { visible: !Kirigami.Settings.isMobile diff --git a/imports/NeoChat/Page/StartChatPage.qml b/imports/NeoChat/Page/StartChatPage.qml index f97340c92..35a597fcc 100644 --- a/imports/NeoChat/Page/StartChatPage.qml +++ b/imports/NeoChat/Page/StartChatPage.qml @@ -42,7 +42,10 @@ Kirigami.ScrollablePage { text: i18n("Chat") highlighted: true - onClicked: Controller.createDirectChat(connection, identifierField.text) + onClicked: { + connection.requestDirectChat(identifierField.text); + applicationWindow().pageStack.layers.pop(); + } } } } @@ -103,23 +106,27 @@ Kirigami.ScrollablePage { } Button { + id: joinChatButton Layout.alignment: Qt.AlignRight - visible: directChats != null + visible: directChats && directChats.length > 0 icon.name: "document-send" onClicked: { - roomListForm.joinRoom(connection.room(directChats[0])) - root.close() + connection.requestDirectChat(userID); + applicationWindow().pageStack.layers.pop(); } } Button { Layout.alignment: Qt.AlignRight icon.name: "irc-join-channel" + // We wants to make sure an user can't start more than one + // chat with someone. + visible: !joinChatButton.visible onClicked: { - Controller.createDirectChat(connection, userID) - root.close() + connection.requestDirectChat(userID); + applicationWindow().pageStack.layers.pop(); } } } diff --git a/qml/main.qml b/qml/main.qml index dbafa5dc1..90fdb0db7 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -54,10 +54,19 @@ Kirigami.ApplicationWindow { /** * Manage opening and close rooms + * TODO this should probably be moved to C++ */ QtObject { id: roomManager + property var actionsHandler: ActionsHandler { + room: roomManager.currentRoom + connection: Controller.activeConnection + onRoomJoined: { + roomManager.enterRoom(Controller.activeConnection.room(roomName)) + } + } + property var currentRoom: null property alias pageStack: root.pageStack property bool invitationOpen: false @@ -262,6 +271,11 @@ Kirigami.ApplicationWindow { } } + function onRoomJoined(roomId) { + const room = Controller.activeConnection.room(roomId); + return roomManager.enterRoom(room); + } + function onConnectionDropped() { if (Controller.accountCount === 0) { pageStack.clear(); @@ -287,6 +301,13 @@ Kirigami.ApplicationWindow { } } + Connections { + target: Controller.activeConnection + onDirectChatAvailable: { + roomManager.enterRoom(Controller.activeConnection.room(directChat.id)); + } + } + Kirigami.OverlaySheet { id: consentSheet diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ebdec3a11..0672282a8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ add_executable(neochat accountlistmodel.cpp controller.cpp + actionshandler.cpp emojimodel.cpp clipboard.cpp matriximageprovider.cpp diff --git a/src/actionshandler.cpp b/src/actionshandler.cpp new file mode 100644 index 000000000..13a824d0c --- /dev/null +++ b/src/actionshandler.cpp @@ -0,0 +1,325 @@ +// SPDX-FileCopyrightText: 2020 Carl Schwan +// +// SPDX-License-Identifier: GPl-3.0-or-later + +#include "actionshandler.h" + +#include "csapi/joining.h" + +#include +#include +#include + +ActionsHandler::ActionsHandler(QObject *parent) + : QObject(parent) +{ +} + +ActionsHandler::~ActionsHandler() +{}; + +NeoChatRoom *ActionsHandler::room() const +{ + return m_room; +} + +void ActionsHandler::setRoom(NeoChatRoom *room) +{ + if (m_room == room) { + return; + } + + m_room = room; + Q_EMIT roomChanged(); +} + +Connection *ActionsHandler::connection() const +{ + return m_connection; +} + +void ActionsHandler::setConnection(Connection *connection) +{ + if (m_connection == connection) { + return; + } + if (m_connection != nullptr) { + disconnect(m_connection, &Connection::directChatAvailable, nullptr, nullptr); + } + m_connection = connection; + if (m_connection != nullptr) { + connect(m_connection, &Connection::directChatAvailable, + this, [this](Quotient::Room *room) { + room->setDisplayed(true); + Q_EMIT roomJoined(room->id()); + }); + } + Q_EMIT connectionChanged(); +} + +QVariantList ActionsHandler::commands() const +{ + QVariantList commands; + // Messages commands + commands.append({ + QStringLiteral("prefix"), QStringLiteral("/shrug "), + QStringLiteral("parameter"), i18nc("@label Parameter of a command", ""), + QStringLiteral("help"), i18n("Prepends ¯\\_(ツ)_/¯ to a plain-text message") + }); + + commands.append({ + QStringLiteral("prefix"), QStringLiteral("/lenny "), + QStringLiteral("parameter"), i18nc("@label Parameter of a command", ""), + QStringLiteral("help"), i18n("Prepends ( ͡° ͜ʖ ͡°) to a plain-text message") + }); + + commands.append({ + QStringLiteral("prefix"), QStringLiteral("/plain "), + QStringLiteral("parameter"), i18nc("@label Parameter of a command", ""), + QStringLiteral("help"), i18n("Sends a message as plain text, without interpreting it as markdown") + }); + + commands.append({ + QStringLiteral("prefix"), QStringLiteral("/html "), + QStringLiteral("parameter"), i18nc("@label Parameter of a command", ""), + QStringLiteral("help"), i18n("Sends a message as html, without interpreting it as markdown") + }); + + commands.append({ + QStringLiteral("prefix"), QStringLiteral("/rainbow "), + QStringLiteral("parameter"), i18nc("@label Parameter of a command", ""), + QStringLiteral("help"), i18n("Sends the given message coloured as a rainbow") + }); + + commands.append({ + QStringLiteral("prefix"), QStringLiteral("/rainbowme "), + QStringLiteral("parameter"), i18nc("@label Parameter of a command", ""), + QStringLiteral("help"), i18n("Sends the given emote coloured as a rainbow") + }); + + commands.append({ + QStringLiteral("prefix"), QStringLiteral("/me "), + QStringLiteral("parameter"), i18nc("@label Parameter of a command", ""), + QStringLiteral("help"), i18n("Displays action") + }); + + // Actions commands + commands.append({ + QStringLiteral("prefix"), QStringLiteral("/join "), + QStringLiteral("parameter"), i18nc("@label Parameter of a command", ""), + QStringLiteral("help"), i18n("Joins room with given address") + }); + + commands.append({ + QStringLiteral("prefix"), QStringLiteral("/part "), + QStringLiteral("parameter"), i18nc("@label Parameter of a command", "[]"), + QStringLiteral("help"), i18n("Leave room") + }); + + commands.append({ + QStringLiteral("prefix"), QStringLiteral("/invite "), + QStringLiteral("parameter"), i18nc("@label Parameter of a command", ""), + QStringLiteral("help"), i18n("Invites user with given id to current room") + }); + + // TODO more see elements /help action + + return commands; +} + +void ActionsHandler::joinRoom(const QString &alias) +{ + if (!alias.contains(":")) { + Q_EMIT showMessage(MessageType::Error, i18n("The room id you are trying to join is not valid")); + return; + } + + const auto knownServer = alias.mid(alias.indexOf(":") + 1); + auto joinRoomJob = m_connection->joinRoom(alias, QStringList{knownServer}); + + Quotient::JoinRoomJob::connect(joinRoomJob, &JoinRoomJob::failure, [=] { + Q_EMIT showMessage(MessageType::Error, i18n("Serveur error when joining the room \"%1\": %2", + joinRoomJob->errorString())); + }); + Quotient::JoinRoomJob::connect(joinRoomJob, &JoinRoomJob::success, [this, joinRoomJob] { + qDebug() << "joined" << joinRoomJob->roomId(); + Q_EMIT roomJoined(joinRoomJob->roomId()); + }); +} + +void ActionsHandler::createRoom(const QString &name, const QString &topic) +{ + auto createRoomJob = m_connection->createRoom(Connection::PublishRoom, "", name, topic, QStringList()); + Quotient::CreateRoomJob::connect(createRoomJob, &CreateRoomJob::failure, [=] { + Q_EMIT showMessage(MessageType::Error, i18n("Room creation failed: \"%1\"", createRoomJob->errorString())); + }); + Quotient::CreateRoomJob::connect(createRoomJob, &CreateRoomJob::success, [=] { + Q_EMIT roomJoined(createRoomJob->roomId()); + }); +} + +void ActionsHandler::postMessage(const QString &text, + const QString &attachementPath, const QString &replyEventId, const QString &editEventId) +{ + QString rawText = text; + QString cleanedText = text; + cleanedText = cleanedText.replace(QRegularExpression("@([^: ]*):([^ ]*\\.[^ ]*)"), + "[@$1:$2](https://matrix.to/#/@$1:$2)"); + + if (attachementPath.length() > 0) { + m_room->uploadFile(attachementPath, cleanedText); + } + + if (cleanedText.length() == 0) { + return; + } + + auto messageEventType = RoomMessageEvent::MsgType::Text; + + // Message commands + static const QString shrugPrefix = QStringLiteral("/shrug "); + static const QString lennyPrefix = QStringLiteral("/lenny "); + static const QString plainPrefix = QStringLiteral("/plain "); // TODO + static const QString htmlPrefix = QStringLiteral("/html "); // TODO + static const QString rainbowPrefix = QStringLiteral("/rainbow "); + static const QString rainbowmePrefix = QStringLiteral("/rainbowme "); + static const QString mePrefix = QStringLiteral("/me "); + static const QString noticePrefix = QStringLiteral("/notice "); + + // Actions commands + static const QString ddgPrefix = QStringLiteral("/ddg "); // TODO + static const QString nickPrefix = QStringLiteral("/nick "); // TODO + static const QString meroomnickPrefix = QStringLiteral("/myroomnick "); // TODO + static const QString roomavatarPrefix = QStringLiteral("/roomavatar "); // TODO + static const QString myroomavatarPrefix = QStringLiteral("/myroomavatar "); // TODO + static const QString myavatarPrefix = QStringLiteral("/myavatar "); // TODO + static const QString invitePrefix = QStringLiteral("/invite "); + static const QString joinPrefix = QStringLiteral("/join "); + static const QString partPrefix = QStringLiteral("/part"); + static const QString ignorePrefix = QStringLiteral("/ignore "); + static const QString unignorePrefix = QStringLiteral("/unignore "); + static const QString queryPrefix = QStringLiteral("/query "); // TODO + static const QString msgPrefix = QStringLiteral("/msg "); // TODO + + // Admin commands + + static QStringList rainbowColors{"#ff2b00", "#ff5500", "#ff8000", "#ffaa00", "#ffd500", + "#ffff00", "#d4ff00", "#aaff00", "#80ff00", "#55ff00", "#2bff00", "#00ff00", "#00ff2b", + "#00ff55", "#00ff80", "#00ffaa", "#00ffd5", "#00ffff", "#00d4ff", "#00aaff", "#007fff", + "#0055ff", "#002bff", "#0000ff", "#2a00ff", "#5500ff", "#7f00ff", "#aa00ff", "#d400ff", + "#ff00ff", "#ff00d4", "#ff00aa", "#ff0080", "#ff0055", "#ff002b", "#ff0000"}; + + if (cleanedText.indexOf(shrugPrefix) == 0) { + cleanedText = QStringLiteral("¯\\\\_(ツ)\\_/¯") % cleanedText.remove(0, shrugPrefix.length()); + m_room->postHtmlMessage(cleanedText, cleanedText, messageEventType, replyEventId, editEventId); + return; + } + + if (cleanedText.indexOf(lennyPrefix) == 0) { + cleanedText = QStringLiteral("( ͡° ͜ʖ ͡°)") % cleanedText.remove(0, lennyPrefix.length()); + m_room->postHtmlMessage(cleanedText, cleanedText, messageEventType, replyEventId, editEventId); + return; + } + + if (cleanedText.indexOf(rainbowPrefix) == 0) { + cleanedText = cleanedText.remove(0, rainbowPrefix.length()); + QString rainbowText; + for (int i = 0; i < cleanedText.length(); i++) { + rainbowText = rainbowText % QStringLiteral("" % cleanedText.at(i) % ""; + } + m_room->postHtmlMessage(cleanedText, rainbowText, RoomMessageEvent::MsgType::Notice, replyEventId, editEventId); + return; + } + + if (cleanedText.indexOf(rainbowmePrefix) == 0) { + cleanedText = cleanedText.remove(0, rainbowmePrefix.length()); + QString rainbowText; + for (int i = 0; i < cleanedText.length(); i++) { + rainbowText = rainbowText % QStringLiteral("" % cleanedText.at(i) % ""; + } + m_room->postHtmlMessage(cleanedText, rainbowText, messageEventType, replyEventId, editEventId); + return; + } + + if (rawText.indexOf(joinPrefix) == 0) { + rawText = rawText.remove(0, joinPrefix.length()); + const QStringList splittedText = rawText.split(" "); + if (text.count() == 0) { + Q_EMIT showMessage(MessageType::Error, i18n("Invalid command")); + return; + } + joinRoom(splittedText[0]); + return; + } + + if (rawText.indexOf(invitePrefix) == 0) { + rawText = rawText.remove(0, invitePrefix.length()); + const QStringList splittedText = rawText.split(" "); + if (splittedText.count() == 0) { + Q_EMIT showMessage(MessageType::Error, i18n("Invalid command")); + return; + } + m_room->inviteToRoom(splittedText[0]); + return; + } + + if (rawText.indexOf(partPrefix) == 0) { + rawText = rawText.remove(0, partPrefix.length()); + const QStringList splittedText = rawText.split(" "); + qDebug() << m_room; + qDebug() << "m_room"; + qDebug() << splittedText; + if (splittedText.count() == 0 || splittedText[0].isEmpty()) { + // leave current room + m_connection->leaveRoom(m_room); + return; + } + m_connection->leaveRoom(m_connection->room(splittedText[0])); + return; + } + + if (rawText.indexOf(ignorePrefix) == 0) { + rawText = rawText.remove(0, ignorePrefix.length()); + const QStringList splittedText = rawText.split(" "); + if (splittedText.count() == 0) { + Q_EMIT showMessage(MessageType::Error, i18n("Invalid command")); + return; + } + + if (m_connection->users().contains(splittedText[0])) { + Q_EMIT showMessage(MessageType::Error, i18n("Invalid command")); + return; + } + + const auto *user = m_connection->users()[splittedText[0]]; + m_connection->addToIgnoredUsers(user); + return; + } + + if (rawText.indexOf(unignorePrefix) == 0) { + rawText = rawText.remove(0, unignorePrefix.length()); + const QStringList splittedText = rawText.split(" "); + if (splittedText.count() == 0) { + Q_EMIT showMessage(MessageType::Error, i18n("Invalid command")); + return; + } + + if (m_connection->users().contains(splittedText[0])) { + Q_EMIT showMessage(MessageType::Error, i18n("Invalid command")); + return; + } + + const auto *user = m_connection->users()[splittedText[0]]; + m_connection->removeFromIgnoredUsers(user); + return; + } + + if (cleanedText.indexOf(mePrefix) == 0) { + cleanedText = cleanedText.remove(0, mePrefix.length()); + messageEventType = RoomMessageEvent::MsgType::Emote; + } else if (cleanedText.indexOf(noticePrefix) == 0) { + cleanedText = cleanedText.remove(0, noticePrefix.length()); + messageEventType = RoomMessageEvent::MsgType::Notice; + } + m_room->postMessage(cleanedText, messageEventType, replyEventId, editEventId); +} diff --git a/src/actionshandler.h b/src/actionshandler.h new file mode 100644 index 000000000..063a0bc2f --- /dev/null +++ b/src/actionshandler.h @@ -0,0 +1,78 @@ +// SPDX-FileCopyrightText: 2020 Carl Schwan +// +// SPDX-License-Identifier: GPl-3.0-or-later + +#include + +#include "connection.h" +#include "neochatroom.h" + +using namespace Quotient; + +/// \brief Handles user interactions with NeoChat (joining room, creating room, +/// sending message). Account management is handled by Controller. +class ActionsHandler : public QObject +{ + Q_OBJECT + + /// \brief List of command definition. Usefull for buiding an autcompletion + /// engine or an help dialog. + Q_PROPERTY(QVariantList commands READ commands CONSTANT) + + /// \brief The connection that will handle sending the message. + Q_PROPERTY(Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged) + + /// \brief The connection that will handle sending the message. + Q_PROPERTY(NeoChatRoom *room READ room WRITE setRoom NOTIFY roomChanged) + +public: + enum MessageType { + Info, + Error, + }; + Q_ENUM(MessageType); + + explicit ActionsHandler(QObject *parent = nullptr); + ~ActionsHandler(); + + QVariantList commands() const; + + [[nodiscard]] Connection *connection() const; + void setConnection(Connection *connection); + + [[nodiscard]] NeoChatRoom *room() const; + void setRoom(NeoChatRoom *room); + +Q_SIGNALS: + /// \brief Show error or information message. + /// + /// These messages will be displayed in the room view header. + void showMessage(MessageType messageType, QString message); + + /// \brief Emmited when an action made the user join a room. + /// + /// Either when a new room was created, a direct chat was started + /// or a group chat was joined. The UI will react to this signal + /// and switch to the newly joined room. + void roomJoined(QString roomName); + + void roomChanged(); + void connectionChanged(); + +public Q_SLOTS: + /// \brief Create new room for a group chat. + void createRoom(const QString &name, const QString &topic); + + /// \brief Join a room. + void joinRoom(const QString &alias); + + /// \brief Post a message. + /// + /// This also interprets commands if any. + void postMessage(const QString &text, const QString &attachementPath, + const QString &replyEventId, const QString &editEventId); + +private: + Connection *m_connection = nullptr; + NeoChatRoom *m_room = nullptr; +}; diff --git a/src/chatdocumenthandler.cpp b/src/chatdocumenthandler.cpp index 74d50c07f..40e496a6e 100644 --- a/src/chatdocumenthandler.cpp +++ b/src/chatdocumenthandler.cpp @@ -167,53 +167,6 @@ QVariantMap ChatDocumentHandler::getAutocompletionInfo() }; } -void ChatDocumentHandler::postMessage(const QString &text, const QString &attachementPath, const QString &replyEventId, const QString &editEventId) const -{ - if (!m_room || !m_document) { - return; - } - - QString cleanedText = text; - - cleanedText = cleanedText.trimmed(); - - if (attachementPath.length() > 0) { - m_room->uploadFile(attachementPath, cleanedText); - } - - if (cleanedText.length() == 0) { - return; - } - - auto messageEventType = RoomMessageEvent::MsgType::Text; - - const QString rainbowPrefix = QStringLiteral("/rainbow "); - const QString mePrefix = QStringLiteral("/me "); - const QString noticePrefix = QStringLiteral("/notice "); - - if (cleanedText.indexOf(rainbowPrefix) == 0) { - cleanedText = cleanedText.remove(0, rainbowPrefix.length()); - QString rainbowText; - QStringList rainbowColors{"#ff2b00", "#ff5500", "#ff8000", "#ffaa00", "#ffd500", "#ffff00", "#d4ff00", "#aaff00", "#80ff00", "#55ff00", "#2bff00", "#00ff00", "#00ff2b", "#00ff55", "#00ff80", "#00ffaa", "#00ffd5", "#00ffff", - "#00d4ff", "#00aaff", "#007fff", "#0055ff", "#002bff", "#0000ff", "#2a00ff", "#5500ff", "#7f00ff", "#aa00ff", "#d400ff", "#ff00ff", "#ff00d4", "#ff00aa", "#ff0080", "#ff0055", "#ff002b", "#ff0000"}; - - for (int i = 0; i < cleanedText.length(); i++) { - rainbowText = rainbowText % QStringLiteral("" % cleanedText.at(i) % ""; - } - m_room->postHtmlMessage(cleanedText, rainbowText, messageEventType, replyEventId, editEventId); - return; - } - - if (cleanedText.indexOf(mePrefix) == 0) { - cleanedText = cleanedText.remove(0, mePrefix.length()); - messageEventType = RoomMessageEvent::MsgType::Emote; - } else if (cleanedText.indexOf(noticePrefix) == 0) { - cleanedText = cleanedText.remove(0, noticePrefix.length()); - messageEventType = RoomMessageEvent::MsgType::Notice; - } - m_room->postMessage(cleanedText, messageEventType, replyEventId, editEventId); -} - void ChatDocumentHandler::replaceAutoComplete(const QString &word) { QTextCursor cursor = textCursor(); diff --git a/src/chatdocumenthandler.h b/src/chatdocumenthandler.h index dcfd2a538..e02aced75 100644 --- a/src/chatdocumenthandler.h +++ b/src/chatdocumenthandler.h @@ -14,6 +14,7 @@ class QTextDocument; class QQuickTextDocument; class NeoChatRoom; +class Controller; class ChatDocumentHandler : public QObject { @@ -51,8 +52,6 @@ public: [[nodiscard]] NeoChatRoom *room() const; void setRoom(NeoChatRoom *room); - Q_INVOKABLE void postMessage(const QString &text, const QString &attachementPath, const QString &replyEventId, const QString &editEventId) const; - /// This function will look at the current QTextCursor and determine if there /// is the posibility to autocomplete it. Q_INVOKABLE QVariantMap getAutocompletionInfo(); @@ -64,6 +63,7 @@ Q_SIGNALS: void selectionStartChanged(); void selectionEndChanged(); void roomChanged(); + void joinRoom(QString roomName); private: [[nodiscard]] QTextCursor textCursor() const; diff --git a/src/controller.cpp b/src/controller.cpp index 9b0321b78..30ef38674 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -12,7 +12,6 @@ #include #include #include - #include #include @@ -23,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -32,11 +30,11 @@ #include #include #include +#include #include #include "csapi/account-data.h" #include "csapi/content-repo.h" -#include "csapi/joining.h" #include "csapi/logout.h" #include "csapi/profile.h" #include "csapi/registration.h" @@ -399,34 +397,6 @@ bool Controller::saveAccessTokenToKeyChain(const AccountSettings &account, const return true; } -void Controller::joinRoom(Connection *c, const QString &alias) -{ - if (!alias.contains(":")) { - return; - } - - auto knownServer = alias.mid(alias.indexOf(":") + 1); - auto joinRoomJob = c->joinRoom(alias, QStringList{knownServer}); - Quotient::JoinRoomJob::connect(joinRoomJob, &JoinRoomJob::failure, [=] { - Q_EMIT errorOccured("Join Room Failed", joinRoomJob->errorString()); - }); -} - -void Controller::createRoom(Connection *c, const QString &name, const QString &topic) -{ - auto createRoomJob = c->createRoom(Connection::PublishRoom, "", name, topic, QStringList()); - Quotient::CreateRoomJob::connect(createRoomJob, &CreateRoomJob::failure, [=] { - Q_EMIT errorOccured("Create Room Failed", createRoomJob->errorString()); - }); -} - -void Controller::createDirectChat(Connection *c, const QString &userID) -{ - auto createRoomJob = c->createDirectChat(userID); - Quotient::CreateRoomJob::connect(createRoomJob, &CreateRoomJob::failure, [=] { - Q_EMIT errorOccured("Create Direct Chat Failed", createRoomJob->errorString()); - }); -} void Controller::playAudio(const QUrl &localFile) { @@ -574,6 +544,7 @@ void Controller::saveWindowGeometry(QQuickWindow *window) dataResource.sync(); } + NeochatDeleteDeviceJob::NeochatDeleteDeviceJob(const QString &deviceId, const Omittable &auth) : Quotient::BaseJob(HttpVerb::Delete, QStringLiteral("DeleteDeviceJob"), QStringLiteral("/_matrix/client/r0/devices/%1").arg(deviceId)) { diff --git a/src/controller.h b/src/controller.h index 25bd56b40..eb965f100 100644 --- a/src/controller.h +++ b/src/controller.h @@ -113,9 +113,6 @@ Q_SIGNALS: public Q_SLOTS: void logout(Quotient::Connection *conn, bool serverSideLogout); - void joinRoom(Quotient::Connection *c, const QString &alias); - void createRoom(Quotient::Connection *c, const QString &name, const QString &topic); - void createDirectChat(Quotient::Connection *c, const QString &userID); static void playAudio(const QUrl &localFile); void changeAvatar(Quotient::Connection *conn, const QUrl &localFile); static void markAllMessagesAsRead(Quotient::Connection *conn); diff --git a/src/main.cpp b/src/main.cpp index a7499e028..c7620e42c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,6 +44,7 @@ #include "sortfilterroomlistmodel.h" #include "userdirectorylistmodel.h" #include "userlistmodel.h" +#include "actionshandler.h" using namespace Quotient; @@ -97,6 +98,7 @@ int main(int argc, char *argv[]) qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "Config", config); qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "FileType", &fileTypeSingleton); qmlRegisterType("org.kde.neochat", 1, 0, "AccountListModel"); + qmlRegisterType("org.kde.neochat", 1, 0, "ActionsHandler"); qmlRegisterType("org.kde.neochat", 1, 0, "ChatDocumentHandler"); qmlRegisterType("org.kde.neochat", 1, 0, "RoomListModel"); qmlRegisterType("org.kde.neochat", 1, 0, "UserListModel");