diff --git a/src/models/messageeventmodel.cpp b/src/models/messageeventmodel.cpp index d2ee909fc..548f8d53f 100644 --- a/src/models/messageeventmodel.cpp +++ b/src/models/messageeventmodel.cpp @@ -979,87 +979,6 @@ int MessageEventModel::eventIdToRow(const QString &eventID) const return it - m_currentRoom->messageEvents().rbegin() + timelineBaseIndex(); } -QVariant MessageEventModel::getLastLocalUserMessageEventId() -{ - QVariantMap targetMessage; - const auto &timelineBottom = m_currentRoom->messageEvents().rbegin(); - - // set a cap limit of 35 messages, to prevent loading a lot of messages - // in rooms where the user has not sent many messages - const auto limit = timelineBottom + std::min(35, m_currentRoom->timelineSize()); - - for (auto it = timelineBottom; it != limit; ++it) { - auto evt = it->event(); - auto e = eventCast(evt); - if (!e) { - return {}; - } - - // check if the current message's sender's id is same as the user's id - if ((*it)->senderId() == m_currentRoom->localUser()->id()) { - auto content = (*it)->contentJson(); - - if (e->msgtype() != MessageEventType::Unknown) { - QString eventId; - if (content.contains("m.new_content")) { - // The message has been edited so we have to return the id of the original message instead of the replacement - eventId = content["m.relates_to"].toObject()["event_id"].toString(); - } else { - // For any message that isn't an edit return the id of the current message - eventId = (*it)->id(); - } - targetMessage.insert("event_id", eventId); - targetMessage.insert("formattedBody", content["formatted_body"].toString()); - // Need to get the message from the original eventId or body will have * on the front - QModelIndex idx = index(eventIdToRow(eventId), 0); - targetMessage.insert("message", idx.data(Qt::UserRole + 2)); - - return targetMessage; - } - } - } - return targetMessage; -} - -QVariant MessageEventModel::getLatestMessageFromRow(const int startRow) -{ - QVariantMap replyResponse; - const auto &timelineBottom = m_currentRoom->messageEvents().rbegin() + startRow; - - // set a cap limit of startRow + 35 messages, to prevent loading a lot of messages - // in rooms where the user has not sent many messages - const auto limit = timelineBottom + std::min(startRow + 35, m_currentRoom->timelineSize()); - - for (auto it = timelineBottom; it != limit; ++it) { - auto evt = it->event(); - auto e = eventCast(evt); - if (!e) { - continue; - } - - auto content = (*it)->contentJson(); - - if (e->msgtype() != MessageEventType::Unknown) { - QString eventId; - if (content.contains("m.new_content")) { - // The message has been edited so we have to return the id of the original message instead of the replacement - eventId = content["m.relates_to"].toObject()["event_id"].toString(); - } else { - // For any message that isn't an edit return the id of the current message - eventId = (*it)->id(); - } - replyResponse.insert("event_id", eventId); - // Need to get the message from the original eventId or body will have * on the front - QModelIndex idx = index(eventIdToRow(eventId), 0); - replyResponse.insert("message", idx.data(Qt::UserRole + 2)); - replyResponse.insert("sender_id", QVariant::fromValue(m_currentRoom->getUser((*it)->senderId()))); - replyResponse.insert("at", -it->index()); - return replyResponse; - } - } - return replyResponse; -} - void MessageEventModel::loadReply(const QModelIndex &index) { auto job = m_currentRoom->connection()->callApi(m_currentRoom->id(), data(index, ReplyIdRole).toString()); diff --git a/src/models/messageeventmodel.h b/src/models/messageeventmodel.h index c83386c66..93091f0a6 100644 --- a/src/models/messageeventmodel.h +++ b/src/models/messageeventmodel.h @@ -142,31 +142,6 @@ public: */ Q_INVOKABLE [[nodiscard]] int eventIdToRow(const QString &eventID) const; - /** - * @brief Get the last message sent by the local user. - * - * @note This checks a maximum of the previous 35 message for performance reasons. - * - * @return a QVariantMap for the event with the following parameters: - * - eventId - The event ID. - * - formattedBody - The message text formatted as Qt::RichText. - * - message - The message text formatted as Qt::PlainText. - */ - Q_INVOKABLE [[nodiscard]] QVariant getLastLocalUserMessageEventId(); - - /** - * @brief Get the last message sent earlier than the given row. - * - * @note This checks a maximum of the previous 35 message for performance reasons. - * - * @return a QVariantMap for the event with the following parameters: - * - eventId - The event ID. - * - message - The message text formatted as Qt::PlainText. - * - sender_id - The matrix ID of the sender. - * - at - The QModelIndex of the message. - */ - Q_INVOKABLE [[nodiscard]] QVariant getLatestMessageFromRow(const int startRow); - /** * @brief Load the event that the item at the given index replied to. * diff --git a/src/neochatroom.cpp b/src/neochatroom.cpp index 1d380eafe..e974ccea9 100644 --- a/src/neochatroom.cpp +++ b/src/neochatroom.cpp @@ -1831,6 +1831,73 @@ void NeoChatRoom::setSavedText(const QString &savedText) m_savedText = savedText; } +void NeoChatRoom::replyLastMessage() +{ + const auto &timelineBottom = messageEvents().rbegin(); + + // set a cap limit of startRow + 35 messages, to prevent loading a lot of messages + // in rooms where the user has not sent many messages + const auto limit = timelineBottom + std::min(35, timelineSize()); + + for (auto it = timelineBottom; it != limit; ++it) { + auto evt = it->event(); + auto e = eventCast(evt); + if (!e) { + continue; + } + + auto content = (*it)->contentJson(); + + if (e->msgtype() != MessageEventType::Unknown) { + QString eventId; + if (content.contains("m.new_content")) { + // The message has been edited so we have to return the id of the original message instead of the replacement + eventId = content["m.relates_to"].toObject()["event_id"].toString(); + } else { + // For any message that isn't an edit return the id of the current message + eventId = (*it)->id(); + } + setChatBoxReplyId(eventId); + return; + } + } +} + +void NeoChatRoom::editLastMessage() +{ + const auto &timelineBottom = messageEvents().rbegin(); + + // set a cap limit of 35 messages, to prevent loading a lot of messages + // in rooms where the user has not sent many messages + const auto limit = timelineBottom + std::min(35, timelineSize()); + + for (auto it = timelineBottom; it != limit; ++it) { + auto evt = it->event(); + auto e = eventCast(evt); + if (!e) { + continue; + } + + // check if the current message's sender's id is same as the user's id + if ((*it)->senderId() == localUser()->id()) { + auto content = (*it)->contentJson(); + + if (e->msgtype() != MessageEventType::Unknown) { + QString eventId; + if (content.contains("m.new_content")) { + // The message has been edited so we have to return the id of the original message instead of the replacement + eventId = content["m.relates_to"].toObject()["event_id"].toString(); + } else { + // For any message that isn't an edit return the id of the current message + eventId = (*it)->id(); + } + setChatBoxEditId(eventId); + return; + } + } + } +} + bool NeoChatRoom::canEncryptRoom() const { #ifdef QUOTIENT_07 diff --git a/src/neochatroom.h b/src/neochatroom.h index 3b5fdb190..3bcca737e 100644 --- a/src/neochatroom.h +++ b/src/neochatroom.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include @@ -735,6 +736,20 @@ public: */ void setSavedText(const QString &savedText); + /** + * @brief Reply to the last message sent in the timeline. + * + * @note This checks a maximum of the previous 35 message for performance reasons. + */ + Q_INVOKABLE void replyLastMessage(); + + /** + * @brief Edit the last message sent by the local user. + * + * @note This checks a maximum of the previous 35 message for performance reasons. + */ + Q_INVOKABLE void editLastMessage(); + #ifdef QUOTIENT_07 /** * @brief Get a PollHandler object for the given event Id. diff --git a/src/qml/Component/ChatBox/ChatBar.qml b/src/qml/Component/ChatBox/ChatBar.qml index 0f6b28aed..d30aa3be8 100644 --- a/src/qml/Component/ChatBox/ChatBar.qml +++ b/src/qml/Component/ChatBox/ChatBar.qml @@ -203,15 +203,9 @@ QQC2.Control { if (event.key === Qt.Key_V && event.modifiers & Qt.ControlModifier) { chatBar.pasteImage(); } else if (event.key === Qt.Key_Up && event.modifiers & Qt.ControlModifier) { - let replyEvent = messageEventModel.getLatestMessageFromRow(0) - if (replyEvent && replyEvent["event_id"]) { - currentRoom.chatBoxReplyId = replyEvent["event_id"] - } + currentRoom.replyLastMessage(); } else if (event.key === Qt.Key_Up && textField.text.length === 0) { - let editEvent = messageEventModel.getLastLocalUserMessageEventId() - if (editEvent) { - currentRoom.chatBoxEditId = editEvent["event_id"] - } + currentRoom.editLastMessage(); } else if (event.key === Qt.Key_Up && completionMenu.visible) { completionMenu.decrementIndex() } else if (event.key === Qt.Key_Down && completionMenu.visible) {