// 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("Server 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, const QVariantMap usernames) { QString rawText = text; QString cleanedText = text; for (const auto username : usernames.keys()) { const auto replacement = usernames.value(username); cleanedText = cleanedText.replace(username, "[" + username + "](https://matrix.to/#/" + replacement.toString() + ")"); } 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; } if (splittedText.count() > 1) { joinRoom(splittedText[0] + ":" + splittedText[1]); return; } else { joinRoom(splittedText[0] + ":matrix.org"); } 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); }